1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
8 
9 /************* Include Files ****************/
10 
11 
12 #include "secureboot_error.h"
13 #include "secureboot_basetypes.h"
14 #include "secureboot_parser_gen_defs.h"
15 #include "secureboot_defs.h"
16 
17 #include "bootimagesverifier_error.h"
18 #include "rsa_bsv.h"
19 #include "cc_pal_log.h"
20 #include "cc_pka_hw_plat_defs.h"
21 
22 #include "secureboot_stage_defs.h"
23 
24 
CCSbCalcPublicKeyHASH(unsigned long hwBaseAddress,uint32_t * NAndRevNp_ptr,uint32_t * hashResult)25 CCError_t CCSbCalcPublicKeyHASH(unsigned long hwBaseAddress,
26                                 uint32_t *NAndRevNp_ptr,
27                                 uint32_t *hashResult)
28 {
29 
30         /* error variable */
31         CCError_t error = CC_OK;
32 
33         if ((NAndRevNp_ptr == NULL) ||
34             (hashResult == NULL)) {
35                 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
36         }
37 
38         error = SBROM_CryptoHash(hwBaseAddress, CONVERT_TO_ADDR(NAndRevNp_ptr),
39                                  (SB_CERT_RSA_KEY_SIZE_IN_WORDS + RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS) * sizeof(uint32_t),
40                                  hashResult);
41 
42         return error;
43 }
44 
CCSbCalcPublicKeyHASHAndCompare(unsigned long hwBaseAddress,uint32_t * NAndRevNp_ptr,uint32_t * NHASH_ptr,uint32_t HashSize)45 CCError_t CCSbCalcPublicKeyHASHAndCompare(unsigned long hwBaseAddress,
46                                           uint32_t *NAndRevNp_ptr,
47                                           uint32_t *NHASH_ptr,
48                                           uint32_t    HashSize)
49 {
50         /* error variable */
51         CCError_t error = CC_OK;
52 
53         /* HASH result of the E||N */
54         CCHashResult_t LocalHashResult;
55 
56 /*------------------
57     CODE
58 -------------------*/
59         if ((NAndRevNp_ptr == NULL) ||
60             (NHASH_ptr == NULL)) {
61                 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
62         }
63 
64         if (HashSize != sizeof(CCHashResult_t) && HashSize != sizeof(CCHashResult_t) / 2) {
65                 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
66         }
67 
68         /* calculate the HASH value of N (big endian)|| Np (reversed - little endian) */
69         error = CCSbCalcPublicKeyHASH(hwBaseAddress, NAndRevNp_ptr, LocalHashResult);
70         if (error != CC_OK) {
71                 return error;
72         }
73 
74         /* compare the HASH results */
75         error = UTIL_MemCmp((uint8_t *)LocalHashResult, (uint8_t *)NHASH_ptr, HashSize);
76         if (error != CC_TRUE) {
77                 CC_PAL_LOG_ERR("PUB KEY HASH VALIDATION FAILURE\n");
78                 return CC_BOOT_IMG_VERIFIER_PUB_KEY_HASH_VALIDATION_FAILURE;
79         }
80 
81         return CC_OK;
82 } /* End of CCSbCalcPublicKeyHASHAndCompare */
83 
84 
85 
CCSbVerifySignature(unsigned long hwBaseAddress,uint32_t * pData,CCSbNParams_t * pNParams,CCSbSignature_t * pSignature,uint32_t sizeOfData,CCSbSignAlg_t sigAlg)86 CCError_t CCSbVerifySignature(unsigned long hwBaseAddress,
87                               uint32_t *pData,
88                               CCSbNParams_t *pNParams,
89                               CCSbSignature_t *pSignature,
90                               uint32_t sizeOfData,
91                               CCSbSignAlg_t sigAlg)
92 {
93 
94         /* error variable */
95         CCError_t error = CC_OK;
96 
97         /* a HASH result variable */
98         CCHashResult_t HashResult;
99 
100 #ifndef CC_CONFIG_SB_CC3X
101         /* reversed N public key */
102         uint32_t RevN[SB_CERT_RSA_KEY_SIZE_IN_WORDS];
103         uint32_t RevNp[RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
104 #endif
105 
106 
107 /*------------------
108     CODE
109 -------------------*/
110         if ((pData == NULL) ||
111             (pNParams == NULL) ||
112             (pSignature == NULL) ||
113             (sizeOfData == 0) ||
114             ((sigAlg == RSA_PSS_3072) && (SB_CERT_RSA_KEY_SIZE_IN_BITS != 3072)) ||
115             ((sigAlg == RSA_PSS_2048) && (SB_CERT_RSA_KEY_SIZE_IN_BITS != 2048))) {
116                 CC_PAL_LOG_ERR("CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM\n");
117                 return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
118         }
119 
120         /* Calculate HASH on the certificate */
121         /*---------------------------------- */
122         /* calc the  HASH according to the length minus the signature struct size (N,Np & signature)*/
123         error = SBROM_CryptoHash(hwBaseAddress, CONVERT_TO_ADDR(pData),
124                                  sizeOfData,
125                                  HashResult);
126         if (error != CC_OK) {
127                 CC_PAL_LOG_ERR("Failed SBROM_CryptoHash 0x%x\n", error);
128                 return error;
129         }
130 #ifndef CC_CONFIG_SB_CC3X
131         /* Verify the RSA signature of the certificate */
132         /*---------------------------------------------*/
133         /* Reverse the N and Np to be little endian arrays for the PKA usage */
134         UTIL_ReverseMemCopy((uint8_t *)RevN, (uint8_t *)pNParams->N, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
135         UTIL_ReverseMemCopy((uint8_t *)RevNp, (uint8_t *)pNParams->Np, RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES);
136         /* Verify the RSA signature */
137         error = _RSA_PSS_Verify(hwBaseAddress, HashResult, RevN, RevNp, pSignature->sig);
138 #else
139         /* Reverse the N and Np to be little endian arrays for the PKA usage */
140         /* NOTICE: Must be after certificate hash is calculated and
141            certificate public key Hash is verified */
142         UTIL_ReverseMemCopy((uint8_t *)pNParams->N, (uint8_t *)pNParams->N, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
143         UTIL_ReverseMemCopy((uint8_t *)pNParams->Np, (uint8_t *)pNParams->Np, RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES);
144         /* Verify the RSA signature */
145         error = RSA_PSS_Verify(hwBaseAddress, HashResult, pNParams->N, pNParams->Np, pSignature->sig);
146 #endif
147 
148         /* on failure exit with an error code */
149         if (error != CC_OK) {
150                 CC_PAL_LOG_ERR("RSA sig verification failed 0x%x\n", error);
151                 return CC_BOOT_IMG_VERIFIER_RSA_SIG_VERIFICATION_FAILED;
152         }
153 
154         return CC_OK;
155 } /* End of CCSbVerifySignature */
156 
157