2 * Copyright (c) 2000-2019 Samsung Electronics Co., Ltd.
4 * Licensed under the Flora License, Version 1.1 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "TADC_Util.h"
20 #include "TADC_ErrorCode.h"
22 #include "drm_intf_tapps.h"
24 #include <openssl/aes.h>
25 #include <openssl/sha.h>
26 #include <openssl/dh.h>
27 #include <openssl/bn.h>
28 #include <openssl/modes.h>
30 //2011.03.08 to verify signature
31 #include <openssl/x509.h>
32 #include <openssl/x509_vfy.h>
33 #include <openssl/evp.h>
34 #include <openssl/rsa.h>
35 #include <openssl/err.h>
36 #include <openssl/pem.h>
43 #include "DUIDGenerator.h"
46 int TADC_IF_GetDUID(char *Duid)
49 DRM_TAPPS_EXCEPTION("Invalid argument.");
50 return TADC_GETDUID_ERROR;
55 if (get_duid(&duid) < 0 || !duid) {
56 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
57 return TADC_GETDUID_ERROR;
60 DRM_TAPPS_LOG("DUID is [%s]", duid);
61 memcpy(Duid, duid, strlen(duid) + 1);
68 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
71 TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
74 DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
77 if ((pDH = DH_new()) == NULL) {
78 DRM_TAPPS_EXCEPTION("DH_new() error!");
83 DRM_TAPPS_LOG("After DH_new");
85 //2. Set the Prime and Generator Value
87 0xAE, 0xD9, 0x65, 0x3C, 0x86, 0x3E, 0xD9, 0x6F, 0x31, 0x6E,
88 0xF6, 0x08, 0x35, 0xD5, 0x01, 0xC1, 0x41, 0x2E, 0xDD, 0x7E,
89 0xE9, 0x09, 0x99, 0x73, 0xF3, 0xB3, 0xAB, 0x1F, 0x80, 0x85,
90 0x44, 0x22, 0xDA, 0x07, 0x32, 0x18, 0xC1, 0xF8, 0xC4, 0xED,
91 0x9F, 0x66, 0x88, 0xCF, 0xD6, 0x18, 0x8B, 0x28, 0x56, 0xA5,
92 0xB3, 0x6A, 0x8E, 0xBB, 0xC4, 0x2B, 0x2B, 0x3A, 0x9C, 0x20,
93 0x4E, 0xF7, 0x7F, 0xC3
95 BYTE generator[1] = {DH_GENERATOR_5};
97 DH_set0_pqg(pDH, BN_bin2bn(prime64, 64, NULL), nullptr,
98 BN_bin2bn(generator, 1, NULL));
100 /* Set a to run with normal modexp and b to use constant time */
101 DH_clear_flags(pDH, DH_FLAG_NO_EXP_CONSTTIME);
104 DRM_TAPPS_LOG("After Set the Prime and Generator Value");
107 if (!DH_generate_key(pDH)) {
108 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
113 DRM_TAPPS_LOG("After DH_generate_key");
115 //4. Save DH Infos ( p, g, A, a )
116 TADC_IF_MemCpy(t_dhinfo->p, prime64, 64);
117 t_dhinfo->pSize = 64;
118 t_dhinfo->g = DH_GENERATOR_5;
119 t_dhinfo->ASize = BN_bn2bin(DH_get0_pub_key(pDH), t_dhinfo->A);
120 t_dhinfo->aSize = BN_bn2bin(DH_get0_priv_key(pDH), t_dhinfo->a);
126 DRM_TAPPS_LOG("After DH_free");
131 int TADC_IF_GetDHKey_K(T_DH_INFO *t_dhinfo)
134 BIGNUM *pPubKey = NULL;
136 char tempbuf[DHKey_SIZE + 1];
139 unsigned char tempG[1];
141 TADC_IF_MemSet(tempbuf, 0, sizeof(tempbuf));
144 if ((pDH = DH_new()) == NULL) {
145 DRM_TAPPS_EXCEPTION("DH_new() error!");
149 //2.Set DH Info to pDH
150 tempG[0] = t_dhinfo->g;
151 DH_set0_pqg(pDH, BN_bin2bn(t_dhinfo->p, t_dhinfo->pSize, NULL), nullptr,
152 BN_bin2bn(tempG, 1, NULL));
153 DH_clear_flags(pDH, DH_FLAG_NO_EXP_CONSTTIME);
154 DH_set0_key(pDH, BN_bin2bn(t_dhinfo->A, t_dhinfo->ASize, NULL),
155 BN_bin2bn(t_dhinfo->a, t_dhinfo->aSize, NULL));
157 //3. Set Public Key of Server
158 pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
160 //4. Compute DH Session Key
161 if ((i = DH_compute_key((BYTE *)tempbuf, pPubKey, pDH)) < 0) {
162 DRM_TAPPS_EXCEPTION("DH_compute_key() error! \n");
166 for (i = 0; i < (t_dhinfo -> BSize / 2); i++) {
167 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
177 /* Only handles 128 bit aes key */
178 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV,
179 int inLen, unsigned char *in, int *pOutLen, unsigned char *out)
186 AES_set_encrypt_key(pKey, 128, &stKey);
190 TADC_IF_MemSet(ecount, 0, sizeof(ecount));
191 TADC_IF_MemSet(chain, 0, sizeof(chain));
192 TADC_IF_MemCpy(chain, pIV, ivLen);
194 CRYPTO_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num, (block128_f)AES_encrypt);
201 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
206 SHA1_Update(&AlgInfo, in, inLen);
207 SHA1_Final(out, &AlgInfo);
212 int TADC_IF_VerifySignature(unsigned char *inData, int inLen,
213 unsigned char *sigData, int sigLen,
214 unsigned char *cert, int certLen)
216 unsigned char hashValue[20];
220 EVP_PKEY *pKey = NULL;
224 if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 ||
225 sigLen < 1 || certLen < 1) {
226 DRM_TAPPS_EXCEPTION("Parameter error!");
232 //1. Make Hash value of indata by using SHA1
233 TADC_IF_SHA1(inData, inLen, hashValue);
235 //2. Get RSA Public Key from cert data ( DER )
236 pX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
239 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
243 pKey = X509_get_pubkey(pX509);
246 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
250 pRsa = EVP_PKEY_get1_RSA(pKey);
253 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
263 iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
267 char tmpBuf[120] = { 0, };
269 while ((err = ERR_get_error()) != 0)
270 DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
284 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
287 X509 *pstX509 = NULL;
289 if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
290 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
294 pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
296 if (pstX509 == NULL) {
297 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
301 sk_X509_push(untrustedCerts, pstX509);
306 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
308 X509 *pstX509 = NULL;
312 file = fopen(filePath, "r");
315 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
320 pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
322 if (pstX509 == NULL) {
323 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
328 X509_STORE_add_cert(pstStore, pstX509);
338 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
343 struct dirent *result = nullptr;
344 char file_path_buff[512];
346 if (pstStore == NULL || dirPath == NULL) {
347 DRM_TAPPS_EXCEPTION("Parameter error!");
352 dir = opendir(dirPath);
355 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
362 result = readdir(dir);
363 if (result == NULL) {
365 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!",
375 if (result->d_type == DT_REG) {
377 memset(file_path_buff, 0, sizeof(file_path_buff));
378 snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
381 if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
382 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
384 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
397 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
398 unsigned char *cert, int certLen)
400 X509_STORE *pstStore = X509_STORE_new();
402 if (pstStore == NULL)
405 std::unique_ptr<X509_STORE, void(*)(X509_STORE *)>
406 _scoped_x509_store(pstStore, X509_STORE_free);
408 STACK_OF(X509) *untrustedCerts = sk_X509_new_null();
410 if (untrustedCerts == NULL)
413 std::unique_ptr<STACK_OF(X509), std::function<void(STACK_OF(X509) *)>>
414 _scoped_x509_stack(untrustedCerts, [](STACK_OF(X509) *s) {
418 //Add RICA Cert to certchain
419 if (AddCertUntrustedCerts(untrustedCerts, rica, ricaLen) != 0) {
420 DRM_TAPPS_EXCEPTION("Add RICA Cert to certchain!");
425 if (AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR) != 0) {
426 DRM_TAPPS_EXCEPTION("Add Root CA Cert!");
431 X509 *pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
433 if (pstX509 == NULL) {
434 DRM_TAPPS_EXCEPTION("Get Cert d2i_X509 error!");
438 X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
439 X509_STORE_CTX *pstStoreCtx = X509_STORE_CTX_new();
441 if (pstStoreCtx == NULL) {
442 DRM_TAPPS_EXCEPTION("509_STORE_CTX_new error!");
446 std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)>
447 _scoped_x509_store_ctx(pstStoreCtx, X509_STORE_CTX_free);
450 if(!X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts)) {
451 DRM_TAPPS_EXCEPTION("509_STORE_CTX_init error!");
456 X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
459 switch (X509_verify_cert(pstStoreCtx)) {
461 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
465 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
466 X509_verify_cert_error_string(
467 X509_STORE_CTX_get_error(pstStoreCtx)));
471 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
476 size_t TADC_IF_StrLen(const char *string)
478 return strlen(string);
481 int TADC_IF_StrCmp(const char *string1, const char *string2)
483 return strcmp(string1, string2);
486 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
488 return strncmp(string1, string2, count);
491 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
493 return strncpy(strDestination, strSource, count);
496 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
498 return strtoul(nptr, endptr, base);
501 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
503 return memcmp(buf1, buf2, count);
506 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
508 memcpy(dest, src, count);
511 void TADC_IF_MemSet(void *dest, int c, size_t count)
513 memset(dest, c, count);
516 void *TADC_IF_Malloc(size_t size)
521 void TADC_IF_Free(void *memblock)
523 if (memblock != NULL)
527 int TADC_IF_AtoI(char *str)