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_util.h"
21 #include "common_util_files.h"
22 #include "common_util_log.h"
23 #include "common_crypto_sym.h"
24 #include "cc_pka_hw_plat_defs.h"
25 #define RSA_OAEP_KEY_SIZE_IN_BITS 2048UL //temp -RC
26 #define RSA_OAEP_KEY_SIZE_IN_BYTES (RSA_OAEP_KEY_SIZE_IN_BITS/8) //temp -RC
27 
28 /************************************* Globals  *************************************/
29 
30 uint8_t gNp[NP_SIZE_IN_BYTES] = {0};
31 DxRsaKeyNandNp_t gNAndNp = {0};
32 uint8_t gN[SB_CERT_RSA_KEY_SIZE_IN_BYTES +1] = {0};
33 
34 
35 /**
36 * @brief The function reads RSA key from the file and returns its N and Np.
37 *
38 * @param[in] PemEncryptedFileName_ptr - file name of the key pair
39 * @param[in] pwdFileName - file name of the password
40 * @param[out] pNbuff - N  buffer
41 * @param[in/out] pNbuffSize - as input - max size of pNbuff
42 *                              as output - actual size of pNbuff
43 */
44 /*********************************************************/
CC_CommonGetNbuffFromKeyPair(int8_t * PemEncryptedFileName_ptr,int8_t * pwdFileName,uint8_t * pNbuff,uint32_t * pNbuffSize)45 int32_t CC_CommonGetNbuffFromKeyPair(int8_t *PemEncryptedFileName_ptr, int8_t *pwdFileName, uint8_t *pNbuff, uint32_t *pNbuffSize)
46 {
47 
48     int32_t status = -1;
49     uint8_t *pwd = NULL;
50     RSA *rsa_pkey = NULL;
51     int32_t i;
52 
53     if ((NULL == pNbuff) ||
54         (NULL == pNbuffSize) ||
55         (NULL == PemEncryptedFileName_ptr)) {
56         return status;
57     }
58     if (*pNbuffSize != SB_CERT_RSA_KEY_SIZE_IN_BYTES) {
59         return status;
60     }
61 
62     /* parse the passphrase for a given file */
63     if ((NULL != pwdFileName)) {
64         if (CC_CommonGetPassphrase(pwdFileName, &pwd) != 0) {
65             UTIL_LOG_ERR("Failed to retrieve pwd\n");
66             goto END;
67         }
68         }
69 
70     rsa_pkey = RSA_new();
71     if (NULL == rsa_pkey) {
72         UTIL_LOG_ERR("Failed RSA_new\n");
73         goto END;
74     }
75     if (CC_CommonGetKeyPair (&rsa_pkey, PemEncryptedFileName_ptr, pwd) != 0) {
76         UTIL_LOG_ERR("Cannot read RSA public key.\n");
77         goto END;
78     }
79 
80     /* get the modulus from BIGNUM to uint8_t* */
81     BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
82     UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
83 
84     /* copy the Np to the end of N */
85     memcpy(pNbuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
86     *pNbuffSize = SB_CERT_RSA_KEY_SIZE_IN_BYTES;
87     status = 0;
88 
89 
90     END:
91     if (rsa_pkey != NULL) {
92         RSA_free(rsa_pkey);
93     }
94     if (pwd != NULL) {
95         free(pwd);
96     }
97     return status;
98 }
99 
100 
101 
102 /**
103 * @brief The function reads RSA key from the file and returns its N and Np.
104 *
105 * @param[in] PemEncryptedFileName_ptr - file name of the key pair
106 * @param[in] pwdFileName - file name of the password
107 * @param[out] pNAndNp - N and Np buffer
108 * @param[in/out] pNAndNpSize - as input - max size of pNAndNp
109 *                              as output - actual size of pNAndNp
110 */
111 /*********************************************************/
CC_CommonGetNAndNpFromKeyPair(int8_t * PemEncryptedFileName_ptr,int8_t * pwdFileName,uint8_t * pNAndNp,uint32_t * pNAndNpSize)112 int32_t CC_CommonGetNAndNpFromKeyPair(int8_t *PemEncryptedFileName_ptr, int8_t *pwdFileName, uint8_t *pNAndNp, uint32_t *pNAndNpSize)
113 {
114 
115     int32_t status = -1;
116     uint8_t *pwd = NULL;
117     RSA *rsa_pkey = NULL;
118     DxRsaKeyNandNp_t *pNandNpBuff = (DxRsaKeyNandNp_t *)pNAndNp;
119     int32_t i;
120 
121     if ((NULL == pNAndNp) ||
122         (NULL == pNAndNpSize) ||
123         (NULL == PemEncryptedFileName_ptr)) {
124         return status;
125     }
126     if (*pNAndNpSize != sizeof(DxRsaKeyNandNp_t)) {
127         return status;
128     }
129 
130     /* parse the passphrase for a given file */
131     if ((NULL != pwdFileName)) {
132         if (CC_CommonGetPassphrase(pwdFileName, &pwd) != 0) {
133             UTIL_LOG_ERR("Failed to retrieve pwd %s\n", pwdFileName);
134             goto END;
135         }
136     }
137 
138     rsa_pkey = RSA_new();
139 
140     if (NULL == rsa_pkey) {
141         UTIL_LOG_ERR("Failed RSA_new\n");
142         goto END;
143     }
144     if (CC_CommonGetKeyPair (&rsa_pkey, PemEncryptedFileName_ptr, pwd)  != 0) {
145         UTIL_LOG_ERR("Cannot read RSA public key.\n");
146         goto END;
147     }
148 
149     /* get the modulus from BIGNUM to uint8_t* */
150     BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
151 
152     /* calculate the Np, and get the output as BIGNUM*/
153     if (CC_CommonRSACalculateNpInt(rsa_pkey->n, gNp, NP_BIN)) {
154         UTIL_LOG_ERR("Failed creating Np\n");
155         goto END;
156     }
157 
158     /* copy the Np to the end of N */
159     memcpy(pNandNpBuff->pNBuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
160     memcpy(pNandNpBuff->pNpBuff, gNp, NP_SIZE_IN_BYTES);
161     *pNAndNpSize = (SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES);
162     UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
163     UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
164     status = 0;
165 
166 
167     END:
168     if (rsa_pkey != NULL) {
169         RSA_free(rsa_pkey);
170     }
171     if (pwd != NULL) {
172         free(pwd);
173     }
174     return status;
175 }
176 
177 
178 
179 /**
180 * @brief The function reads RSA key from the file and returns its N and Np.
181 *
182 * @param[in] pubKeyFileName_ptr - file name of the key pair
183 * @param[out] pNAndNp - N and Np buffer
184 * @param[in/out] pNAndNpSize - as input - max size of pNAndNp
185 *                              as output - actual size of pNAndNp
186 */
187 /*********************************************************/
CC_CommonGetNAndNpFromPubKey(int8_t * pubKeyFileName_ptr,uint8_t * pNAndNp,uint32_t * pNAndNpSize)188 int32_t CC_CommonGetNAndNpFromPubKey(int8_t *pubKeyFileName_ptr, uint8_t *pNAndNp, uint32_t *pNAndNpSize)
189 {
190     int32_t status = -1;
191     int32_t i;
192     RSA *rsa_pkey = NULL;
193     DxRsaKeyNandNp_t *pNandNpBuff = (DxRsaKeyNandNp_t *)pNAndNp;
194 
195     if ((NULL == pNAndNp) ||
196         (NULL == pNAndNpSize) ||
197         (NULL == pubKeyFileName_ptr)) {
198         return status;
199     }
200     if (*pNAndNpSize != sizeof(DxRsaKeyNandNp_t)) {
201         return status;
202     }
203     rsa_pkey = RSA_new();
204     if (NULL == rsa_pkey) {
205         UTIL_LOG_ERR("Failed RSA_new\n");
206         goto END;
207     }
208     if (CC_CommonGetPubKey (&rsa_pkey, pubKeyFileName_ptr) < 0) {
209         UTIL_LOG_ERR("Cannot read RSA public key.\n");
210         goto END;
211     }
212 
213     /* get the modulus from BIGNUM to uint8_t* */
214     BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
215 
216     /* calculate the Np, and get the output as BIGNUM*/
217     if (CC_CommonRSACalculateNpInt(rsa_pkey->n, gNp, NP_BIN) != 0) {
218         UTIL_LOG_ERR("Failed creating Np\n");
219         goto END;
220     }
221 
222     /* copy the Np to the end of N */
223     memcpy(pNandNpBuff->pNBuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
224     memcpy(pNandNpBuff->pNpBuff, gNp, NP_SIZE_IN_BYTES);
225     *pNAndNpSize = (SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES);
226     UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
227     UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
228     status = 0;
229 
230     END:
231     if (rsa_pkey != NULL) {
232         RSA_free(rsa_pkey);
233     }
234     return status;
235 }
236 
237 
238 /**
239 * @brief The CC_CommonCalcHBKFromBuff calculates Np from given pNbuff.
240 *        Then calculates HASH both N and Np
241 *
242 * @param[in] pNBuff - the N - modulus buff
243 * @param[out] pHash - hash output
244 * @param[in] hashSize - hash output size
245 */
246 /*********************************************************/
CC_CommonCalcHBKFromBuff(int8_t * pNBuff,uint8_t * pHash,int32_t hashSize)247 int32_t CC_CommonCalcHBKFromBuff(int8_t* pNBuff, uint8_t *pHash, int32_t hashSize)
248 {
249 
250     int32_t status = -1;
251     int32_t i;
252     BIGNUM *bn_n = NULL;
253 
254     memcpy((uint8_t *)&gNAndNp, pNBuff, RSA_OAEP_KEY_SIZE_IN_BYTES);
255     UTIL_LOG_BYTE_BUFF("gN", (uint8_t *)&gNAndNp, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
256 
257     /* calculate the Np */
258     bn_n = BN_bin2bn(pNBuff, SB_CERT_RSA_KEY_SIZE_IN_BYTES, bn_n);
259     if (NULL == bn_n) {
260         UTIL_LOG_ERR ("BN_bin2bn failed\n");
261         return -1;
262     }
263 
264     if (CC_CommonRSACalculateNpInt(bn_n, gNp, NP_BIN) != 0) {
265         UTIL_LOG_ERR ("BN_bin2bn failed\n");
266         goto END;
267     }
268     UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
269 
270     /* copy the Np to the end of N and calc hash on both */
271     memcpy(gNAndNp.pNpBuff, gNp, NP_SIZE_IN_BYTES);
272 
273     /* write hash*/
274     /* calculate hash and write to */
275     if (CC_CommonCalcHash((uint8_t *)&gNAndNp, sizeof(gNAndNp), pHash, hashSize) != 0) {
276         UTIL_LOG_ERR ("Common_CalcHashOnPubKey failed\n");
277         goto END;
278     }
279 
280     /* write hash*/
281     status = 0;
282 
283     END:
284     if (bn_n != NULL) {
285         BN_free(bn_n);
286     }
287     return status;
288 }
289 
290 /**
291 * @brief The CC_CommonCalcHBKFromFile reads RSA key from the file using passphrase
292 *        and returns its decrypted value.
293 *
294 * @param[in] pubKeyFileName_ptr - file name of the public key
295 * @param[out] pHash - hash output
296 * @param[in] hashSize - hash output size
297 */
298 /*********************************************************/
CC_CommonCalcHBKFromFile(int8_t * pubKeyFileName_ptr,uint8_t * pHash,int32_t hashSize)299 int32_t CC_CommonCalcHBKFromFile(int8_t* pubKeyFileName_ptr, uint8_t *pHash, int32_t hashSize)
300 {
301 
302     int32_t status = -1;
303     int32_t i;
304     RSA *rsa_pkey = NULL;
305 
306     rsa_pkey = RSA_new();
307     if (NULL == rsa_pkey) {
308         UTIL_LOG_ERR("Failed RSA_new\n");
309         goto END;
310     }
311     if (CC_CommonGetPubKey (&rsa_pkey, pubKeyFileName_ptr) != 0) {
312         UTIL_LOG_ERR("Cannot read RSA public key\n");
313         goto END;
314     }
315 
316     /* get the modulus from BIGNUM to uint8_t* */
317     BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
318     UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
319 
320     /* calculate the Np, and get the output as BIGNUM*/
321     if (CC_CommonRSACalculateNpInt(rsa_pkey->n, gNp, NP_BIN) != 0) {
322         UTIL_LOG_ERR("Failed creating Np\n");
323         goto END;
324     }
325     UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
326 
327     /* copy the Np to the end of N and calc hash on both */
328     memcpy(gNAndNp.pNBuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
329     memcpy(gNAndNp.pNpBuff, gNp, NP_SIZE_IN_BYTES);
330     /* write hash*/
331 
332     /* calculate hash and write to */
333     if (CC_CommonCalcHash((uint8_t *)&gNAndNp, SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES, pHash, hashSize) != 0) {
334         UTIL_LOG_ERR ("Common_CalcHashOnPubKey failed\n");
335         goto END;
336     }
337 
338     /* write hash*/
339     status = 0;
340 
341     END:
342     if (rsa_pkey != NULL) {
343         RSA_free(rsa_pkey);
344     }
345     return status;
346 }
347 
348 
349 
350