• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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