blob: 400260ef5252121b1f5a95b479f2bd165227c3a4 [file] [log] [blame]
Raef Colesa657a9c2019-10-24 14:36:43 +01001/*
Tamas Ban190dbaa2020-06-29 14:05:03 +01002 * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
Raef Colesa657a9c2019-10-24 14:36:43 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8#include "crypto_hw.h"
9
10#include "cc_lib.h"
11#include "cc_pal_buff_attr.h"
12#include "cc_rnd_common.h"
13#include "mbedtls/platform.h"
14#include "mbedtls/ctr_drbg.h"
15#include "mbedtls/entropy.h"
Tamas Ban80f28242019-10-25 22:13:53 +010016#include "mbedtls_cc_mng_int.h"
Raef Colesa657a9c2019-10-24 14:36:43 +010017#include "arm_cmse.h"
Xu Yong84678d02019-09-30 10:13:28 +080018#include "mbedtls_cc_util_key_derivation.h"
19#include "tfm_attest_hal.h"
Xu Yong4dd59b02019-11-01 18:38:12 +080020#include "prod_hw_defs.h"
21#include "cc_otp_defs.h"
Xu Yong84678d02019-09-30 10:13:28 +080022
Vishnu Banavath0b572be2020-03-14 14:46:06 +000023#include "region_defs.h"
24
Xu Yong84678d02019-09-30 10:13:28 +080025#define CC312_NULL_CONTEXT "NO SALT!"
Raef Colesa657a9c2019-10-24 14:36:43 +010026
27CCRndContext_t* CC312_pRndCtx = NULL;
28CCRndWorkBuff_t* CC312_pRndWorkBuff = NULL;
29mbedtls_ctr_drbg_context* CC312_pRndState = NULL;
30mbedtls_entropy_context* CC312_pMbedtlsEntropy = NULL;
31
32CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,
33 size_t buffSize, uint8_t buffType,
34 uint8_t *pBuffNs)
35{
36 CC_UNUSED_PARAM(buffType);
37
38 *pBuffNs = DATA_BUFFER_IS_SECURE;
Vishnu Banavath0b572be2020-03-14 14:46:06 +000039#if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
Raef Colesa657a9c2019-10-24 14:36:43 +010040 if (cmse_check_address_range((void*)pDataBuffer, buffSize, CMSE_NONSECURE)) {
41 *pBuffNs = DATA_BUFFER_IS_NONSECURE;
42 }
Vishnu Banavath0b572be2020-03-14 14:46:06 +000043#else
44 if (pDataBuffer >= (uint8_t *)NS_DATA_START &&
45 (pDataBuffer + buffSize) <= (uint8_t *)NS_DATA_LIMIT) {
46 *pBuffNs = DATA_BUFFER_IS_NONSECURE;
47 }
48#endif
Raef Colesa657a9c2019-10-24 14:36:43 +010049
50 return CC_OK;
51}
52
53/*
54 * \brief Initialize the CC312 crypto accelerator
55 */
56
57int crypto_hw_accelerator_init(void)
58{
59 int ret = 0;
60
61 /* Allocate memory on heap */
62 CC312_pRndCtx = mbedtls_calloc(1, sizeof(CCRndContext_t));
63 CC312_pRndWorkBuff = mbedtls_calloc(1, sizeof(CCRndWorkBuff_t));
64 CC312_pRndState = mbedtls_calloc(1, sizeof(mbedtls_ctr_drbg_context));
65 CC312_pMbedtlsEntropy = mbedtls_calloc(1, sizeof(mbedtls_entropy_context));
66
67 /* Check if memory allocation was successful */
68 if ( !CC312_pRndCtx || !CC312_pRndWorkBuff
69 || !CC312_pRndState || !CC312_pMbedtlsEntropy) {
70 mbedtls_free(CC312_pRndCtx);
71 mbedtls_free(CC312_pRndWorkBuff);
72 mbedtls_free(CC312_pRndState);
73 mbedtls_free(CC312_pMbedtlsEntropy);
74
75 return -1;
76 }
77
78 /* Init Rnd context's inner members */
79 CC312_pRndCtx->rndState = CC312_pRndState;
80 CC312_pRndCtx->entropyCtx = CC312_pMbedtlsEntropy;
81
82 /* Initialise CryptoCell library */
83 ret = CC_LibInit(CC312_pRndCtx, CC312_pRndWorkBuff);
84 if (ret != CC_LIB_RET_OK) {
85 mbedtls_free(CC312_pRndCtx);
86 mbedtls_free(CC312_pRndWorkBuff);
87 mbedtls_free(CC312_pRndState);
88 mbedtls_free(CC312_pMbedtlsEntropy);
89
90 return ret;
91 }
92
93 return 0;
94}
95
96/*
97 * \brief Deallocate the CC312 crypto accelerator
98 */
99int crypto_hw_accelerator_finish(void)
100{
101 int ret = 0;
102
103 ret = CC_LibFini(CC312_pRndCtx);
104 if(ret != CC_LIB_RET_OK) {
105 return ret;
106 }
107
108 mbedtls_free(CC312_pRndCtx);
109 mbedtls_free(CC312_pRndWorkBuff);
110 mbedtls_free(CC312_pRndState);
111 mbedtls_free(CC312_pMbedtlsEntropy);
112
113 return 0;
114}
Tamas Ban80f28242019-10-25 22:13:53 +0100115
116int crypto_hw_accelerator_get_lcs(uint32_t *lcs)
117{
118 return mbedtls_mng_lcsGet(lcs);
119}
Xu Yong84678d02019-09-30 10:13:28 +0800120
121int crypto_hw_accelerator_huk_derive_key(const uint8_t *label,
122 size_t label_size,
123 const uint8_t *context,
124 size_t context_size,
125 uint8_t *key,
126 size_t key_size)
127{
128
129 if (context == NULL || context_size == 0) {
130 /* The CC312 requires the context to not be null, so a default
131 * is given.
132 */
133 context = (const uint8_t *)CC312_NULL_CONTEXT;
134 context_size = sizeof(CC312_NULL_CONTEXT);
135 }
136
137 return mbedtls_util_key_derivation_cmac(CC_UTIL_ROOT_KEY, NULL,
138 label, label_size,
139 context, context_size,
140 key, key_size);
Xu Yong4dd59b02019-11-01 18:38:12 +0800141}
Xu Yong84678d02019-09-30 10:13:28 +0800142
Xu Yong4dd59b02019-11-01 18:38:12 +0800143/*
144 * Count number of zero bits in 32-bit word.
145 * Copied from:
146 * lib/ext/cryptocell-312-runtime/host/src/ \
147 * cc3x_productionlib/common/prod_util.c: CC_PROD_GetZeroCount(..)
148 */
149static int get_zero_bits_count(uint32_t *buf,
150 uint32_t buf_word_size,
151 uint32_t *zero_count)
152{
153 uint32_t val;
154 uint32_t index = 0;
155
156 *zero_count = 0;
157 for (index = 0; index < buf_word_size; index++) {
158 val = buf[index];
159 val = val - ((val >> 1) & 0x55555555);
160 val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
161 val = ((((val + (val >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);
162 *zero_count += (32 - val);
163 }
164 /* All 0's and all 1's is forbidden */
165 if ((*zero_count == 0)
166 || (*zero_count == buf_word_size*CC_BITS_IN_32BIT_WORD)) {
167 *zero_count = 0;
168 return -1;
169 }
170
171 return 0;
172}
173
174/*
175 * Get attestation private key from CC312 OTP
176 */
177int crypto_hw_accelerator_get_attestation_private_key(uint8_t *buf,
178 uint32_t *size)
179{
180 uint32_t *key = (uint32_t *)buf;
181 uint32_t otp_val;
182 uint32_t otp_zero_count;
183 uint32_t zero_count;
184 int i;
185 int rc;
186
187 if (key == NULL ||
188 *size < CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS * sizeof(uint32_t)) {
189 return -1;
190 }
191 *size = CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS * sizeof(uint32_t);
192
193 /* Get provisioned key from OTP, 8 words */
194 for (i = 0; i < CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS; i++) {
195 CC_PROD_OTP_READ(otp_val, CC_OTP_ATTESTATION_KEY_OFFSET + i);
196 *key = otp_val;
197 key++;
198 }
199
200 /* Verify the zero number of private key */
201 rc = get_zero_bits_count((uint32_t *)buf,
202 CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS,
203 &zero_count);
204 if (rc) {
205 return -1;
206 }
207
208 CC_PROD_OTP_READ(otp_zero_count, CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET);
209 if (otp_zero_count != zero_count) {
210 return -1;
211 }
212
213 return 0;
Xu Yong84678d02019-09-30 10:13:28 +0800214}
Tamas Ban2e297a52019-10-27 21:44:22 +0100215
Tamas Ban190dbaa2020-06-29 14:05:03 +0100216#ifdef BL2
Tamas Ban2e297a52019-10-27 21:44:22 +0100217int crypto_hw_accelerator_get_rotpk_hash(uint8_t image_id,
218 uint8_t *rotpk_hash,
219 uint32_t *rotpk_hash_size)
220{
221 int32_t ret;
222 mbedtls_mng_pubKeyType_t key_index;
223 uint32_t rotpk_hash_size_in_words;
224
225 if (image_id == 0) {
226#if (MCUBOOT_IMAGE_NUMBER == 1)
227 key_index = CC_MNG_HASH_BOOT_KEY_256B;
228 rotpk_hash_size_in_words = 8;
229#elif (MCUBOOT_IMAGE_NUMBER == 2)
230 key_index = CC_MNG_HASH_BOOT_KEY_0_128B;
231 rotpk_hash_size_in_words = 4;
232 } else if (image_id == 1) {
233 key_index = CC_MNG_HASH_BOOT_KEY_1_128B;
234 rotpk_hash_size_in_words = 4;
235#endif /* MCUBOOT_IMAGE_NUMBER == 1 */
236 } else {
237 return -1;
238 }
239
240 if (*rotpk_hash_size < rotpk_hash_size_in_words * sizeof(uint32_t)) {
241 return -1;
242 }
243 *rotpk_hash_size = rotpk_hash_size_in_words * sizeof(uint32_t);
244
245 ret = mbedtls_mng_pubKeyHashGet(key_index, (uint32_t *)rotpk_hash,
246 rotpk_hash_size_in_words);
247 if (ret) {
248 return ret;
249 }
250
251 return 0;
252}
Tamas Ban190dbaa2020-06-29 14:05:03 +0100253#endif /* BL2 */