@@ -1167,24 +1167,42 @@ static int wc_linuxkm_drbg_generate(struct crypto_rng *tfm,
11671167 }
11681168 }
11691169
1170- ret = wc_RNG_GenerateBlock (& drbg -> rng , dst , dlen );
1171-
1172- if (unlikely (ret == WC_NO_ERR_TRACE (RNG_FAILURE_E )) && (! retried )) {
1173- retried = 1 ;
1174- wc_FreeRng (& drbg -> rng );
1175- ret = wc_InitRng (& drbg -> rng );
1176- if (ret == 0 ) {
1177- pr_warn ("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E." , raw_smp_processor_id ());
1178- goto retry ;
1170+ for (;;) {
1171+ #define RNG_MAX_BLOCK_LEN_ROUNDED (RNG_MAX_BLOCK_LEN & ~0xfU)
1172+ if (dlen > RNG_MAX_BLOCK_LEN_ROUNDED ) {
1173+ ret = wc_RNG_GenerateBlock (& drbg -> rng , dst , RNG_MAX_BLOCK_LEN_ROUNDED );
1174+ if (ret == 0 ) {
1175+ dlen -= RNG_MAX_BLOCK_LEN_ROUNDED ;
1176+ dst += RNG_MAX_BLOCK_LEN_ROUNDED ;
1177+ }
11791178 }
1179+ #undef RNG_MAX_BLOCK_LEN_ROUNDED
11801180 else {
1181- pr_warn_once ("ERROR: reinitialization of DRBG #%d after RNG_FAILURE_E failed with ret %d." , raw_smp_processor_id (), ret );
1181+ ret = wc_RNG_GenerateBlock (& drbg -> rng , dst , dlen );
1182+ dlen -= dlen ;
1183+ }
1184+
1185+ if (unlikely (ret == WC_NO_ERR_TRACE (RNG_FAILURE_E )) && (! retried )) {
1186+ retried = 1 ;
1187+ wc_FreeRng (& drbg -> rng );
1188+ ret = wc_InitRng (& drbg -> rng );
1189+ if (ret == 0 ) {
1190+ pr_warn ("WARNING: reinitialized DRBG #%d after RNG_FAILURE_E." , raw_smp_processor_id ());
1191+ goto retry ;
1192+ }
1193+ else {
1194+ pr_warn_once ("ERROR: reinitialization of DRBG #%d after RNG_FAILURE_E failed with ret %d." , raw_smp_processor_id (), ret );
1195+ ret = - EINVAL ;
1196+ }
1197+ }
1198+ else if (ret != 0 ) {
1199+ pr_warn_once ("WARNING: wc_RNG_GenerateBlock returned %d\n" ,ret );
11821200 ret = - EINVAL ;
1201+ break ;
11831202 }
1184- }
1185- else if (ret != 0 ) {
1186- pr_warn_once ("WARNING: wc_RNG_GenerateBlock returned %d\n" ,ret );
1187- ret = - EINVAL ;
1203+
1204+ if (! dlen )
1205+ break ;
11881206 }
11891207
11901208out :
0 commit comments