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 X509_STORE_add_cert(pstStore, pstX509);
339 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
344 struct dirent *result = nullptr;
345 char file_path_buff[512];
347 if (pstStore == NULL || dirPath == NULL) {
348 DRM_TAPPS_EXCEPTION("Parameter error!");
353 dir = opendir(dirPath);
356 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
363 result = readdir(dir);
364 if (result == NULL) {
366 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!",
376 if (result->d_type == DT_REG) {
378 memset(file_path_buff, 0, sizeof(file_path_buff));
379 snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
382 if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
383 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
385 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
398 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
399 unsigned char *cert, int certLen)
401 X509_STORE *pstStore = X509_STORE_new();
403 if (pstStore == NULL)
406 std::unique_ptr<X509_STORE, void(*)(X509_STORE *)>
407 _scoped_x509_store(pstStore, X509_STORE_free);
409 STACK_OF(X509) *untrustedCerts = sk_X509_new_null();
411 if (untrustedCerts == NULL)
414 std::unique_ptr<STACK_OF(X509), std::function<void(STACK_OF(X509) *)>>
415 _scoped_x509_stack(untrustedCerts, [](STACK_OF(X509) *s) {
419 //Add RICA Cert to certchain
420 if (AddCertUntrustedCerts(untrustedCerts, rica, ricaLen) != 0) {
421 DRM_TAPPS_EXCEPTION("Add RICA Cert to certchain!");
426 if (AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR) != 0) {
427 DRM_TAPPS_EXCEPTION("Add Root CA Cert!");
432 X509 *pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
434 if (pstX509 == NULL) {
435 DRM_TAPPS_EXCEPTION("Get Cert d2i_X509 error!");
439 X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
440 X509_STORE_CTX *pstStoreCtx = X509_STORE_CTX_new();
442 if (pstStoreCtx == NULL) {
443 DRM_TAPPS_EXCEPTION("509_STORE_CTX_new error!");
447 std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)>
448 _scoped_x509_store_ctx(pstStoreCtx, X509_STORE_CTX_free);
451 if(!X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts)) {
452 DRM_TAPPS_EXCEPTION("509_STORE_CTX_init error!");
457 X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
460 switch (X509_verify_cert(pstStoreCtx)) {
462 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
466 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
467 X509_verify_cert_error_string(
468 X509_STORE_CTX_get_error(pstStoreCtx)));
472 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
477 size_t TADC_IF_StrLen(const char *string)
479 return strlen(string);
482 int TADC_IF_StrCmp(const char *string1, const char *string2)
484 return strcmp(string1, string2);
487 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
489 return strncmp(string1, string2, count);
492 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
494 return strncpy(strDestination, strSource, count);
497 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
499 return strtoul(nptr, endptr, base);
502 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
504 return memcmp(buf1, buf2, count);
507 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
509 memcpy(dest, src, count);
512 void TADC_IF_MemSet(void *dest, int c, size_t count)
514 memset(dest, c, count);
517 void *TADC_IF_Malloc(size_t size)
522 void TADC_IF_Free(void *memblock)
524 if (memblock != NULL)
528 int TADC_IF_AtoI(char *str)