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>
41 #include "DUIDGenerator.h"
44 int TADC_IF_GetDUID(char *Duid)
47 DRM_TAPPS_EXCEPTION("Invalid argument.");
48 return TADC_GETDUID_ERROR;
53 if (get_duid(&duid) < 0 || !duid) {
54 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
55 return TADC_GETDUID_ERROR;
58 DRM_TAPPS_LOG("DUID is [%s]", duid);
59 memcpy(Duid, duid, strlen(duid) + 1);
66 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
69 TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
72 DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
75 if ((pDH = DH_new()) == NULL) {
76 DRM_TAPPS_EXCEPTION("DH_new() error!");
81 DRM_TAPPS_LOG("After DH_new");
83 //2. Set the Prime and Generator Value
85 0xAE, 0xD9, 0x65, 0x3C, 0x86, 0x3E, 0xD9, 0x6F, 0x31, 0x6E,
86 0xF6, 0x08, 0x35, 0xD5, 0x01, 0xC1, 0x41, 0x2E, 0xDD, 0x7E,
87 0xE9, 0x09, 0x99, 0x73, 0xF3, 0xB3, 0xAB, 0x1F, 0x80, 0x85,
88 0x44, 0x22, 0xDA, 0x07, 0x32, 0x18, 0xC1, 0xF8, 0xC4, 0xED,
89 0x9F, 0x66, 0x88, 0xCF, 0xD6, 0x18, 0x8B, 0x28, 0x56, 0xA5,
90 0xB3, 0x6A, 0x8E, 0xBB, 0xC4, 0x2B, 0x2B, 0x3A, 0x9C, 0x20,
91 0x4E, 0xF7, 0x7F, 0xC3
93 BYTE generator[1] = {DH_GENERATOR_5};
95 pDH->p = BN_bin2bn(prime64, 64, NULL);
96 pDH->g = BN_bin2bn(generator, 1, NULL);
98 /* Set a to run with normal modexp and b to use constant time */
99 pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
102 DRM_TAPPS_LOG("After Set the Prime and Generator Value");
105 if (!DH_generate_key(pDH)) {
106 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
111 DRM_TAPPS_LOG("After DH_generate_key");
113 //4. Save DH Infos ( p, g, A, a )
114 TADC_IF_MemCpy(t_dhinfo->p, prime64, 64);
115 t_dhinfo->pSize = 64;
116 t_dhinfo->g = DH_GENERATOR_5;
117 t_dhinfo->ASize = BN_bn2bin(pDH->pub_key, t_dhinfo->A);
118 t_dhinfo->aSize = BN_bn2bin(pDH->priv_key, t_dhinfo->a);
124 DRM_TAPPS_LOG("After DH_free");
129 int TADC_IF_GetDHKey_K(T_DH_INFO *t_dhinfo)
132 BIGNUM *pPubKey = NULL;
134 char tempbuf[DHKey_SIZE + 1];
137 unsigned char tempG[1];
139 TADC_IF_MemSet(tempbuf, 0, sizeof(tempbuf));
142 if ((pDH = DH_new()) == NULL) {
143 DRM_TAPPS_EXCEPTION("DH_new() error!");
147 //2.Set DH Info to pDH
148 pDH->p = BN_bin2bn(t_dhinfo->p, t_dhinfo->pSize, NULL);
149 tempG[0] = t_dhinfo->g;
150 pDH->g = BN_bin2bn(tempG, 1, NULL);
151 pDH->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
152 pDH->pub_key = BN_bin2bn(t_dhinfo->A, t_dhinfo->ASize, NULL);
153 pDH->priv_key = BN_bin2bn(t_dhinfo->a, t_dhinfo->aSize, NULL);
155 //3. Set Public Key of Server
156 pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
158 //4. Compute DH Session Key
159 if ((i = DH_compute_key((BYTE *)tempbuf, pPubKey, pDH)) < 0) {
160 DRM_TAPPS_EXCEPTION("DH_compute_key() error! \n");
164 for (i = 0; i < (t_dhinfo -> BSize / 2); i++) {
165 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
175 /* Only handles 128 bit aes key */
176 int TADC_IF_AES_CTR(unsigned char *pKey, int ivLen, unsigned char *pIV,
177 int inLen, unsigned char *in, int *pOutLen, unsigned char *out)
184 AES_set_encrypt_key(pKey, 128, &stKey);
188 TADC_IF_MemSet(ecount, 0, sizeof(ecount));
189 TADC_IF_MemSet(chain, 0, sizeof(chain));
190 TADC_IF_MemCpy(chain, pIV, ivLen);
192 AES_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num);
199 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
204 SHA1_Update(&AlgInfo, in, inLen);
205 SHA1_Final(out, &AlgInfo);
210 int TADC_IF_VerifySignature(unsigned char *inData, int inLen,
211 unsigned char *sigData, int sigLen,
212 unsigned char *cert, int certLen)
214 unsigned char hashValue[20];
218 EVP_PKEY *pKey = NULL;
222 if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 ||
223 sigLen < 1 || certLen < 1) {
224 DRM_TAPPS_EXCEPTION("Parameter error!");
230 //1. Make Hash value of indata by using SHA1
231 TADC_IF_SHA1(inData, inLen, hashValue);
233 //2. Get RSA Public Key from cert data ( DER )
234 pX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
237 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
241 pKey = X509_get_pubkey(pX509);
244 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
248 pRsa = EVP_PKEY_get1_RSA(pKey);
251 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
261 iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
265 char tmpBuf[120] = { 0, };
267 while ((err = ERR_get_error()) != 0)
268 DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
282 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
285 X509 *pstX509 = NULL;
287 if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
288 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
292 pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
294 if (pstX509 == NULL) {
295 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
299 sk_X509_push(untrustedCerts, pstX509);
304 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
306 X509 *pstX509 = NULL;
310 file = fopen(filePath, "r");
313 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
318 pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
320 if (pstX509 == NULL) {
321 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
326 X509_STORE_add_cert(pstStore, pstX509);
336 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
342 struct dirent *result;
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);
361 error = readdir_r(dir, &entry, &result);
364 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!", dirPath);
369 // readdir_r returns NULL in *result if the end
370 // of the directory stream is reached
374 if (entry.d_type == DT_REG) { // regular file
375 memset(file_path_buff, 0, sizeof(file_path_buff));
376 snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
379 if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
380 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
382 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
395 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
396 unsigned char *cert, int certLen)
398 OpenSSL_add_all_algorithms();
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 X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts);
453 X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
456 switch (X509_verify_cert(pstStoreCtx)) {
458 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
462 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
463 X509_verify_cert_error_string(
464 X509_STORE_CTX_get_error(pstStoreCtx)));
468 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
473 size_t TADC_IF_StrLen(const char *string)
475 return strlen(string);
478 int TADC_IF_StrCmp(const char *string1, const char *string2)
480 return strcmp(string1, string2);
483 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
485 return strncmp(string1, string2, count);
488 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
490 return strncpy(strDestination, strSource, count);
493 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
495 return strtoul(nptr, endptr, base);
498 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
500 return memcmp(buf1, buf2, count);
503 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
505 memcpy(dest, src, count);
508 void TADC_IF_MemSet(void *dest, int c, size_t count)
510 memset(dest, c, count);
513 void *TADC_IF_Malloc(size_t size)
518 void TADC_IF_Free(void *memblock)
520 if (memblock != NULL)
524 int TADC_IF_AtoI(char *str)