44
44
/* Input FIFO length is 64 bytes (16 x 32 bits) */
45
45
#define OT_HMAC_FIFO_LENGTH 64u
46
46
47
- /* Digest length is 32 bytes (256 bits) */
48
- #define OT_HMAC_DIGEST_LENGTH 32u
47
+ /* (Maximum) digest length is 64 bytes (512 bits) */
48
+ #define OT_HMAC_MAX_DIGEST_LENGTH 64u
49
49
50
- /* HMAC key length is 32 bytes (256 bits) */
51
- #define OT_HMAC_KEY_LENGTH 32u
50
+ /* HMAC (maximum) key length is 128 bytes (1024 bits) */
51
+ #define OT_HMAC_MAX_KEY_LENGTH 128u
52
52
53
53
#define PARAM_NUM_IRQS 3u
54
54
@@ -231,8 +231,8 @@ struct OtHMACRegisters {
231
231
uint32_t cmd ;
232
232
uint32_t err_code ;
233
233
uint32_t wipe_secret ;
234
- uint32_t key [OT_HMAC_KEY_LENGTH / sizeof (uint32_t )];
235
- uint32_t digest [OT_HMAC_DIGEST_LENGTH / sizeof (uint32_t )];
234
+ uint32_t key [OT_HMAC_MAX_KEY_LENGTH / sizeof (uint32_t )];
235
+ uint32_t digest [OT_HMAC_MAX_DIGEST_LENGTH / sizeof (uint32_t )];
236
236
uint64_t msg_length ;
237
237
};
238
238
typedef struct OtHMACRegisters OtHMACRegisters ;
@@ -291,6 +291,41 @@ static inline enum OtHMACDigestSize ot_hmac_get_digest_size(uint32_t cfg_reg)
291
291
}
292
292
}
293
293
294
+ static inline size_t ot_hmac_get_digest_bytes (OtHMACState * s )
295
+ {
296
+ switch (ot_hmac_get_digest_size (s -> regs -> cfg )) {
297
+ case HMAC_SHA2_256 :
298
+ return 32u ;
299
+ case HMAC_SHA2_384 :
300
+ return 48u ;
301
+ case HMAC_SHA2_512 :
302
+ return 64u ;
303
+ case HMAC_SHA2_NONE :
304
+ default :
305
+ qemu_log_mask (LOG_GUEST_ERROR ,
306
+ "%s: Cannot get digest size if it is not set. \n" ,
307
+ __func__ );
308
+ return 0u ;
309
+ }
310
+ }
311
+
312
+ static inline size_t ot_hmac_get_block_size_bytes (OtHMACState * s )
313
+ {
314
+ switch (ot_hmac_get_digest_size (s -> regs -> cfg )) {
315
+ case HMAC_SHA2_256 :
316
+ return 64u ;
317
+ case HMAC_SHA2_384 :
318
+ case HMAC_SHA2_512 :
319
+ return 128u ;
320
+ case HMAC_SHA2_NONE :
321
+ default :
322
+ qemu_log_mask (LOG_GUEST_ERROR ,
323
+ "%s: Cannot get block size if digest size is not set. \n" ,
324
+ __func__ );
325
+ return 0u ;
326
+ }
327
+ }
328
+
294
329
static inline enum OtHMACKeyLength ot_hmac_get_key_length (uint32_t cfg_reg )
295
330
{
296
331
switch ((cfg_reg & R_CFG_KEY_LENGTH_MASK ) >> R_CFG_KEY_LENGTH_SHIFT ) {
@@ -310,6 +345,27 @@ static inline enum OtHMACKeyLength ot_hmac_get_key_length(uint32_t cfg_reg)
310
345
}
311
346
}
312
347
348
+ static inline size_t ot_hmac_get_key_bytes (OtHMACState * s )
349
+ {
350
+ switch (ot_hmac_get_key_length (s -> regs -> cfg )) {
351
+ case HMAC_KEY_128 :
352
+ return 16u ;
353
+ case HMAC_KEY_256 :
354
+ return 32u ;
355
+ case HMAC_KEY_384 :
356
+ return 48u ;
357
+ case HMAC_KEY_512 :
358
+ return 64u ;
359
+ case HMAC_KEY_1024 :
360
+ return 128u ;
361
+ case HMAC_KEY_NONE :
362
+ default :
363
+ qemu_log_mask (LOG_GUEST_ERROR ,
364
+ "%s: Cannot get key size if it is not set. \n" , __func__ );
365
+ return 0u ;
366
+ }
367
+ }
368
+
313
369
static inline bool ot_hmac_key_length_supported (
314
370
enum OtHMACDigestSize digest_size , enum OtHMACKeyLength key_length )
315
371
{
@@ -344,8 +400,7 @@ static void ot_hmac_writeback_digest_state(OtHMACState *s)
344
400
/* copy intermediary digest to mock HMAC operation for stop/continue
345
401
behaviour. */
346
402
/* TODO: add support for SHA2-384 and SHA2-512 */
347
- unsigned digest_length = OT_HMAC_DIGEST_LENGTH / sizeof (uint32_t );
348
- for (unsigned i = 0 ; i < digest_length ; i ++ ) {
403
+ for (unsigned i = 0 ; i < 8u ; i ++ ) {
349
404
STORE32H (s -> ctx -> state .sha256 .state [i ], s -> regs -> digest + i );
350
405
}
351
406
}
@@ -383,16 +438,22 @@ static void ot_hmac_compute_digest(OtHMACState *s)
383
438
if (s -> regs -> cfg & R_CFG_HMAC_EN_MASK ) {
384
439
ot_hmac_sha_done (s );
385
440
386
- uint64_t opad [8u ];
441
+ size_t key_length_b = ot_hmac_get_key_bytes (s );
442
+ size_t block_size_b = ot_hmac_get_block_size_bytes (s );
443
+ /* If the key is smaller than the block size, we must pad it to the
444
+ right with 0s. */
445
+ size_t pad_length_b = MAX (key_length_b , block_size_b );
446
+ size_t pad_length_w = pad_length_b / sizeof (uint32_t );
447
+ uint32_t opad [OT_HMAC_MAX_KEY_LENGTH / sizeof (uint32_t )];
387
448
memset (opad , 0 , sizeof (opad ));
388
- memcpy (opad , s -> regs -> key , sizeof ( s -> regs -> key ) );
389
- for (unsigned i = 0 ; i < ARRAY_SIZE ( opad ) ; i ++ ) {
390
- opad [i ] ^= 0x5c5c5c5c5c5c5c5cull ;
449
+ memcpy (opad , s -> regs -> key , key_length_b );
450
+ for (unsigned i = 0 ; i < pad_length_w ; i ++ ) {
451
+ opad [i ] ^= 0x5c5c5c5cul ;
391
452
}
392
453
ot_hmac_sha_init (s , false);
393
- ot_hmac_sha_process (s , (const uint8_t * )opad , sizeof ( opad ) , false);
454
+ ot_hmac_sha_process (s , (const uint8_t * )opad , pad_length_b , false);
394
455
ot_hmac_sha_process (s , (const uint8_t * )s -> regs -> digest ,
395
- sizeof ( s -> regs -> digest ), true);
456
+ ot_hmac_get_digest_bytes ( s ), true);
396
457
}
397
458
ot_hmac_sha_done (s );
398
459
}
@@ -736,13 +797,19 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value,
736
797
737
798
/* HMAC mode, process input padding */
738
799
if (s -> regs -> cfg & R_CFG_HMAC_EN_MASK ) {
739
- uint64_t ipad [8u ];
800
+ size_t key_length_b = ot_hmac_get_key_bytes (s );
801
+ size_t block_size_b = ot_hmac_get_block_size_bytes (s );
802
+ /* If the key is smaller than the block size, we must pad it to
803
+ the right with 0s. */
804
+ size_t pad_length_b = MAX (key_length_b , block_size_b );
805
+ size_t pad_length_w = pad_length_b / sizeof (uint32_t );
806
+ uint32_t ipad [OT_HMAC_MAX_KEY_LENGTH / sizeof (uint32_t )];
740
807
memset (ipad , 0 , sizeof (ipad ));
741
- memcpy (ipad , s -> regs -> key , sizeof ( s -> regs -> key ) );
742
- for (unsigned i = 0 ; i < ARRAY_SIZE ( ipad ) ; i ++ ) {
743
- ipad [i ] ^= 0x3636363636363636u ;
808
+ memcpy (ipad , s -> regs -> key , key_length_b );
809
+ for (unsigned i = 0 ; i < pad_length_w ; i ++ ) {
810
+ ipad [i ] ^= 0x36363636ul ;
744
811
}
745
- ot_hmac_sha_process (s , (const uint8_t * )ipad , sizeof ( ipad ) ,
812
+ ot_hmac_sha_process (s , (const uint8_t * )ipad , pad_length_b ,
746
813
true);
747
814
}
748
815
}
@@ -794,8 +861,7 @@ static void ot_hmac_regs_write(void *opaque, hwaddr addr, uint64_t value,
794
861
/* Restore SHA256 context */
795
862
s -> ctx -> state .sha256 .curlen = 0 ;
796
863
s -> ctx -> state .sha256 .length = s -> regs -> msg_length ;
797
- unsigned digest_length = OT_HMAC_DIGEST_LENGTH / sizeof (uint32_t );
798
- for (unsigned i = 0 ; i < digest_length ; i ++ ) {
864
+ for (unsigned i = 0 ; i < 8u ; i ++ ) {
799
865
s -> ctx -> state .sha256 .state [i ] = s -> regs -> digest [i ];
800
866
}
801
867
0 commit comments