Update RSA selftest code to use a 2048 bit RSA and only a single KAT
[oweals/openssl.git] / fips / fips.c
index 4b66537342dfbd536d22f386b1639afe2f0325c9..a4ed4f28fbe33521de967de5cec54e880ac460c0 100644 (file)
@@ -1,5 +1,5 @@
 /* ====================================================================
- * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 2011 The OpenSSL Project.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define PATH_MAX 1024
 #endif
 
-static int fips_selftest_fail;
-static int fips_mode;
+static int fips_selftest_fail = 0;
+static int fips_mode = 0;
 static int fips_started = 0;
-static const void *fips_rand_check;
 
 static int fips_is_owning_thread(void);
 static int fips_set_owning_thread(void);
 static int fips_clear_owning_thread(void);
 static unsigned char *fips_signature_witness(void);
 
-static void fips_w_lock(void)  { CRYPTO_w_lock(CRYPTO_LOCK_FIPS); }
-static void fips_w_unlock(void)        { CRYPTO_w_unlock(CRYPTO_LOCK_FIPS); }
-static void fips_r_lock(void)  { CRYPTO_r_lock(CRYPTO_LOCK_FIPS); }
-static void fips_r_unlock(void)        { CRYPTO_r_unlock(CRYPTO_LOCK_FIPS); }
+#define fips_w_lock()  CRYPTO_w_lock(CRYPTO_LOCK_FIPS)
+#define fips_w_unlock()        CRYPTO_w_unlock(CRYPTO_LOCK_FIPS)
+#define fips_r_lock()  CRYPTO_r_lock(CRYPTO_LOCK_FIPS)
+#define fips_r_unlock()        CRYPTO_r_unlock(CRYPTO_LOCK_FIPS)
 
 static void fips_set_mode(int onoff)
        {
@@ -97,18 +96,6 @@ static void fips_set_mode(int onoff)
                }
        }
 
-static void fips_set_rand_check(const void *rand_check)
-       {
-       int owning_thread = fips_is_owning_thread();
-
-       if (fips_started)
-               {
-               if (!owning_thread) fips_w_lock();
-               fips_rand_check = rand_check;
-               if (!owning_thread) fips_w_unlock();
-               }
-       }
-
 int FIPS_mode(void)
        {
        int ret = 0;
@@ -123,20 +110,6 @@ int FIPS_mode(void)
        return ret;
        }
 
-const void *FIPS_rand_check(void)
-       {
-       const void *ret = 0;
-       int owning_thread = fips_is_owning_thread();
-
-       if (fips_started)
-               {
-               if (!owning_thread) fips_r_lock();
-               ret = fips_rand_check;
-               if (!owning_thread) fips_r_unlock();
-               }
-       return ret;
-       }
-
 int FIPS_selftest_failed(void)
     {
     int ret = 0;
@@ -174,10 +147,12 @@ int FIPS_selftest(void)
 
     return FIPS_selftest_sha1()
        && FIPS_selftest_hmac()
+       && FIPS_selftest_cmac()
        && FIPS_selftest_aes()
        && FIPS_selftest_aes_gcm()
        && FIPS_selftest_des()
        && FIPS_selftest_rsa()
+       && FIPS_selftest_ecdsa()
        && FIPS_selftest_dsa();
     }
 
@@ -275,7 +250,6 @@ int FIPS_mode_set(int onoff)
 
     if(onoff)
        {
-       unsigned char buf[48];
 
        fips_selftest_fail = 0;
 
@@ -314,30 +288,21 @@ int FIPS_mode_set(int onoff)
            goto end;
            }
 
-       /* Perform RNG KAT before seeding */
-       if (!FIPS_selftest_rng())
+       if (!FIPS_selftest_drbg())
            {
            fips_selftest_fail = 1;
            ret = 0;
            goto end;
            }
 
-       /* automagically seed PRNG if not already seeded */
-       if(!FIPS_rand_status())
+       /* Perform RNG KAT before seeding */
+       if (!FIPS_selftest_x931())
            {
-           if(RAND_bytes(buf,sizeof buf) <= 0)
-               {
-               fips_selftest_fail = 1;
-               ret = 0;
-               goto end;
-               }
-           FIPS_rand_set_key(buf,32);
-           FIPS_rand_seed(buf+32,16);
+           fips_selftest_fail = 1;
+           ret = 0;
+           goto end;
            }
 
-       /* now switch into FIPS mode */
-       fips_set_rand_check(FIPS_rand_method());
-       RAND_set_rand_method(FIPS_rand_method());
        if(FIPS_selftest())
            fips_set_mode(1);
        else
@@ -391,6 +356,7 @@ int fips_set_owning_thread(void)
                        {
                        CRYPTO_THREADID_current(&fips_thread);
                        ret = 1;
+                       fips_thread_set = 1;
                        }
                CRYPTO_w_unlock(CRYPTO_LOCK_FIPS2);
                }
@@ -483,14 +449,20 @@ int fips_pkey_signature_test(EVP_PKEY *pkey,
                if (!esig)
                        goto error;
                }
-#if 0
-       else if (!EVP_SignFinal(&mctx, sig, &siglen, pkey))
-               goto error;
-#endif
 
        if (kat && ((siglen != katlen) || memcmp(kat, sig, katlen)))
                goto error;
-
+#if 0
+       {
+       /* Debug code to print out self test KAT discrepancies */
+       unsigned int i;
+       fprintf(stderr, "%s=", fail_str);
+       for (i = 0; i < siglen; i++)
+                       fprintf(stderr, "%02X", sig[i]);
+       fprintf(stderr, "\n");
+       goto error;
+       }
+#endif
        if (!FIPS_digestinit(&mctx, digest))
                goto error;
        if (!FIPS_digestupdate(&mctx, tbs, tbslen))
@@ -508,10 +480,6 @@ int fips_pkey_signature_test(EVP_PKEY *pkey,
                {
                ret = FIPS_ecdsa_verify_ctx(pkey->pkey.ec, &mctx, esig);
                }
-#if 0
-       else
-               ret = EVP_VerifyFinal(&mctx, sig, siglen, pkey);
-#endif
 
        error:
        if (dsig != NULL)
@@ -545,9 +513,12 @@ int fips_cipher_test(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
        unsigned char pltmp[FIPS_MAX_CIPHER_TEST_SIZE];
        unsigned char citmp[FIPS_MAX_CIPHER_TEST_SIZE];
        OPENSSL_assert(len <= FIPS_MAX_CIPHER_TEST_SIZE);
+       memset(pltmp, 0, FIPS_MAX_CIPHER_TEST_SIZE);
+       memset(citmp, 0, FIPS_MAX_CIPHER_TEST_SIZE);
        if (FIPS_cipherinit(ctx, cipher, key, iv, 1) <= 0)
                return 0;
-       FIPS_cipher(ctx, citmp, plaintext, len);
+       if (!FIPS_cipher(ctx, citmp, plaintext, len))
+               return 0;
        if (memcmp(citmp, ciphertext, len))
                return 0;
        if (FIPS_cipherinit(ctx, cipher, key, iv, 0) <= 0)