@@ -444,6 +444,297 @@ int wc_Stm32_Hash_Final(STM32_HASH_Context* stmCtx, word32 algo,
444444 return ret ;
445445}
446446
447+ #if defined(STM32_HMAC ) && !defined(NO_HMAC )
448+
449+ /* STM32 Port HMAC Functions */
450+ #include <wolfssl/wolfcrypt/hmac.h>
451+
452+ int wc_Stm32_Hmac_GetAlgoInfo (int macType , word32 * algo , word32 * blockSize ,
453+ word32 * digestSize )
454+ {
455+ int ret = 0 ;
456+
457+ switch (macType ) {
458+ #if !defined(NO_MD5 ) && !defined(STM32_NOMD5 )
459+ case WC_MD5 :
460+ if (algo ) * algo = HASH_AlgoSelection_MD5 ;
461+ if (blockSize ) * blockSize = WC_MD5_BLOCK_SIZE ;
462+ if (digestSize ) * digestSize = WC_MD5_DIGEST_SIZE ;
463+ break ;
464+ #endif
465+ #ifndef NO_SHA
466+ case WC_SHA :
467+ if (algo ) * algo = HASH_AlgoSelection_SHA1 ;
468+ if (blockSize ) * blockSize = WC_SHA_BLOCK_SIZE ;
469+ if (digestSize ) * digestSize = WC_SHA_DIGEST_SIZE ;
470+ break ;
471+ #endif
472+ #ifdef WOLFSSL_SHA224
473+ case WC_SHA224 :
474+ if (algo ) * algo = HASH_AlgoSelection_SHA224 ;
475+ if (blockSize ) * blockSize = WC_SHA224_BLOCK_SIZE ;
476+ if (digestSize ) * digestSize = WC_SHA224_DIGEST_SIZE ;
477+ break ;
478+ #endif
479+ #ifndef NO_SHA256
480+ case WC_SHA256 :
481+ if (algo ) * algo = HASH_AlgoSelection_SHA256 ;
482+ if (blockSize ) * blockSize = WC_SHA256_BLOCK_SIZE ;
483+ if (digestSize ) * digestSize = WC_SHA256_DIGEST_SIZE ;
484+ break ;
485+ #endif
486+ #ifdef STM32_HASH_SHA384
487+ case WC_SHA384 :
488+ if (algo ) * algo = HASH_ALGOSELECTION_SHA384 ;
489+ if (blockSize ) * blockSize = WC_SHA384_BLOCK_SIZE ;
490+ if (digestSize ) * digestSize = WC_SHA384_DIGEST_SIZE ;
491+ break ;
492+ #endif
493+ #ifdef STM32_HASH_SHA512
494+ case WC_SHA512 :
495+ if (algo ) * algo = HASH_ALGOSELECTION_SHA512 ;
496+ if (blockSize ) * blockSize = WC_SHA512_BLOCK_SIZE ;
497+ if (digestSize ) * digestSize = WC_SHA512_DIGEST_SIZE ;
498+ break ;
499+ #endif
500+ default :
501+ ret = BAD_FUNC_ARG ;
502+ break ;
503+ }
504+
505+ return ret ;
506+ }
507+
508+ static void wc_Stm32_Hmac_RestoreContext (STM32_HASH_Context * ctx ,
509+ word32 algo , word32 keyLen , word32 blockSize )
510+ {
511+ int i ;
512+
513+ if (ctx -> HASH_CR == 0 ) {
514+ /* first-time init */
515+
516+ #if defined(HASH_IMR_DINIE ) && defined(HASH_IMR_DCIE )
517+ /* Disable IRQ's */
518+ HASH -> IMR &= ~(HASH_IMR_DINIE | HASH_IMR_DCIE );
519+ #endif
520+
521+ /* reset the control register */
522+ HASH -> CR &= ~(HASH_CR_ALGO | HASH_CR_MODE | HASH_CR_DATATYPE
523+ #ifdef HASH_CR_LKEY
524+ | HASH_CR_LKEY
525+ #endif
526+ );
527+
528+ /* configure algorithm, HMAC mode and data type */
529+ HASH -> CR |= (algo | HASH_ALGOMODE_HMAC | HASH_DATATYPE_8B );
530+
531+ #ifdef HASH_CR_LKEY
532+ /* set LKEY bit if key is longer than block size */
533+ if (keyLen > blockSize ) {
534+ HASH -> CR |= HASH_CR_LKEY ;
535+ }
536+ #endif
537+
538+ /* reset HASH processor */
539+ HASH -> CR |= HASH_CR_INIT ;
540+
541+ /* by default mark all bits valid */
542+ wc_Stm32_Hash_NumValidBits (0 );
543+
544+ #ifdef DEBUG_STM32_HASH
545+ printf ("STM HMAC Init algo %x, keyLen %d\n" , (unsigned int )algo ,
546+ (int )keyLen );
547+ #endif
548+ }
549+ else {
550+ /* restore context registers */
551+ HASH -> IMR = ctx -> HASH_IMR ;
552+ HASH -> STR = ctx -> HASH_STR ;
553+ HASH -> CR = ctx -> HASH_CR ;
554+ #ifdef STM32_HASH_SHA3
555+ HASH -> SHA3CFGR = ctx -> SHA3CFGR ;
556+ #endif
557+
558+ /* Initialize the hash processor */
559+ HASH -> CR |= HASH_CR_INIT ;
560+
561+ /* continue restoring context registers */
562+ for (i = 0 ; i < HASH_CR_SIZE ; i ++ ) {
563+ HASH -> CSR [i ] = ctx -> HASH_CSR [i ];
564+ }
565+
566+ #ifdef DEBUG_STM32_HASH
567+ printf ("STM HMAC Restore CR %lx, IMR %lx, STR %lx\n" ,
568+ HASH -> CR , HASH -> IMR , HASH -> STR );
569+ #endif
570+ }
571+
572+ (void )keyLen ;
573+ (void )blockSize ;
574+ }
575+
576+ static void wc_Stm32_Hmac_FeedKey (const byte * key , word32 keySz )
577+ {
578+ word32 i , blocks ;
579+ word32 tmp ;
580+
581+ /* feed key words into HASH->DIN */
582+ blocks = keySz / STM32_HASH_REG_SIZE ;
583+ for (i = 0 ; i < blocks ; i ++ ) {
584+ XMEMCPY (& tmp , key + (i * STM32_HASH_REG_SIZE ), STM32_HASH_REG_SIZE );
585+ HASH -> DIN = tmp ;
586+ }
587+ /* handle remaining bytes in last partial word */
588+ if (keySz % STM32_HASH_REG_SIZE ) {
589+ tmp = 0 ;
590+ XMEMCPY (& tmp , key + (blocks * STM32_HASH_REG_SIZE ),
591+ keySz % STM32_HASH_REG_SIZE );
592+ HASH -> DIN = tmp ;
593+ }
594+
595+ #ifdef DEBUG_STM32_HASH
596+ printf ("STM HMAC FeedKey %d bytes\n" , (int )keySz );
597+ #endif
598+ }
599+
600+
601+ /* STM32 HMAC Exposed Functions */
602+
603+ int wc_Stm32_Hmac_SetKey (STM32_HASH_Context * stmCtx , int macType ,
604+ const byte * key , word32 keySz )
605+ {
606+ int ret ;
607+ word32 algo , blockSize , digestSize ;
608+
609+ if (stmCtx == NULL || key == NULL )
610+ return BAD_FUNC_ARG ;
611+
612+ ret = wc_Stm32_Hmac_GetAlgoInfo (macType , & algo , & blockSize , & digestSize );
613+ if (ret != 0 )
614+ return ret ;
615+
616+ #ifdef DEBUG_STM32_HASH
617+ printf ("STM HMAC SetKey: macType %d, keySz %d\n" , macType , (int )keySz );
618+ #endif
619+
620+ /* clear context for fresh HMAC */
621+ wc_Stm32_Hash_Init (stmCtx );
622+
623+ /* turn on hash clock */
624+ STM32_HASH_CLOCK_ENABLE (stmCtx );
625+
626+ /* initialize hardware for HMAC mode */
627+ wc_Stm32_Hmac_RestoreContext (stmCtx , algo , keySz , blockSize );
628+
629+ /* Phase 1: Feed key into HASH->DIN */
630+ wc_Stm32_Hmac_FeedKey (key , keySz );
631+
632+ /* set number of valid bits in last word and trigger DCAL */
633+ wc_Stm32_Hash_NumValidBits (keySz );
634+ HASH -> STR |= HASH_STR_DCAL ;
635+
636+ /* wait for data input ready (phase 1 complete) */
637+ ret = wc_Stm32_Hash_WaitDataReady (stmCtx );
638+
639+ if (ret == 0 ) {
640+ /* save context for context switching */
641+ wc_Stm32_Hash_SaveContext (stmCtx );
642+ }
643+
644+ /* turn off hash clock */
645+ STM32_HASH_CLOCK_DISABLE (stmCtx );
646+
647+ return ret ;
648+ }
649+
650+ int wc_Stm32_Hmac_Update (STM32_HASH_Context * stmCtx , int macType ,
651+ const byte * data , word32 len )
652+ {
653+ int ret ;
654+ word32 algo , blockSize , digestSize ;
655+
656+ if (stmCtx == NULL || (data == NULL && len > 0 ))
657+ return BAD_FUNC_ARG ;
658+ if (len == 0 )
659+ return 0 ;
660+
661+ ret = wc_Stm32_Hmac_GetAlgoInfo (macType , & algo , & blockSize , & digestSize );
662+ if (ret != 0 )
663+ return ret ;
664+
665+ #ifdef DEBUG_STM32_HASH
666+ printf ("STM HMAC Update: macType %d, len %d\n" , macType , (int )len );
667+ #endif
668+
669+ /* Reuse Hash_Update - the saved context CR already contains
670+ * HASH_ALGOMODE_HMAC, so RestoreContext will preserve HMAC mode */
671+ ret = wc_Stm32_Hash_Update (stmCtx , algo , data , len , blockSize );
672+
673+ return ret ;
674+ }
675+
676+ int wc_Stm32_Hmac_Final (STM32_HASH_Context * stmCtx , int macType ,
677+ const byte * key , word32 keySz , byte * hash )
678+ {
679+ int ret ;
680+ word32 algo , blockSize , digestSize ;
681+
682+ if (stmCtx == NULL || key == NULL || hash == NULL )
683+ return BAD_FUNC_ARG ;
684+
685+ ret = wc_Stm32_Hmac_GetAlgoInfo (macType , & algo , & blockSize , & digestSize );
686+ if (ret != 0 )
687+ return ret ;
688+
689+ #ifdef DEBUG_STM32_HASH
690+ printf ("STM HMAC Final: macType %d, keySz %d, buffLen %d, fifoBytes %d\n" ,
691+ macType , (int )keySz , (int )stmCtx -> buffLen , (int )stmCtx -> fifoBytes );
692+ #endif
693+
694+ /* turn on hash clock */
695+ STM32_HASH_CLOCK_ENABLE (stmCtx );
696+
697+ /* restore HMAC context */
698+ wc_Stm32_Hash_RestoreContext (stmCtx , algo );
699+
700+ /* finish reading any trailing bytes into FIFO */
701+ if (stmCtx -> buffLen > 0 ) {
702+ wc_Stm32_Hash_Data (stmCtx , stmCtx -> buffLen );
703+ }
704+
705+ /* Phase 2 complete: set valid bits and trigger DCAL */
706+ wc_Stm32_Hash_NumValidBits (stmCtx -> loLen + stmCtx -> buffLen );
707+ HASH -> STR |= HASH_STR_DCAL ;
708+
709+ /* wait for data input ready (phase 2 complete, ready for phase 3) */
710+ ret = wc_Stm32_Hash_WaitDataReady (stmCtx );
711+ if (ret != 0 ) {
712+ STM32_HASH_CLOCK_DISABLE (stmCtx );
713+ return ret ;
714+ }
715+
716+ /* Phase 3: Feed key again into HASH->DIN */
717+ wc_Stm32_Hmac_FeedKey (key , keySz );
718+
719+ /* set valid bits for key and trigger DCAL */
720+ wc_Stm32_Hash_NumValidBits (keySz );
721+ HASH -> STR |= HASH_STR_DCAL ;
722+
723+ /* wait for hash done (digest computation complete) */
724+ ret = wc_Stm32_Hash_WaitCalcComp (stmCtx );
725+ if (ret == 0 ) {
726+ /* read message digest */
727+ wc_Stm32_Hash_GetDigest (hash , digestSize );
728+ }
729+
730+ /* turn off hash clock */
731+ STM32_HASH_CLOCK_DISABLE (stmCtx );
732+
733+ return ret ;
734+ }
735+
736+ #endif /* STM32_HMAC && !NO_HMAC */
737+
447738#endif /* STM32_HASH */
448739
449740
0 commit comments