Return error codes for selftest failure instead of hard assertion errors.
[openssl.git] / fips / rand / fips_rand.c
index f573b26b6107090a1819c776488c975eee0ba3e7..cb9184e1f7a2bf9575262c6fbd8844ef99241275 100644 (file)
@@ -52,7 +52,7 @@
 /*
  * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4.
  */
-
+#include <openssl/crypto.h>
 #include "e_os.h"
 
 /* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't
 #include <openssl/aes.h>
 #include <openssl/err.h>
 #include <openssl/fips_rand.h>
-#ifndef OPENSSL_SYS_WIN32
-#include <sys/time.h>
+#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS))
+# include <sys/time.h>
+#endif
+#if defined(OPENSSL_SYS_VXWORKS)
+# include <time.h>
 #endif
 #include <assert.h>
 #ifndef OPENSSL_SYS_WIN32
@@ -111,7 +114,7 @@ static FIPS_PRNG_CTX sctx;
 
 static int fips_prng_fail = 0;
 
-void FIPS_rng_stick(void)
+void FIPS_x931_stick(void)
        {
        fips_prng_fail = 1;
        }
@@ -133,7 +136,11 @@ static void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
 static int fips_set_prng_key(FIPS_PRNG_CTX *ctx,
                        const unsigned char *key, unsigned int keylen)
        {
-       FIPS_selftest_check();
+       if (FIPS_selftest_failed())
+               {
+               FIPSerr(FIPS_F_FIPS_SET_PRNG_KEY, FIPS_R_SELFTEST_FAILED);
+               return 0;
+               }
        if (keylen != 16 && keylen != 24 && keylen != 32)
                {
                /* error: invalid key size */
@@ -205,30 +212,31 @@ static int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
        return 1;
        }
 
-int FIPS_rand_test_mode(void)
+int FIPS_x931_test_mode(void)
        {
        return fips_set_test_mode(&sctx);
        }
 
-int FIPS_rand_set_dt(unsigned char *dt)
+int FIPS_x931_set_dt(unsigned char *dt)
        {
        if (!sctx.test_mode)
                {
-               RANDerr(RAND_F_FIPS_RAND_SET_DT,RAND_R_NOT_IN_TEST_MODE);
+               RANDerr(RAND_F_FIPS_X931_SET_DT,RAND_R_NOT_IN_TEST_MODE);
                return 0;
                }
        memcpy(sctx.DT, dt, AES_BLOCK_LENGTH);
        return 1;
        }
 
-static void fips_get_dt(FIPS_PRNG_CTX *ctx)
-    {
+void FIPS_get_timevec(unsigned char *buf, unsigned long *pctr)
+       {
 #ifdef OPENSSL_SYS_WIN32
        FILETIME ft;
+#elif defined(OPENSSL_SYS_VXWORKS)
+        struct timespec ts;
 #else
        struct timeval tv;
 #endif
-       unsigned char *buf = ctx->DT;
 
 #ifndef GETPID_IS_MEANINGLESS
        unsigned long pid;
@@ -244,6 +252,16 @@ static void fips_get_dt(FIPS_PRNG_CTX *ctx)
        buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff);
        buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff);
        buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff);
+#elif defined(OPENSSL_SYS_VXWORKS)
+       clock_gettime(CLOCK_REALTIME, &ts);
+       buf[0] = (unsigned char) (ts.tv_sec & 0xff);
+       buf[1] = (unsigned char) ((ts.tv_sec >> 8) & 0xff);
+       buf[2] = (unsigned char) ((ts.tv_sec >> 16) & 0xff);
+       buf[3] = (unsigned char) ((ts.tv_sec >> 24) & 0xff);
+       buf[4] = (unsigned char) (ts.tv_nsec & 0xff);
+       buf[5] = (unsigned char) ((ts.tv_nsec >> 8) & 0xff);
+       buf[6] = (unsigned char) ((ts.tv_nsec >> 16) & 0xff);
+       buf[7] = (unsigned char) ((ts.tv_nsec >> 24) & 0xff);
 #else
        gettimeofday(&tv,NULL);
        buf[0] = (unsigned char) (tv.tv_sec & 0xff);
