@@ -639,6 +639,43 @@ int wh_MessageCrypto_TranslateEd25519VerifyResponse(
639639 return 0 ;
640640}
641641
642+ /* Number of chaining words in a SHA-2 intermediate state, for every variant */
643+ #define WH_MESSAGE_CRYPTO_SHA2_STATE_WORDS 8
644+
645+ /* Swap the host-order chaining words of a serialized SHA-2 state, as the SHA3
646+ * Keccak state does. wordSize is 4 (SHA224/256) or 8 (SHA384/512); any other
647+ * value, including 0 for a finalized digest, copies the array verbatim. */
648+ static void _TranslateSha2State (uint16_t magic , uint8_t * dest ,
649+ const uint8_t * src , uint32_t hashSz ,
650+ uint32_t wordSize )
651+ {
652+ uint32_t i ;
653+ uint32_t stateSz = WH_MESSAGE_CRYPTO_SHA2_STATE_WORDS * wordSize ;
654+ uint32_t w32 ;
655+ uint64_t w64 ;
656+
657+ if (dest != src ) {
658+ memcpy (dest , src , hashSz );
659+ }
660+ if (stateSz > hashSz ) {
661+ return ;
662+ }
663+ if (wordSize == sizeof (uint32_t )) {
664+ for (i = 0 ; i < stateSz ; i += wordSize ) {
665+ memcpy (& w32 , dest + i , sizeof (w32 ));
666+ w32 = wh_Translate32 (magic , w32 );
667+ memcpy (dest + i , & w32 , sizeof (w32 ));
668+ }
669+ }
670+ else if (wordSize == sizeof (uint64_t )) {
671+ for (i = 0 ; i < stateSz ; i += wordSize ) {
672+ memcpy (& w64 , dest + i , sizeof (w64 ));
673+ w64 = wh_Translate64 (magic , w64 );
674+ memcpy (dest + i , & w64 , sizeof (w64 ));
675+ }
676+ }
677+ }
678+
642679/* SHA256 Request translation. Only the fixed-size header is translated; any
643680 * trailing variable-length input bytes (uint8_t in[inSz]) are raw bytes that
644681 * do not need endian translation. */
@@ -651,11 +688,10 @@ int wh_MessageCrypto_TranslateSha256Request(
651688 }
652689 WH_T32 (magic , dest , src , resumeState .hiLen );
653690 WH_T32 (magic , dest , src , resumeState .loLen );
654- /* Hash value is just a byte array, no translation needed */
655- if (src != dest ) {
656- memcpy (dest -> resumeState .hash , src -> resumeState .hash ,
657- sizeof (src -> resumeState .hash ));
658- }
691+ /* A request always carries intermediate state, even on the last block */
692+ _TranslateSha2State (magic , dest -> resumeState .hash , src -> resumeState .hash ,
693+ (uint32_t )sizeof (src -> resumeState .hash ),
694+ (uint32_t )sizeof (uint32_t ));
659695 WH_T32 (magic , dest , src , isLastBlock );
660696 WH_T32 (magic , dest , src , inSz );
661697 return 0 ;
@@ -675,32 +711,38 @@ int wh_MessageCrypto_TranslateSha512Request(
675711 WH_T32 (magic , dest , src , resumeState .hiLen );
676712 WH_T32 (magic , dest , src , resumeState .loLen );
677713 WH_T32 (magic , dest , src , resumeState .hashType );
678- /* Hash value is just a byte array, no translation needed */
679- if (src != dest ) {
680- memcpy (dest -> resumeState .hash , src -> resumeState .hash ,
681- sizeof (src -> resumeState .hash ));
682- }
714+ /* A request always carries intermediate state, even on the last block */
715+ _TranslateSha2State (magic , dest -> resumeState .hash , src -> resumeState .hash ,
716+ (uint32_t )sizeof (src -> resumeState .hash ),
717+ (uint32_t )sizeof (uint64_t ));
683718 WH_T32 (magic , dest , src , isLastBlock );
684719 WH_T32 (magic , dest , src , inSz );
685720 return 0 ;
686721}
687722#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
688723
689- /* SHA2 Response translation */
724+ /* SHA2 Response translation, treating hash as a finalized digest */
690725int wh_MessageCrypto_TranslateSha2Response (
691726 uint16_t magic , const whMessageCrypto_Sha2Response * src ,
692727 whMessageCrypto_Sha2Response * dest )
728+ {
729+ return wh_MessageCrypto_TranslateSha2Response_ex (magic , src , dest , 0 );
730+ }
731+
732+ /* SHA2 Response translation. stateWordSize is the chaining word size when hash
733+ * carries intermediate state, or 0 when it carries a finalized digest. */
734+ int wh_MessageCrypto_TranslateSha2Response_ex (
735+ uint16_t magic , const whMessageCrypto_Sha2Response * src ,
736+ whMessageCrypto_Sha2Response * dest , uint32_t stateWordSize )
693737{
694738 if ((src == NULL ) || (dest == NULL )) {
695739 return WH_ERROR_BADARGS ;
696740 }
697741 WH_T32 (magic , dest , src , hiLen );
698742 WH_T32 (magic , dest , src , loLen );
699743 WH_T32 (magic , dest , src , hashType );
700- /* Hash value is just a byte array, no translation needed */
701- if (src != dest ) {
702- memcpy (dest -> hash , src -> hash , sizeof (src -> hash ));
703- }
744+ _TranslateSha2State (magic , dest -> hash , src -> hash ,
745+ (uint32_t )sizeof (src -> hash ), stateWordSize );
704746 return 0 ;
705747}
706748
@@ -1024,10 +1066,9 @@ int wh_MessageCrypto_TranslateSha256DmaRequest(
10241066
10251067 WH_T32 (magic , dest , src , resumeState .hiLen );
10261068 WH_T32 (magic , dest , src , resumeState .loLen );
1027- if (src != dest ) {
1028- memcpy (dest -> resumeState .hash , src -> resumeState .hash ,
1029- sizeof (src -> resumeState .hash ));
1030- }
1069+ _TranslateSha2State (magic , dest -> resumeState .hash , src -> resumeState .hash ,
1070+ (uint32_t )sizeof (src -> resumeState .hash ),
1071+ (uint32_t )sizeof (uint32_t ));
10311072
10321073 ret = wh_MessageCrypto_TranslateDmaBuffer (magic , & src -> input , & dest -> input );
10331074 if (ret != 0 ) {
@@ -1053,10 +1094,9 @@ int wh_MessageCrypto_TranslateSha512DmaRequest(
10531094
10541095 WH_T32 (magic , dest , src , resumeState .hiLen );
10551096 WH_T32 (magic , dest , src , resumeState .loLen );
1056- if (src != dest ) {
1057- memcpy (dest -> resumeState .hash , src -> resumeState .hash ,
1058- sizeof (src -> resumeState .hash ));
1059- }
1097+ _TranslateSha2State (magic , dest -> resumeState .hash , src -> resumeState .hash ,
1098+ (uint32_t )sizeof (src -> resumeState .hash ),
1099+ (uint32_t )sizeof (uint64_t ));
10601100 WH_T32 (magic , dest , src , resumeState .hashType );
10611101
10621102 ret = wh_MessageCrypto_TranslateDmaBuffer (magic , & src -> input , & dest -> input );
@@ -1070,20 +1110,28 @@ int wh_MessageCrypto_TranslateSha512DmaRequest(
10701110 return 0 ;
10711111}
10721112
1073- /* SHA2 DMA Response translation */
1113+ /* SHA2 DMA Response translation, treating hash as a finalized digest */
10741114int wh_MessageCrypto_TranslateSha2DmaResponse (
10751115 uint16_t magic , const whMessageCrypto_Sha2DmaResponse * src ,
10761116 whMessageCrypto_Sha2DmaResponse * dest )
1117+ {
1118+ return wh_MessageCrypto_TranslateSha2DmaResponse_ex (magic , src , dest , 0 );
1119+ }
1120+
1121+ /* SHA2 DMA Response translation. stateWordSize is the chaining word size when
1122+ * hash carries intermediate state, or 0 when it carries a finalized digest. */
1123+ int wh_MessageCrypto_TranslateSha2DmaResponse_ex (
1124+ uint16_t magic , const whMessageCrypto_Sha2DmaResponse * src ,
1125+ whMessageCrypto_Sha2DmaResponse * dest , uint32_t stateWordSize )
10771126{
10781127 if ((src == NULL ) || (dest == NULL )) {
10791128 return WH_ERROR_BADARGS ;
10801129 }
10811130
10821131 WH_T32 (magic , dest , src , hiLen );
10831132 WH_T32 (magic , dest , src , loLen );
1084- if (src != dest ) {
1085- memcpy (dest -> hash , src -> hash , sizeof (src -> hash ));
1086- }
1133+ _TranslateSha2State (magic , dest -> hash , src -> hash ,
1134+ (uint32_t )sizeof (src -> hash ), stateWordSize );
10871135 WH_T32 (magic , dest , src , hashType );
10881136
10891137 return wh_MessageCrypto_TranslateDmaAddrStatus (magic , & src -> dmaAddrStatus ,
0 commit comments