@@ -109,30 +109,46 @@ public void testGetMinRsaSize() {
109109 assertTrue (minRsaSize > 0 );
110110 }
111111
112+ /**
113+ * Helper to make RSA key with retry. In FIPS mode the prime generation
114+ * loop has a finite retry count (NIST FIPS 186-4 B.3.3). On rare occasions
115+ * this can fail with PRIME_GEN_E even with a healthy RNG, so retry once
116+ * on that error.
117+ *
118+ * JCE level classes have retry built in, but not at the JNI class
119+ * level.
120+ */
121+ private void makeKeyWithRetry (int size , long e , Rng rng ) {
122+
123+ Rsa key = new Rsa ();
124+ try {
125+ key .makeKey (size , e , rng );
126+ } catch (WolfCryptException ex ) {
127+ if (Fips .enabled &&
128+ ex .getMessage ().contains ("Unable to find a prime" )) {
129+ /* Retry once on transient PRIME_GEN_E */
130+ key .releaseNativeStruct ();
131+ key = new Rsa ();
132+ key .makeKey (size , e , rng );
133+ } else {
134+ throw ex ;
135+ }
136+ }
137+ key .releaseNativeStruct ();
138+ }
139+
112140 @ Test
113141 public void testMakeKey () {
114142
115- Rsa key = null ;
116-
117143 /* FIPS after 2425 doesn't allow 1024-bit RSA key gen */
118144 if ((Fips .enabled && Fips .fipsVersion < 5 ) ||
119145 (!Fips .enabled && Rsa .RSA_MIN_SIZE <= 1024 )) {
120- key = new Rsa ();
121- key .makeKey (1024 , 65537 , rng );
122- key .releaseNativeStruct ();
146+ makeKeyWithRetry (1024 , 65537 , rng );
123147 }
124148
125- key = new Rsa ();
126- key .makeKey (2048 , 65537 , rng );
127- key .releaseNativeStruct ();
128-
129- key = new Rsa ();
130- key .makeKey (3072 , 65537 , rng );
131- key .releaseNativeStruct ();
132-
133- key = new Rsa ();
134- key .makeKey (4096 , 65537 , rng );
135- key .releaseNativeStruct ();
149+ makeKeyWithRetry (2048 , 65537 , rng );
150+ makeKeyWithRetry (3072 , 65537 , rng );
151+ makeKeyWithRetry (4096 , 65537 , rng );
136152 }
137153
138154 @ Test
0 commit comments