Skip to content

Commit 7d0b7ef

Browse files
committed
Phase 2: PQ in boundary and SHA512 DRBG
1 parent 5d6a23b commit 7d0b7ef

20 files changed

Lines changed: 2249 additions & 260 deletions

File tree

configure.ac

Lines changed: 414 additions & 135 deletions
Large diffs are not rendered by default.

doc/dox_comments/header_files/random.h

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,3 +583,241 @@ int wc_Entropy_Get(int bits, unsigned char* entropy, word32 len);
583583
\sa wc_Entropy_Get
584584
*/
585585
int wc_Entropy_OnDemandTest(void);
586+
587+
/*!
588+
\ingroup Random
589+
590+
\brief Runs the SHA-512 Hash_DRBG Known Answer Test (KAT) per
591+
SP 800-90A. Instantiates a SHA-512 DRBG with seedA, optionally
592+
reseeds with seedB, generates output, and compares against known
593+
test vectors. Available when WOLFSSL_DRBG_SHA512 is defined.
594+
595+
\return 0 On success
596+
\return BAD_FUNC_ARG If seedA or output is NULL, or if reseed is
597+
set and seedB is NULL
598+
\return -1 Test failed
599+
600+
\param reseed Non-zero to test reseeding
601+
\param seedA Initial entropy seed
602+
\param seedASz Size of seedA in bytes
603+
\param seedB Reseed entropy (required if reseed is set)
604+
\param seedBSz Size of seedB in bytes
605+
\param output Buffer to receive generated output
606+
\param outputSz Size of output in bytes
607+
608+
_Example_
609+
\code
610+
byte output[WC_SHA512_DIGEST_SIZE * 4];
611+
const byte seedA[] = { ... };
612+
const byte seedB[] = { ... };
613+
614+
ret = wc_RNG_HealthTest_SHA512(0, seedA, sizeof(seedA), NULL, 0,
615+
output, sizeof(output));
616+
if (ret != 0)
617+
return -1;
618+
619+
ret = wc_RNG_HealthTest_SHA512(1, seedA, sizeof(seedA),
620+
seedB, sizeof(seedB),
621+
output, sizeof(output));
622+
if (ret != 0)
623+
return -1;
624+
\endcode
625+
626+
\sa wc_RNG_HealthTest
627+
\sa wc_RNG_HealthTest_SHA512_ex
628+
*/
629+
int wc_RNG_HealthTest_SHA512(int reseed, const byte* seedA, word32 seedASz,
630+
const byte* seedB, word32 seedBSz,
631+
byte* output, word32 outputSz);
632+
633+
/*!
634+
\ingroup Random
635+
636+
\brief Extended SHA-512 Hash_DRBG health test with nonce,
637+
personalization string, and additional input support. Suitable
638+
for full ACVP / CAVP test vector validation. Available when
639+
WOLFSSL_DRBG_SHA512 is defined.
640+
641+
\return 0 On success
642+
\return BAD_FUNC_ARG If required params are NULL
643+
\return -1 Test failed
644+
645+
\param reseed Non-zero to test reseeding
646+
\param nonce Nonce buffer (can be NULL)
647+
\param nonceSz Nonce size
648+
\param persoString Personalization string (can be NULL)
649+
\param persoStringSz Personalization string size
650+
\param seedA Initial entropy seed
651+
\param seedASz Initial seed size
652+
\param seedB Reseed entropy (required if reseed is set)
653+
\param seedBSz Reseed size
654+
\param additionalA Additional input for first generate (can be NULL)
655+
\param additionalASz Additional input A size
656+
\param additionalB Additional input for second generate (can be NULL)
657+
\param additionalBSz Additional input B size
658+
\param output Output buffer
659+
\param outputSz Output size
660+
\param heap Heap hint (can be NULL)
661+
\param devId Device ID (INVALID_DEVID for software)
662+
663+
_Example_
664+
\code
665+
byte output[WC_SHA512_DIGEST_SIZE * 4];
666+
const byte seedA[] = { ... };
667+
const byte nonce[] = { ... };
668+
669+
int ret = wc_RNG_HealthTest_SHA512_ex(0, nonce, sizeof(nonce),
670+
NULL, 0,
671+
seedA, sizeof(seedA),
672+
NULL, 0,
673+
NULL, 0, NULL, 0,
674+
output, sizeof(output),
675+
NULL, INVALID_DEVID);
676+
\endcode
677+
678+
\sa wc_RNG_HealthTest_SHA512
679+
\sa wc_RNG_HealthTest_ex
680+
*/
681+
int wc_RNG_HealthTest_SHA512_ex(int reseed, const byte* nonce, word32 nonceSz,
682+
const byte* persoString, word32 persoStringSz,
683+
const byte* seedA, word32 seedASz,
684+
const byte* seedB, word32 seedBSz,
685+
const byte* additionalA, word32 additionalASz,
686+
const byte* additionalB, word32 additionalBSz,
687+
byte* output, word32 outputSz,
688+
void* heap, int devId);
689+
690+
/*!
691+
\ingroup Random
692+
693+
\brief Disables the SHA-256 Hash_DRBG at runtime. When disabled,
694+
newly initialized WC_RNG instances will not use the SHA-256 DRBG.
695+
If the SHA-512 DRBG is enabled (WOLFSSL_DRBG_SHA512), new RNG
696+
instances will use SHA-512 instead. Requires HAVE_HASHDRBG.
697+
698+
\return 0 On success
699+
700+
_Example_
701+
\code
702+
wc_Sha256Drbg_Disable();
703+
// New WC_RNG instances will now use SHA-512 DRBG if available
704+
WC_RNG rng;
705+
wc_InitRng(&rng);
706+
\endcode
707+
708+
\sa wc_Sha256Drbg_Enable
709+
\sa wc_Sha256Drbg_GetStatus
710+
\sa wc_Sha512Drbg_Disable
711+
*/
712+
int wc_Sha256Drbg_Disable(void);
713+
714+
/*!
715+
\ingroup Random
716+
717+
\brief Re-enables the SHA-256 Hash_DRBG at runtime after a prior
718+
call to wc_Sha256Drbg_Disable(). Requires HAVE_HASHDRBG.
719+
720+
\return 0 On success
721+
722+
_Example_
723+
\code
724+
wc_Sha256Drbg_Disable();
725+
// ... use SHA-512 DRBG only ...
726+
wc_Sha256Drbg_Enable();
727+
// New WC_RNG instances can use SHA-256 DRBG again
728+
\endcode
729+
730+
\sa wc_Sha256Drbg_Disable
731+
\sa wc_Sha256Drbg_GetStatus
732+
*/
733+
int wc_Sha256Drbg_Enable(void);
734+
735+
/*!
736+
\ingroup Random
737+
738+
\brief Returns the current status of the SHA-256 Hash_DRBG
739+
(disabled or enabled). Requires HAVE_HASHDRBG.
740+
741+
\return 1 SHA-256 DRBG is disabled
742+
\return 0 SHA-256 DRBG is enabled
743+
744+
_Example_
745+
\code
746+
if (wc_Sha256Drbg_GetStatus()) {
747+
printf("SHA-256 DRBG is off\n");
748+
}
749+
\endcode
750+
751+
\sa wc_Sha256Drbg_Disable
752+
\sa wc_Sha256Drbg_Enable
753+
*/
754+
int wc_Sha256Drbg_GetStatus(void);
755+
756+
/*!
757+
\ingroup Random
758+
759+
\brief Disables the SHA-512 Hash_DRBG at runtime. When disabled,
760+
newly initialized WC_RNG instances will not use the SHA-512 DRBG.
761+
If the SHA-256 DRBG is still enabled, new RNG instances will fall
762+
back to SHA-256. Available when WOLFSSL_DRBG_SHA512 is defined.
763+
Requires HAVE_HASHDRBG.
764+
765+
\return 0 On success
766+
767+
_Example_
768+
\code
769+
wc_Sha512Drbg_Disable();
770+
// New WC_RNG instances will now use SHA-256 DRBG
771+
WC_RNG rng;
772+
wc_InitRng(&rng);
773+
\endcode
774+
775+
\sa wc_Sha512Drbg_Enable
776+
\sa wc_Sha512Drbg_GetStatus
777+
\sa wc_Sha256Drbg_Disable
778+
*/
779+
int wc_Sha512Drbg_Disable(void);
780+
781+
/*!
782+
\ingroup Random
783+
784+
\brief Re-enables the SHA-512 Hash_DRBG at runtime after a prior
785+
call to wc_Sha512Drbg_Disable(). Available when WOLFSSL_DRBG_SHA512
786+
is defined. Requires HAVE_HASHDRBG.
787+
788+
\return 0 On success
789+
790+
_Example_
791+
\code
792+
wc_Sha512Drbg_Disable();
793+
// ... use SHA-256 DRBG only ...
794+
wc_Sha512Drbg_Enable();
795+
// New WC_RNG instances can use SHA-512 DRBG again
796+
\endcode
797+
798+
\sa wc_Sha512Drbg_Disable
799+
\sa wc_Sha512Drbg_GetStatus
800+
*/
801+
int wc_Sha512Drbg_Enable(void);
802+
803+
/*!
804+
\ingroup Random
805+
806+
\brief Returns the current status of the SHA-512 Hash_DRBG
807+
(disabled or enabled). Available when WOLFSSL_DRBG_SHA512 is
808+
defined. Requires HAVE_HASHDRBG.
809+
810+
\return 1 SHA-512 DRBG is disabled
811+
\return 0 SHA-512 DRBG is enabled
812+
813+
_Example_
814+
\code
815+
if (wc_Sha512Drbg_GetStatus()) {
816+
printf("SHA-512 DRBG is off\n");
817+
}
818+
\endcode
819+
820+
\sa wc_Sha512Drbg_Disable
821+
\sa wc_Sha512Drbg_Enable
822+
*/
823+
int wc_Sha512Drbg_GetStatus(void);

