@@ -950,6 +950,55 @@ static int mlkemkey_encapsulate(MlKemKey* key, const byte* m, byte* r, byte* c)
950950}
951951#endif
952952
953+ #if !defined(WOLFSSL_MLKEM_NO_ENCAPSULATE ) || \
954+ !defined(WOLFSSL_MLKEM_NO_DECAPSULATE )
955+ static int wc_mlkemkey_check_h (MlKemKey * key )
956+ {
957+ int ret = 0 ;
958+
959+ /* If public hash (h) is not stored against key, calculate it
960+ * (fields set explicitly instead of using decode).
961+ * Step 1: ... H(ek)...
962+ */
963+ if ((key -> flags & MLKEM_FLAG_H_SET ) == 0 ) {
964+ #ifndef WOLFSSL_NO_MALLOC
965+ byte * pubKey = NULL ;
966+ word32 pubKeyLen ;
967+ #else
968+ byte pubKey [WC_ML_KEM_MAX_PUBLIC_KEY_SIZE ];
969+ word32 pubKeyLen ;
970+ #endif
971+
972+ /* Determine how big an encoded public key will be. */
973+ ret = wc_KyberKey_PublicKeySize (key , & pubKeyLen );
974+ if (ret == 0 ) {
975+ #ifndef WOLFSSL_NO_MALLOC
976+ /* Allocate dynamic memory for encoded public key. */
977+ pubKey = (byte * )XMALLOC (pubKeyLen , key -> heap ,
978+ DYNAMIC_TYPE_TMP_BUFFER );
979+ if (pubKey == NULL ) {
980+ ret = MEMORY_E ;
981+ }
982+ }
983+ if (ret == 0 ) {
984+ #endif
985+ /* Encode public key - h is hash of encoded public key. */
986+ ret = wc_KyberKey_EncodePublicKey (key , pubKey , pubKeyLen );
987+ }
988+ #ifndef WOLFSSL_NO_MALLOC
989+ /* Dispose of encoded public key. */
990+ XFREE (pubKey , key -> heap , DYNAMIC_TYPE_TMP_BUFFER );
991+ #endif
992+ }
993+ if ((ret == 0 ) && ((key -> flags & MLKEM_FLAG_H_SET ) == 0 )) {
994+ /* Implementation issue if h not cached and flag set. */
995+ ret = BAD_STATE_E ;
996+ }
997+
998+ return ret ;
999+ }
1000+ #endif
1001+
9531002#ifndef WOLFSSL_MLKEM_NO_ENCAPSULATE
9541003/**
9551004 * Encapsulate with random number generator and derive secret.
@@ -1084,43 +1133,8 @@ int wc_MlKemKey_EncapsulateWithRandom(MlKemKey* key, unsigned char* c,
10841133 }
10851134#endif
10861135
1087- /* If public hash (h) is not stored against key, calculate it
1088- * (fields set explicitly instead of using decode).
1089- * Step 1: ... H(ek)...
1090- */
1091- if ((ret == 0 ) && ((key -> flags & MLKEM_FLAG_H_SET ) == 0 )) {
1092- #ifndef WOLFSSL_NO_MALLOC
1093- byte * pubKey = NULL ;
1094- word32 pubKeyLen ;
1095- #else
1096- byte pubKey [WC_ML_KEM_MAX_PUBLIC_KEY_SIZE ];
1097- word32 pubKeyLen = WC_ML_KEM_MAX_PUBLIC_KEY_SIZE ;
1098- #endif
1099-
1100- #ifndef WOLFSSL_NO_MALLOC
1101- /* Determine how big an encoded public key will be. */
1102- ret = wc_KyberKey_PublicKeySize (key , & pubKeyLen );
1103- if (ret == 0 ) {
1104- /* Allocate dynamic memory for encoded public key. */
1105- pubKey = (byte * )XMALLOC (pubKeyLen , key -> heap ,
1106- DYNAMIC_TYPE_TMP_BUFFER );
1107- if (pubKey == NULL ) {
1108- ret = MEMORY_E ;
1109- }
1110- }
1111- if (ret == 0 ) {
1112- #endif
1113- /* Encode public key - h is hash of encoded public key. */
1114- ret = wc_KyberKey_EncodePublicKey (key , pubKey , pubKeyLen );
1115- #ifndef WOLFSSL_NO_MALLOC
1116- }
1117- /* Dispose of encoded public key. */
1118- XFREE (pubKey , key -> heap , DYNAMIC_TYPE_TMP_BUFFER );
1119- #endif
1120- }
1121- if ((ret == 0 ) && ((key -> flags & MLKEM_FLAG_H_SET ) == 0 )) {
1122- /* Implementation issue if h not cached and flag set. */
1123- ret = BAD_STATE_E ;
1136+ if (ret == 0 ) {
1137+ ret = wc_mlkemkey_check_h (key );
11241138 }
11251139
11261140#ifdef WOLFSSL_MLKEM_KYBER
@@ -1487,6 +1501,10 @@ int wc_MlKemKey_Decapsulate(MlKemKey* key, unsigned char* ss,
14871501 /* Decapsulate the cipher text. */
14881502 ret = mlkemkey_decapsulate (key , msg , ct );
14891503 }
1504+ if (ret == 0 ) {
1505+ /* Check we have H, hash of public, set. */
1506+ ret = wc_mlkemkey_check_h (key );
1507+ }
14901508 if (ret == 0 ) {
14911509 /* Hash message into seed buffer. */
14921510 ret = MLKEM_HASH_G (& key -> hash , msg , WC_ML_KEM_SYM_SZ , key -> h ,
0 commit comments