@@ -85,6 +85,7 @@ REG32(ERR_CODE, 0x1cu)
85
85
#define R_ERR_CODE_UPDATE_SECRET_KEY_INPROCESS 0x00000003u
86
86
#define R_ERR_CODE_HASH_START_WHEN_ACTIVE 0x00000004u
87
87
#define R_ERR_CODE_PUSH_MSG_WHEN_DISALLOWED 0x00000005u
88
+ #define R_ERR_CODE_INVALID_CONFIG 0x00000006u
88
89
REG32 (WIPE_SECRET , 0x20u )
89
90
REG32 (KEY_0 , 0x24u )
90
91
REG32 (KEY_1 , 0x28u )
@@ -259,6 +260,62 @@ struct OtHMACState {
259
260
char * ot_id ;
260
261
};
261
262
263
+ enum OtHMACDigestSize {
264
+ HMAC_SHA2_256 ,
265
+ HMAC_SHA2_384 ,
266
+ HMAC_SHA2_512 ,
267
+ HMAC_SHA2_NONE ,
268
+ };
269
+
270
+ enum OtHMACKeyLength {
271
+ HMAC_KEY_128 ,
272
+ HMAC_KEY_256 ,
273
+ HMAC_KEY_384 ,
274
+ HMAC_KEY_512 ,
275
+ HMAC_KEY_1024 ,
276
+ HMAC_KEY_NONE ,
277
+ };
278
+
279
+ static inline enum OtHMACDigestSize ot_hmac_get_digest_size (uint32_t cfg_reg )
280
+ {
281
+ switch ((cfg_reg & R_CFG_DIGEST_SIZE_MASK ) >> R_CFG_DIGEST_SIZE_SHIFT ) {
282
+ case 0x1u :
283
+ return HMAC_SHA2_256 ;
284
+ case 0x2u :
285
+ return HMAC_SHA2_384 ;
286
+ case 0x4u :
287
+ return HMAC_SHA2_512 ;
288
+ case 0x8u :
289
+ default :
290
+ return HMAC_SHA2_NONE ;
291
+ }
292
+ }
293
+
294
+ static inline enum OtHMACKeyLength ot_hmac_get_key_length (uint32_t cfg_reg )
295
+ {
296
+ switch ((cfg_reg & R_CFG_KEY_LENGTH_MASK ) >> R_CFG_KEY_LENGTH_SHIFT ) {
297
+ case 0x01u :
298
+ return HMAC_KEY_128 ;
299
+ case 0x02u :
300
+ return HMAC_KEY_256 ;
301
+ case 0x04u :
302
+ return HMAC_KEY_384 ;
303
+ case 0x08u :
304
+ return HMAC_KEY_512 ;
305
+ case 0x10u :
306
+ return HMAC_KEY_1024 ;
307
+ case 0x20u :
308
+ default :
309
+ return HMAC_KEY_NONE ;
310
+ }
311
+ }
312
+
313
+ static inline bool ot_hmac_key_length_supported (
314
+ enum OtHMACDigestSize digest_size , enum OtHMACKeyLength key_length )
315
+ {
316
+ return !(digest_size == HMAC_SHA2_256 && key_length == HMAC_KEY_1024 );
317
+ }
318
+
262
319
static void ot_hmac_update_irqs (OtHMACState * s )
263
320
{
264
321
uint32_t levels = s -> regs -> intr_state & s -> regs -> intr_enable ;
@@ -589,6 +646,9 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value,
589
646
uint32_t pc = ibex_get_current_pc ();
590
647
trace_ot_hmac_io_write (s -> ot_id , (uint32_t )addr , REG_NAME (reg ), val32 , pc );
591
648
649
+ enum OtHMACDigestSize digest_size ;
650
+ enum OtHMACKeyLength key_length ;
651
+
592
652
switch (reg ) {
593
653
case R_INTR_STATE :
594
654
s -> regs -> intr_state &= ~(val32 & INTR_MASK );
@@ -612,19 +672,51 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value,
612
672
break ;
613
673
}
614
674
615
- s -> regs -> cfg =
616
- val32 &
675
+ val32 &=
617
676
(R_CFG_HMAC_EN_MASK | R_CFG_SHA_EN_MASK | R_CFG_ENDIAN_SWAP_MASK |
618
677
R_CFG_DIGEST_SWAP_MASK | R_CFG_KEY_SWAP_MASK |
619
678
R_CFG_DIGEST_SIZE_MASK | R_CFG_KEY_LENGTH_MASK );
620
679
680
+ /* If the digest size is invalid, it gets mapped to SHA2_NONE. */
681
+ digest_size = ot_hmac_get_digest_size (val32 );
682
+ if (digest_size == HMAC_SHA2_NONE ) {
683
+ val32 &= ~R_CFG_DIGEST_SIZE_MASK ;
684
+ val32 |= 0x8u << R_CFG_DIGEST_SIZE_SHIFT ;
685
+ }
686
+
687
+ /* If the key length is invalid, it gets mapped to KEY_NONE. */
688
+ key_length = ot_hmac_get_key_length (val32 );
689
+ if (key_length == HMAC_KEY_NONE ) {
690
+ val32 &= ~R_CFG_KEY_LENGTH_MASK ;
691
+ val32 |= 0x20u << R_CFG_KEY_LENGTH_SHIFT ;
692
+ }
693
+
694
+ s -> regs -> cfg = val32 ;
695
+
621
696
/* clear digest when SHA is disabled */
622
697
if (!(s -> regs -> cfg & R_CFG_SHA_EN_MASK )) {
623
698
ot_hmac_wipe_buffer (s , s -> regs -> digest ,
624
699
ARRAY_SIZE (s -> regs -> digest ));
625
700
}
626
701
break ;
627
702
case R_CMD :
703
+ if (val32 & (R_CMD_HASH_START_MASK | R_CMD_HASH_CONTINUE_MASK )) {
704
+ digest_size = ot_hmac_get_digest_size (s -> regs -> cfg );
705
+ if (digest_size == HMAC_SHA2_NONE ) {
706
+ ot_hmac_report_error (s , R_ERR_CODE_INVALID_CONFIG );
707
+ break ;
708
+ }
709
+
710
+ if (s -> regs -> cfg & R_CFG_HMAC_EN_MASK ) {
711
+ key_length = ot_hmac_get_key_length (s -> regs -> cfg );
712
+ if (key_length == HMAC_KEY_NONE ||
713
+ !ot_hmac_key_length_supported (digest_size , key_length )) {
714
+ ot_hmac_report_error (s , R_ERR_CODE_INVALID_CONFIG );
715
+ break ;
716
+ }
717
+ }
718
+ }
719
+
628
720
if (val32 & R_CMD_HASH_START_MASK ) {
629
721
if (!(s -> regs -> cfg & R_CFG_SHA_EN_MASK )) {
630
722
ot_hmac_report_error (s ,
0 commit comments