1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include <openssl/objects.h>
13 #include <openssl/pem.h>
14 #include <openssl/evp.h>
15 #include <openssl/rand.h>
16 #include <openssl/bn.h>
17 #include <openssl/aes.h>
18 #include <openssl/err.h>
19 #include <openssl/rsa.h>
20 #include "common_rsa_keypair.h"
21 #include "common_crypto_asym.h"
22 #include "common_util_log.h"
23 #include "common_util_files.h"
24 #include "cc_crypto_defs.h"
25 #include "cc_pka_hw_plat_defs.h"
26 
27 
28 
29 /**
30  * @brief The Sign_v15 generates RSA signature using PKCS#1 v1.5 algorithm.
31  *
32  * The function
33  * 1. Create RSA signature
34  * 2. Verify the signature correctness
35  * @param[in] pRsaPrivKey - the private key
36  * @param[in] pDataIn - the data to sign on
37  * @param[in] dataInSize - the data size
38  * @param[in] Key_ptr - passphrase string
39  * @param[out] pSignature - the RSA signature
40  *
41  */
42 /*********************************************************/
Sign_v15(RSA * pRsaPrivKey,int8_t * pDataIn,int32_t dataInSize,int8_t * pSignature,int8_t * Key_ptr)43 int32_t Sign_v15(RSA  *pRsaPrivKey,
44          int8_t *pDataIn,
45          int32_t  dataInSize,
46          int8_t *pSignature,
47          int8_t *Key_ptr)
48 {
49     RSA *pRsaPubKey    = NULL;
50     BIO *bio           = NULL;
51     int32_t status         = -1;
52     EVP_PKEY *pKey     = NULL;
53     EVP_MD_CTX *md_ctx = NULL;
54     int32_t SignatureSize  = SB_CERT_RSA_KEY_SIZE_IN_BYTES;
55 
56     if ((NULL == pRsaPrivKey) ||
57         (NULL == pDataIn) ||
58         (NULL == pSignature) ||
59         (NULL == Key_ptr)) {
60         UTIL_LOG_ERR("ilegal input\n");
61         return(status);
62     }
63     /*EVP_PKEY_new() allocates an empty EVP_PKEY structure which
64     is used by OpenSSL to store private keys.*/
65     pKey = EVP_PKEY_new();
66     if (NULL == pKey) {
67         UTIL_LOG_ERR("failed to EVP_PKEY_new\n");
68         goto rsaSign_v15_end;
69     }
70     /*set the referenced key to key*/
71     if (!EVP_PKEY_assign_RSA(pKey, pRsaPrivKey)) {
72         UTIL_LOG_ERR("failed to EVP_PKEY_assign_RSA\n");
73         goto rsaSign_v15_end;
74     }
75 
76     /* fill and sign on the HASH output */
77     md_ctx = EVP_MD_CTX_create();
78     if (NULL == md_ctx) {
79         UTIL_LOG_ERR("failed to EVP_MD_CTX_create\n");
80         goto rsaSign_v15_end;
81     }
82     /* initializes a signing context to use the default implementation of digest type.*/
83     if (!EVP_SignInit(md_ctx, EVP_sha256())) {
84         UTIL_LOG_ERR("failed to EVP_SignInit\n");
85         goto rsaSign_v15_end;
86     }
87     /*hash data into the signature */
88     if (!EVP_SignUpdate(md_ctx, pDataIn, dataInSize)) {
89         UTIL_LOG_ERR("failed to EVP_SignUpdate\n");
90         goto rsaSign_v15_end;
91     }
92     /*signs the data using the private key pkey and places the signature*/
93     if (!EVP_SignFinal(md_ctx, pSignature, &SignatureSize, pKey)) {
94         UTIL_LOG_ERR("failed to EVP_SignFinal\n");
95         goto rsaSign_v15_end;
96     }
97 
98     // Create public key
99     bio = BIO_new(BIO_s_mem());
100     if (NULL == bio) {
101         UTIL_LOG_ERR("failed to BIO_new\n");
102         goto rsaSign_v15_end;
103     }
104     pRsaPubKey = RSA_new();
105     if (NULL == pRsaPubKey) {
106         UTIL_LOG_ERR("failed to RSA_new\n");
107         goto rsaSign_v15_end;
108     }
109     if (!PEM_write_bio_RSA_PUBKEY(bio, pRsaPrivKey)) {
110         UTIL_LOG_ERR("failed to PEM_write_bio_RSA_PUBKEY\n");
111         goto rsaSign_v15_end;
112     }
113 
114     if (PEM_read_bio_RSA_PUBKEY(bio,&pRsaPubKey,NULL,Key_ptr) == NULL) {
115         UTIL_LOG_ERR("failed to PEM_read_bio_RSA_PUBKEY\n");
116         goto rsaSign_v15_end;
117     }
118 
119     if (!EVP_PKEY_assign_RSA(pKey, pRsaPubKey)) {
120         UTIL_LOG_ERR("failed to EVP_PKEY_assign_RSA\n");
121         goto rsaSign_v15_end;
122     }
123     /* initializes verification context ctx to use the default implementation of digest type*/
124     if (!EVP_VerifyInit(md_ctx, EVP_sha256())) {
125         UTIL_LOG_ERR("failed to EVP_VerifyInit\n");
126         goto rsaSign_v15_end;
127     }
128     /*hashes bytes of data into the verification context*/
129     if (!EVP_VerifyUpdate(md_ctx, pDataIn, dataInSize)) {
130         UTIL_LOG_ERR("failed to EVP_VerifyUpdate\n");
131         goto rsaSign_v15_end;
132     }
133     /*verifies the data in, using the public.*/
134     if (!EVP_VerifyFinal(md_ctx, pSignature, SignatureSize, pKey)) {
135         UTIL_LOG_ERR("failed to EVP_VerifyFinal\n");
136         goto rsaSign_v15_end;
137     }
138 
139     status = 0;
140 
141     rsaSign_v15_end:
142     if (pRsaPubKey != NULL) {
143         RSA_free(pRsaPubKey);
144     }
145     if (bio != NULL) {
146         BIO_free_all(bio);
147     }
148     if (pKey != NULL) {
149         EVP_PKEY_free(pKey);
150     }
151     if (md_ctx != NULL) {
152         EVP_MD_CTX_destroy(md_ctx);
153     }
154     return(status);
155 }
156 
157 /**
158  * @brief The Sign_v21 generates RSA signature using PKCS#1 v2.1 algorithm.
159  *
160  * The function
161  * 1. Create RSA signature
162  * 2. Verify the signature correctness
163  * @param[in] pRsaPrivKey - the private key
164  * @param[in] pDataIn - the data to sign on
165  * @param[in] dataInSize - the data size
166  * @param[out] pSignature - the RSA signature
167  *
168  */
169 /*********************************************************/
Sign_v21(RSA * pRsaPrivKey,int8_t * pDataIn,uint32_t dataInSize,int8_t * pSignature)170 int32_t Sign_v21(RSA   *pRsaPrivKey,
171          int8_t  *pDataIn,
172          uint32_t   dataInSize,
173          int8_t  *pSignature)
174 {
175     uint8_t pDigest[HASH_SHA256_DIGEST_SIZE_IN_BYTES] = {0};
176     uint32_t uDigestLen = HASH_SHA256_DIGEST_SIZE_IN_BYTES;
177     EVP_MD_CTX md_ctx;
178     uint8_t EM[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
179     uint8_t pDecrypted[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
180     int32_t status = -1;
181 
182     if ((NULL == pRsaPrivKey) ||
183         (NULL == pDataIn) ||
184         (NULL == pSignature)) {
185         UTIL_LOG_ERR("ilegal input\n");
186         return(status);
187     }
188     /* hash the message */
189     EVP_MD_CTX_init(&md_ctx);
190     EVP_DigestInit(&md_ctx, EVP_sha256());
191     EVP_DigestUpdate(&md_ctx, (const void*) pDataIn, dataInSize);
192     EVP_DigestFinal(&md_ctx, pDigest, &uDigestLen);
193     EVP_MD_CTX_cleanup(&md_ctx);
194 
195     /* compute the PSS padded data */
196     if (!RSA_padding_add_PKCS1_PSS(pRsaPrivKey, EM, pDigest, EVP_sha256(), RSA_SALT_LEN)) {
197         return(status);
198     }
199 
200     /* perform digital signature */
201     if (RSA_private_encrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, EM, pSignature, pRsaPrivKey, RSA_NO_PADDING) == -1) {
202         return(status);
203     }
204 
205     /* verify the data */
206     if (RSA_public_decrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, pSignature, pDecrypted, pRsaPrivKey, RSA_NO_PADDING) == -1) {
207         return(status);
208     }
209 
210     if (RSA_verify_PKCS1_PSS(pRsaPrivKey, pDigest, EVP_sha256(), pDecrypted, RSA_SALT_LEN) != 1) {
211         return(status);
212     }
213 
214 
215     status = 0;
216 
217     return(status);
218 }
219 
220 /**
221  * @brief The Sign_v21 generates RSA signature using PKCS#1 v2.1 algorithm.
222  *
223  * The function
224  * 1. Verify RSA signature
225  * 2. Verify the signature correctness
226  * @param[in] pRsaPrivKey - the private key
227  * @param[in] pDataIn - the data to sign on
228  * @param[in] dataInSize - the data size
229  * @param[out] pSignature - the RSA signature
230  *
231  */
232 /*********************************************************/
Verify_v21(RSA * pRsaPubKey,int8_t * pDataIn,int32_t dataInSize,int8_t * pSignature)233 int32_t Verify_v21(RSA *pRsaPubKey,
234            int8_t  *pDataIn,
235            int32_t   dataInSize,
236            int8_t  *pSignature)
237 {
238     uint8_t pDigest[HASH_SHA256_DIGEST_SIZE_IN_BYTES] = {0};
239     uint32_t uDigestLen = HASH_SHA256_DIGEST_SIZE_IN_BYTES;
240     EVP_MD_CTX md_ctx;
241     uint8_t EM[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
242     uint8_t pDecrypted[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
243     int32_t status = -1;
244 
245     if ((NULL == pRsaPubKey) ||
246         (NULL == pDataIn) ||
247         (NULL == pSignature)) {
248         UTIL_LOG_ERR("ilegal input\n");
249         return(status);
250     }
251 
252     /* hash the message */
253     EVP_MD_CTX_init(&md_ctx);
254     EVP_DigestInit(&md_ctx, EVP_sha256());
255     EVP_DigestUpdate(&md_ctx, (const void*) pDataIn, dataInSize);
256     EVP_DigestFinal(&md_ctx, pDigest, &uDigestLen);
257     EVP_MD_CTX_cleanup(&md_ctx);
258 
259     /* decrypt the signature to get the hash */
260     if (RSA_public_decrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, pSignature, pDecrypted, pRsaPubKey, RSA_NO_PADDING) == -1) {
261         return(status);
262     }
263 
264     if (RSA_verify_PKCS1_PSS(pRsaPubKey,  pDigest, EVP_sha256(), pDecrypted,RSA_SALT_LEN) != 1) {
265         return(status);
266     }
267 
268     UTIL_LOG_INFO("\nVerify_v21: OK\n");
269     status = 0;
270 
271     return(status);
272 }
273 
274 /**
275  * @brief Verifies RSA signature.
276  *
277  * The function follows the steps:
278  * 1. Read RSA private key structure
279  * 2. Call function according to PKCS version to create RSA signature
280  *
281  * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
282  * @param[in] pDataIn - the data to sign on
283  * @param[in] dataInSize - the data size
284  * @param[in] pPrivKeyFileName - the private key file
285  * @param[in] pPrivKeyPwd - the passphrase string
286  * @param[out] pSignature - the RSA signature
287  *
288  */
289 /*********************************************************/
CC_CommonRsaVerify(int32_t pkcsVersion,int8_t * pPubKey,int8_t * pDataIn,int32_t dataInSize,int8_t * pSignature)290 int32_t CC_CommonRsaVerify(int32_t  pkcsVersion,
291              int8_t *pPubKey,
292              int8_t *pDataIn,
293              int32_t  dataInSize,
294              int8_t *pSignature)
295 {
296     RSA  *pRsaPubKey = NULL;
297     int32_t status = -1;
298     uint8_t pubKeyExp[] = {0x01, 0x00, 0x01};
299 
300     if ((NULL == pPubKey) ||
301         (NULL == pDataIn) ||
302         (NULL == pSignature)) {
303         UTIL_LOG_ERR("ilegal input\n");
304         return(status);
305     }
306 
307     pRsaPubKey = RSA_new();
308     if (NULL == pRsaPubKey) {
309         UTIL_LOG_ERR("Failed RSA_new\n");
310         goto END;
311     }
312 
313     /* set the modulus  and exponent from int8_t * into RSA key as BIGNUM */
314     pRsaPubKey->n = BN_bin2bn(pPubKey, SB_CERT_RSA_KEY_SIZE_IN_BYTES, NULL);
315     if (NULL == pRsaPubKey->n) {
316         UTIL_LOG_ERR("Failed BN_bin2bn for n\n");
317         goto END;
318     }
319     pRsaPubKey->e = BN_bin2bn(pubKeyExp, sizeof(pubKeyExp),NULL);
320     if (NULL == pRsaPubKey->e) {
321         UTIL_LOG_ERR("Failed BN_bin2bn for e\n");
322         goto END;
323     }
324 
325     if (RSA_USE_PKCS_21_VERSION == pkcsVersion) {
326         status = Verify_v21(pRsaPubKey, pDataIn, dataInSize, pSignature);
327     } else {
328         UTIL_LOG_ERR("\nCC_CommonRsaVerify: Invalid pkcs version\n");
329         goto END;
330     }
331 
332     END:
333     if (pRsaPubKey != NULL) {
334         RSA_free(pRsaPubKey);
335     }
336     return status;
337 }
338 
339 
340 /**
341  * @brief Generates RSA signature and returns it.
342  *
343  * The function follows the steps:
344  * 1. Read RSA private key structure
345  * 2. Call function according to PKCS version to create RSA signature
346  *
347  * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
348  * @param[in] pDataIn - the data to sign on
349  * @param[in] dataInSize - the data size
350  * @param[in] pPrivKeyFileName - the private key file
351  * @param[in] pPrivKeyPwd - the passphrase string
352  * @param[out] pSignature - the RSA signature
353  *
354  */
355 /*********************************************************/
CC_CommonRsaSign(int32_t pkcsVersion,int8_t * pDataIn,uint32_t dataInSize,int8_t * pPrivKeyFileName,int8_t * pPrivKeyPwd,int8_t * pSignature)356 int32_t CC_CommonRsaSign(int32_t pkcsVersion,
357                int8_t *pDataIn,
358                uint32_t dataInSize,
359                int8_t *pPrivKeyFileName,
360                int8_t *pPrivKeyPwd,
361                int8_t *pSignature)
362 {
363     RSA  *pRsaPrivKey = NULL;
364     uint8_t *pwd = NULL;
365     int32_t status = -1;
366 
367     if ((NULL == pDataIn) ||
368         (NULL == pPrivKeyFileName) ||
369         (NULL == pSignature)) {
370         UTIL_LOG_ERR("ilegal input\n");
371         return(status);
372     }
373 
374     /* parse the passphrase for a given file */
375     if ((NULL != pPrivKeyPwd)) {
376         if (CC_CommonGetPassphrase(pPrivKeyPwd, &pwd)) {
377         UTIL_LOG_ERR("Failed to retrieve pwd\n");
378         goto END;
379         }
380     }
381 
382     pRsaPrivKey = RSA_new();
383 
384     if (NULL == pRsaPrivKey) {
385         UTIL_LOG_ERR("Failed RSA_new\n");
386         goto END;
387     }
388     if (CC_CommonGetKeyPair (&pRsaPrivKey, pPrivKeyFileName, pwd) < 0) {
389         UTIL_LOG_ERR("CC_CommonGetKeyPair Cannot read RSA private key\n");
390         goto END;
391     }
392 
393     if (RSA_USE_PKCS_21_VERSION == pkcsVersion) {
394         status = Sign_v21(pRsaPrivKey, pDataIn, dataInSize, pSignature);
395     } else if (RSA_USE_PKCS_15_VERSION == pkcsVersion) {
396         status = Sign_v15(pRsaPrivKey, pDataIn, dataInSize, pSignature, pwd);
397     } else {
398         UTIL_LOG_ERR("\nCC_CommonRsaSign: Invalid pkcs version\n");
399         goto END;
400     }
401 
402     END:
403     if (pRsaPrivKey != NULL) {
404         RSA_free(pRsaPrivKey);
405     }
406     if (pwd != NULL) {
407         free(pwd);
408     }
409     return status;
410 }
411 
412 
413 
414 /**
415  * @brief Encrypts data using RSA.
416  *
417  * The function follows the steps:
418  * 1. Read RSA private key structure
419  * 2. Call function according to PKCS version to create RSA signature
420  *
421  * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
422  * @param[in] pPrivKeyFileName - the private key file
423  * @param[in] pPrivKeyPwd - the passphrase string
424  * @param[in] pDataIn - the data to encrypt
425  * @param[in] dataInSize - the data size
426  * @param[out] pEncData - the encrypted data
427  *
428  */
429 /*********************************************************/
CC_CommonRsaEncrypt(int32_t pkcsVersion,int8_t * pPubKey,int8_t * pDataIn,int32_t dataInSize,int8_t * pEncData)430 int32_t CC_CommonRsaEncrypt(int32_t pkcsVersion,
431               int8_t *pPubKey,
432               int8_t *pDataIn,
433               int32_t  dataInSize,
434               int8_t *pEncData)
435 {
436 
437     RSA  *pRsaPubKey = NULL;
438     int32_t status = -1;
439     uint8_t pubKeyExp[] = {0x01, 0x00, 0x01};
440 
441     if ((NULL == pPubKey) ||
442         (NULL == pDataIn) ||
443         (NULL == pEncData)) {
444         UTIL_LOG_ERR("ilegal input\n");
445         return(status);
446     }
447     /* get RSA public key from provided buffer */
448     pRsaPubKey = RSA_new();
449     if (NULL == pRsaPubKey) {
450         UTIL_LOG_ERR("Failed RSA_new\n");
451         goto rsaEncryptEnd;
452     }
453 
454     /* set the modulus  and exponent from int8_t * into RSA key as BIGNUM */
455     pRsaPubKey->n = BN_bin2bn(pPubKey, SB_CERT_RSA_KEY_SIZE_IN_BYTES, NULL);
456     if (NULL == pRsaPubKey->n) {
457         UTIL_LOG_ERR("Failed BN_bin2bn for n\n");
458         goto rsaEncryptEnd;
459     }
460     pRsaPubKey->e = BN_bin2bn(pubKeyExp, sizeof(pubKeyExp),NULL);
461     if (NULL == pRsaPubKey->e) {
462         UTIL_LOG_ERR("Failed BN_bin2bn for e\n");
463         goto rsaEncryptEnd;
464     }
465 
466     /* now encrypt the data */
467     status = RSA_public_encrypt(dataInSize, pDataIn, pEncData, pRsaPubKey, RSA_PKCS1_OAEP_PADDING); /* returns the size of the encrypted data, On error, -1 is returned*/
468     if (status != SB_CERT_RSA_KEY_SIZE_IN_BYTES) { /* expected encryped size is RSA modulus sieze */
469         UTIL_LOG_ERR("Failed RSA_public_encrypt\n");
470         status = -1;
471         goto rsaEncryptEnd;
472     }
473     status = 0;
474 
475     rsaEncryptEnd:
476     if (pRsaPubKey != NULL) {
477         RSA_free(pRsaPubKey);
478     }
479     return status;
480 }
481 
482 
483 /**
484  * @brief Decrypts data using RSA.
485  *
486  * The function follows the steps:
487  * 1. Read RSA private key structure
488  * 2. Call function according to PKCS version to create RSA signature
489  *
490  * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
491  * @param[in] pPrivKeyFileName - the private key file
492  * @param[in] pPrivKeyPwd - the passphrase string
493  * @param[in] pEnDataIn - the data to decrypt
494  * @param[in] enDataInSize - the encrypted data size
495  * @param[out] pData - the decrypted data
496  *
497  */
498 /*********************************************************/
CC_CommonRsaDecrypt(int32_t pkcsVersion,int8_t * pPrivKeyFileName,int8_t * pPrivKeyPwd,int8_t * pEnDataIn,int32_t enDataInSize,int8_t * pData)499 int32_t CC_CommonRsaDecrypt(int32_t pkcsVersion,
500               int8_t *pPrivKeyFileName,
501               int8_t *pPrivKeyPwd,
502               int8_t *pEnDataIn,
503               int32_t  enDataInSize,
504               int8_t *pData)
505 {
506     RSA  *pRsaPrivKey = NULL;
507     uint8_t *pwd = NULL;
508     int32_t status = -1;
509 
510     if ((NULL == pPrivKeyFileName) ||
511         (NULL == pEnDataIn) ||
512         (NULL == pData)) {
513         UTIL_LOG_ERR("ilegal input\n");
514         return(status);
515     }
516 
517     /* parse the passphrase for a given file */
518     if ((NULL != pPrivKeyPwd)) {
519         if (CC_CommonGetPassphrase(pPrivKeyPwd, &pwd)) {
520         UTIL_LOG_ERR("Failed to retrieve pwd\n");
521         goto rsaDecryptEnd;
522         }
523     }
524 
525     /* build RSA key from pem private key file */
526     pRsaPrivKey = RSA_new();
527     if (NULL == pRsaPrivKey) {
528         UTIL_LOG_ERR("Failed RSA_new\n");
529         goto rsaDecryptEnd;
530     }
531     if (CC_CommonGetKeyPair (&pRsaPrivKey, pPrivKeyFileName, pwd) < 0) {
532         UTIL_LOG_ERR("Cannot read RSA key pair\n");
533         goto rsaDecryptEnd;
534     }
535 
536     /* now decrypt the data */
537     status = RSA_private_decrypt(enDataInSize, pEnDataIn, pData, pRsaPrivKey, RSA_PKCS1_OAEP_PADDING);
538     if (status != (-1)) {  /* RSA_private_decrypt returns the size of the recovered plaintext. On error, -1 is returned */
539         status = 0;
540     }
541 
542     rsaDecryptEnd:
543     if (pRsaPrivKey != NULL) {
544         RSA_free(pRsaPrivKey);
545     }
546     if (pwd != NULL) {
547         free(pwd);
548     }
549     return status;
550 }
551 
552 
553 
554 
555 
556 /**
557 * @brief Calculates the H it returns it as binary string
558 *
559 * @param[in] N_ptr - public key N, represented as array of ascii's (0xbc is translated
560 *                    to 0x62 0x63)
561 * @param[out] H_ptr - The H result. H size is N_SIZE_IN_BYTES*2 + 1
562 *
563 */
564 /*********************************************************/
CC_CommonRsaCalculateH(const int8_t * N_ptr,int8_t * H_ptr)565 int32_t CC_CommonRsaCalculateH(const int8_t *N_ptr, int8_t *H_ptr)
566 {
567     int8_t *H_res = NULL, *N_Temp = NULL, *H_resTemp = NULL;
568     int32_t len, i;
569     int32_t status = -1;
570     uint32_t s = SB_CERT_RSA_KEY_SIZE_IN_BITS + 2;
571 
572     BN_CTX *bn_ctx = BN_CTX_new();
573 
574     BIGNUM *bn_two   = BN_new();
575     BIGNUM *bn_twos  = BN_new();
576     BIGNUM *bn_n     = BN_new();
577     BIGNUM *bn_h     = BN_new();
578 
579     if ((NULL == N_ptr) || ( NULL == H_ptr)) {
580         UTIL_LOG_ERR("illegal input\n");
581         goto calcH_end;
582     }
583 
584     /* Copy the N to temporary N, allocate temporary N in N size + 2 */
585     N_Temp= (int8_t *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (int8_t));
586     if (NULL == N_Temp) {
587         UTIL_LOG_ERR("malloc N_Temp failed\n");
588         goto calcH_end;
589     }
590 
591     /* set the temporary N to 0 */
592     memset (N_Temp, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2));
593 
594     /* Copy the N to temp N */
595     memcpy (N_Temp, N_ptr, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2);
596 
597     /* Allocate the output buffer */
598     H_res = (int8_t *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (int8_t));
599     if (NULL == H_res) {
600         UTIL_LOG_ERR("malloc H_res failed\n");
601         goto calcH_end;
602     }
603 
604     BN_set_word (bn_two, 2);
605     BN_set_word (bn_twos, 2 * s);
606 
607     if (!BN_hex2bn(&bn_n, N_Temp)) {
608         UTIL_LOG_ERR("BN_hex2bn failed.");
609         goto calcH_end;
610     }
611 
612     if (!BN_mod_exp(bn_h, bn_two, bn_twos, bn_n, bn_ctx)) {
613         UTIL_LOG_ERR("BN_mod_exp failed\n");
614         goto calcH_end;
615     }
616 
617     H_resTemp = BN_bn2hex(bn_h);
618     if (H_resTemp == NULL) {
619         UTIL_LOG_ERR("BN_bn2hex failed\n");
620         goto calcH_end;
621     }
622 
623     if (H_resTemp[0] == '-'){ // in case the output is negative
624         UTIL_LOG_ERR("BN_bn2hex returned negative value\n");
625         goto calcH_end;
626     }
627     len = (int32_t)strlen (H_resTemp);
628     memcpy(H_res, H_resTemp, len);
629 
630     if (len < SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2) {
631         memmove (H_res + (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 - len), H_res, len + 1);
632         for (i = 0; i < (int32_t)(SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 - len); i++) {
633             H_res[i] = '0';
634         }
635     }
636 
637     /* Set the output with 0 and than copy the result */
638     memset (H_ptr, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2)); //VERIFY THAT USER SENDS THE SAME SIZE
639     memcpy ((int8_t *)H_ptr, (int8_t *)H_res, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2);
640 
641     status = 0;
642 
643     calcH_end:
644     if (N_Temp != NULL) {
645         free(N_Temp);
646     }
647     if (H_res != NULL) {
648         free(H_res);
649     }
650     if (bn_two != NULL) {
651         BN_free(bn_two);
652     }
653     if (bn_twos != NULL) {
654         BN_free(bn_twos);
655     }
656     if (bn_n != NULL) {
657         BN_free(bn_n);
658     }
659     if (bn_h != NULL) {
660         BN_free(bn_h);
661     }
662     if (bn_ctx != NULL) {
663         BN_CTX_free(bn_ctx);
664     }
665     if (H_resTemp != NULL) {
666         OPENSSL_free(H_resTemp);
667     }
668     return(status);
669 }
670 
671 
672 /**
673 * @brief Reads RSA key from the file using passphrase and returns its decrypted value.
674 *
675 * @param[in] PemEncryptedFileName_ptr - file name
676 * @param[in] Key_ptr - passphrase
677 */
678 /*********************************************************/
CC_CommonRsaLoadKey(int8_t * PemEncryptedFileName_ptr,int8_t * Key_ptr,int8_t * PemDecryted)679 int32_t CC_CommonRsaLoadKey(int8_t *PemEncryptedFileName_ptr, int8_t *Key_ptr, int8_t *PemDecryted)
680 {
681     RSA *rsa_pkey = NULL;
682     int8_t buffer [256];
683     BIO *out=NULL;
684     int32_t status = -1;
685 
686     *PemDecryted = '\0';
687     if (CC_CommonGetKeyPair (&rsa_pkey, PemEncryptedFileName_ptr, Key_ptr) < 0) {
688         UTIL_LOG_ERR ("failed to CC_CommonGetKeyPair\n");
689         goto rsaLoadKey_end;
690     }
691 
692     out = BIO_new (BIO_s_mem());
693     if (PEM_write_bio_RSAPrivateKey (out, rsa_pkey, NULL, NULL, 0, 0, NULL) <= 0) {
694         UTIL_LOG_ERR ("failed to PEM_write_bio_RSAPrivateKey\n");
695         goto rsaLoadKey_end;
696     }
697 
698     while (BIO_gets (out, buffer, sizeof(buffer)) > 0) {
699         if (strlen (PemDecryted) + strlen (buffer) + 2 > RSA_PRIVATE_KEY_SIZE) {
700             UTIL_LOG_ERR ("Internal error: The output buffer is too few\n");
701             break;
702         }
703         strncat (PemDecryted, buffer, strlen (buffer));
704     }
705     status = 0;
706 
707     rsaLoadKey_end:
708     if (rsa_pkey != NULL) {
709         RSA_free (rsa_pkey);
710     }
711     if (out != NULL) {
712         BIO_free_all(out);
713     }
714     return status;
715 }
716 
717 /**
718 * @brief Generates random byte buffer
719 *
720 * @param[in] numBytes - nuber of bytes to random
721 * @param[out] buf - buffer
722 */
723 /*********************************************************/
CC_CommonRandBytes(int32_t numBytes,int8_t * buf)724 int32_t CC_CommonRandBytes(int32_t numBytes, int8_t *buf)
725 {
726     int32_t result = -1;
727 
728     if (numBytes > 0) {
729         result = RAND_bytes (buf, numBytes);
730         if (result <= 0) {
731             UTIL_LOG_ERR("\nCC_CommonRandBytes - Internal error: Function RAND_bytes failed\n");
732             return 1;
733         }
734         return 0;
735     }
736     return result;
737 }
738 
739 
740 
741