Fix a build error for toolchain upgrade (gcc6->gcc9)
[platform/core/security/drm-service-core-tizen.git] / tadcore / TADCInterface / TADC_IF.cpp
1 /*
2  * Copyright (c) 2000-2019 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  *     http://floralicense.org/license/
9  *
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.
15  */
16
17 //#define _SLP_SIMUL
18 #include "TADC_IF.h"
19 #include "TADC_Util.h"
20 #include "TADC_ErrorCode.h"
21
22 #include "drm_intf_tapps.h"
23
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>
29
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>
37
38 #include <dirent.h>
39
40 #include <cerrno>
41 #include <memory>
42 #include <functional>
43
44 #include "DUIDGenerator.h"
45
46
47 int TADC_IF_GetDUID(char *Duid)
48 {
49         if (!Duid) {
50                 DRM_TAPPS_EXCEPTION("Invalid argument.");
51                 return TADC_GETDUID_ERROR;
52         }
53
54         char *duid = NULL;
55
56         if (get_duid(&duid) < 0 || !duid) {
57                 DRM_TAPPS_EXCEPTION("Failed to get DUID.");
58                 return TADC_GETDUID_ERROR;
59         }
60
61         DRM_TAPPS_LOG("DUID is [%s]", duid);
62         memcpy(Duid, duid, strlen(duid) + 1);
63
64         free(duid);
65
66         return TADC_SUCCESS;
67 }
68
69 int TADC_IF_GetDHKey(T_DH_INFO *t_dhinfo)
70 {
71         DH *pDH = NULL;
72         TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info));
73
74         // Debug
75         DRM_TAPPS_LOG("After TADC_IF_MemSet(t_dhinfo, 0, sizeof(t_dh_info))");
76
77         //1. dh new
78         if ((pDH = DH_new()) == NULL) {
79                 DRM_TAPPS_EXCEPTION("DH_new() error!");
80                 return -1;
81         }
82
83         // Debug
84         DRM_TAPPS_LOG("After DH_new");
85
86         //2. Set the Prime and Generator Value
87         BYTE prime64[64] = {
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
95         };
96         BYTE generator[1] = {DH_GENERATOR_5};
97
98         DH_set0_pqg(pDH, BN_bin2bn(prime64, 64, NULL), nullptr,
99                         BN_bin2bn(generator, 1, NULL));
100
101         /* Set a to run with normal modexp and b to use constant time */
102         DH_clear_flags(pDH, DH_FLAG_NO_EXP_CONSTTIME);
103
104         // Debug
105         DRM_TAPPS_LOG("After Set the Prime and Generator Value");
106
107         //3. Generate DH Key
108         if (!DH_generate_key(pDH)) {
109                 DRM_TAPPS_EXCEPTION("DH_generate_key() error!");
110                 return -1;
111         }
112
113         // Debug
114         DRM_TAPPS_LOG("After DH_generate_key");
115
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);
122
123         //5. DH Free
124         DH_free(pDH);
125
126         // Debug
127         DRM_TAPPS_LOG("After DH_free");
128
129         return 0;
130 }
131
132 int TADC_IF_GetDHKey_K(T_DH_INFO *t_dhinfo)
133 {
134         DH *pDH = NULL;
135         BIGNUM *pPubKey = NULL;
136
137         char tempbuf[DHKey_SIZE + 1];
138         int i = 0;
139
140         unsigned char tempG[1];
141
142         TADC_IF_MemSet(tempbuf, 0, sizeof(tempbuf));
143
144         //1. dh new
145         if ((pDH = DH_new()) == NULL) {
146                 DRM_TAPPS_EXCEPTION("DH_new() error!");
147                 return -1;
148         }
149
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));
157
158         //3. Set Public Key of Server
159         pPubKey = BN_bin2bn(t_dhinfo->B, t_dhinfo->BSize, NULL);
160
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");
164                 return -1;
165         }
166
167         for (i = 0; i < (t_dhinfo -> BSize / 2); i++) {
168                 t_dhinfo->K[i] = tempbuf[i * 2] ^ tempbuf[(i * 2) + 1];
169         }
170
171         //5. DH Free
172         DH_free(pDH);
173         BN_free(pPubKey);
174
175         return 0;
176 }
177
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)
181 {
182         AES_KEY stKey;
183         UINT num;
184         TADC_U8 ecount[16];
185         TADC_U8 chain[16];
186
187         AES_set_encrypt_key(pKey, 128, &stKey);
188
189         num = 0;
190
191         TADC_IF_MemSet(ecount, 0, sizeof(ecount));
192         TADC_IF_MemSet(chain, 0, sizeof(chain));
193         TADC_IF_MemCpy(chain, pIV, ivLen);
194
195         CRYPTO_ctr128_encrypt(in, out, inLen, &stKey, chain, ecount, &num, (block128_f)AES_encrypt);
196
197         *pOutLen = inLen;
198
199         return 0;
200 }
201
202 int TADC_IF_SHA1(unsigned char *in, int inLen, unsigned char *out)
203 {
204         SHA_CTX AlgInfo;
205
206         SHA1_Init(&AlgInfo);
207         SHA1_Update(&AlgInfo, in, inLen);
208         SHA1_Final(out, &AlgInfo);
209
210         return 0;
211 }
212
213 int TADC_IF_VerifySignature(unsigned char *inData, int inLen,
214                                                         unsigned char *sigData, int sigLen,
215                                                         unsigned char *cert, int certLen)
216 {
217         unsigned char hashValue[20];
218         int iRet = 0;
219
220         X509 *pX509 = NULL;
221         EVP_PKEY *pKey = NULL;
222         RSA *pRsa = NULL;
223
224         //Check parameters
225         if (inData == NULL || sigData == NULL || cert == NULL || inLen < 1 ||
226                         sigLen < 1 || certLen < 1) {
227                 DRM_TAPPS_EXCEPTION("Parameter error!");
228                 return -1;
229         }
230
231         iRet = 0;
232
233         //1. Make Hash value of indata by using SHA1
234         TADC_IF_SHA1(inData, inLen, hashValue);
235
236         //2. Get RSA Public Key from cert data ( DER )
237         pX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
238
239         if (pX509 == NULL) {
240                 DRM_TAPPS_EXCEPTION("Get RSA Public Key from cert data!");
241                 return -1;
242         }
243
244         pKey = X509_get_pubkey(pX509);
245
246         if (pKey == NULL) {
247                 DRM_TAPPS_EXCEPTION("X509_get_pubkey!");
248                 return -1;
249         }
250
251         pRsa = EVP_PKEY_get1_RSA(pKey);
252
253         if (pRsa == NULL) {
254                 DRM_TAPPS_EXCEPTION("EVP_PKEY_get1_RSA!");
255
256                 if (NULL != pKey) {
257                         EVP_PKEY_free(pKey);
258                 }
259
260                 return -1;
261         }
262
263         //3. Verify RSA Sign
264         iRet = RSA_verify(NID_sha1, hashValue, 20, sigData, sigLen, pRsa);
265
266         if (1 != iRet) {
267                 int err = 0;
268                 char tmpBuf[120] = { 0, };
269
270                 while ((err = ERR_get_error()) != 0)
271                         DRM_TAPPS_EXCEPTION("RSA_verify error(%s)", ERR_error_string(err, tmpBuf));
272
273                 if (NULL != pKey)
274                         EVP_PKEY_free(pKey);
275
276                 return -1;
277         }
278
279         if (NULL != pKey)
280                 EVP_PKEY_free(pKey);
281
282         return 0;
283 }
284
285 int AddCertUntrustedCerts(STACK_OF(X509)* untrustedCerts, unsigned char *cert,
286                                                   int certLen)
287 {
288         X509 *pstX509 = NULL;
289
290         if (untrustedCerts == NULL || cert == NULL || certLen < 1) {
291                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : Parameter error!");
292                 return -1;
293         }
294
295         pstX509 = d2i_X509(NULL, (const unsigned char **) &cert, certLen);
296
297         if (pstX509 == NULL) {
298                 DRM_TAPPS_EXCEPTION("AddCertSTORE Error : d2i_X509 error!");
299                 return -1;
300         }
301
302         sk_X509_push(untrustedCerts, pstX509);
303
304         return 0;
305 }
306
307 int AddCertSTOREFromFile(X509_STORE *pstStore, const char *filePath)
308 {
309         X509 *pstX509 = NULL;
310         FILE *file = NULL;
311         int ret = 0;
312
313         file = fopen(filePath, "r");
314
315         if (!file) {
316                 DRM_TAPPS_EXCEPTION("Parameter error! Fail to open a cert file.");
317                 ret = -1;
318                 goto error;
319         }
320
321         pstX509 = PEM_read_X509(file, NULL, NULL, NULL);
322
323         if (pstX509 == NULL) {
324                 DRM_TAPPS_EXCEPTION("d2i_X509 error!");
325                 ret = -1;
326                 goto error;
327         }
328
329         X509_STORE_add_cert(pstStore, pstX509);
330
331 error:
332
333         if (file != NULL)
334                 fclose(file);
335
336         return ret;
337 }
338
339 int AddCertSTOREFromDir(X509_STORE *pstStore, const char *dirPath)
340 {
341         int ret = 0;
342
343         DIR *dir = NULL;
344         struct dirent *result = nullptr;
345         char file_path_buff[512];
346
347         if (pstStore == NULL || dirPath == NULL) {
348                 DRM_TAPPS_EXCEPTION("Parameter error!");
349                 ret = -1;
350                 goto error;
351         }
352
353         dir = opendir(dirPath);
354
355         if (dir == NULL) {
356                 DRM_TAPPS_EXCEPTION("cannot open directory(%s)!", dirPath);
357                 ret = -1;
358                 goto error;
359         }
360
361         while (true) {
362                 errno = 0;
363                 result = readdir(dir);
364                 if (result == NULL) {
365                         if (errno != 0) {
366                                 DRM_TAPPS_EXCEPTION("fail to read entries from a directory(%s)!",
367                                                                         dirPath);
368                                 ret = -1;
369                                 goto error;
370                         } else {
371                                 // end of stream
372                                 break;
373                         }
374                 }
375
376                 if (result->d_type == DT_REG) {
377                         // regular file
378                         memset(file_path_buff, 0, sizeof(file_path_buff));
379                         snprintf(file_path_buff, sizeof(file_path_buff), "%s/%s", dirPath,
380                                          result->d_name);
381
382                         if (AddCertSTOREFromFile(pstStore, file_path_buff) == 0) {
383                                 DRM_TAPPS_LOG("Add root cert : file=%s", file_path_buff);
384                         } else {
385                                 DRM_TAPPS_LOG("Fail to add root cert : file=%s", file_path_buff);
386                         }
387                 }
388         }
389
390 error:
391
392         if (dir != NULL)
393                 closedir(dir);
394
395         return ret;
396 }
397
398 int TADC_IF_VerifyCertChain(unsigned char *rica, int ricaLen,
399                                                         unsigned char *cert, int certLen)
400 {
401         X509_STORE *pstStore = X509_STORE_new();
402
403         if (pstStore == NULL)
404                 return -1;
405
406         std::unique_ptr<X509_STORE, void(*)(X509_STORE *)>
407         _scoped_x509_store(pstStore, X509_STORE_free);
408
409         STACK_OF(X509) *untrustedCerts = sk_X509_new_null();
410
411         if (untrustedCerts == NULL)
412                 return -1;
413
414         std::unique_ptr<STACK_OF(X509), std::function<void(STACK_OF(X509) *)>>
415         _scoped_x509_stack(untrustedCerts, [](STACK_OF(X509) *s) {
416                 sk_X509_free(s);
417         });
418
419         //Add RICA Cert to certchain
420         if (AddCertUntrustedCerts(untrustedCerts, rica, ricaLen) != 0) {
421                 DRM_TAPPS_EXCEPTION("Add RICA Cert to certchain!");
422                 return -1;
423         }
424
425         //Add Root CA Cert
426         if (AddCertSTOREFromDir(pstStore, RO_ISSUER_ROOT_CERTS_DIR) != 0) {
427                 DRM_TAPPS_EXCEPTION("Add Root CA Cert!");
428                 return -1;
429         }
430
431         //Get Cert
432         X509 *pstX509 = d2i_X509(NULL, (const unsigned char **)&cert, certLen);
433
434         if (pstX509 == NULL) {
435                 DRM_TAPPS_EXCEPTION("Get Cert d2i_X509 error!");
436                 return -1;
437         }
438
439         X509_STORE_set_flags(pstStore, X509_V_FLAG_CB_ISSUER_CHECK);
440         X509_STORE_CTX *pstStoreCtx = X509_STORE_CTX_new();
441
442         if (pstStoreCtx == NULL) {
443                 DRM_TAPPS_EXCEPTION("509_STORE_CTX_new error!");
444                 return -1;
445         }
446
447         std::unique_ptr<X509_STORE_CTX, void(*)(X509_STORE_CTX *)>
448         _scoped_x509_store_ctx(pstStoreCtx, X509_STORE_CTX_free);
449
450         //init
451         if(!X509_STORE_CTX_init(pstStoreCtx, pstStore, pstX509, untrustedCerts)) {
452                 DRM_TAPPS_EXCEPTION("509_STORE_CTX_init error!");
453                 return -1;
454     }
455
456         //Set Flag
457         X509_STORE_CTX_set_flags(pstStoreCtx, X509_V_FLAG_CB_ISSUER_CHECK);
458
459         //verify
460         switch (X509_verify_cert(pstStoreCtx)) {
461         case 1:
462                 DRM_TAPPS_LOG("TADC_IF_VerifyCertChain Success!");
463                 return 0;
464
465         case 0:
466                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Failed: %s",
467                                                         X509_verify_cert_error_string(
468                                                                 X509_STORE_CTX_get_error(pstStoreCtx)));
469                 return -1;
470
471         default:
472                 DRM_TAPPS_EXCEPTION("TADC_IF_VerifyCertChain Error: X509_verify_cert error!");
473                 return -1;
474         }
475 }
476
477 size_t TADC_IF_StrLen(const char *string)
478 {
479         return strlen(string);
480 }
481
482 int TADC_IF_StrCmp(const char *string1, const char *string2)
483 {
484         return strcmp(string1, string2);
485 }
486
487 int TADC_IF_StrNCmp(const char *string1, const char *string2, size_t count)
488 {
489         return strncmp(string1, string2, count);
490 }
491
492 char *TADC_IF_StrNCpy(char *strDestination, const char *strSource, size_t count)
493 {
494         return strncpy(strDestination, strSource, count);
495 }
496
497 unsigned long TADC_IF_StrtOul(const char *nptr, char **endptr, int base)
498 {
499         return strtoul(nptr, endptr, base);
500 }
501
502 int TADC_IF_MemCmp(const void *buf1, const void *buf2, size_t count)
503 {
504         return memcmp(buf1, buf2, count);
505 }
506
507 void TADC_IF_MemCpy(void *dest, const void *src, size_t count)
508 {
509         memcpy(dest, src, count);
510 }
511
512 void TADC_IF_MemSet(void *dest, int c, size_t count)
513 {
514         memset(dest, c, count);
515 }
516
517 void *TADC_IF_Malloc(size_t size)
518 {
519         return malloc(size);
520 }
521
522 void TADC_IF_Free(void *memblock)
523 {
524         if (memblock != NULL)
525                 free(memblock);
526 }
527
528 int TADC_IF_AtoI(char *str)
529 {
530         return atoi(str);
531 }