tests/api.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26098,8 +26098,6 @@ static int error_test(void)
2609826098
{27, 26 },
2609926099
#endif
2610026100
{ -9, WC_SPAN1_FIRST_E + 1 },
26101-
{ -124, -124 },
26102-
{ -167, -169 },
2610326101
{ -300, -300 },
2610426102
{ -335, -336 },
2610526103
{ -346, -349 },

tests/api/test_mldsa.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,8 @@ int test_wc_dilithium(void)
553553
ExpectIntEQ(wc_InitRng(&rng), 0);
554554
#endif
555555

556+
PRIVATE_KEY_UNLOCK();
557+
556558
ExpectIntEQ(wc_dilithium_init(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
557559
ExpectIntEQ(wc_dilithium_init_ex(NULL, NULL, INVALID_DEVID), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
558560
wc_dilithium_free(NULL);
@@ -673,6 +675,8 @@ int test_wc_dilithium(void)
673675
WC_NO_ERR_TRACE(BAD_FUNC_ARG));
674676
#endif
675677

678+
PRIVATE_KEY_LOCK();
679+
676680
wc_dilithium_free(key);
677681
#if !defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) || \
678682
!defined(WOLFSSL_DILITHIUM_NO_SIGN)
@@ -765,6 +769,8 @@ int test_wc_dilithium_sign(void)
765769
ExpectIntEQ(wc_InitRng(&rng), 0);
766770
ExpectIntEQ(wc_dilithium_init(key), 0);
767771

772+
PRIVATE_KEY_UNLOCK();
773+
768774
#ifndef WOLFSSL_NO_ML_DSA_44
769775
ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
770776
#elif !defined(WOLFSSL_NO_ML_DSA_65)
@@ -878,6 +884,8 @@ int test_wc_dilithium_sign(void)
878884
#endif
879885
wc_dilithium_free(importKey);
880886

887+
PRIVATE_KEY_LOCK();
888+
881889
wc_dilithium_free(key);
882890
wc_FreeRng(&rng);
883891

@@ -1251,6 +1259,8 @@ int test_wc_dilithium_check_key(void)
12511259

12521260
ExpectIntEQ(wc_InitRng(&rng), 0);
12531261

1262+
PRIVATE_KEY_UNLOCK();
1263+
12541264
ExpectIntEQ(wc_dilithium_check_key(NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
12551265

12561266
ExpectIntEQ(wc_dilithium_init(checkKey), 0);
@@ -1337,6 +1347,8 @@ int test_wc_dilithium_check_key(void)
13371347
pubCheckKey[48] ^= 0x80;
13381348
}
13391349

1350+
PRIVATE_KEY_LOCK();
1351+
13401352
wc_dilithium_free(checkKey);
13411353
wc_FreeRng(&rng);
13421354

@@ -2940,6 +2952,8 @@ int test_wc_dilithium_der(void)
29402952
ExpectIntEQ(wc_InitRng(&rng), 0);
29412953
ExpectIntEQ(wc_dilithium_init(key), 0);
29422954

2955+
PRIVATE_KEY_UNLOCK();
2956+
29432957
ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE,
29442958
0), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
29452959
ExpectIntEQ(wc_Dilithium_PublicKeyToDer(key, der, DILITHIUM_MAX_DER_SIZE,
@@ -3091,6 +3105,7 @@ int test_wc_dilithium_der(void)
30913105
idx = 0;
30923106
ExpectIntEQ(wc_Dilithium_PrivateKeyDecode(der, &idx, key, len), 0);
30933107

3108+
PRIVATE_KEY_LOCK();
30943109

30953110
wc_dilithium_free(key);
30963111
wc_FreeRng(&rng);
@@ -12346,6 +12361,9 @@ int test_wc_dilithium_sig_kats(void)
1234612361
}
1234712362

1234812363
ExpectIntEQ(wc_dilithium_init_ex(key, NULL, INVALID_DEVID), 0);
12364+
12365+
PRIVATE_KEY_UNLOCK();
12366+
1234912367
#ifndef WOLFSSL_NO_ML_DSA_44
1235012368
ExpectIntEQ(wc_dilithium_set_level(key, WC_ML_DSA_44), 0);
1235112369
ExpectIntEQ(wc_dilithium_import_private(sk_44, (word32)sizeof(sk_44), key),
@@ -12377,6 +12395,8 @@ int test_wc_dilithium_sig_kats(void)
1237712395
ExpectIntEQ(XMEMCMP(sig, sig_87, sizeof(sig_87)), 0);
1237812396
#endif
1237912397

12398+
PRIVATE_KEY_LOCK();
12399+
1238012400
wc_dilithium_free(key);
1238112401
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1238212402
#endif
@@ -16745,6 +16765,8 @@ int test_wc_Dilithium_PrivateKeyDecode_OpenSSL_form(void)
1674516765
ExpectNotNull(der = (byte*) XMALLOC(derMaxSz, NULL,
1674616766
DYNAMIC_TYPE_TMP_BUFFER));
1674716767

16768+
PRIVATE_KEY_UNLOCK();
16769+
1674816770
for (size_t i = 0; i < sizeof(ossl_form) / sizeof(ossl_form[0]); ++i) {
1674916771
ExpectNotNull(fp = XFOPEN(ossl_form[i].fileName, "rb"));
1675016772
ExpectIntGT(derSz = XFREAD(der, 1, derMaxSz, fp), 0);
@@ -16811,6 +16833,8 @@ int test_wc_Dilithium_PrivateKeyDecode_OpenSSL_form(void)
1681116833
wc_dilithium_free(&key);
1681216834
}
1681316835

16836+
PRIVATE_KEY_LOCK();
16837+
1681416838
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1681516839
#endif
1681616840
return EXPECT_RESULT();

tests/api/test_mlkem.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,8 @@ int test_wc_mlkem_make_key_kats(void)
14511451
XMEMSET(key, 0, sizeof(MlKemKey));
14521452
}
14531453

1454+
PRIVATE_KEY_UNLOCK();
1455+
14541456
#ifndef WOLFSSL_NO_ML_KEM_512
14551457
ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_512, NULL, INVALID_DEVID), 0);
14561458
ExpectIntEQ(wc_MlKemKey_MakeKeyWithRandom(key, seed_512, sizeof(seed_512)),
@@ -1488,6 +1490,8 @@ int test_wc_mlkem_make_key_kats(void)
14881490
wc_MlKemKey_Free(key);
14891491
#endif
14901492

1493+
PRIVATE_KEY_LOCK();
1494+
14911495
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
14921496
#endif
14931497
return EXPECT_RESULT();
@@ -3845,6 +3849,8 @@ int test_wc_mlkem_decapsulate_kats(void)
38453849
XMEMSET(key, 0, sizeof(MlKemKey));
38463850
}
38473851

3852+
PRIVATE_KEY_UNLOCK();
3853+
38483854
#ifndef WOLFSSL_NO_ML_KEM_512
38493855
ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_512, NULL, INVALID_DEVID), 0);
38503856
ExpectIntEQ(wc_MlKemKey_DecodePrivateKey(key, dk_512, sizeof(dk_512)), 0);
@@ -3867,6 +3873,8 @@ int test_wc_mlkem_decapsulate_kats(void)
38673873
wc_MlKemKey_Free(key);
38683874
#endif
38693875

3876+
PRIVATE_KEY_LOCK();
3877+
38703878
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
38713879
#endif
38723880
return EXPECT_RESULT();

0 commit comments

Comments
 (0)