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 #include <stdint.h>
12 
13 
14 #include <openssl/err.h>
15 #include <openssl/pem.h>
16 #include <openssl/opensslv.h>
17 #include <openssl/conf.h>
18 #include <openssl/x509v3.h>
19 
20 #include "common_crypto_x509.h"
21 #include "common_crypto_asym.h"
22 #include "common_rsa_keypair.h"
23 #include "common_util_files.h"
24 #include "common_util_log.h"
25 #include "cc_crypto_boot_defs.h"
26 #include "cc_crypto_x509_defs.h"
27 
28 #ifdef CC_SB_SUPPORT_IOT
29 #include "secdebug_defs.h"
30 #endif
31 
32 #define X509_VER_3  2  /* version 3 certificate */
33 #define ENDLESS_VALIDITY  0xFFFFFFFE
34 #define MAX_OBJ_ID_LEN  15
35 #define EXT_PREFIX_LEN  16
36 #ifdef CC_SB_SUPPORT_IOT
37 #define MAX_EXT_VAL_LIST (CC_SB_MAX_CONTENT_CERT_BODY_SIZE_IN_BYTES)
38 #else
39 #define MAX_EXT_VAL_LIST 80 // additional data
40 #endif
41 #define MAX_EXT_INT_VAL_LEN  80
42 
43 /* multiple each byte by 3 for: each byte has 2 character representaion + ":" */
44 #define MAX_EXT_VAL_LEN  (MAX_EXT_VAL_LIST *3 + EXT_PREFIX_LEN)
45 #define CHAR_STR_LEN 6
46 
47 #define OPEN_SSL_ERROR   0
48 #define IS_VALID_ENC_FLAG(encFlag) ((0 == (encFlag)) || (1 == (encFlag)) || (0xFF == (encFlag)))
49 #define IS_VALID_HBK(hbkType) ((CC_SB_HASH_BOOT_KEY_0_128B == (hbkType)) ||\
50                    (CC_SB_HASH_BOOT_KEY_1_128B == (hbkType)) ||\
51                    (CC_SB_HASH_BOOT_KEY_256B == (hbkType)) ||\
52                    (CC_SB_HASH_BOOT_NOT_USED == (hbkType)))
53 
54 const uint8_t *certType2Str[CC_X509_CERT_TYPE_MAX] = {NULL,
55   /*CC_X509_CERT_TYPE_KEY      */      (uint8_t *)CC_X509_CERT_KEY_CERT,
56   /*CC_X509_CERT_TYPE_CONTENT  */      (uint8_t *)CC_X509_CERT_CNT_CERT,
57   /*CC_X509_CERT_TYPE_ENABLER_DBG */      (uint8_t *)CC_X509_CERT_ENABLER_CERT,
58   /*CC_X509_CERT_TYPE_DEVELOPER_DBG */      (uint8_t *)CC_X509_CERT_DEVELOPER_CERT
59 };
60 
61 
62 /**
63 * @brief free X509 certificate
64 *
65 * @param[in/out] ppCertBuff          - x.509 certificate
66 */
67 /*********************************************************/
CC_CommonX509Free(uint8_t ** ppCertBuff)68 void CC_CommonX509Free(uint8_t **ppCertBuff)
69 {
70     /* validate inputs */
71     if ((NULL == ppCertBuff) ||
72         (NULL == *ppCertBuff)) {
73         UTIL_LOG_ERR("ilegal input\n");
74         return;
75     }
76 
77     UTIL_LOG_INFO("about to X509_free\n");
78     /* create the certificate buffer */
79     X509_free((X509 *)*ppCertBuff);
80     *ppCertBuff = NULL;
81     return;
82 }
83 
84 
85 /**
86 * @brief Creates X509 certificate and set its header fields
87 *
88 * @param[in/out] ppCertBuff     - x.509 certificate
89 * @param[in] certType           - certificate type
90 */
91 /*********************************************************/
CC_CommonX509CreateAndSetHeader(uint8_t ** ppCertBuff,CCX509CertType_t certType,CCX509CertHeaderParamsIn_t * pCertHeaderParams)92 int32_t CC_CommonX509CreateAndSetHeader(uint8_t **ppCertBuff,
93                 CCX509CertType_t  certType,CCX509CertHeaderParamsIn_t *pCertHeaderParams)
94 {
95     int32_t rc = 0;
96     long endDate = 0;
97     uint32_t  serialNum = 0;
98     long notBefore = 0; /*X509_CURRENT_TIME*/
99     long notAfter = ENDLESS_VALIDITY;
100     char* pIssuerName = CC_X509_CERT_ISSUER_NAME;
101     const char* pSubjectName = certType2Str[certType];
102     X509 *plCert = NULL;
103     ASN1_TIME *pDummy = NULL;
104 
105     /* validate inputs */
106     if ((NULL == ppCertBuff) ||
107         (certType >= CC_X509_CERT_TYPE_MAX) ) {
108         UTIL_LOG_ERR("ilegal input\n");
109         return(-1);
110     }
111 
112     /* create the certificate buffer */
113     plCert = (X509 *)X509_new();
114     if (OPEN_SSL_ERROR == plCert) {
115         UTIL_LOG_ERR("failed to X509_new\n");
116         return 1;
117     }
118 
119     /* set certificate version to V3 */
120     rc = X509_set_version(plCert, X509_VER_3);
121     if (OPEN_SSL_ERROR == rc) {
122         UTIL_LOG_ERR("failed to X509_set_version\n");
123         rc = 1;
124         goto END;
125     }
126     /* set certificate serial number */
127     if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setSerialNum) ) {
128         serialNum = pCertHeaderParams->serialNum;
129     } else {
130         rc = CC_CommonRandBytes(4, (int8_t *)&serialNum);
131         if (rc != 0) {
132             UTIL_LOG_ERR("failed to set CC_CommonRandBytes\n");
133             rc = 1;
134             goto END;
135         }
136     }
137 
138     rc = ASN1_INTEGER_set(X509_get_serialNumber(plCert), serialNum);
139     if (OPEN_SSL_ERROR == rc) {
140         UTIL_LOG_ERR("failed to set X509_get_serialNumber\n");
141         rc = 1;
142         goto END;
143     }
144     /* set ecrtificate start time to current time, and end date according to input */
145     if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setNotBefore) ) {
146         notBefore = pCertHeaderParams->notBefore;
147     }
148     pDummy = X509_gmtime_adj(X509_get_notBefore(plCert), (long)notBefore );
149     if (NULL == pDummy) {
150         UTIL_LOG_ERR("failed set X509_get_notBefore\n");
151         rc = 1;
152         goto END;
153     }
154     if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setNotAfter) ) {
155         notAfter = pCertHeaderParams->notAfter;
156     }
157     pDummy = X509_gmtime_adj(X509_get_notAfter(plCert),(long)notAfter);
158     if (NULL == pDummy) {
159         UTIL_LOG_ERR("failed set X509_get_notAfter\n");
160         rc = 1;
161         goto END;
162     }
163 
164     /* set subject name */
165     if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setSubjectName) ) {
166         pSubjectName = pCertHeaderParams->SubjectName;
167     }
168     rc = X509_NAME_add_entry_by_txt(X509_get_subject_name(plCert),
169                         "CN",       /* common name */
170                         MBSTRING_ASC,
171                         pSubjectName,
172                         -1,
173                         -1, 0);
174     if (OPEN_SSL_ERROR == rc) {
175         UTIL_LOG_ERR("failed to set X509_get_subject_name\n");
176         rc = 1;
177         goto END;
178     }
179 
180     /* set issuer name */
181     if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setIssuerName) ) {
182         pIssuerName = pCertHeaderParams->IssuerName;
183     }
184     rc = X509_NAME_add_entry_by_txt(X509_get_issuer_name(plCert),
185                         "CN",
186                         MBSTRING_ASC,
187                         pIssuerName,
188                         -1,
189                         -1, 0);
190     if (OPEN_SSL_ERROR == rc) {
191         UTIL_LOG_ERR("failed to set X509_get_issuer_name\n");
192         rc = 1;
193         goto END;
194     }
195 
196 
197 
198     *ppCertBuff = (uint8_t *)plCert;
199     rc = 0;
200     UTIL_LOG_INFO("OK\n");
201 
202     END:
203     if (rc != 0) {
204         if (plCert != NULL) {
205             X509_free(plCert);
206         }
207         *ppCertBuff = NULL;
208     }
209     return rc;
210 }
211 
212 
213 /**
214 * @brief Add ASN.1 critical integer extension to X.509V3 certificate
215 *
216 * @param[in/out] pCertBuff          - x.509 certificate
217 * @param[in] certType                 - certificate type
218 * @param[in] extType              - extension type
219 * @param[in] val              - Extension value
220 */
221 /*********************************************************/
CC_CommonX509AddIntegerExtension(uint8_t * pCertBuff,CCX509CertType_t certType,CCX509ExtType_t extType,int32_t val)222 int32_t CC_CommonX509AddIntegerExtension(uint8_t *pCertBuff,
223                        CCX509CertType_t certType,
224                        CCX509ExtType_t  extType,
225                        int32_t val)
226 
227 {
228     int32_t rc = 0;
229     int32_t nid = 0;
230     X509 *plCert = (X509 *)pCertBuff;
231     X509_EXTENSION *ext = NULL;
232     uint8_t objId[MAX_OBJ_ID_LEN];
233     uint8_t extValue[MAX_EXT_INT_VAL_LEN];
234     int32_t writtenBytes = 0;
235 
236     /* validate inputs */
237     if (NULL == pCertBuff) {
238         UTIL_LOG_ERR("Illegal parameters \n");
239         return (-1);
240     }
241 
242     /* create new object */
243     snprintf(objId, MAX_OBJ_ID_LEN, "2.20.%d.%d",certType,extType);
244     nid = OBJ_create(objId, "MyAlias", "My Test Alias Extension");
245     if (OPEN_SSL_ERROR == nid) {
246         UTIL_LOG_ERR("failed to OBJ_create\n");
247         ERR_print_errors_fp(stderr);
248         rc = 1;
249         goto END;
250     }
251     rc = X509V3_EXT_add_alias(nid, NID_netscape_comment);
252     if (OPEN_SSL_ERROR == nid) {
253         UTIL_LOG_ERR("failed to X509V3_EXT_add_alias\n");
254         ERR_print_errors_fp(stderr);
255         rc = 1;
256         goto END;
257     }
258     /* create the extension value */
259     writtenBytes = snprintf(extValue, MAX_EXT_INT_VAL_LEN, "critical,ASN1:INTEGER:0x%X",val);
260     /* build the extension */
261     ext = X509V3_EXT_conf_nid(NULL, NULL, nid, extValue);
262     if (OPEN_SSL_ERROR == ext) {
263         UTIL_LOG_ERR("failed to X509V3_EXT_conf_nid\n");
264         ERR_print_errors_fp(stderr);
265         rc = 1;
266         goto END;
267     }
268 
269     /* Add the extension to the certificate */
270     rc = X509_add_ext(plCert, ext, -1);
271     if (OPEN_SSL_ERROR == rc) {
272         UTIL_LOG_ERR("failed to X509_add_ext\n");
273         ERR_print_errors_fp(stderr);
274         rc = 1;
275         goto END;
276     }
277     rc = 0;
278     UTIL_LOG_INFO("OK\n");
279 
280     END:
281     X509_EXTENSION_free(ext);
282     return rc;
283 }
284 
285 
286 /**
287 * @brief Add critical DER extension to X.509V3 certificate
288 *
289 * @param[in/out] pCertBuff          - x.509 certificate
290 * @param[in] certType                 - certificate tyoes
291 * @param[in] extType              - extension type
292 * @param[in] pVal                 - Extension data
293 * @param[in] valLen               - extension data length
294 */
295 /*********************************************************/
CC_CommonX509AddStringExtension(uint8_t * pCertBuff,CCX509CertType_t certType,CCX509ExtType_t extType,uint8_t * pVal,uint32_t valLen)296 int32_t CC_CommonX509AddStringExtension(uint8_t *pCertBuff,
297                       CCX509CertType_t  certType,
298                       CCX509ExtType_t  extType,
299                       uint8_t *pVal,
300                       uint32_t valLen)
301 
302 {
303     int32_t rc = 0;
304     int32_t nid;
305     X509 *plCert = (X509 *)pCertBuff;
306     X509_EXTENSION *ext = NULL;
307     uint8_t objId[MAX_OBJ_ID_LEN];
308     uint8_t extValue[MAX_EXT_VAL_LEN];
309     int32_t writtenBytes = 0;
310     int32_t pValIdx = 0;
311 
312     /* validate inputs */
313     if ((NULL == pCertBuff) ||
314         (NULL == pVal)||
315         (valLen > MAX_EXT_VAL_LIST)) {
316         UTIL_LOG_ERR("Illegal parameters \n");
317         return (-1);
318     }
319     /* create new object */
320     snprintf(objId, MAX_OBJ_ID_LEN, "2.20.%d.%d",certType,extType);
321     nid = OBJ_create(objId, "MyAlias", "My Test Alias Extension");
322     if (OPEN_SSL_ERROR == nid) {
323         UTIL_LOG_ERR("failed to OBJ_create\n");
324         ERR_print_errors_fp(stderr);
325         rc = 1;
326         goto END;
327     }
328 
329     pValIdx = 0;
330     writtenBytes = snprintf(extValue, MAX_EXT_VAL_LEN, "critical,DER: %02X",pVal[pValIdx++]);
331     UTIL_LOG_INFO("writtenBytes %d, extValue %s\n",writtenBytes, extValue);
332     while (pValIdx < valLen) {
333         writtenBytes += snprintf((extValue+writtenBytes), CHAR_STR_LEN, ":%02X", pVal[pValIdx++]);
334         UTIL_LOG_INFO("writtenBytes %d, extValue %s\n",writtenBytes, extValue);
335     }
336 
337     rc = X509V3_EXT_add_alias(nid, NID_netscape_comment);  // if NID is unknown openssl ignores it. meaning it is not added to cert.
338     if (OPEN_SSL_ERROR == rc) {
339         UTIL_LOG_ERR("failed to X509V3_EXT_add_alias\n");
340         ERR_print_errors_fp(stderr);
341         rc = 1;
342         goto END;
343     }
344 
345     ext = X509V3_EXT_conf_nid(NULL, NULL, nid, extValue);
346     if (OPEN_SSL_ERROR == ext) {
347         UTIL_LOG_ERR("failed to X509V3_EXT_conf_nid\n");
348         ERR_print_errors_fp(stderr);
349         rc = 1;
350         goto END;
351     }
352 
353     /* Add the extension to the certificate */
354     rc = X509_add_ext(plCert, ext, -1);
355     if (OPEN_SSL_ERROR == rc) {
356         UTIL_LOG_ERR("failed to X509_add_ext\n");
357         ERR_print_errors_fp(stderr);
358         rc = 1;
359         goto END;
360     }
361     rc = 0;
362     UTIL_LOG_INFO("OK\n");
363 
364     END:
365         if (ext != NULL) {
366                 X509_EXTENSION_free(ext);
367         }
368     return rc;
369 }
370 
371 
372 /**
373 * @brief Add subject public key to the X509 certificate
374 *   and sign the certificate
375 *
376 * @param[in/out] pCertBuff      - x.509 certificate
377 * @param[in] pKeyPairFileName   - key pair file name in PEM format
378 * @param[in] pKeyPairPwd    - passphrase of key pair
379 */
380 /*********************************************************/
CC_CommonX509SetKeyAndSign(uint8_t * pCertBuff,uint8_t * pKeyPairFileName,uint8_t * pKeyPairPwd)381 int32_t CC_CommonX509SetKeyAndSign(uint8_t *pCertBuff,
382                 uint8_t *pKeyPairFileName,
383                 uint8_t *pKeyPairPwd)
384 {
385     int32_t rc = 0;
386     X509 *plCert = (X509 *)pCertBuff;
387     RSA  *pRsaKeyPair = NULL;
388     uint8_t *pwd = NULL;
389     EVP_PKEY *pKey     = NULL;
390     EVP_MD_CTX  mdCtx;
391     EVP_PKEY_CTX *pKeyCtx = NULL;
392 
393     /* validate inputs */
394     if ((NULL == pCertBuff) ||
395         (NULL == pKeyPairFileName)) {
396         UTIL_LOG_ERR("ilegal input\n");
397         return(-1);
398     }
399 
400     /* get certificate Subject's RSA public and private key from key pair file */
401     /* parse the passphrase for a given file */
402     if (pKeyPairPwd != NULL) {
403         rc = CC_CommonGetPassphrase(pKeyPairPwd, &pwd);
404         if (rc != CC_COMMON_OK) {
405             UTIL_LOG_ERR("Failed to retrieve pwd\n");
406             goto END;
407         }
408     }
409     pRsaKeyPair = RSA_new();
410     if (NULL == pRsaKeyPair) {
411         UTIL_LOG_ERR("Failed RSA_new\n");
412         goto END;
413     }
414     rc = CC_CommonGetKeyPair(&pRsaKeyPair, pKeyPairFileName, pwd);
415     if (rc != CC_COMMON_OK) {
416         UTIL_LOG_ERR("CC_CommonGetKeyPair Cannot read RSA private key\n");
417         rc = 1;
418         goto END;
419     }
420     /* allocate an empty EVP_PKEY structure which
421     is used by OpenSSL to store private keys.*/
422     pKey = EVP_PKEY_new();
423     if (NULL == pKey) {
424         UTIL_LOG_ERR("failed to EVP_PKEY_new\n");
425         rc = 1;
426         goto END;
427     }
428     /*set the referenced key to RSA key*/
429     rc = EVP_PKEY_assign_RSA(pKey, pRsaKeyPair);
430     if (OPEN_SSL_ERROR == rc) {
431         UTIL_LOG_ERR("failed to EVP_PKEY_assign_RSA\n");
432         rc = 1;
433         goto END;
434     }
435 
436 
437     EVP_MD_CTX_init(&mdCtx);
438     rc = EVP_DigestSignInit(&mdCtx, &pKeyCtx, EVP_sha256(), NULL, pKey);
439     if (OPEN_SSL_ERROR == rc) {
440         UTIL_LOG_ERR("failed to EVP_DigestSignInit\n");
441         rc = 1;
442         goto END;
443     }
444     rc = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING);
445     if (rc <= OPEN_SSL_ERROR) {
446         UTIL_LOG_ERR("failed to EVP_PKEY_CTX_set_rsa_padding\n");
447         rc = 1;
448         goto END;
449     }
450     rc = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN);
451     if (rc <= OPEN_SSL_ERROR) {
452         UTIL_LOG_ERR("failed to EVP_PKEY_CTX_set_rsa_pss_saltlen\n");
453         rc = 1;
454         goto END;
455     }
456     rc = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256());
457     if (rc <= OPEN_SSL_ERROR) {
458         UTIL_LOG_ERR("failed to EVP_PKEY_CTX_set_rsa_mgf1_md\n");
459         rc = 1;
460         goto END;
461     }
462     UTIL_LOG_INFO("about to X509_set_pubkey\n");
463     /*set the key into certificate*/
464     rc = X509_set_pubkey(plCert,pKey);
465     if (OPEN_SSL_ERROR == rc) {
466         UTIL_LOG_ERR("failed to X509_set_pubkey\n");
467         ERR_print_errors_fp(stderr);
468         rc = 1;
469         goto END;
470     }
471 
472     UTIL_LOG_INFO("about to X509_sign_ctx\n");
473     rc = X509_sign_ctx(plCert, &mdCtx);
474     if (OPEN_SSL_ERROR == rc) {
475         UTIL_LOG_ERR("failed to X509_sign\n");
476         rc = 1;
477         goto END;
478     }
479     rc = 0;
480     UTIL_LOG_INFO("OK\n");
481 
482 END:
483     EVP_MD_CTX_cleanup(&mdCtx);
484     if (pRsaKeyPair != NULL) {
485         RSA_free(pRsaKeyPair); // free pKey as well
486     }
487     if (pwd != NULL) {
488         free(pwd);
489     }
490     return rc;
491 }
492 
493 
494 /**
495 * @brief convert the x.509 certificate to DER format
496 *
497 * @param[in/out] ppCertBuff      - x.509 certificate
498 * @param[out] pOutCertSize  - certificate size in DER format
499 */
500 /*********************************************************/
CC_CommonX509ToDer(uint8_t ** ppCertBuff,uint32_t * pOutCertSize)501 int32_t CC_CommonX509ToDer(uint8_t **ppCertBuff,
502                 uint32_t *pOutCertSize)
503 {
504     unsigned char *outBuff = NULL;
505     uint8_t *pPemCertData = NULL;
506 
507     /* validate inputs */
508     if ((NULL == ppCertBuff) ||
509         (NULL == pOutCertSize)) {
510         UTIL_LOG_ERR("ilegal input\n");
511         return(-1);
512     }
513 
514 
515     *pOutCertSize = i2d_X509((X509 *)*ppCertBuff, &outBuff);
516     CC_CommonX509Free(ppCertBuff);
517     *ppCertBuff = outBuff;
518 
519     UTIL_LOG_INFO("OK\n");
520 
521     return 0;
522 }
523 
524 
525 #ifdef CC_SB_SUPPORT_IOT
526 
527 /**
528 * @brief build package for the certificate
529 *
530 * @param[in] ppCertBuff          - the x509 certificate  in PEM format
531 * @param[in] certSize       - certificate size
532 * @param[in] certType           - certificate type
533 * @param[in] encFlag        - indicates whether images were encrypted
534 * @param[in] hbkType        - hbk type to use by target, in the verification
535 * @param[in] pAddData       - additional data to add to package
536 * @param[in] addDataSize        - length of additional data
537 * @param[in] outPkgFile     - package file name to write the package to
538 */
539 /*********************************************************/
CC_CommonX509BuildCertPkg(uint8_t ** ppCertBuff,uint32_t certSize,uint8_t * pAddData,uint32_t addDataSize,uint8_t * outPkgFile)540 int32_t CC_CommonX509BuildCertPkg(uint8_t **ppCertBuff,
541                 uint32_t certSize,
542                 uint8_t *pAddData,
543                 uint32_t addDataSize,
544                 uint8_t *outPkgFile)
545 {
546     int32_t rc = 0;
547     FILE *fp = NULL;
548     uint8_t *pCertPkg = NULL;
549     uint32_t pkgBytesSize = 0;
550 
551     UTIL_LOG_INFO("started\n");
552     /* check inputs */
553     if ((NULL == outPkgFile) ||
554         (NULL == ppCertBuff) || (NULL == *ppCertBuff) ||
555         (0 == certSize) ||
556         (certSize >= CC_X509_MAX_CERT_SIZE) ||
557         ((pAddData != NULL) && (0 == addDataSize)) ||
558         ((NULL == pAddData) && (addDataSize != 0))) {
559         UTIL_LOG_ERR("illegal input\n");
560         rc = (-1);
561         goto END;
562     }
563 
564     /* calcultae package size */
565     pkgBytesSize = (certSize + addDataSize + 1); /* Adding 1 for "\0"*/
566 
567     UTIL_LOG_INFO("openning certificate pkg file for writing\n");
568     fp = fopen(outPkgFile, "w");
569     if (NULL == fp) {
570         UTIL_LOG_ERR("failed to open %s\n", outPkgFile);
571         rc = (-1);
572         goto END;
573     }
574 
575     UTIL_LOG_INFO("about to allocate memory for pkg:size %d, certSize %d, addDataSize %d\n",pkgBytesSize, certSize, addDataSize);
576 
577     /* create the package buffer */
578     pCertPkg = (uint8_t *) malloc(pkgBytesSize);
579     if (pCertPkg == NULL){
580         UTIL_LOG_ERR("failed to allocate pkg\n");
581         rc = (-1);
582         goto END;
583     }
584     /* copy additional data to package */
585     if (pAddData != NULL) {
586         memcpy(&pCertPkg[0], pAddData, addDataSize);
587     }
588     /* copy certificate PEM  to package */
589     memcpy(&pCertPkg[addDataSize], *ppCertBuff, certSize);
590 
591 
592     /* write out the package in binary format  */
593     UTIL_LOG_INFO("writing pkg to file\n");
594     rc = CC_CommonUtilCopyBuffToBinFile(outPkgFile, pCertPkg, pkgBytesSize);
595     if (rc != 0) {
596         UTIL_LOG_ERR("failed to CC_CommonUtilCopyBuffToBinFile\n");
597         rc = 1;
598         goto END;
599     }
600     rc = 0;
601     UTIL_LOG_INFO("OK\n");
602 
603 END:
604     if (fp != NULL){
605         fclose(fp);
606     }
607     if (pCertPkg != NULL) {
608         free(pCertPkg);
609     }
610     return rc;
611 }
612 
613 #else
614 /**
615 * @brief build package for the certificate
616 *
617 * @param[in] ppCertBuff          - the x509 certificate  in PEM format
618 * @param[in] certSize       - certificate size
619 * @param[in] certType           - certificate type
620 * @param[in] encFlag        - indicates whether images were encrypted
621 * @param[in] hbkType        - hbk type to use by target, in the verification
622 * @param[in] pAddData       - additional data to add to package
623 * @param[in] addDataSize        - length of additional data
624 * @param[in] outPkgFile     - package file name to write the package to
625 */
626 /*********************************************************/
CC_CommonX509BuildCertPkg(uint8_t ** ppCertBuff,uint32_t certSize,CCX509CertType_t certType,uint8_t encFlag,uint8_t hbkType,uint8_t * pAddData,uint32_t addDataSize,uint8_t * outPkgFile)627 int32_t CC_CommonX509BuildCertPkg(uint8_t **ppCertBuff,
628                 uint32_t certSize,
629                 CCX509CertType_t certType,
630                 uint8_t encFlag,
631                 uint8_t hbkType,
632                 uint8_t *pAddData,
633                 uint32_t addDataSize,
634                 uint8_t *outPkgFile)
635 {
636     int32_t rc = 0;
637     FILE *fp = NULL;
638     uint8_t *pCertPkg = NULL;
639     uint32_t nextBlockOffset = 0;
640     uint32_t pkgBytesSize = 0;
641 
642     UTIL_LOG_INFO("started\n");
643     /* check inputs */
644     if ((NULL == outPkgFile) ||
645         (NULL == ppCertBuff) || (NULL == *ppCertBuff) ||
646         (0 == certSize) ||
647         (certSize >= CC_X509_MAX_CERT_SIZE) ||
648         ((certType <= CC_X509_CERT_TYPE_MIN) || (certType >= CC_X509_CERT_TYPE_MAX)) ||
649         ((pAddData != NULL) && (0 == addDataSize)) ||
650         ((NULL == pAddData) && (addDataSize != 0)) ||
651         (!IS_VALID_ENC_FLAG(encFlag & 0xFF)) ||
652         (!IS_VALID_HBK(hbkType & 0xFF))) {
653         UTIL_LOG_ERR("illegal input\n");
654         rc = (-1);
655         goto END;
656     }
657 
658     /* calcultae package size */
659     pkgBytesSize = (sizeof(CCX509PkgHeader_t) + addDataSize);
660 
661     UTIL_LOG_INFO("openning certificate pkg file for writing\n");
662     fp = fopen(outPkgFile, "w");
663     if (NULL == fp) {
664         UTIL_LOG_ERR("failed to open %s\n", outPkgFile);
665         rc = (-1);
666         goto END;
667     }
668 
669     pkgBytesSize += certSize + 1; /* Adding 1 for "\0"*/
670     UTIL_LOG_INFO("about to allocate memory for pkg:size %d, certSize %d, addDataSize %d\n",pkgBytesSize, certSize, addDataSize);
671 
672     /* create the package buffer */
673     pCertPkg = (uint8_t *) malloc(pkgBytesSize);
674     if (pCertPkg == NULL){
675         UTIL_LOG_ERR("failed to allocate pkg\n");
676         rc = (-1);
677         goto END;
678     }
679     nextBlockOffset = sizeof(CCX509PkgHeader_t);
680     /* copy additional data to package */
681     if (pAddData != NULL) {
682         memcpy(&pCertPkg[nextBlockOffset], pAddData, addDataSize);
683         nextBlockOffset += addDataSize;
684     }
685       /* copy certificate PEM  to package */
686     memcpy(&pCertPkg[nextBlockOffset], *ppCertBuff, certSize);
687 
688     /* setting pkg header */
689     UTIL_LOG_INFO("setting pkg header\n");
690     ((CCX509PkgHeader_t *)pCertPkg)->pkgToken = CC_X509_CERT_PKG_TOKEN;
691     ((CCX509PkgHeader_t *)pCertPkg)->pkgVer = CC_X509_CERT_PKG_VERSION;
692     ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsWord = 0;
693     ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsBits.certType = certType & 0xFF;
694     ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsBits.imageEnc = encFlag & 0xFF;
695     ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsBits.hbkType = hbkType & 0xFF;
696     ((CCX509PkgHeader_t *)pCertPkg)->certInfo.certInfoWord = 0;
697     ((CCX509PkgHeader_t *)pCertPkg)->certInfo.certInfoBits.certOffset = (sizeof(CCX509PkgHeader_t)+addDataSize) & 0xFFFF;
698     ((CCX509PkgHeader_t *)pCertPkg)->certInfo.certInfoBits.certSize = certSize;
699 
700 
701 
702     /* write out the package in binary format  */
703     UTIL_LOG_INFO("writing pkg to file\n");
704     rc = CC_CommonUtilCopyBuffToBinFile(outPkgFile, pCertPkg, pkgBytesSize);
705     if (rc != 0) {
706         UTIL_LOG_ERR("failed to CC_CommonUtilCopyBuffToBinFile\n");
707         rc = 1;
708         goto END;
709     }
710     rc = 0;
711     UTIL_LOG_INFO("OK\n");
712 
713 END:
714     if (fp != NULL){
715         fclose(fp);
716     }
717     if (pCertPkg != NULL) {
718         free(pCertPkg);
719     }
720     return rc;
721 }
722 #endif
723