blob: 29fe2683146f08e77c82b8b0d2809ec77f0934f4 [file] [log] [blame]
Raef Colesa657a9c2019-10-24 14:36:43 +01001/*
2 * Copyright (c) 2019, Arm Limited. All rights reserved.
3 *
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
23#define CC312_NULL_CONTEXT "NO SALT!"
Raef Colesa657a9c2019-10-24 14:36:43 +010024
25CCRndContext_t* CC312_pRndCtx = NULL;
26CCRndWorkBuff_t* CC312_pRndWorkBuff = NULL;
27mbedtls_ctr_drbg_context* CC312_pRndState = NULL;
28mbedtls_entropy_context* CC312_pMbedtlsEntropy = NULL;
29
30CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,
31 size_t buffSize, uint8_t buffType,
32 uint8_t *pBuffNs)
33{
34 CC_UNUSED_PARAM(buffType);
35
36 *pBuffNs = DATA_BUFFER_IS_SECURE;
37 if (cmse_check_address_range((void*)pDataBuffer, buffSize, CMSE_NONSECURE)) {
38 *pBuffNs = DATA_BUFFER_IS_NONSECURE;
39 }
40
41 return CC_OK;
42}
43
44/*
45 * \brief Initialize the CC312 crypto accelerator
46 */
47
48int crypto_hw_accelerator_init(void)
49{
50 int ret = 0;
51
52 /* Allocate memory on heap */
53 CC312_pRndCtx = mbedtls_calloc(1, sizeof(CCRndContext_t));
54 CC312_pRndWorkBuff = mbedtls_calloc(1, sizeof(CCRndWorkBuff_t));
55 CC312_pRndState = mbedtls_calloc(1, sizeof(mbedtls_ctr_drbg_context));
56 CC312_pMbedtlsEntropy = mbedtls_calloc(1, sizeof(mbedtls_entropy_context));
57
58 /* Check if memory allocation was successful */
59 if ( !CC312_pRndCtx || !CC312_pRndWorkBuff
60 || !CC312_pRndState || !CC312_pMbedtlsEntropy) {
61 mbedtls_free(CC312_pRndCtx);
62 mbedtls_free(CC312_pRndWorkBuff);
63 mbedtls_free(CC312_pRndState);
64 mbedtls_free(CC312_pMbedtlsEntropy);
65
66 return -1;
67 }
68
69 /* Init Rnd context's inner members */
70 CC312_pRndCtx->rndState = CC312_pRndState;
71 CC312_pRndCtx->entropyCtx = CC312_pMbedtlsEntropy;
72
73 /* Initialise CryptoCell library */
74 ret = CC_LibInit(CC312_pRndCtx, CC312_pRndWorkBuff);
75 if (ret != CC_LIB_RET_OK) {
76 mbedtls_free(CC312_pRndCtx);
77 mbedtls_free(CC312_pRndWorkBuff);
78 mbedtls_free(CC312_pRndState);
79 mbedtls_free(CC312_pMbedtlsEntropy);
80
81 return ret;
82 }
83
84 return 0;
85}
86
87/*
88 * \brief Deallocate the CC312 crypto accelerator
89 */
90int crypto_hw_accelerator_finish(void)
91{
92 int ret = 0;
93
94 ret = CC_LibFini(CC312_pRndCtx);
95 if(ret != CC_LIB_RET_OK) {
96 return ret;
97 }
98
99 mbedtls_free(CC312_pRndCtx);
100 mbedtls_free(CC312_pRndWorkBuff);
101 mbedtls_free(CC312_pRndState);
102 mbedtls_free(CC312_pMbedtlsEntropy);
103
104 return 0;
105}
Tamas Ban80f28242019-10-25 22:13:53 +0100106
107int crypto_hw_accelerator_get_lcs(uint32_t *lcs)
108{
109 return mbedtls_mng_lcsGet(lcs);
110}
Xu Yong84678d02019-09-30 10:13:28 +0800111
112int crypto_hw_accelerator_huk_derive_key(const uint8_t *label,
113 size_t label_size,
114 const uint8_t *context,
115 size_t context_size,
116 uint8_t *key,
117 size_t key_size)
118{
119
120 if (context == NULL || context_size == 0) {
121 /* The CC312 requires the context to not be null, so a default
122 * is given.
123 */
124 context = (const uint8_t *)CC312_NULL_CONTEXT;
125 context_size = sizeof(CC312_NULL_CONTEXT);
126 }
127
128 return mbedtls_util_key_derivation_cmac(CC_UTIL_ROOT_KEY, NULL,
129 label, label_size,
130 context, context_size,
131 key, key_size);
Xu Yong4dd59b02019-11-01 18:38:12 +0800132}
Xu Yong84678d02019-09-30 10:13:28 +0800133
Xu Yong4dd59b02019-11-01 18:38:12 +0800134/*
135 * Count number of zero bits in 32-bit word.
136 * Copied from:
137 * lib/ext/cryptocell-312-runtime/host/src/ \
138 * cc3x_productionlib/common/prod_util.c: CC_PROD_GetZeroCount(..)
139 */
140static int get_zero_bits_count(uint32_t *buf,
141 uint32_t buf_word_size,
142 uint32_t *zero_count)
143{
144 uint32_t val;
145 uint32_t index = 0;
146
147 *zero_count = 0;
148 for (index = 0; index < buf_word_size; index++) {
149 val = buf[index];
150 val = val - ((val >> 1) & 0x55555555);
151 val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
152 val = ((((val + (val >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);
153 *zero_count += (32 - val);
154 }
155 /* All 0's and all 1's is forbidden */
156 if ((*zero_count == 0)
157 || (*zero_count == buf_word_size*CC_BITS_IN_32BIT_WORD)) {
158 *zero_count = 0;
159 return -1;
160 }
161
162 return 0;
163}
164
165/*
166 * Get attestation private key from CC312 OTP
167 */
168int crypto_hw_accelerator_get_attestation_private_key(uint8_t *buf,
169 uint32_t *size)
170{
171 uint32_t *key = (uint32_t *)buf;
172 uint32_t otp_val;
173 uint32_t otp_zero_count;
174 uint32_t zero_count;
175 int i;
176 int rc;
177
178 if (key == NULL ||
179 *size < CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS * sizeof(uint32_t)) {
180 return -1;
181 }
182 *size = CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS * sizeof(uint32_t);
183
184 /* Get provisioned key from OTP, 8 words */
185 for (i = 0; i < CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS; i++) {
186 CC_PROD_OTP_READ(otp_val, CC_OTP_ATTESTATION_KEY_OFFSET + i);
187 *key = otp_val;
188 key++;
189 }
190
191 /* Verify the zero number of private key */
192 rc = get_zero_bits_count((uint32_t *)buf,
193 CC_OTP_ATTESTATION_KEY_SIZE_IN_WORDS,
194 &zero_count);
195 if (rc) {
196 return -1;
197 }
198
199 CC_PROD_OTP_READ(otp_zero_count, CC_OTP_ATTESTATION_KEY_ZERO_COUNT_OFFSET);
200 if (otp_zero_count != zero_count) {
201 return -1;
202 }
203
204 return 0;
Xu Yong84678d02019-09-30 10:13:28 +0800205}
Tamas Ban2e297a52019-10-27 21:44:22 +0100206
207int crypto_hw_accelerator_get_rotpk_hash(uint8_t image_id,
208 uint8_t *rotpk_hash,
209 uint32_t *rotpk_hash_size)
210{
211 int32_t ret;
212 mbedtls_mng_pubKeyType_t key_index;
213 uint32_t rotpk_hash_size_in_words;
214
215 if (image_id == 0) {
216#if (MCUBOOT_IMAGE_NUMBER == 1)
217 key_index = CC_MNG_HASH_BOOT_KEY_256B;
218 rotpk_hash_size_in_words = 8;
219#elif (MCUBOOT_IMAGE_NUMBER == 2)
220 key_index = CC_MNG_HASH_BOOT_KEY_0_128B;
221 rotpk_hash_size_in_words = 4;
222 } else if (image_id == 1) {
223 key_index = CC_MNG_HASH_BOOT_KEY_1_128B;
224 rotpk_hash_size_in_words = 4;
225#endif /* MCUBOOT_IMAGE_NUMBER == 1 */
226 } else {
227 return -1;
228 }
229
230 if (*rotpk_hash_size < rotpk_hash_size_in_words * sizeof(uint32_t)) {
231 return -1;
232 }
233 *rotpk_hash_size = rotpk_hash_size_in_words * sizeof(uint32_t);
234
235 ret = mbedtls_mng_pubKeyHashGet(key_index, (uint32_t *)rotpk_hash,
236 rotpk_hash_size_in_words);
237 if (ret) {
238 return ret;
239 }
240
241 return 0;
242}