@@ -255,12 +273,12 @@ static void fips_get_dt(FIPS_PRNG_CTX *ctx)
        buf[6] = (unsigned char) ((tv.tv_usec >> 16) & 0xff);
        buf[7] = (unsigned char) ((tv.tv_usec >> 24) & 0xff);
 #endif
-       buf[8] = (unsigned char) (ctx->counter & 0xff);
-       buf[9] = (unsigned char) ((ctx->counter >> 8) & 0xff);
-       buf[10] = (unsigned char) ((ctx->counter >> 16) & 0xff);
-       buf[11] = (unsigned char) ((ctx->counter >> 24) & 0xff);
+       buf[8] = (unsigned char) (*pctr & 0xff);
+       buf[9] = (unsigned char) ((*pctr >> 8) & 0xff);
+       buf[10] = (unsigned char) ((*pctr >> 16) & 0xff);
+       buf[11] = (unsigned char) ((*pctr >> 24) & 0xff);
 
-       ctx->counter++;
+       (*pctr)++;
 
 
 #ifndef GETPID_IS_MEANINGLESS
@@ -296,7 +314,7 @@ static int fips_rand(FIPS_PRNG_CTX *ctx,
        for (;;)
                {
                if (!ctx->test_mode)
-                       fips_get_dt(ctx);
+                       FIPS_get_timevec(ctx->DT, &ctx->counter);
                AES_encrypt(ctx->DT, I, &ctx->ks);
                for (i = 0; i < AES_BLOCK_LENGTH; i++)
                        tmp[i] = I[i] ^ ctx->V[i];
@@ -339,7 +357,7 @@ static int fips_rand(FIPS_PRNG_CTX *ctx,
        }
 
 
-int FIPS_rand_set_key(const unsigned char *key, int keylen)
+int FIPS_x931_set_key(const unsigned char *key, int keylen)
        {
        int ret;
        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
@@ -348,7 +366,7 @@ int FIPS_rand_set_key(const unsigned char *key, int keylen)
        return ret;
        }
 
-int FIPS_rand_seed(const void *seed, int seedlen)
+int FIPS_x931_seed(const void *seed, int seedlen)
        {
        int ret;
        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
@@ -358,7 +376,7 @@ int FIPS_rand_seed(const void *seed, int seedlen)
        }
 
 
-int FIPS_rand_bytes(unsigned char *out, int count)
+int FIPS_x931_bytes(unsigned char *out, int count)
        {
        int ret;
        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
@@ -367,7 +385,7 @@ int FIPS_rand_bytes(unsigned char *out, int count)
        return ret;
        }
 
-int FIPS_rand_status(void)
+int FIPS_x931_status(void)
        {
        int ret;
        CRYPTO_r_lock(CRYPTO_LOCK_RAND);
@@ -376,7 +394,7 @@ int FIPS_rand_status(void)
        return ret;
        }
 
-void FIPS_rand_reset(void)
+void FIPS_x931_reset(void)
        {
        CRYPTO_w_lock(CRYPTO_LOCK_RAND);
        fips_rand_prng_reset(&sctx);
@@ -385,30 +403,30 @@ void FIPS_rand_reset(void)
 
 static int fips_do_rand_seed(const void *seed, int seedlen)
        {
-       FIPS_rand_seed(seed, seedlen);
+       FIPS_x931_seed(seed, seedlen);
        return 1;
        }
 
 static int fips_do_rand_add(const void *seed, int seedlen,
                                        double add_entropy)
        {
-       FIPS_rand_seed(seed, seedlen);
+       FIPS_x931_seed(seed, seedlen);
        return 1;
        }
 
-static const RAND_METHOD rand_fips_meth=
+static const RAND_METHOD rand_x931_meth=
     {
     fips_do_rand_seed,
-    FIPS_rand_bytes,
-    FIPS_rand_reset,
+    FIPS_x931_bytes,
+    FIPS_x931_reset,
     fips_do_rand_add,
-    FIPS_rand_bytes,
-    FIPS_rand_status
+    FIPS_x931_bytes,
+    FIPS_x931_status
     };
 
-const RAND_METHOD *FIPS_rand_method(void)
+const RAND_METHOD *FIPS_x931_method(void)
 {
-  return &rand_fips_meth;
+  return &rand_x931_meth;
 }
 
 #endif