1 /*
2 * Copyright (c) 2021-2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7 #include "hpm_sdp_drv.h"
8 #include "hpm_soc_feature.h"
9
10 /***********************************************************************************************************************
11 * Definitions
12 **********************************************************************************************************************/
13 /**
14 * AES Key source definition
15 */
16 #define AES_KEY_SRC_SDP_START_IDX 0U
17 #define AES128_KEY_SRC_SDP_END_IDX 0xFU
18 #define AES256_KEY_SRC_SDP_END_IDX 0x7U
19 #define AES_KEY_SRC_KEYMAN_START_IDX 0x20U
20 #define AES128_KEY_SRC_KEYMAN_END_IDX 0x2FU
21 #define AES256_KEY_SRC_KEYMAN_END_IDX 0x2FU
22 #define AES_KEY_SRC_UNIQUE_KEY_START_IDX 0x3EU
23 #define AES_KEY_SRC_OTP_KEY_START_IDX 0x3FU
24
25 #define AES_256_KEY_SIZE_IN_WORDS (8U)
26 #define AES_256_KEY_SIZE_IN_BYTES (32U)
27
28 #define CRC32_DIGEST_SIZE_IN_BYTES (4U)
29 #define SHA1_DIGEST_SIZE_IN_BYTES (20U)
30 #define SHA256_DIGEST_SIZE_IN_BYTES (32U)
31
32 #define AES_CTR_BLOCK_UNIT (16U)
33
34 typedef enum {
35 sdp_state_hash_init, sdp_state_hash_update,
36 } sdp_hash_alg_state_t;
37
38 #define AES_BLOCK_SIZE (16U)
39 #define HASH_BLOCK_SIZE (64U)
40 #define HASH_DIGEST_SIZE_MAX (32)
41
42 #define SDP_CRYPTO_ALG_IDX_AES128 (0U)
43 #define SDP_CRYPTO_ALG_IDX_AES256 (1U)
44 #define SDP_CRYPTO_ALG_IDX_SM4 (8U)
45
46 typedef struct {
47 union {
48 uint32_t words[HASH_BLOCK_SIZE / sizeof(uint32_t)];
49 uint8_t bytes[HASH_BLOCK_SIZE];
50 } block;
51 uint32_t blk_size;
52 uint32_t full_msg_size;
53 uint32_t running_hash[HASH_DIGEST_SIZE_MAX / sizeof(uint32_t)];
54 sdp_hash_alg_t alg;
55 sdp_hash_alg_state_t state;
56 bool hash_init;
57 bool hash_finish;
58 } sdp_hash_internal_ctx_t;
59
60 /***********************************************************************************************************************
61 * Prototypes
62 **********************************************************************************************************************/
63 static void sdp_hash_internal_engine_init(SDP_Type *base, sdp_hash_ctx_t *hash_ctx);
64
65 static hpm_stat_t sdp_hash_process_message(SDP_Type *base, sdp_hash_ctx_t *ctx, const uint8_t *msg, uint32_t msg_size);
66
67 static hpm_stat_t sdp_hash_internal_update(SDP_Type *base, sdp_hash_ctx_t *ctx, const uint8_t *msg, uint32_t msg_size);
68
69 static hpm_stat_t sdp_hash_finalize(SDP_Type *base, sdp_hash_ctx_t *hash_ctx);
70
sdp_clear_error_status(SDP_Type * base)71 static inline void sdp_clear_error_status(SDP_Type *base)
72 {
73 base->STA = 0xFFFFFFFFUL;
74 }
75
76 static void sdp_increment_bn(uint8_t *big_num, uint32_t bytes);
77
78 static void uint32_to_be(uint8_t *dst, uint32_t len, uint32_t num);
79
80 static hpm_stat_t aes_ccm_auth_crypt(SDP_Type *base,
81 sdp_aes_ctx_t *aes_ctx,
82 sdp_aes_op_t op,
83 uint32_t input_len,
84 const uint8_t *iv,
85 uint32_t iv_len,
86 const uint8_t *aad,
87 uint32_t aad_len,
88 const uint8_t *input,
89 uint8_t *output,
90 uint8_t *mac,
91 uint32_t mac_len);
92
93 static void aes_ccm_format_b0(uint8_t *block,
94 const uint8_t *iv,
95 uint32_t iv_len,
96 uint32_t mac_len,
97 uint32_t aad_len,
98 uint32_t input_len);
99
100 static void aes_ccm_format_ctr0(uint8_t *ctr, const uint8_t *iv, uint8_t iv_len);
101
102 static uint8_t sdp_constant_time_cmp(const void *dst, const void *src, uint32_t len);
103
104 /***********************************************************************************************************************
105 * Codes
106 **********************************************************************************************************************/
sdp_wait_done(SDP_Type * base)107 hpm_stat_t sdp_wait_done(SDP_Type *base)
108 {
109 hpm_stat_t status;
110 uint32_t sdp_sta;
111 do {
112 sdp_sta = base->STA;
113 if (IS_HPM_BITMASK_SET(sdp_sta, SDP_STA_ERRSET_MASK)) {
114 status = status_sdp_error_setup;
115 } else if (IS_HPM_BITMASK_SET(sdp_sta, SDP_STA_ERRPKT_MASK)) {
116 status = status_sdp_error_packet;
117 } else if (IS_HPM_BITMASK_SET(sdp_sta, SDP_STA_ERRSRC_MASK)) {
118 status = status_sdp_error_src;
119 } else if (IS_HPM_BITMASK_SET(sdp_sta, SDP_STA_ERRDST_MASK)) {
120 status = status_sdp_error_dst;
121 } else if (IS_HPM_BITMASK_SET(sdp_sta, SDP_STA_ERRHAS_MASK)) {
122 status = status_sdp_error_hash;
123 } else if (IS_HPM_BITMASK_SET(sdp_sta, SDP_STA_ERRCHAIN_MASK)) {
124 status = status_sdp_error_chain;
125 } else {
126 status = status_success;
127 }
128 } while (IS_HPM_BITMASK_CLR(sdp_sta, SDP_STA_PKTCNT0_MASK));
129
130 return status;
131 }
132
sdp_init(SDP_Type * base)133 hpm_stat_t sdp_init(SDP_Type *base)
134 {
135 hpm_stat_t status = status_invalid_argument;
136 if (base != NULL) {
137 base->SDPCR &= ~(SDP_SDPCR_CLKGAT_MASK | SDP_SDPCR_SFTRST_MASK);
138
139 status = status_success;
140 }
141
142 return status;
143 }
144
sdp_deinit(SDP_Type * base)145 hpm_stat_t sdp_deinit(SDP_Type *base)
146 {
147 hpm_stat_t status = status_invalid_argument;
148 if (base != NULL) {
149 base->SDPCR |= SDP_SDPCR_CLKGAT_MASK;
150 status = status_success;
151 }
152 return status;
153 }
154
sdp_aes_set_key(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,const uint8_t * key,sdp_aes_key_bits_t key_bits,uint32_t key_idx)155 hpm_stat_t sdp_aes_set_key(SDP_Type *base,
156 sdp_aes_ctx_t *aes_ctx,
157 const uint8_t *key,
158 sdp_aes_key_bits_t key_bits,
159 uint32_t key_idx)
160 {
161 union {
162 uint32_t words[AES_256_KEY_SIZE_IN_WORDS];
163 uint8_t bytes[AES_256_KEY_SIZE_IN_BYTES];
164 } aes_key;
165
166 assert((base != NULL) && (aes_ctx != NULL) && (key_bits <= sdp_aes_keybits_256));
167
168 hpm_stat_t status = status_invalid_argument;
169 do {
170 aes_ctx->crypto_algo = sdp_crypto_alg_aes;
171
172 if (IS_HPM_BITMASK_SET(base->SDPCR, SDP_SDPCR_CIPDIS_MASK)) {
173 status = status_sdp_no_crypto_support;
174 break;
175 }
176
177 HPM_BREAK_IF((key_bits != sdp_aes_keybits_128) && (key_bits != sdp_aes_keybits_256));
178
179 aes_ctx->key_bits = key_bits;
180
181 uint32_t key128_idx = key_idx;
182 if (key_bits == sdp_aes_keybits_256) {
183 if (key_idx <= AES256_KEY_SRC_SDP_END_IDX) {
184 (void) memcpy(aes_key.bytes, key, 32);
185 key128_idx = key_idx * 2U;
186 uint32_t idx = 0;
187 for (uint32_t i = 0; i < 2; i++) {
188 base->KEYADDR = SDP_KEYADDR_INDEX_SET(key128_idx + i);
189 for (uint32_t j = 0; j < 4; j++) {
190 base->KEYDAT = aes_key.words[idx++];
191 }
192 }
193 } else if ((key_idx >= AES_KEY_SRC_KEYMAN_START_IDX) && (key_idx <= AES256_KEY_SRC_KEYMAN_END_IDX)) {
194 key128_idx = (key_idx - AES_KEY_SRC_KEYMAN_START_IDX) * 2U + AES_KEY_SRC_KEYMAN_START_IDX;
195 }
196 } else {
197 if (key_idx <= AES128_KEY_SRC_SDP_END_IDX) {
198 (void) memcpy(aes_key.bytes, key, 16);
199 base->KEYADDR = SDP_KEYADDR_INDEX_SET(key_idx);
200 for (uint32_t j = 0; j < 4; j++) {
201 base->KEYDAT = aes_key.words[j];
202 }
203 }
204 }
205
206 aes_ctx->key_idx = key128_idx;
207 aes_ctx->key_bits = key_bits;
208 status = status_success;
209
210 } while (false);
211
212 return status;
213 }
214
215 #if defined(SDP_HAS_SM4_SUPPORT) && (SDP_HAS_SM4_SUPPORT == 1)
sdp_sm4_set_key(SDP_Type * base,sdp_sm4_ctx_t * sm4_ctx,const uint8_t * key,sdp_sm4_key_bits_t key_bits,uint32_t key_idx)216 hpm_stat_t sdp_sm4_set_key(SDP_Type *base,
217 sdp_sm4_ctx_t *sm4_ctx,
218 const uint8_t *key,
219 sdp_sm4_key_bits_t key_bits,
220 uint32_t key_idx)
221 {
222 hpm_stat_t status = status_invalid_argument;
223 if (key_bits != sdp_sm4_keybits_128) {
224 return status;
225 }
226 status = sdp_aes_set_key(base, sm4_ctx, key, (sdp_aes_key_bits_t) key_bits, key_idx);
227 if (status != status_success) {
228 return status;
229 }
230 sm4_ctx->crypto_algo = sdp_crypto_alg_sm4;
231
232 return status;
233 }
234 #endif
235
sdp_aes_crypt_ecb(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,sdp_aes_op_t op,uint32_t len,const uint8_t * in,uint8_t * out)236 hpm_stat_t sdp_aes_crypt_ecb(SDP_Type *base,
237 sdp_aes_ctx_t *aes_ctx,
238 sdp_aes_op_t op,
239 uint32_t len,
240 const uint8_t *in,
241 uint8_t *out)
242 {
243 assert((base != NULL) && (aes_ctx != NULL));
244
245 hpm_stat_t status;
246
247 base->SDPCR = SDP_SDPCR_CIPHEN_MASK;
248 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
249 base->SDPCR |= HPM_BITSMASK(1, 8);
250 base->PKTCTL = SDP_PKT_CTRL_DERSEMA_MASK;
251 base->PKTSRC = (uint32_t) in;
252 base->PKTDST = (uint32_t) out;
253 base->PKTBUF = len;
254 #else
255 sdp_pkt_struct_t *pkt_desc = &aes_ctx->sdp_pkt;
256 pkt_desc->next_cmd = NULL;
257 pkt_desc->pkt_ctrl.PKT_CTRL = SDP_PKT_CTRL_DERSEMA_MASK;
258 pkt_desc->src_addr = (uint32_t) in;
259 pkt_desc->dst_addr = (uint32_t) out;
260 pkt_desc->buf_size = len;
261
262 #endif
263 sdp_clear_error_status(base);
264
265 if (aes_ctx->crypto_algo == sdp_crypto_alg_aes) {
266 if (aes_ctx->key_bits == sdp_aes_keybits_128) {
267 base->MODCTRL =
268 SDP_MODCTRL_AESALG_SET(SDP_CRYPTO_ALG_IDX_AES128) | SDP_MODCTRL_AESKS_SET(aes_ctx->key_idx) |
269 SDP_MODCTRL_AESDIR_SET(op);
270 } else {
271 base->MODCTRL =
272 SDP_MODCTRL_AESALG_SET(SDP_CRYPTO_ALG_IDX_AES256) | SDP_MODCTRL_AESKS_SET(aes_ctx->key_idx) |
273 SDP_MODCTRL_AESDIR_SET(op);
274 }
275 }
276 #if defined(SDP_HAS_SM4_SUPPORT) && (SDP_HAS_SM4_SUPPORT == 1)
277 else if (aes_ctx->crypto_algo == sdp_crypto_alg_sm4) {
278 base->MODCTRL = SDP_MODCTRL_AESALG_SET(SDP_CRYPTO_ALG_IDX_SM4) | SDP_MODCTRL_AESKS_SET(aes_ctx->key_idx) |
279 SDP_MODCTRL_AESDIR_SET(op);
280 }
281 #endif
282 else {
283 return status_sdp_invalid_alg;
284 }
285
286 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
287 base->CMDPTR = 0;
288 #else
289 base->CMDPTR = (uint32_t) pkt_desc;
290 #endif
291 base->PKTCNT = 1U;
292
293 status = sdp_wait_done(base);
294
295 return status;
296 }
297
sdp_aes_crypt_cbc(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,sdp_aes_op_t op,uint32_t length,const uint8_t iv[16],const uint8_t * input,uint8_t * output)298 hpm_stat_t sdp_aes_crypt_cbc(SDP_Type *base,
299 sdp_aes_ctx_t *aes_ctx,
300 sdp_aes_op_t op,
301 uint32_t length,
302 const uint8_t iv[16],
303 const uint8_t *input,
304 uint8_t *output)
305 {
306 assert((base != NULL) && (aes_ctx != NULL));
307 assert((op <= sdp_aes_op_decrypt) && (input != NULL) && (output != NULL));
308
309 hpm_stat_t status;
310
311 base->SDPCR = SDP_SDPCR_CIPHEN_MASK;
312 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
313 base->SDPCR |= HPM_BITSMASK(1, 8);
314 base->PKTCTL = SDP_PKT_CTRL_DERSEMA_MASK | SDP_PKT_CTRL_CIPHIV_MASK;
315 base->PKTSRC = (uint32_t) input;
316 base->PKTDST = (uint32_t) output;
317 base->PKTBUF = length;
318 #else
319 sdp_pkt_struct_t *pkt_desc = &aes_ctx->sdp_pkt;
320 pkt_desc->next_cmd = NULL;
321 pkt_desc->pkt_ctrl.PKT_CTRL = SDP_PKT_CTRL_DERSEMA_MASK | SDP_PKT_CTRL_CIPHIV_MASK;
322 pkt_desc->src_addr = (uint32_t) input;
323 pkt_desc->dst_addr = (uint32_t) output;
324 pkt_desc->buf_size = length;
325 #endif
326
327 sdp_clear_error_status(base);
328
329 if (aes_ctx->crypto_algo == sdp_crypto_alg_aes) {
330 if (aes_ctx->key_bits == sdp_aes_keybits_128) {
331 base->MODCTRL =
332 SDP_MODCTRL_AESALG_SET(SDP_CRYPTO_ALG_IDX_AES128) | SDP_MODCTRL_AESKS_SET(aes_ctx->key_idx) |
333 SDP_MODCTRL_AESDIR_SET(op) | SDP_MODCTRL_AESMOD_SET(1);
334 } else {
335 base->MODCTRL =
336 SDP_MODCTRL_AESALG_SET(SDP_CRYPTO_ALG_IDX_AES256) | SDP_MODCTRL_AESKS_SET(aes_ctx->key_idx) |
337 SDP_MODCTRL_AESDIR_SET(op) | SDP_MODCTRL_AESMOD_SET(1);
338 }
339 }
340 #if defined(SDP_HAS_SM4_SUPPORT) && (SDP_HAS_SM4_SUPPORT == 1)
341 else if (aes_ctx->crypto_algo == sdp_crypto_alg_sm4) {
342 base->MODCTRL = SDP_MODCTRL_AESALG_SET(SDP_CRYPTO_ALG_IDX_SM4) | SDP_MODCTRL_AESKS_SET(aes_ctx->key_idx) |
343 SDP_MODCTRL_AESDIR_SET(op) | SDP_MODCTRL_AESMOD_SET(1);
344 }
345 #endif
346 else {
347 return status_sdp_invalid_alg;
348 }
349
350 /* Set IV, copy the IV to the context first in case the IV address is not 32-bit aligned */
351 uint32_t iv_32[4];
352 (void) memcpy(iv_32, iv, 16);
353 for (uint32_t i = 0; i < 4; i++) {
354 base->CIPHIV[i] = iv_32[i];
355 }
356 (void) memset(iv_32, 0, sizeof(iv_32));
357 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
358 base->CMDPTR = 0;
359 #else
360 base->CMDPTR = (uint32_t) pkt_desc;
361 #endif
362 base->PKTCNT = 1U;
363
364 status = sdp_wait_done(base);
365
366 return status;
367 }
368
369 /*
370 * In the AES-CTR algorithm, all the numbers are represented in big-endian format, namely, LSB is in last byte
371 */
sdp_increment_bn(uint8_t * big_num,uint32_t bytes)372 static void sdp_increment_bn(uint8_t *big_num, uint32_t bytes)
373 {
374 for (uint32_t i = bytes - 1; i > 0u; i--) {
375 big_num[i]++;
376 if (big_num[i] != 0) {
377 break;
378 }
379 }
380 }
381
sdp_aes_crypt_ctr(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,uint8_t * nonce_counter,uint8_t * input,uint8_t * output,uint32_t length)382 hpm_stat_t sdp_aes_crypt_ctr(SDP_Type *base,
383 sdp_aes_ctx_t *aes_ctx,
384 uint8_t *nonce_counter,
385 uint8_t *input,
386 uint8_t *output,
387 uint32_t length)
388 {
389 hpm_stat_t status = status_invalid_argument;
390
391 do {
392 HPM_BREAK_IF(
393 (base == NULL) || (aes_ctx == NULL) || (nonce_counter == NULL) || (input == NULL) || (output == NULL));
394
395 uint32_t calc_len;
396 uint8_t *cipher_nonce = (uint8_t *) &aes_ctx->buf3;
397 while (length > 0) {
398 calc_len = (length < 16U) ? length : 16U;
399 status = sdp_aes_crypt_ecb(base, aes_ctx, sdp_aes_op_encrypt, 16, nonce_counter, cipher_nonce);
400 HPM_BREAK_IF(status != status_success);
401 uint8_t tmp;
402 for (uint32_t i = 0; i < calc_len; i++) {
403 tmp = *input++;
404 *output++ = (uint8_t) (tmp ^ cipher_nonce[i]);
405 }
406
407 length -= calc_len;
408 /* Increment counter, (128-bit big-endian */
409 sdp_increment_bn(nonce_counter, AES_CTR_BLOCK_UNIT);
410 }
411
412 } while (false);
413
414 return status;
415 }
416
uint32_to_be(uint8_t * dst,uint32_t len,uint32_t num)417 static void uint32_to_be(uint8_t *dst, uint32_t len, uint32_t num)
418 {
419 uint32_t i = 0;
420
421 (void) memset(dst, 0, len);
422
423 while (num > 0) {
424 dst[len - 1 - i] = num & 0xFF;
425 num >>= 8;
426 i++;
427 }
428 }
429
430 /*
431 * See section A2.1 in NIST Special Publication 800-38C
432 * q + n = 15
433 * n - nonce / iv
434 * byte0 = FLAG
435 * bit[2:0] - (q-1)
436 * bit[5:3] - (t-2/2
437 * bit[6] - adata
438 * bit[7] - reserved
439 *
440 * byte (1... 15-q) nonce
441 * byte (16-q...15) input length
442 *
443 */
aes_ccm_format_b0(uint8_t * block,const uint8_t * iv,uint32_t iv_len,uint32_t mac_len,uint32_t aad_len,uint32_t input_len)444 static void aes_ccm_format_b0(uint8_t *block,
445 const uint8_t *iv,
446 uint32_t iv_len,
447 uint32_t mac_len,
448 uint32_t aad_len,
449 uint32_t input_len)
450 {
451 uint8_t q = 15U - iv_len;
452 block[0] = 0;
453 block[0] |= (aad_len > 0) ? (1U << 6) : 0U;
454 block[0] |= ((mac_len - 2U) / 2U) << 3;
455 block[0] |= q - 1U;
456
457 (void) memcpy(block + 1U, iv, iv_len);
458
459 uint32_to_be(block + 1U + iv_len, q, input_len);
460
461 }
462
463 /*
464 * See section A2.3 in NIST Special Publication 800-38C
465 * q + n = 15
466 * n - nonce/iv
467 * byte 0 = FLAG
468 * bit[2:0] : (q - 1)
469 * bit[5:3] : 0
470 * bit[7:6] : 0
471 *
472 * byte (1...15-q) nonce
473 * byte (16-q ...15) i
474 */
aes_ccm_format_ctr0(uint8_t * ctr,const uint8_t * iv,uint8_t iv_len)475 static void aes_ccm_format_ctr0(uint8_t *ctr, const uint8_t *iv, uint8_t iv_len)
476 {
477 uint8_t q = 15U - iv_len;
478 (void) memset(ctr, 0, 16);
479 ctr[0] |= q - 1U;
480 (void) memcpy(ctr + 1U, iv, iv_len);
481 }
482
aes_ccm_auth_crypt(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,sdp_aes_op_t op,uint32_t input_len,const uint8_t * iv,uint32_t iv_len,const uint8_t * aad,uint32_t aad_len,const uint8_t * input,uint8_t * output,uint8_t * tag,uint32_t tag_len)483 static hpm_stat_t aes_ccm_auth_crypt(SDP_Type *base,
484 sdp_aes_ctx_t *aes_ctx,
485 sdp_aes_op_t op,
486 uint32_t input_len,
487 const uint8_t *iv,
488 uint32_t iv_len,
489 const uint8_t *aad,
490 uint32_t aad_len,
491 const uint8_t *input,
492 uint8_t *output,
493 uint8_t *tag,
494 uint32_t tag_len)
495 {
496 hpm_stat_t status = status_invalid_argument;
497
498 do {
499 HPM_BREAK_IF((base == NULL) || (aes_ctx == NULL) || (input == NULL) || (output == NULL) || (tag == NULL));
500
501
502 /*See section A.1 in NIST Special Publication 800-38C */
503
504 /* Valid Tlen is 4, 6, 8, 10, 12, 14, 16 */
505 HPM_BREAK_IF((tag_len % 2U != 0U) || (tag_len / 2U < 2) || (tag_len / 2U > 8));
506 /* Valid Nonce length is 7, 8, 9, 10, 11, 12, 13 */
507 HPM_BREAK_IF((iv_len < 7U) || (iv_len > 13U));
508
509 /* Note, this API supports maximum 2^32 - 1 bytes of data, so the valid q value should be 2, 3, or 4 */
510 uint8_t *b = (uint8_t *) &aes_ctx->buf0;
511 uint8_t *y = (uint8_t *) &aes_ctx->buf1;
512 uint8_t *ctr = (uint8_t *) &aes_ctx->buf2;
513
514 /* Format B0 */
515 aes_ccm_format_b0(b, iv, iv_len, tag_len, aad_len, input_len);
516
517 /* Calculate Y0 */
518 sdp_aes_crypt_ecb(base, aes_ctx, sdp_aes_op_encrypt, 16, b, y);
519
520
521 /*
522 * Follow A2.2.2 in NIST Special Publication 800-38C, only supports up to 2^32 bytes
523 */
524 if (aad_len > 0U) {
525 uint32_t calc_len = 0U;
526 const uint8_t *aad_src = aad;
527 uint32_t remaining_len = aad_len;
528 (void) memset(b, 0, 16);
529 /* format B1
530 * Follow A2.2.2 in NIST Special Publication 800-38C, only supports up to 2^32 bytes
531 */
532 if (aad_len < ((1UL << 16) - (1U << 8))) {
533 uint32_to_be(b, 2, aad_len);
534 calc_len = MIN(remaining_len, 14U);
535 (void) memcpy(&b[2], aad_src, calc_len);
536 } else {
537 b[0] = 0xFFU;
538 b[1] = 0xFEU;
539 uint32_to_be(&b[6], 4, calc_len);
540 calc_len = 10U;
541 (void) memcpy(&b[2], aad_src, calc_len);
542 }
543 aad_src += calc_len;
544 remaining_len -= calc_len;
545 /* Calculate Y(i) = CIPHk(B(i) ^ Y(i-1)) */
546 sdp_aes_crypt_cbc(base, aes_ctx, sdp_aes_op_encrypt, 16, b, y, y);
547
548 while (remaining_len > 0U) {
549 calc_len = MIN(remaining_len, 16U);
550 (void) memcpy(b, aad_src, calc_len);
551 if (calc_len < 16U) {
552 (void) memset(&b[calc_len], 0, 16U - calc_len);
553 }
554 aad_src += calc_len;
555 remaining_len -= calc_len;
556 /* Calculate Y(i) = CIPHk(B(i) ^ Y(i-1)) */
557 sdp_aes_crypt_cbc(base, aes_ctx, sdp_aes_op_encrypt, 16, b, y, y);
558 }
559 }
560
561 aes_ccm_format_ctr0(ctr, iv, iv_len);
562 /* Encryption/Decryption starts from CTR1 */
563 sdp_increment_bn(ctr, 16);
564 /* Continue CBC-MAC calculation + Encryption/Decryption */
565 uint32_t remaining_len = input_len;
566 uint8_t *src = (uint8_t *) input;
567 uint8_t *dst = output;
568 while (remaining_len > 0U) {
569 uint32_t calc_len = MIN(remaining_len, 16U);
570 if (op == sdp_aes_op_encrypt) {
571 (void) memcpy(b, src, calc_len);
572 if (calc_len < 16U) {
573 (void) memset(&b[calc_len], 0, 16U - calc_len);
574 }
575 /* Calculate Y(i) = CIPHk(B(i) ^ Y(i-1)) */
576 sdp_aes_crypt_cbc(base, aes_ctx, sdp_aes_op_encrypt, 16, b, y, y);
577 }
578 sdp_aes_crypt_ctr(base, aes_ctx, ctr, src, dst, calc_len);
579 if (op == sdp_aes_op_decrypt) {
580 (void) memcpy(b, dst, calc_len);
581 if (calc_len < 16U) {
582 (void) memset(&b[calc_len], 0, 16U - calc_len);
583 }
584 /* Calculate Y(i) = CIPHk(B(i) ^ Y(i-1)) */
585 sdp_aes_crypt_cbc(base, aes_ctx, sdp_aes_op_encrypt, 16, b, y, y);
586 }
587 src += calc_len;
588 dst += calc_len;
589 remaining_len -= calc_len;
590 }
591
592 /* Get CTR0 */
593 aes_ccm_format_ctr0(ctr, iv, iv_len);
594 /* Get MAC */
595 sdp_aes_crypt_ctr(base, aes_ctx, ctr, y, b, 16);
596 /* Copy mac to the destination */
597 (void) memcpy(tag, b, tag_len);
598
599 /* Wipe-out temporary data */
600 (void) memset(b, 0, 16U);
601 (void) memset(y, 0, 16);
602 (void) memset(ctr, 0, 16);
603
604 status = status_success;
605
606 } while (false);
607 return status;
608 }
609
sdp_aes_ccm_generate_encrypt(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,uint32_t input_len,const uint8_t * iv,uint32_t iv_len,const uint8_t * aad,uint32_t aad_len,const uint8_t * input,uint8_t * output,uint8_t * tag,uint32_t tag_len)610 hpm_stat_t sdp_aes_ccm_generate_encrypt(SDP_Type *base,
611 sdp_aes_ctx_t *aes_ctx,
612 uint32_t input_len,
613 const uint8_t *iv,
614 uint32_t iv_len,
615 const uint8_t *aad,
616 uint32_t aad_len,
617 const uint8_t *input,
618 uint8_t *output,
619 uint8_t *tag,
620 uint32_t tag_len)
621 {
622 return aes_ccm_auth_crypt(base,
623 aes_ctx,
624 sdp_aes_op_encrypt,
625 input_len,
626 iv,
627 iv_len,
628 aad,
629 aad_len,
630 input,
631 output,
632 tag,
633 tag_len);
634 }
635
sdp_constant_time_cmp(const void * dst,const void * src,uint32_t len)636 static uint8_t sdp_constant_time_cmp(const void *dst, const void *src, uint32_t len)
637 {
638 uint8_t result = 0U;
639
640 const uint8_t *dst_8 = (const uint8_t *) dst;
641 const uint8_t *src_8 = (const uint8_t *) src;
642
643 while (len-- > 0U) {
644 result |= *dst_8 ^ *src_8;
645 ++dst_8;
646 ++src_8;
647
648 }
649 return result;
650 }
651
sdp_aes_ccm_decrypt_verify(SDP_Type * base,sdp_aes_ctx_t * aes_ctx,uint32_t input_len,const uint8_t * iv,uint32_t iv_len,const uint8_t * aad,uint32_t aad_len,const uint8_t * input,uint8_t * output,const uint8_t * tag,uint32_t tag_len)652 hpm_stat_t sdp_aes_ccm_decrypt_verify(SDP_Type *base,
653 sdp_aes_ctx_t *aes_ctx,
654 uint32_t input_len,
655 const uint8_t *iv,
656 uint32_t iv_len,
657 const uint8_t *aad,
658 uint32_t aad_len,
659 const uint8_t *input,
660 uint8_t *output,
661 const uint8_t *tag,
662 uint32_t tag_len)
663 {
664 hpm_stat_t status;
665
666 do {
667
668 uint32_t calc_mac[4];
669
670 status = aes_ccm_auth_crypt(base,
671 aes_ctx,
672 sdp_aes_op_decrypt,
673 input_len,
674 iv,
675 iv_len,
676 aad,
677 aad_len,
678 input,
679 output,
680 (uint8_t *) &calc_mac,
681 tag_len);
682 HPM_BREAK_IF(status != status_success);
683 if (sdp_constant_time_cmp(calc_mac, tag, tag_len) != 0U) {
684 status = status_sdp_error_invalid_mac;
685 } else {
686 status = status_success;
687 }
688
689 } while (false);
690
691 return status;
692 }
693
sdp_hash_init(SDP_Type * base,sdp_hash_ctx_t * hash_ctx,sdp_hash_alg_t alg)694 hpm_stat_t sdp_hash_init(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, sdp_hash_alg_t alg)
695 {
696 hpm_stat_t status = status_invalid_argument;
697 do {
698 if (IS_HPM_BITMASK_SET(base->SDPCR, SDP_SDPCR_HASDIS_MASK)) {
699 status = status_sdp_no_hash_support;
700 break;
701 }
702
703 /* Initialize the SDP HASH context */
704 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &hash_ctx->internal;
705 (void) memset(ctx_internal, 0, sizeof(*ctx_internal));
706 ctx_internal->alg = alg;
707 ctx_internal->blk_size = 0;
708 ctx_internal->state = sdp_state_hash_init;
709 ctx_internal->full_msg_size = 0;
710
711 status = status_success;
712
713 } while (false);
714
715 return status;
716 }
717
sdp_hash_internal_engine_init(SDP_Type * base,sdp_hash_ctx_t * hash_ctx)718 static void sdp_hash_internal_engine_init(SDP_Type *base, sdp_hash_ctx_t *hash_ctx)
719 {
720 (void) base;
721 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &hash_ctx->internal;
722
723 ctx_internal->hash_init = true;
724 ctx_internal->hash_finish = false;
725 }
726
sdp_hash_internal_update(SDP_Type * base,sdp_hash_ctx_t * ctx,const uint8_t * msg,uint32_t msg_size)727 static hpm_stat_t sdp_hash_internal_update(SDP_Type *base, sdp_hash_ctx_t *ctx, const uint8_t *msg, uint32_t msg_size)
728 {
729 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &ctx->internal;
730 sdp_pkt_struct_t *pkt_desc = (sdp_pkt_struct_t *) &ctx->sdp_pkt;
731
732 pkt_desc->next_cmd = NULL;
733 uint32_t pkt_ctrl = SDP_PKT_CTRL_DERSEMA_MASK;
734 if (ctx_internal->hash_init) {
735 pkt_ctrl |= SDP_PKT_CTRL_HASHINIT_MASK;
736 ctx_internal->hash_init = false;
737 }
738 if (ctx_internal->hash_finish) {
739 pkt_ctrl |= SDP_PKT_CTRL_HASHFINISH_MASK;
740 ctx_internal->hash_finish = false;
741 }
742
743 base->SDPCR = SDP_SDPCR_HASHEN_MASK;
744 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
745 base->SDPCR |= HPM_BITSMASK(1, 8);
746 base->NPKTPTR = 0UL;
747 base->PKTCTL = pkt_ctrl;
748 base->PKTSRC = (uint32_t) msg;
749 base->PKTDST = (uint32_t) 0;
750 base->PKTBUF = msg_size;
751 #else
752 pkt_desc->pkt_ctrl.PKT_CTRL = pkt_ctrl;
753 pkt_desc->src_addr = (uint32_t) msg;
754 pkt_desc->dst_addr = 0;
755 pkt_desc->buf_size = msg_size;
756 pkt_desc->reserved[0] = 0;
757 pkt_desc->reserved[1] = 0;
758 pkt_desc->reserved[2] = 0;
759 #endif
760
761 sdp_clear_error_status(base);
762 base->MODCTRL = SDP_MODCTRL_HASALG_SET(ctx_internal->alg);
763 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
764 base->CMDPTR = 0;
765 #else
766 base->CMDPTR = (uint32_t) pkt_desc;
767 #endif
768 base->PKTCNT = 1;
769
770 hpm_stat_t status = sdp_wait_done(base);
771
772 return status;
773 }
774
sdp_hash_process_message(SDP_Type * base,sdp_hash_ctx_t * ctx,const uint8_t * msg,uint32_t msg_size)775 static hpm_stat_t sdp_hash_process_message(SDP_Type *base, sdp_hash_ctx_t *ctx, const uint8_t *msg, uint32_t msg_size)
776 {
777 hpm_stat_t status = status_invalid_argument;
778
779 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &ctx->internal;
780 /* If there is partially filled internal buffer, fill it to full block */
781 if (ctx_internal->blk_size > 0U) {
782 uint32_t size_to_copy = HASH_BLOCK_SIZE - ctx_internal->blk_size;
783 (void) memcpy(&ctx_internal->block.bytes[ctx_internal->blk_size], msg, size_to_copy);
784 msg += size_to_copy;
785 msg_size -= size_to_copy;
786
787 /* process the full internal block */
788 status = sdp_hash_internal_update(base, ctx, &ctx_internal->block.bytes[0], HASH_BLOCK_SIZE);
789 if (status != status_success) {
790 return status;
791 }
792 }
793
794 /* Process all full blocks in message */
795 uint32_t full_blk_size = (msg_size >> 6) << 6;
796 if (full_blk_size > 0U) {
797 status = sdp_hash_internal_update(base, ctx, msg, full_blk_size);
798 if (status != status_success) {
799 return status;
800 }
801 msg += full_blk_size;
802 msg_size -= full_blk_size;
803 }
804
805 (void) memcpy(&ctx_internal->block.bytes[0], msg, msg_size);
806 ctx_internal->blk_size = msg_size;
807
808 return status;
809 }
810
sdp_hash_update(SDP_Type * base,sdp_hash_ctx_t * hash_ctx,const uint8_t * data,uint32_t length)811 hpm_stat_t sdp_hash_update(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, const uint8_t *data, uint32_t length)
812 {
813 assert((base != NULL) && (hash_ctx != NULL) && (data != NULL));
814 hpm_stat_t status = status_invalid_argument;
815 do {
816 if (length == 0) {
817 status = status_success;
818 break;
819 }
820
821 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &hash_ctx->internal;
822 uint32_t block_size = HASH_BLOCK_SIZE;
823 ctx_internal->full_msg_size += length;
824 /* If the data is still less than HASH_BLOCK_SIZE, keep them only in the buffer */
825 if ((ctx_internal->blk_size + length) <= block_size) {
826 (void) memcpy(&ctx_internal->block.bytes[0] + ctx_internal->blk_size, data, length);
827 ctx_internal->blk_size += length;
828 status = status_success;
829 break;
830 } else {
831 if (ctx_internal->state != sdp_state_hash_update) {
832 sdp_hash_internal_engine_init(base, hash_ctx);
833 ctx_internal->state = sdp_state_hash_update;
834 }
835 }
836
837 /* Process input data */
838 status = sdp_hash_process_message(base, hash_ctx, data, length);
839 } while (false);
840
841 return status;
842 }
843
sdp_hash_finalize(SDP_Type * base,sdp_hash_ctx_t * hash_ctx)844 static hpm_stat_t sdp_hash_finalize(SDP_Type *base, sdp_hash_ctx_t *hash_ctx)
845 {
846 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &hash_ctx->internal;
847 hpm_stat_t status;
848 ctx_internal->hash_finish = true;
849
850 status = sdp_hash_internal_update(base, hash_ctx, &ctx_internal->block.bytes[0], ctx_internal->blk_size);
851
852 return status;
853 }
854
sdp_hash_finish(SDP_Type * base,sdp_hash_ctx_t * hash_ctx,uint8_t * digest)855 hpm_stat_t sdp_hash_finish(SDP_Type *base, sdp_hash_ctx_t *hash_ctx, uint8_t *digest)
856 {
857 assert((base != NULL) && (hash_ctx != NULL) && (digest != NULL));
858
859 hpm_stat_t status = status_invalid_argument;
860 do {
861 sdp_hash_internal_ctx_t *ctx_internal = (sdp_hash_internal_ctx_t *) &hash_ctx->internal;
862 if (ctx_internal->state == sdp_state_hash_init) {
863 sdp_hash_internal_engine_init(base, hash_ctx);
864 }
865 status = sdp_hash_finalize(base, hash_ctx);
866 HPM_BREAK_IF(status != status_success);
867
868 uint32_t copy_bytes = 0;
869 uint32_t digest_words = 0;
870 switch (ctx_internal->alg) {
871 case sdp_hash_alg_crc32:
872 copy_bytes = CRC32_DIGEST_SIZE_IN_BYTES;
873 ctx_internal->running_hash[0] = base->HASWRD[0];
874 break;
875 case sdp_hash_alg_sha1:
876 copy_bytes = SHA1_DIGEST_SIZE_IN_BYTES;
877 digest_words = copy_bytes / sizeof(uint32_t);
878 for (uint32_t i = 0; i < digest_words; i++) {
879 ctx_internal->running_hash[i] = base->HASWRD[i];
880 }
881 break;
882 case sdp_hash_alg_sha256:
883 #if defined(SDP_HAS_SM3_SUPPORT) && (SDP_HAS_SM3_SUPPORT == 1)
884 case sdp_hash_alg_sm3:
885 #endif
886 copy_bytes = SHA256_DIGEST_SIZE_IN_BYTES;
887 digest_words = copy_bytes / sizeof(uint32_t);
888 for (uint32_t i = 0; i < digest_words; i++) {
889 ctx_internal->running_hash[i] = base->HASWRD[i];
890 }
891 break;
892 default:
893 /* Never reach here */
894 break;
895 }
896 (void) memcpy(digest, ctx_internal->running_hash, copy_bytes);
897 } while (false);
898
899 return status;
900 }
901
sdp_memcpy(SDP_Type * base,sdp_dma_ctx_t * dma_ctx,void * dst,const void * src,uint32_t length)902 hpm_stat_t sdp_memcpy(SDP_Type *base, sdp_dma_ctx_t *dma_ctx, void *dst, const void *src, uint32_t length)
903 {
904 (void) dma_ctx;
905 hpm_stat_t status = status_invalid_argument;
906
907 if (length == 0) {
908 status = status_success;
909 return status;
910 }
911
912 base->SDPCR = SDP_SDPCR_MCPEN_MASK;
913 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
914 base->SDPCR |= HPM_BITSMASK(1, 8);
915 base->NPKTPTR = 0;
916 base->PKTCTL = SDP_PKT_CTRL_DERSEMA_MASK | SDP_PKTCTL_PKTTAG_SET(1);
917 base->PKTSRC = (uint32_t) src;
918 base->PKTDST = (uint32_t) dst;
919 base->PKTBUF = length;
920 #else
921 sdp_pkt_struct_t *pkt_desc = &dma_ctx->sdp_pkt;
922 pkt_desc->next_cmd = NULL;
923 pkt_desc->pkt_ctrl.PKT_CTRL = SDP_PKT_CTRL_DERSEMA_MASK;
924 pkt_desc->src_addr = (uint32_t) src;
925 pkt_desc->dst_addr = (uint32_t) dst;
926 pkt_desc->buf_size = length;
927 #endif
928
929 sdp_clear_error_status(base);
930
931 base->MODCTRL = 0;
932 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
933 base->CMDPTR = 0;
934 #else
935 base->CMDPTR = (uint32_t) pkt_desc;
936 #endif
937 base->PKTCNT = 1;
938
939 status = sdp_wait_done(base);
940
941 return status;
942 }
943
sdp_memset(SDP_Type * base,sdp_dma_ctx_t * sdp_ctx,void * dst,uint8_t pattern,uint32_t length)944 hpm_stat_t sdp_memset(SDP_Type *base, sdp_dma_ctx_t *sdp_ctx, void *dst, uint8_t pattern, uint32_t length)
945 {
946 (void) sdp_ctx;
947 hpm_stat_t status;
948
949 uint32_t
950 pattern_32 = (pattern) | ((uint32_t) pattern << 8) | ((uint32_t) pattern << 16) | ((uint32_t) pattern << 24);
951
952 base->SDPCR = SDP_SDPCR_CONFEN_MASK;
953 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
954 base->SDPCR |= HPM_BITSMASK(1, 8);
955 base->PKTCTL = SDP_PKT_CTRL_DERSEMA_MASK;
956 base->PKTSRC = (uint32_t) pattern_32;
957 base->PKTDST = (uint32_t) dst;
958 base->PKTBUF = length;
959 #else
960 sdp_pkt_struct_t *pkt_desc = &sdp_ctx->sdp_pkt;
961 pkt_desc->next_cmd = NULL;
962 pkt_desc->pkt_ctrl.PKT_CTRL = SDP_PKT_CTRL_DERSEMA_MASK;
963 pkt_desc->src_addr = pattern_32;
964 pkt_desc->dst_addr = (uint32_t) dst;
965 pkt_desc->buf_size = length;
966 #endif
967
968 sdp_clear_error_status(base);
969 base->MODCTRL = 0;
970 #if defined(SDP_REGISTER_DESCRIPTOR_COUNT) && SDP_REGISTER_DESCRIPTOR_COUNT
971 base->CMDPTR = 0;
972 #else
973 base->CMDPTR = (uint32_t) pkt_desc;
974 #endif
975 base->PKTCNT = 1;
976
977 status = sdp_wait_done(base);
978
979 return status;
980 }
981