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>
44 #include "DUIDGenerator.h"
47 int TADC_IF_GetDUID(char *Duid)
50 DRM_TAPPS_EXCEPTION("Invalid argument.");
51 return TADC_GETDUID_ERROR;
56 if (get_duid(&duid) < 0 || !duid) {
57 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
58 return TADC_GETDUID_ERROR;
61 DRM_TAPPS_LOG("DUID is [%s]", duid);
62 memcpy(Duid, duid, strlen(duid) + 1);
69 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
72 TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
75 DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
78 if ((pDH = DH_new()) == NULL) {
79 DRM_TAPPS_EXCEPTION("DH_new() error!");
84 DRM_TAPPS_LOG("After DH_new");
86 //2. Set the Prime and Generator Value
88 0xAE, 0xD9, 0x65, 0x3C, 0x86, 0x3E, 0xD9, 0x6F, 0x31, 0x6E,
89 0xF6, 0x08, 0x35, 0xD5, 0x01, 0xC1, 0x41, 0x2E, 0xDD, 0x7E,
90 0xE9, 0x09, 0x99, 0x73, 0xF3, 0xB3, 0xAB, 0x1F, 0x80, 0x85,
91 0x44, 0x22, 0xDA, 0x07, 0x32, 0x18, 0xC1, 0xF8, 0xC4, 0xED,
92 0x9F, 0x66, 0x88, 0xCF, 0xD6, 0x18, 0x8B, 0x28, 0x56, 0xA5,
93 0xB3, 0x6A, 0x8E, 0xBB, 0xC4, 0x2B, 0x2B, 0x3A, 0x9C, 0x20,
94 0x4E, 0xF7, 0x7F, 0xC3
96 BYTE generator[1] = {DH_GENERATOR_5};
98 DH_set0_pqg(pDH, BN_bin2bn(prime64, 64, NULL), nullptr,
99 BN_bin2bn(generator, 1, NULL));
101 /* Set a to run with normal modexp and b to use constant time */
102 DH_clear_flags(pDH, DH_FLAG_NO_EXP_CONSTTIME);
105 DRM_TAPPS_LOG("After Set the Prime and Generator Value");
108 if (!DH_generate_key(pDH)) {
109 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
114 DRM_TAPPS_LOG("After DH_generate_key");
116 //4. Save DH Infos ( p, g, A, a )
117 TADC_IF_MemCpy(t_dhinfo->p, prime64, 64);
118 t_dhinfo->pSize = 64;
119 t_dhinfo->g = DH_GENERATOR_5;
120 t_dhinfo->ASize = BN_bn2bin(DH_get0_pub_key(pDH), t_dhinfo->A);
121 t_dhinfo->aSize = BN_bn2bin(DH_get0_priv_key(pDH), t_dhinfo->a);
127 DRM_TAPPS_LOG("After DH_free");
132 int TADC_IF_GetDHKey_K(T_DH_INFO *t_dhinfo)
135 BIGNUM *pPubKey = NULL;
137 char tempbuf[DHKey_SIZE + 1];
140 unsigned char tempG[1];
142 TADC_IF_MemSet(tempbuf, 0, sizeof(tempbuf));
145 if ((pDH = DH_new()) == NULL) {
146 DRM_TAPPS_EXCEPTION("DH_new() error!");
150 //2.Set DH Info to pDH
151 tempG[0] = t_dhinfo->g;
152 DH_set0_pqg(pDH, BN_bin2bn(t_dhinfo->p, t_dhinfo->pSize, NULL), nullptr,
153 BN_bin2bn(tempG, 1, NULL));
154 DH_clear_flags(pDH, DH_FLAG_NO_EXP_CONSTTIME);
155 DH_set0_key(pDH, BN_bin2bn(t_dhinfo->A, t_dhinfo->ASize, NULL),
156 BN_bin2bn(t_dhinfo->a, t_dhinfo->aSize, NULL));
158 //3. Set Public Key of Server
159 pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
161 //4. Compute DH Session Key
162 if ((i = DH_compute_key((BYTE *)tempbuf, pPubKey, pDH)) < 0) {
163 DRM_TAPPS_EXCEPTION("DH_compute_key() error! \n");
167 for (i = 0; i < (t_dhinfo -> BSize / 2); i++) {
168 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
178 /* Only handles 128 bit aes key */
179 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV,
180 int inLen, unsigned char *in, int *pOutLen, unsigned char *out)
187 AES_set_encrypt_key(pKey, 128, &stKey);
191 TADC_IF_MemSet(ecount, 0, sizeof(ecount));
192 TADC_IF_MemSet(chain, 0, sizeof(chain));
193 TADC_IF_MemCpy(chain, pIV, ivLen);
195 CRYPTO_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num, (block128_f)AES_encrypt);
202 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
207 SHA1_Update(&AlgInfo, in, inLen);
208 SHA1_Final(out, &AlgInfo);
213 int TADC_IF_VerifySignature(unsigned char *inData, int inLen,
214 unsigned char *sigData, int sigLen,
215 unsigned char *cert, int certLen)
217 unsigned char hashValue[20];
221 EVP_PKEY *pKey = NULL;
225 if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 ||
226 sigLen < 1 || certLen < 1) {
227 DRM_TAPPS_EXCEPTION("Parameter error!");
233 //1. Make Hash value of indata by using SHA1
234 TADC_IF_SHA1(inData, inLen, hashValue);
236 //2. Get RSA Public Key from cert data ( DER )
237 pX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
240 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
244 pKey = X509_get_pubkey(pX509);
247 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
251 pRsa = EVP_PKEY_get1_RSA(pKey);
254 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
264 iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
268 char tmpBuf[120] = { 0, };
270 while ((err = ERR_get_error()) != 0)
271 DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
285 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
288 X509 *pstX509 = NULL;
290 if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
291 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
295 pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
297 if (pstX509 == NULL) {
298 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
302 sk_X509_push(untrustedCerts, pstX509);
307 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
309 X509 *pstX509 = NULL;
313 file = fopen(filePath, "r");
316 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
321 pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
323 if (pstX509 == NULL) {
324 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
329 if (!X509_STORE_add_cert(pstStore, pstX509)) {
330 DRM_TAPPS_EXCEPTION("X509_STORE_add_cert error!");
343 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
348 struct dirent *result = nullptr;
349 char file_path_buff[512];
351 if (pstStore == NULL || dirPath == NULL) {
352 DRM_TAPPS_EXCEPTION("Parameter error!");
357 dir = opendir(dirPath);
360 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
367 result = readdir(dir);
368 if (result == NULL) {
370 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!",
380 if (result->d_type == DT_REG) {
382 memset(file_path_buff, 0, sizeof(file_path_buff));
383 snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
386 if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
387 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
389 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
402 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
403 unsigned char *cert, int certLen)
405 X509_STORE *pstStore = X509_STORE_new();
407 if (pstStore == NULL)
410 std::unique_ptr<X509_STORE, void(*)(X509_STORE *)>
411 _scoped_x509_store(pstStore, X509_STORE_free);
413 STACK_OF(X509) *untrustedCerts = sk_X509_new_null();
415 if (untrustedCerts == NULL)
418 std::unique_ptr<STACK_OF(X509), std::function<void(STACK_OF(X509) *)>>
419 _scoped_x509_stack(untrustedCerts, [](STACK_OF(X509) *s) {
423 //Add RICA Cert to certchain
424 if (AddCertUntrustedCerts(untrustedCerts, rica, ricaLen) != 0) {
425 DRM_TAPPS_EXCEPTION("Add RICA Cert to certchain!");
430 if (AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR) != 0) {
431 DRM_TAPPS_EXCEPTION("Add Root CA Cert!");
436 X509 *pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
438 if (pstX509 == NULL) {
439 DRM_TAPPS_EXCEPTION("Get Cert d2i_X509 error!");
443 X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
444 X509_STORE_CTX *pstStoreCtx = X509_STORE_CTX_new();
446 if (pstStoreCtx == NULL) {
447 DRM_TAPPS_EXCEPTION("509_STORE_CTX_new error!");
451 std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)>
452 _scoped_x509_store_ctx(pstStoreCtx, X509_STORE_CTX_free);
455 if(!X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts)) {
456 DRM_TAPPS_EXCEPTION("509_STORE_CTX_init error!");
461 X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
464 switch (X509_verify_cert(pstStoreCtx)) {
466 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
470 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
471 X509_verify_cert_error_string(
472 X509_STORE_CTX_get_error(pstStoreCtx)));
476 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
481 size_t TADC_IF_StrLen(const char *string)
483 return strlen(string);
486 int TADC_IF_StrCmp(const char *string1, const char *string2)
488 return strcmp(string1, string2);
491 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
493 return strncmp(string1, string2, count);
496 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
498 return strncpy(strDestination, strSource, count);
501 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
503 return strtoul(nptr, endptr, base);
506 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
508 return memcmp(buf1, buf2, count);
511 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
513 memcpy(dest, src, count);
516 void TADC_IF_MemSet(void *dest, int c, size_t count)
518 memset(dest, c, count);
521 void *TADC_IF_Malloc(size_t size)
526 void TADC_IF_Free(void *memblock)
528 if (memblock != NULL)
532 int TADC_IF_AtoI(char *str)