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