2 * Copyright (c) 2000-2015 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>
29 //2011.03.08 to verify signature
30 #include <openssl/x509.h>
31 #include <openssl/x509_vfy.h>
32 #include <openssl/evp.h>
33 #include <openssl/rsa.h>
34 #include <openssl/err.h>
35 #include <openssl/pem.h>
42 #include "DUIDGenerator.h"
45 int TADC_IF_GetDUID(char *Duid)
48 DRM_TAPPS_EXCEPTION("Invalid argument.");
49 return TADC_GETDUID_ERROR;
54 if (get_duid(&duid) < 0 || !duid) {
55 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
56 return TADC_GETDUID_ERROR;
59 DRM_TAPPS_LOG("DUID is [%s]", duid);
60 memcpy(Duid, duid, strlen(duid) + 1);
67 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
70 TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
73 DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
76 if ((pDH = DH_new()) == NULL) {
77 DRM_TAPPS_EXCEPTION("DH_new() error!");
82 DRM_TAPPS_LOG("After DH_new");
84 //2. Set the Prime and Generator Value
86 0xAE, 0xD9, 0x65, 0x3C, 0x86, 0x3E, 0xD9, 0x6F, 0x31, 0x6E,
87 0xF6, 0x08, 0x35, 0xD5, 0x01, 0xC1, 0x41, 0x2E, 0xDD, 0x7E,
88 0xE9, 0x09, 0x99, 0x73, 0xF3, 0xB3, 0xAB, 0x1F, 0x80, 0x85,
89 0x44, 0x22, 0xDA, 0x07, 0x32, 0x18, 0xC1, 0xF8, 0xC4, 0xED,
90 0x9F, 0x66, 0x88, 0xCF, 0xD6, 0x18, 0x8B, 0x28, 0x56, 0xA5,
91 0xB3, 0x6A, 0x8E, 0xBB, 0xC4, 0x2B, 0x2B, 0x3A, 0x9C, 0x20,
92 0x4E, 0xF7, 0x7F, 0xC3
94 BYTE generator[1] = {DH_GENERATOR_5};
96 pDH->p = BN_bin2bn(prime64, 64, NULL);
97 pDH->g = BN_bin2bn(generator, 1, NULL);
99 /* Set a to run with normal modexp and b to use constant time */
100 pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
103 DRM_TAPPS_LOG("After Set the Prime and Generator Value");
106 if (!DH_generate_key(pDH)) {
107 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
112 DRM_TAPPS_LOG("After DH_generate_key");
114 //4. Save DH Infos ( p, g, A, a )
115 TADC_IF_MemCpy(t_dhinfo->p, prime64, 64);
116 t_dhinfo->pSize = 64;
117 t_dhinfo->g = DH_GENERATOR_5;
118 t_dhinfo->ASize = BN_bn2bin(pDH->pub_key, t_dhinfo->A);
119 t_dhinfo->aSize = BN_bn2bin(pDH->priv_key, t_dhinfo->a);
125 DRM_TAPPS_LOG("After DH_free");
130 int TADC_IF_GetDHKey_K(T_DH_INFO *t_dhinfo)
133 BIGNUM *pPubKey = NULL;
135 char tempbuf[DHKey_SIZE + 1];
138 unsigned char tempG[1];
140 TADC_IF_MemSet(tempbuf, 0, sizeof(tempbuf));
143 if ((pDH = DH_new()) == NULL) {
144 DRM_TAPPS_EXCEPTION("DH_new() error!");
148 //2.Set DH Info to pDH
149 pDH->p = BN_bin2bn(t_dhinfo->p, t_dhinfo->pSize, NULL);
150 tempG[0] = t_dhinfo->g;
151 pDH->g = BN_bin2bn(tempG, 1, NULL);
152 pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
153 pDH->pub_key = BN_bin2bn(t_dhinfo->A, t_dhinfo->ASize, NULL);
154 pDH->priv_key = BN_bin2bn(t_dhinfo->a, t_dhinfo->aSize, NULL);
156 //3. Set Public Key of Server
157 pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
159 //4. Compute DH Session Key
160 if ((i = DH_compute_key((BYTE *)tempbuf, pPubKey, pDH)) < 0) {
161 DRM_TAPPS_EXCEPTION("DH_compute_key() error! \n");
165 for (i = 0; i < (t_dhinfo -> BSize / 2); i++) {
166 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
176 /* Only handles 128 bit aes key */
177 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV,
178 int inLen, unsigned char *in, int *pOutLen, unsigned char *out)
185 AES_set_encrypt_key(pKey, 128, &stKey);
189 TADC_IF_MemSet(ecount, 0, sizeof(ecount));
190 TADC_IF_MemSet(chain, 0, sizeof(chain));
191 TADC_IF_MemCpy(chain, pIV, ivLen);
193 AES_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num);
200 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
205 SHA1_Update(&AlgInfo, in, inLen);
206 SHA1_Final(out, &AlgInfo);
211 int TADC_IF_VerifySignature(unsigned char *inData, int inLen,
212 unsigned char *sigData, int sigLen,
213 unsigned char *cert, int certLen)
215 unsigned char hashValue[20];
219 EVP_PKEY *pKey = NULL;
223 if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 ||
224 sigLen < 1 || certLen < 1) {
225 DRM_TAPPS_EXCEPTION("Parameter error!");
231 //1. Make Hash value of indata by using SHA1
232 TADC_IF_SHA1(inData, inLen, hashValue);
234 //2. Get RSA Public Key from cert data ( DER )
235 pX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
238 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
242 pKey = X509_get_pubkey(pX509);
245 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
249 pRsa = EVP_PKEY_get1_RSA(pKey);
252 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
262 iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
266 char tmpBuf[120] = { 0, };
268 while ((err = ERR_get_error()) != 0)
269 DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
283 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
286 X509 *pstX509 = NULL;
288 if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
289 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
293 pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
295 if (pstX509 == NULL) {
296 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
300 sk_X509_push(untrustedCerts, pstX509);
305 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
307 X509 *pstX509 = NULL;
311 file = fopen(filePath, "r");
314 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
319 pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
321 if (pstX509 == NULL) {
322 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
327 X509_STORE_add_cert(pstStore, pstX509);
337 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
342 struct dirent *result = nullptr;
343 char file_path_buff[512];
345 if (pstStore == NULL || dirPath == NULL) {
346 DRM_TAPPS_EXCEPTION("Parameter error!");
351 dir = opendir(dirPath);
354 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
361 result = readdir(dir);
362 if (result == NULL) {
364 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!",
374 if (result->d_type == DT_REG) {
376 memset(file_path_buff, 0, sizeof(file_path_buff));
377 snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
380 if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
381 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
383 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
396 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
397 unsigned char *cert, int certLen)
399 OpenSSL_add_all_algorithms();
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 X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts);
454 X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
457 switch (X509_verify_cert(pstStoreCtx)) {
459 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
463 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
464 X509_verify_cert_error_string(
465 X509_STORE_CTX_get_error(pstStoreCtx)));
469 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
474 size_t TADC_IF_StrLen(const char *string)
476 return strlen(string);
479 int TADC_IF_StrCmp(const char *string1, const char *string2)
481 return strcmp(string1, string2);
484 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
486 return strncmp(string1, string2, count);
489 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
491 return strncpy(strDestination, strSource, count);
494 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
496 return strtoul(nptr, endptr, base);
499 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
501 return memcmp(buf1, buf2, count);
504 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
506 memcpy(dest, src, count);
509 void TADC_IF_MemSet(void *dest, int c, size_t count)
511 memset(dest, c, count);
514 void *TADC_IF_Malloc(size_t size)
519 void TADC_IF_Free(void *memblock)
521 if (memblock != NULL)
525 int TADC_IF_AtoI(char *str)