2 * Copyright (c) 2000-2019 Samsung Electronics Co., Ltd. All rights reserved
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.
25 #include <openssl/bio.h>
26 #include <openssl/evp.h>
27 #include <openssl/buffer.h>
28 #include <openssl/bn.h>
29 #include <openssl/crypto.h>
30 #include <openssl/err.h>
31 #include <openssl/pem.h>
32 #include <openssl/rsa.h>
33 #include <openssl/aes.h>
34 #include <openssl/sha.h>
37 #include <drm-tizen-apps.h>
38 #include <TADC_Util.h>
40 #include "drm_testutil.h"
42 #define _INITIALIZED 0
43 #define _UNINITIALIZED -1
45 using Binary = std::vector<unsigned char>;
47 static unsigned char g_baAESKey[32] = {
48 0xf8, 0x87, 0x0a, 0xc5, 0xd3, 0x6d, 0x44, 0x49,
49 0x03, 0x9f, 0xbd, 0x1e, 0xa8, 0x2f, 0xf6, 0xc3,
50 0xdf, 0x3b, 0x02, 0x13, 0x58, 0x1b, 0x12, 0x30,
51 0x1c, 0xd7, 0xad, 0xa5, 0x1f, 0x5d, 0x01, 0x33
55 int __get_random_bytes(char *output, int random_len)
57 FILE *fp = fopen("/dev/urandom", "r");
58 auto size = fread(output, 1, random_len, fp);
62 if (size != static_cast<size_t>(random_len))
63 return DRMTEST_ERR_IO;
65 return DRMTEST_SUCCESS;
68 int __file_copy(const char *target_path, const char *source_path)
70 int ret = DRMTEST_SUCCESS;
74 unsigned char buffer[8192];
76 source = fopen(source_path, "r");
83 target = fopen(target_path, "w");
90 while ((l1 = fread(buffer, 1, sizeof buffer, source)) > 0) {
91 l2 = fwrite(buffer, 1, l1, target);
112 void _base64_encode(const unsigned char *input, int length, char **output)
114 *output = Base64Encode((unsigned char *)input, length);
117 void _base64_decode(const char *input, unsigned char **output, int *out_len)
119 *output = Base64Decode((char *)input, out_len);
122 char *_replace_all(char *s, const char *olds, const char *news)
124 char *result = NULL, *sr = NULL;
126 size_t oldlen = strlen(olds);
128 if (oldlen < 1) return s;
130 size_t newlen = strlen(news);
132 if (newlen != oldlen) {
133 for (i = 0; s[i] != '\0';) {
134 if (memcmp(&s[i], olds, oldlen) == 0) count++, i += oldlen;
141 result = (char *) malloc(i + 1 + count * (newlen - oldlen));
143 if (result == NULL) return NULL;
148 if (memcmp(s, olds, oldlen) == 0) {
149 memcpy(sr, news, newlen);
162 Binary _read_ro_file(const char *filename)
165 std::ifstream is(filename, std::ifstream::binary);
167 if (!is || !is.is_open())
171 int length = is.tellg();
174 Binary buffer(length + 1); /* for null-terminated */
176 is.read(reinterpret_cast<char *>(buffer.data()), length);
183 std::cerr << "Failed to read ro file: " << filename << std::endl;
188 int _create_dh_key(const char *dh_key_p_hex, const char *dh_key_g_hex,
191 int ret = DRMTEST_SUCCESS;
193 BIGNUM *p = NULL, *g = NULL;
195 if ((pDH = DH_new()) == NULL) {
196 printf("...FAIL: DH_new() error");
197 ret = DRMTEST_ERR_CRYPTO;
201 BN_hex2bn(&p, dh_key_p_hex);
202 BN_hex2bn(&g, dh_key_g_hex);
203 DH_set0_pqg(pDH, p, nullptr, g);
205 /* Set a to run with normal modexp and b to use constant time */
206 DH_clear_flags(pDH, DH_FLAG_NO_EXP_CONSTTIME);
209 if (!DH_generate_key(pDH)) {
210 printf("...FAIL: DH_generate_key");
211 ret = DRMTEST_ERR_CRYPTO;
218 if (ret != DRMTEST_SUCCESS && pDH != NULL)
224 int _free_dh_key(DH *pkey)
229 return DRMTEST_SUCCESS;
233 int _get_dh_hex_pubkey(const DH *pkey, char **dh_pubkey)
235 *dh_pubkey = BN_bn2hex(DH_get0_pub_key(pkey));
236 return DRMTEST_SUCCESS;
239 int _get_dh_shared_secret_key(const char *dh_hex_pubkey, DH *pkey,
240 unsigned char **dh_shared_secret_key, int *dh_sec_key_len)
242 int ret = DRMTEST_SUCCESS;
244 BIGNUM *pPubKey = NULL;
245 unsigned char *secret_key_buff = NULL;
246 unsigned char tmp_buff[DH_size(pkey)] = { 0, };
248 BN_hex2bn(&pPubKey, dh_hex_pubkey);
250 if (DH_compute_key(tmp_buff, pPubKey, pkey) < 0) {
251 ret = DRMTEST_ERR_CRYPTO;
255 secret_key_buff = (unsigned char *) malloc(DH_size(pkey) / 2);
257 if (secret_key_buff == NULL) {
258 ret = DRMTEST_ERR_CRYPTO;
262 memset(secret_key_buff, 0, DH_size(pkey) / 2);
264 printf("APP_DRM TEST: shared secret : ");
266 for (int i = 0; i < (DH_size(pkey) / 2); i++) {
267 secret_key_buff[i] = tmp_buff[i * 2] ^ tmp_buff[(i * 2) + 1];
268 printf("%02x", secret_key_buff[i]);
273 *dh_shared_secret_key = secret_key_buff;
274 *dh_sec_key_len = DH_size(pkey) / 2;
280 if (ret != DRMTEST_SUCCESS && secret_key_buff != NULL)
281 free(secret_key_buff);
287 int _create_right_object_without_signature(const char *ro_template_path,
288 const char *cid, const char *duid,
291 int ret = DRMTEST_SUCCESS;
292 char *cid_filled = NULL;
293 char *duid_filled = NULL;
295 auto buf = _read_ro_file(ro_template_path);
297 cid_filled = _replace_all(reinterpret_cast<char *>(buf.data()),
298 STR_PLACE_HOLDER_CID, cid);
299 duid_filled = _replace_all(cid_filled, STR_PLACE_HOLDER_DUID, duid);
301 *ro_buff = duid_filled;
303 if (cid_filled != NULL)
306 if (ret != DRMTEST_SUCCESS && duid_filled != NULL)
312 int _create_ro_signature(const char *ro_buff, const char *signer_prikey_path,
315 int ret = DRMTEST_SUCCESS;
317 EVP_PKEY *pkey = NULL;
319 const char *END_STR = "</CertificateChain>";
320 const char *tmp_end_hash_input = NULL;
321 int hash_input_size = 0;
322 unsigned char hash_value[20];
323 unsigned char sig_value[MAX_CERT_SIZE]; // enough buffer
324 unsigned int sig_len = 0;
325 char *b64_sig_value = NULL;
330 file = fopen(signer_prikey_path, "r");
333 ret = DRMTEST_ERR_IO;
337 pkey = PEM_read_PrivateKey(file, &pkey, NULL, NULL);
340 ret = DRMTEST_ERR_IO;
344 prsa = EVP_PKEY_get1_RSA(pkey);
347 ret = DRMTEST_ERR_CRYPTO;
351 // get hash input size
352 tmp_end_hash_input = strstr(ro_buff, END_STR);
353 hash_input_size = (tmp_end_hash_input - ro_buff) + strlen(END_STR);
358 SHA1_Update(&alginfo, ro_buff, hash_input_size);
359 SHA1_Final(hash_value, &alginfo);
361 // get signature value
362 if (1 != RSA_sign(NID_sha1, hash_value, 20, sig_value, &sig_len, prsa)) {
363 ret = DRMTEST_ERR_CRYPTO;
367 // convert to base64 string
368 _base64_encode(sig_value, (int) sig_len, &b64_sig_value);
370 *signature = b64_sig_value;
379 if (ret != DRMTEST_SUCCESS && b64_sig_value != NULL)
385 int _add_signature_to_ro(const char *ro_buff, const char *signature,
386 char **ro_with_signature)
388 int ret = DRMTEST_SUCCESS;
390 buff = _replace_all((char *)ro_buff, STR_PLACE_HOLDER_SIGNATURE, signature);
391 *ro_with_signature = buff;
395 int _encrypt_ro_with_dh_sec_key(const char *ro_with_signature,
396 const unsigned char *dh_secret_key, const int dh_sec_key_len,
399 int ret = DRMTEST_SUCCESS;
400 TADC_U8 key[16] = {0, };
401 TADC_U8 iv[16] = {0, };
402 int encrypted_len = 0;
403 unsigned char encrypted_buff[MAX_CERT_SIZE] = {0, };;
405 (void) dh_sec_key_len; // to prevent unused varialbe error
407 TADC_IF_MemCpy(key, dh_secret_key, 16);
408 TADC_IF_MemCpy(iv, (dh_secret_key + 16), 16);
409 ret = TADC_IF_AES_CTR(key, 16, iv, strlen(ro_with_signature),
410 (unsigned char *)ro_with_signature,
411 &encrypted_len, (unsigned char *)encrypted_buff);
414 ret = DRMTEST_ERR_CRYPTO;
418 _base64_encode(encrypted_buff, encrypted_len, encrypted_ro);
424 int _create_response_data_in_ro_response(const char *reqid,
425 const char *encrypted_ro, const char *dh_pubkey,
426 char **response_data)
428 int ret = DRMTEST_SUCCESS;
429 char tmp_buff[MAX_CERT_SIZE] = { 0, };
430 unsigned char hashed_reqid[20] = { 0, };
431 char hex_hashed_reqid[256] = { 0, };
432 unsigned char hash_value[20] = { 0, };
434 unsigned char hmac[1024 * 10] = { 0, };
435 char *hmac_base64 = NULL;
436 char *resp_data = NULL;
439 SHA_CTX alginfoForReqId;
440 SHA1_Init(&alginfoForReqId);
441 SHA1_Update(&alginfoForReqId, reqid, strlen(reqid));
442 SHA1_Final(hashed_reqid, &alginfoForReqId);
444 for (size_t i = 0; i < sizeof(hashed_reqid); i++)
445 sprintf(hex_hashed_reqid + i * 2, "%02x", hashed_reqid[i]);
447 sprintf(tmp_buff, "reqid=%s;B=%s;license=%s", hex_hashed_reqid, dh_pubkey,
453 SHA1_Update(&alginfo, tmp_buff, strlen(tmp_buff));
454 SHA1_Final(hash_value, &alginfo);
456 // encrypt hash value
457 TADC_U8 key[16] = {0, };
458 TADC_U8 iv[16] = {0, };
460 TADC_IF_MemCpy(key, g_baAESKey, 16);
461 TADC_IF_MemCpy(iv, (g_baAESKey + 16), 16);
462 ret = TADC_IF_AES_CTR(key, 16, iv, 20, hash_value, &hmac_len, hmac);
465 ret = DRMTEST_ERR_CRYPTO;
470 _base64_encode(hmac, 20, &hmac_base64);
473 strncat(tmp_buff, ";hmac=", strlen(";hmac="));
474 strncat(tmp_buff, hmac_base64, strlen(hmac_base64));
477 resp_data = (char *) malloc(strlen(tmp_buff) + 1);
479 if (resp_data == NULL) {
480 ret = DRMTEST_ERR_MEMORY;
484 memset(resp_data, 0, strlen(tmp_buff) + 1);
485 strncpy(resp_data, tmp_buff, strlen(tmp_buff));
487 *response_data = resp_data;
491 if (hmac_base64 != NULL)
494 if (ret != DRMTEST_SUCCESS && resp_data != NULL)
500 int _create_time_stamp(const unsigned char *dh_secret_key, char **time_stamp)
502 int ret = DRMTEST_SUCCESS;
504 char tmp_time_buff[128] = {0, };
505 unsigned char enc_time_buff[512] = {0, };
506 char *time_base64 = NULL;
507 int enc_time_buff_len = 0;
508 time_t now = time(NULL);
509 const struct tm *gt = gmtime(&now);
511 sprintf(tmp_time_buff, "%d-%d-%dT%d:%d:00:Z",
512 gt->tm_year + 1900, gt->tm_mon + 1, gt->tm_mday,
513 gt->tm_hour + 1, gt->tm_min + 1);
515 // encrypt time_stamp
516 TADC_U8 key[16] = {0, };
517 TADC_U8 iv[16] = {0, };
519 TADC_IF_MemCpy(key, dh_secret_key, 16);
520 TADC_IF_MemCpy(iv, (dh_secret_key + 16), 16);
521 ret = TADC_IF_AES_CTR(key, 16, iv, strlen(tmp_time_buff),
522 (unsigned char *)tmp_time_buff,
523 &enc_time_buff_len, enc_time_buff);
526 ret = DRMTEST_ERR_CRYPTO;
531 _base64_encode(enc_time_buff, enc_time_buff_len, &time_base64);
533 *time_stamp = time_base64;
536 if (ret != DRMTEST_SUCCESS && time_base64 != NULL)
542 int generate_purchase_response(char **purchase_response_buff, char **req_id)
544 int ret = DRMTEST_SUCCESS;
545 char resp_buff[1024 * 5] = {0, };
548 char random[64] = {0, };
550 const char *format1 = "<?xml version=\"1.0\">\n";
551 const char *format2 = "<response result=\"0\" message=\"\">\n";
552 const char *format3 = " <DRMType>%d</DRMType>\n";
553 const char *format4 = " <riurl>%s</riurl>\n";
554 const char *format5 = " <reqid>%s</reqid>\n";
555 const char *format6 = "</response>";
557 resp = (char *) malloc(sizeof(resp_buff));
560 ret = DRMTEST_ERR_MEMORY;
564 memset(resp, 0, sizeof(resp_buff));
566 __get_random_bytes(random, sizeof(random));
567 rid = (char *) malloc(1024);
570 ret = DRMTEST_ERR_MEMORY;
574 memset(rid, 0, 1024);
576 for (size_t i = 0; i < sizeof(random); i++)
577 sprintf(rid + i * 2, "%02x", random[i]);
579 strncat(resp_buff, format1, strlen(format1));
580 strncat(resp_buff, format2, strlen(format2));
581 strncat(resp_buff, format3, strlen(format3));
582 strncat(resp_buff, format4, strlen(format4));
583 strncat(resp_buff, format5, strlen(format5));
584 strncat(resp_buff, format6, strlen(format6));
586 sprintf(resp, resp_buff, 1, RIURL, rid);
588 *purchase_response_buff = resp;
593 if (ret != DRMTEST_SUCCESS && resp != NULL)
596 if (ret != DRMTEST_SUCCESS && rid != NULL)
602 int generate_right_object_request(const char *license_response_buff)
604 int ret = DRMTEST_SUCCESS;
605 unsigned int req_buff_len = 1024 * 5;
606 char url_buff[1024] = {0, };
607 unsigned int url_buff_len = sizeof(url_buff);
608 char *req_buff = NULL;
610 req_buff = (char *)malloc(1024 * 5);
612 if (req_buff == NULL) {
613 ret = DRMTEST_ERR_MEMORY;
617 memset(req_buff, 0, req_buff_len);
619 ret = drm_tizen_generate_license_request(license_response_buff,
620 strlen(license_response_buff),
621 req_buff, &req_buff_len, url_buff, &url_buff_len);
624 ret = DRMTEST_ERR_TIZDRM;
630 if (ret != DRMTEST_SUCCESS && req_buff != NULL)
637 int get_dh_key_from_ro_request(const char *ro_request_buff,
638 char **dh_key_p, char **dh_key_g, char **dh_key_a)
640 int ret = DRMTEST_SUCCESS;
642 const char *PFX_P = "p=";
643 const char *PFX_G = ";g=";
644 const char *PFX_A = ";A=";
645 const char *PFX_HMAC = ";hmac=";
647 const char *idx_p = strstr(ro_request_buff, PFX_P);
648 const char *idx_g = strstr(ro_request_buff, PFX_G);
649 const char *idx_a = strstr(ro_request_buff, PFX_A);
650 const char *idx_hmac = strstr(ro_request_buff, PFX_HMAC);
652 int len_p = idx_g - idx_p - strlen(PFX_P);
653 int len_g = idx_a - idx_g - strlen(PFX_G);
654 int len_a = idx_hmac - idx_a - strlen(PFX_A);
660 buff_p = (char *)malloc(len_p + 1);
662 if (buff_p == NULL) {
663 ret = DRMTEST_ERR_MEMORY;
667 memset(buff_p, 0, len_p + 1);
668 strncpy(buff_p, idx_p + strlen(PFX_P), len_p);
671 buff_g = (char *)malloc(len_g + 1);
673 if (buff_g == NULL) {
674 ret = DRMTEST_ERR_MEMORY;
678 memset(buff_g, 0, len_g + 1);
679 strncpy(buff_g, idx_g + strlen(PFX_G), len_g);
682 buff_a = (char *)malloc(len_a + 1);
684 if (buff_a == NULL) {
685 ret = DRMTEST_ERR_MEMORY;
689 memset(buff_a, 0, len_a + 1);
690 strncpy(buff_a, idx_a + strlen(PFX_A), len_a);
695 if (ret != DRMTEST_SUCCESS && buff_p != NULL)
698 if (ret != DRMTEST_SUCCESS && buff_g != NULL)
701 if (ret != DRMTEST_SUCCESS && buff_a != NULL)
707 int generate_right_object_response(const char *dh_key_p, const char *dh_key_g,
708 const char *dh_key_a,
709 const char *req_id, const char *cid,
710 const char *ro_template_path,
711 const char *duid, char **ro_response_buff)
713 int ret = DRMTEST_SUCCESS;
716 char *dh_pubkey = NULL;
717 unsigned char *dh_shared_secret_key = NULL;
718 int dh_sec_key_len = 0;
719 char *ro_buff = NULL;
720 char *ro_signature = NULL;
721 char *ro_with_signature = NULL;
722 char *encrypted_ro = NULL;
723 char *response_data = NULL;
724 char *time_stamp = NULL;
725 char *ro_resp_buff = NULL;
726 int ro_resp_buff_len = 0;
728 const char *format = "<?xml version=\"1.0\">\n"
729 "<response result=\"0\" message=\"\">\n"
730 " <responsedata>%s</responsedata>\n"
731 " <timeStamp>%s</timeStamp>\n"
734 ret = _create_dh_key(dh_key_p, dh_key_g, &pkey);
736 if (ret != DRMTEST_SUCCESS) {
740 ret = _get_dh_hex_pubkey(pkey, &dh_pubkey);
742 if (ret != DRMTEST_SUCCESS) {
746 ret = _get_dh_shared_secret_key(dh_key_a, pkey, &dh_shared_secret_key,
749 if (ret != DRMTEST_SUCCESS) {
753 ret = _create_right_object_without_signature(ro_template_path, cid, duid,
756 if (ret != DRMTEST_SUCCESS) {
760 ret = _create_ro_signature(ro_buff, RO_ISSUER_SIGNER_KEY_FILE, &ro_signature);
762 if (ret != DRMTEST_SUCCESS) {
766 ret = _add_signature_to_ro(ro_buff, ro_signature, &ro_with_signature);
768 if (ret != DRMTEST_SUCCESS) {
772 //printf("...right object:\n%s\n", ro_with_signature);
774 ret = _encrypt_ro_with_dh_sec_key(ro_with_signature, dh_shared_secret_key,
778 if (ret != DRMTEST_SUCCESS) {
782 ret = _create_response_data_in_ro_response(req_id, encrypted_ro, dh_pubkey,
785 if (ret != DRMTEST_SUCCESS) {
789 ret = _create_time_stamp(dh_shared_secret_key, &time_stamp);
791 if (ret != DRMTEST_SUCCESS) {
795 ro_resp_buff_len = strlen(format) + strlen(response_data) + strlen(
797 ro_resp_buff = (char *) malloc(ro_resp_buff_len);
799 if (ro_resp_buff == NULL) {
800 ret = DRMTEST_ERR_MEMORY;
804 memset(ro_resp_buff, 0, ro_resp_buff_len);
805 sprintf(ro_resp_buff, format, response_data, time_stamp);
807 *ro_response_buff = ro_resp_buff;
814 if (dh_pubkey != NULL)
817 if (dh_shared_secret_key != NULL)
818 free(dh_shared_secret_key);
823 if (ro_signature != NULL)
826 if (ro_with_signature != NULL)
827 free(ro_with_signature);
829 if (encrypted_ro != NULL)
832 if (response_data != NULL)
835 if (time_stamp != NULL)
838 if (ret != DRMTEST_SUCCESS && ro_resp_buff != NULL)
845 int is_identical_files(const char *file1, const char *file2, int *identical)
847 int ret = DRMTEST_SUCCESS;
849 FILE *fp1 = NULL, *fp2 = NULL;
852 fp1 = fopen(file1, "r");
855 ret = DRMTEST_ERR_IO;
859 fp2 = fopen(file2, "r");
862 ret = DRMTEST_ERR_IO;
869 while ((ch1 != EOF) && (ch2 != EOF) && (ch1 == ch2)) {
875 *identical = DRMTEST_IDENTICAL;
877 *identical = DRMTEST_NOTIDENTICAL;