@@ -383,6 +383,32 @@ char* myoptarg = NULL;
383383int DoneHandShake = 0 ;
384384#endif
385385
386+
387+ #if defined(HAVE_FIPS ) && defined(HAVE_FIPS_VERSION ) && (HAVE_FIPS_VERSION == 5 )
388+ static int run_all_CAST (void )
389+ {
390+ int ret = 0 ;
391+ int cast_idx = 0 ;
392+
393+ for (cast_idx = 0 ; cast_idx < FIPS_CAST_COUNT ; cast_idx ++ ) {
394+ if ((ret = wc_RunCast_fips (cast_idx )) != 0 ) {
395+ #ifdef NO_ERROR_STRINGS
396+ fprintf (stderr ,
397+ "ERROR: FIPS CAST failed with return code: %d\n" , ret );
398+ #else
399+ fprintf (stderr ,
400+ "ERROR: FIPS CAST failed for algorithm: %s\n" ,
401+ wc_GetErrorString (ret ));
402+ #endif
403+ return ret ;
404+ }
405+ }
406+
407+ return ret ;
408+ }
409+ #endif /* HAVE_FIPS && HAVE_FIPS_VERSION == 5 */
410+
411+
386412static double gettime_secs (int reset )
387413{
388414 struct timeval tv ;
@@ -1863,6 +1889,23 @@ int bench_tls(void* args)
18631889 /* Initialize wolfSSL */
18641890 wolfSSL_Init ();
18651891
1892+ #if defined(HAVE_FIPS ) && defined(HAVE_FIPS_VERSION ) && (HAVE_FIPS_VERSION == 5 )
1893+ /*
1894+ * When running benchmarks on FIPS builds, we need to run ALL CASTs up
1895+ * front before spawning client/server threads, otherwise there is the
1896+ * possibility that both threads try to run a CAST at the same time during
1897+ * the handshake. In this scenario, the thread that doesn't win the race
1898+ * will not be able to run the CAST, since it returns "busy", which is treated
1899+ * as a failure. Running the CASTs up front is a simpler solution than
1900+ * implementing an additional layer of synchronization.
1901+ */
1902+ if ((ret = run_all_CAST ()) != 0 )
1903+ {
1904+ fprintf (stderr , "CAST failed. Exiting benchmark\n" );
1905+ goto exit ;
1906+ }
1907+ #endif /* HAVE_FIPS && HAVE_FIPS_VERSION == 5 */
1908+
18661909 /* Parse command line arguments */
18671910 while ((ch = mygetopt (argc , argv , "?" "udeil:p:t:vT:sch:P:mS:g" )) != -1 ) {
18681911 switch (ch ) {
0 commit comments