aboutsummaryrefslogtreecommitdiff
path: root/openssl/fips/rand
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/fips/rand')
-rw-r--r--openssl/fips/rand/Makefile149
-rw-r--r--openssl/fips/rand/fips_rand.c410
-rw-r--r--openssl/fips/rand/fips_rand.h77
-rw-r--r--openssl/fips/rand/fips_rand_selftest.c371
-rw-r--r--openssl/fips/rand/fips_randtest.c248
-rw-r--r--openssl/fips/rand/fips_rngvs.c230
6 files changed, 1485 insertions, 0 deletions
diff --git a/openssl/fips/rand/Makefile b/openssl/fips/rand/Makefile
new file mode 100644
index 000000000..20303c862
--- /dev/null
+++ b/openssl/fips/rand/Makefile
@@ -0,0 +1,149 @@
+#
+# OpenSSL/fips/rand/Makefile
+#
+
+DIR= rand
+TOP= ../..
+CC= cc
+INCLUDES=
+CFLAG=-g
+INSTALL_PREFIX=
+OPENSSLDIR= /usr/local/ssl
+INSTALLTOP=/usr/local/ssl
+MAKEDEPPROG= makedepend
+MAKEDEPEND= $(TOP)/util/domd $(TOP) -MD $(MAKEDEPPROG)
+MAKEFILE= Makefile
+AR= ar r
+
+CFLAGS= $(INCLUDES) $(CFLAG)
+
+GENERAL=Makefile
+TEST= fips_randtest.c fips_rngvs.c
+APPS=
+
+LIB=$(TOP)/libcrypto.a
+LIBSRC=fips_rand.c fips_rand_selftest.c
+LIBOBJ=fips_rand.o fips_rand_selftest.o
+
+SRC= $(LIBSRC)
+
+EXHEADER= fips_rand.h
+HEADER= $(EXHEADER)
+
+ALL= $(GENERAL) $(SRC) $(HEADER)
+
+top:
+ (cd $(TOP); $(MAKE) DIRS=fips SDIRS=$(DIR) sub_all)
+
+all: lib
+
+lib: $(LIBOBJ)
+ @echo $(LIBOBJ) > lib
+
+files:
+ $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+
+links:
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/include/openssl $(EXHEADER)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/test $(TEST)
+ @$(PERL) $(TOP)/util/mklink.pl $(TOP)/apps $(APPS)
+
+install:
+ @headerlist="$(EXHEADER)"; for i in $$headerlist; \
+ do \
+ (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
+ chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
+ done
+
+tags:
+ ctags $(SRC)
+
+tests:
+
+Q=../testvectors/rng/req
+A=../testvectors/rng/rsp
+
+fips_test:
+ -rm -rf $(A)
+ mkdir $(A)
+ if [ -f $(Q)/ANSI931_AES128MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES128MCT.req > $(A)/ANSI931_AES128MCT.rsp; fi
+ if [ -f $(Q)/ANSI931_AES192MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES192MCT.req > $(A)/ANSI931_AES192MCT.rsp; fi
+ if [ -f $(Q)/ANSI931_AES256MCT.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs mct < $(Q)/ANSI931_AES256MCT.req > $(A)/ANSI931_AES256MCT.rsp; fi
+ if [ -f $(Q)/ANSI931_AES128VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES128VST.req > $(A)/ANSI931_AES128VST.rsp; fi
+ if [ -f $(Q)/ANSI931_AES192VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES192VST.req > $(A)/ANSI931_AES192VST.rsp; fi
+ if [ -f $(Q)/ANSI931_AES256VST.req ]; then $(TOP)/util/shlib_wrap.sh $(TOP)/test/fips_rngvs vst < $(Q)/ANSI931_AES256VST.req > $(A)/ANSI931_AES256VST.rsp; fi
+
+lint:
+ lint -DLINT $(INCLUDES) $(SRC)>fluff
+
+depend:
+ $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(SRC) $(TEST)
+
+dclean:
+ $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
+ mv -f Makefile.new $(MAKEFILE)
+
+clean:
+ rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+fips_rand.o: ../../e_os.h ../../include/openssl/aes.h
+fips_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
+fips_rand.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rand.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
+fips_rand.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
+fips_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
+fips_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rand.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_rand.o: ../fips_locl.h fips_rand.c
+fips_rand_selftest.o: ../../include/openssl/bio.h
+fips_rand_selftest.o: ../../include/openssl/crypto.h
+fips_rand_selftest.o: ../../include/openssl/des.h
+fips_rand_selftest.o: ../../include/openssl/des_old.h
+fips_rand_selftest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_rand_selftest.o: ../../include/openssl/fips.h
+fips_rand_selftest.o: ../../include/openssl/fips_rand.h
+fips_rand_selftest.o: ../../include/openssl/lhash.h
+fips_rand_selftest.o: ../../include/openssl/opensslconf.h
+fips_rand_selftest.o: ../../include/openssl/opensslv.h
+fips_rand_selftest.o: ../../include/openssl/ossl_typ.h
+fips_rand_selftest.o: ../../include/openssl/rand.h
+fips_rand_selftest.o: ../../include/openssl/safestack.h
+fips_rand_selftest.o: ../../include/openssl/stack.h
+fips_rand_selftest.o: ../../include/openssl/symhacks.h
+fips_rand_selftest.o: ../../include/openssl/ui.h
+fips_rand_selftest.o: ../../include/openssl/ui_compat.h fips_rand_selftest.c
+fips_randtest.o: ../../e_os.h ../../include/openssl/bio.h
+fips_randtest.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h
+fips_randtest.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_randtest.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
+fips_randtest.o: ../../include/openssl/fips_rand.h
+fips_randtest.o: ../../include/openssl/lhash.h
+fips_randtest.o: ../../include/openssl/opensslconf.h
+fips_randtest.o: ../../include/openssl/opensslv.h
+fips_randtest.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
+fips_randtest.o: ../../include/openssl/safestack.h
+fips_randtest.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_randtest.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_randtest.o: ../fips_utl.h fips_randtest.c
+fips_rngvs.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
+fips_rngvs.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
+fips_rngvs.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h
+fips_rngvs.o: ../../include/openssl/des.h ../../include/openssl/des_old.h
+fips_rngvs.o: ../../include/openssl/dsa.h ../../include/openssl/e_os2.h
+fips_rngvs.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
+fips_rngvs.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h
+fips_rngvs.o: ../../include/openssl/evp.h ../../include/openssl/fips.h
+fips_rngvs.o: ../../include/openssl/fips_rand.h ../../include/openssl/lhash.h
+fips_rngvs.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
+fips_rngvs.o: ../../include/openssl/opensslconf.h
+fips_rngvs.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
+fips_rngvs.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
+fips_rngvs.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
+fips_rngvs.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
+fips_rngvs.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
+fips_rngvs.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
+fips_rngvs.o: ../../include/openssl/x509v3.h ../fips_utl.h fips_rngvs.c
diff --git a/openssl/fips/rand/fips_rand.c b/openssl/fips/rand/fips_rand.c
new file mode 100644
index 000000000..58453e996
--- /dev/null
+++ b/openssl/fips/rand/fips_rand.c
@@ -0,0 +1,410 @@
+/* ====================================================================
+ * Copyright (c) 2007 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * This is a FIPS approved AES PRNG based on ANSI X9.31 A.2.4.
+ */
+
+#include "e_os.h"
+
+/* If we don't define _XOPEN_SOURCE_EXTENDED, struct timeval won't
+ be defined and gettimeofday() won't be declared with strict compilers
+ like DEC C in ANSI C mode. */
+#ifndef _XOPEN_SOURCE_EXTENDED
+#define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include <openssl/rand.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/fips_rand.h>
+#ifndef OPENSSL_SYS_WIN32
+#include <sys/time.h>
+#endif
+#include <assert.h>
+#ifndef OPENSSL_SYS_WIN32
+# ifdef OPENSSL_UNISTD
+# include OPENSSL_UNISTD
+# else
+# include <unistd.h>
+# endif
+#endif
+#include <string.h>
+#include <openssl/fips.h>
+#include "fips_locl.h"
+
+#ifdef OPENSSL_FIPS
+
+void *OPENSSL_stderr(void);
+
+#define AES_BLOCK_LENGTH 16
+
+
+/* AES FIPS PRNG implementation */
+
+typedef struct
+ {
+ int seeded;
+ int keyed;
+ int test_mode;
+ int second;
+ int error;
+ unsigned long counter;
+ AES_KEY ks;
+ int vpos;
+ /* Temporary storage for key if it equals seed length */
+ unsigned char tmp_key[AES_BLOCK_LENGTH];
+ unsigned char V[AES_BLOCK_LENGTH];
+ unsigned char DT[AES_BLOCK_LENGTH];
+ unsigned char last[AES_BLOCK_LENGTH];
+ } FIPS_PRNG_CTX;
+
+static FIPS_PRNG_CTX sctx;
+
+static int fips_prng_fail = 0;
+
+void FIPS_rng_stick(void)
+ {
+ fips_prng_fail = 1;
+ }
+
+void fips_rand_prng_reset(FIPS_PRNG_CTX *ctx)
+ {
+ ctx->seeded = 0;
+ ctx->keyed = 0;
+ ctx->test_mode = 0;
+ ctx->counter = 0;
+ ctx->second = 0;
+ ctx->error = 0;
+ ctx->vpos = 0;
+ OPENSSL_cleanse(ctx->V, AES_BLOCK_LENGTH);
+ OPENSSL_cleanse(&ctx->ks, sizeof(AES_KEY));
+ }
+
+
+static int fips_set_prng_key(FIPS_PRNG_CTX *ctx,
+ const unsigned char *key, FIPS_RAND_SIZE_T keylen)
+ {
+ FIPS_selftest_check();
+ if (keylen != 16 && keylen != 24 && keylen != 32)
+ {
+ /* error: invalid key size */
+ return 0;
+ }
+ AES_set_encrypt_key(key, keylen << 3, &ctx->ks);
+ if (keylen == 16)
+ {
+ memcpy(ctx->tmp_key, key, 16);
+ ctx->keyed = 2;
+ }
+ else
+ ctx->keyed = 1;
+ ctx->seeded = 0;
+ ctx->second = 0;
+ return 1;
+ }
+
+static int fips_set_prng_seed(FIPS_PRNG_CTX *ctx,
+ const unsigned char *seed, FIPS_RAND_SIZE_T seedlen)
+ {
+ int i;
+ if (!ctx->keyed)
+ return 0;
+ /* In test mode seed is just supplied data */
+ if (ctx->test_mode)
+ {
+ if (seedlen != AES_BLOCK_LENGTH)
+ return 0;
+ memcpy(ctx->V, seed, AES_BLOCK_LENGTH);
+ ctx->seeded = 1;
+ return 1;
+ }
+ /* Outside test mode XOR supplied data with existing seed */
+ for (i = 0; i < seedlen; i++)
+ {
+ ctx->V[ctx->vpos++] ^= seed[i];
+ if (ctx->vpos == AES_BLOCK_LENGTH)
+ {
+ ctx->vpos = 0;
+ /* Special case if first seed and key length equals
+ * block size check key and seed do not match.
+ */
+ if (ctx->keyed == 2)
+ {
+ if (!memcmp(ctx->tmp_key, ctx->V, 16))
+ {
+ RANDerr(RAND_F_FIPS_SET_PRNG_SEED,
+ RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY);
+ return 0;
+ }
+ OPENSSL_cleanse(ctx->tmp_key, 16);
+ ctx->keyed = 1;
+ }
+ ctx->seeded = 1;
+ }
+ }
+ return 1;
+ }
+
+int fips_set_test_mode(FIPS_PRNG_CTX *ctx)
+ {
+ if (ctx->keyed)
+ {
+ RANDerr(RAND_F_FIPS_SET_TEST_MODE,RAND_R_PRNG_KEYED);
+ return 0;
+ }
+ ctx->test_mode = 1;
+ return 1;
+ }
+
+int FIPS_rand_test_mode(void)
+ {
+ return fips_set_test_mode(&sctx);
+ }
+
+int FIPS_rand_set_dt(unsigned char *dt)
+ {
+ if (!sctx.test_mode)
+ {
+ RANDerr(RAND_F_FIPS_RAND_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)
+ {
+#ifdef OPENSSL_SYS_WIN32
+ FILETIME ft;
+#else
+ struct timeval tv;
+#endif
+ unsigned char *buf = ctx->DT;
+
+#ifndef GETPID_IS_MEANINGLESS
+ unsigned long pid;
+#endif
+
+#ifdef OPENSSL_SYS_WIN32
+ GetSystemTimeAsFileTime(&ft);
+ buf[0] = (unsigned char) (ft.dwHighDateTime & 0xff);
+ buf[1] = (unsigned char) ((ft.dwHighDateTime >> 8) & 0xff);
+ buf[2] = (unsigned char) ((ft.dwHighDateTime >> 16) & 0xff);
+ buf[3] = (unsigned char) ((ft.dwHighDateTime >> 24) & 0xff);
+ buf[4] = (unsigned char) (ft.dwLowDateTime & 0xff);
+ buf[5] = (unsigned char) ((ft.dwLowDateTime >> 8) & 0xff);
+ buf[6] = (unsigned char) ((ft.dwLowDateTime >> 16) & 0xff);
+ buf[7] = (unsigned char) ((ft.dwLowDateTime >> 24) & 0xff);
+#else
+ gettimeofday(&tv,NULL);
+ buf[0] = (unsigned char) (tv.tv_sec & 0xff);
+ buf[1] = (unsigned char) ((tv.tv_sec >> 8) & 0xff);
+ buf[2] = (unsigned char) ((tv.tv_sec >> 16) & 0xff);
+ buf[3] = (unsigned char) ((tv.tv_sec >> 24) & 0xff);
+ buf[4] = (unsigned char) (tv.tv_usec & 0xff);
+ buf[5] = (unsigned char) ((tv.tv_usec >> 8) & 0xff);
+ 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);
+
+ ctx->counter++;
+
+
+#ifndef GETPID_IS_MEANINGLESS
+ pid=(unsigned long)getpid();
+ buf[12] = (unsigned char) (pid & 0xff);
+ buf[13] = (unsigned char) ((pid >> 8) & 0xff);
+ buf[14] = (unsigned char) ((pid >> 16) & 0xff);
+ buf[15] = (unsigned char) ((pid >> 24) & 0xff);
+#endif
+ }
+
+static int fips_rand(FIPS_PRNG_CTX *ctx,
+ unsigned char *out, FIPS_RAND_SIZE_T outlen)
+ {
+ unsigned char R[AES_BLOCK_LENGTH], I[AES_BLOCK_LENGTH];
+ unsigned char tmp[AES_BLOCK_LENGTH];
+ int i;
+ if (ctx->error)
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_ERROR);
+ return 0;
+ }
+ if (!ctx->keyed)
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_NO_KEY_SET);
+ return 0;
+ }
+ if (!ctx->seeded)
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_NOT_SEEDED);
+ return 0;
+ }
+ for (;;)
+ {
+ if (!ctx->test_mode)
+ fips_get_dt(ctx);
+ AES_encrypt(ctx->DT, I, &ctx->ks);
+ for (i = 0; i < AES_BLOCK_LENGTH; i++)
+ tmp[i] = I[i] ^ ctx->V[i];
+ AES_encrypt(tmp, R, &ctx->ks);
+ for (i = 0; i < AES_BLOCK_LENGTH; i++)
+ tmp[i] = R[i] ^ I[i];
+ AES_encrypt(tmp, ctx->V, &ctx->ks);
+ /* Continuous PRNG test */
+ if (ctx->second)
+ {
+ if (fips_prng_fail)
+ memcpy(ctx->last, R, AES_BLOCK_LENGTH);
+ if (!memcmp(R, ctx->last, AES_BLOCK_LENGTH))
+ {
+ RANDerr(RAND_F_FIPS_RAND,RAND_R_PRNG_STUCK);
+ ctx->error = 1;
+ fips_set_selftest_fail();
+ return 0;
+ }
+ }
+ memcpy(ctx->last, R, AES_BLOCK_LENGTH);
+ if (!ctx->second)
+ {
+ ctx->second = 1;
+ if (!ctx->test_mode)
+ continue;
+ }
+
+ if (outlen <= AES_BLOCK_LENGTH)
+ {
+ memcpy(out, R, outlen);
+ break;
+ }
+
+ memcpy(out, R, AES_BLOCK_LENGTH);
+ out += AES_BLOCK_LENGTH;
+ outlen -= AES_BLOCK_LENGTH;
+ }
+ return 1;
+ }
+
+
+int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen)
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ ret = fips_set_prng_key(&sctx, key, keylen);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+int FIPS_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen)
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ ret = fips_set_prng_seed(&sctx, seed, seedlen);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+
+int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T count)
+ {
+ int ret;
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ ret = fips_rand(&sctx, out, count);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+int FIPS_rand_status(void)
+ {
+ int ret;
+ CRYPTO_r_lock(CRYPTO_LOCK_RAND);
+ ret = sctx.seeded;
+ CRYPTO_r_unlock(CRYPTO_LOCK_RAND);
+ return ret;
+ }
+
+void FIPS_rand_reset(void)
+ {
+ CRYPTO_w_lock(CRYPTO_LOCK_RAND);
+ fips_rand_prng_reset(&sctx);
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ }
+
+static void fips_do_rand_seed(const void *seed, FIPS_RAND_SIZE_T seedlen)
+ {
+ FIPS_rand_seed(seed, seedlen);
+ }
+
+static void fips_do_rand_add(const void *seed, FIPS_RAND_SIZE_T seedlen,
+ double add_entropy)
+ {
+ FIPS_rand_seed(seed, seedlen);
+ }
+
+static const RAND_METHOD rand_fips_meth=
+ {
+ fips_do_rand_seed,
+ FIPS_rand_bytes,
+ FIPS_rand_reset,
+ fips_do_rand_add,
+ FIPS_rand_bytes,
+ FIPS_rand_status
+ };
+
+const RAND_METHOD *FIPS_rand_method(void)
+{
+ return &rand_fips_meth;
+}
+
+#endif
diff --git a/openssl/fips/rand/fips_rand.h b/openssl/fips/rand/fips_rand.h
new file mode 100644
index 000000000..a175aaf6c
--- /dev/null
+++ b/openssl/fips/rand/fips_rand.h
@@ -0,0 +1,77 @@
+/* ====================================================================
+ * Copyright (c) 2003 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef HEADER_FIPS_RAND_H
+#define HEADER_FIPS_RAND_H
+
+#include "des.h"
+
+#ifdef OPENSSL_FIPS
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int FIPS_rand_set_key(const unsigned char *key, FIPS_RAND_SIZE_T keylen);
+int FIPS_rand_seed(const void *buf, FIPS_RAND_SIZE_T num);
+int FIPS_rand_bytes(unsigned char *out, FIPS_RAND_SIZE_T outlen);
+
+int FIPS_rand_test_mode(void);
+void FIPS_rand_reset(void);
+int FIPS_rand_set_dt(unsigned char *dt);
+
+int FIPS_rand_status(void);
+
+const RAND_METHOD *FIPS_rand_method(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+#endif
diff --git a/openssl/fips/rand/fips_rand_selftest.c b/openssl/fips/rand/fips_rand_selftest.c
new file mode 100644
index 000000000..2194a76cd
--- /dev/null
+++ b/openssl/fips/rand/fips_rand_selftest.c
@@ -0,0 +1,371 @@
+/* ====================================================================
+ * Copyright (c) 2003 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/fips.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+
+#ifdef OPENSSL_FIPS
+
+
+
+typedef struct
+ {
+ unsigned char DT[16];
+ unsigned char V[16];
+ unsigned char R[16];
+ } AES_PRNG_TV;
+
+/* The following test vectors are taken directly from the RGNVS spec */
+
+static unsigned char aes_128_key[16] =
+ {0xf3,0xb1,0x66,0x6d,0x13,0x60,0x72,0x42,
+ 0xed,0x06,0x1c,0xab,0xb8,0xd4,0x62,0x02};
+
+static AES_PRNG_TV aes_128_tv[] = {
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xf9},
+ /* V */
+ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x59,0x53,0x1e,0xd1,0x3b,0xb0,0xc0,0x55,
+ 0x84,0x79,0x66,0x85,0xc1,0x2f,0x76,0x41}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfa},
+ /* V */
+ {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x7c,0x22,0x2c,0xf4,0xca,0x8f,0xa2,0x4c,
+ 0x1c,0x9c,0xb6,0x41,0xa9,0xf3,0x22,0x0d}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfb},
+ /* V */
+ {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x8a,0xaa,0x00,0x39,0x66,0x67,0x5b,0xe5,
+ 0x29,0x14,0x28,0x81,0xa9,0x4d,0x4e,0xc7}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfc},
+ /* V */
+ {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x88,0xdd,0xa4,0x56,0x30,0x24,0x23,0xe5,
+ 0xf6,0x9d,0xa5,0x7e,0x7b,0x95,0xc7,0x3a}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x22,0xfd},
+ /* V */
+ {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x05,0x25,0x92,0x46,0x61,0x79,0xd2,0xcb,
+ 0x78,0xc4,0x0b,0x14,0x0a,0x5a,0x9a,0xc8}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x77},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
+ /* R */
+ {0x0d,0xd5,0xa0,0x36,0x7a,0x59,0x26,0xbc,
+ 0x48,0xd9,0x38,0xbf,0xf0,0x85,0x8f,0xea}
+ },
+ {
+ /* DT */
+ {0xe6,0xb3,0xbe,0x78,0x2a,0x23,0xfa,0x62,
+ 0xd7,0x1d,0x4a,0xfb,0xb0,0xe9,0x23,0x78},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+ /* R */
+ {0xae,0x53,0x87,0xee,0x8c,0xd9,0x12,0xf5,
+ 0x73,0x53,0xae,0x03,0xf9,0xd5,0x13,0x33}
+ },
+};
+
+static unsigned char aes_192_key[24] =
+ {0x15,0xd8,0x78,0x0d,0x62,0xd3,0x25,0x6e,
+ 0x44,0x64,0x10,0x13,0x60,0x2b,0xa9,0xbc,
+ 0x4a,0xfb,0xca,0xeb,0x4c,0x8b,0x99,0x3b};
+
+static AES_PRNG_TV aes_192_tv[] = {
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4b},
+ /* V */
+ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x17,0x07,0xd5,0x28,0x19,0x79,0x1e,0xef,
+ 0xa5,0x0c,0xbf,0x25,0xe5,0x56,0xb4,0x93}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4c},
+ /* V */
+ {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x92,0x8d,0xbe,0x07,0xdd,0xc7,0x58,0xc0,
+ 0x6f,0x35,0x41,0x9b,0x17,0xc9,0xbd,0x9b}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4d},
+ /* V */
+ {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0xd5,0xde,0xf4,0x50,0xf3,0xb7,0x10,0x4e,
+ 0xb8,0xc6,0xf8,0xcf,0xe2,0xb1,0xca,0xa2}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4e},
+ /* V */
+ {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0xce,0x29,0x08,0x43,0xfc,0x34,0x41,0xe7,
+ 0x47,0x8f,0xb3,0x66,0x2b,0x46,0xb1,0xbb}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0x4f},
+ /* V */
+ {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0xb3,0x26,0x0f,0xf5,0xd6,0xca,0xa8,0xbf,
+ 0x89,0xb8,0x5e,0x2f,0x22,0x56,0x92,0x2f}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xc9},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
+ /* R */
+ {0x05,0xeb,0x18,0x52,0x34,0x43,0x00,0x43,
+ 0x6e,0x5a,0xa5,0xfe,0x7b,0x32,0xc4,0x2d}
+ },
+ {
+ /* DT */
+ {0x3f,0xd8,0xff,0xe8,0x80,0x69,0x8b,0xc1,
+ 0xbf,0x99,0x7d,0xa4,0x24,0x78,0xf3,0xca},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+ /* R */
+ {0x15,0x3c,0xe8,0xd1,0x04,0xc7,0xad,0x50,
+ 0x0b,0xf0,0x07,0x16,0xe7,0x56,0x7a,0xea}
+ },
+};
+
+static unsigned char aes_256_key[32] =
+ {0x6d,0x14,0x06,0x6c,0xb6,0xd8,0x21,0x2d,
+ 0x82,0x8d,0xfa,0xf2,0x7a,0x03,0xb7,0x9f,
+ 0x0c,0xc7,0x3e,0xcd,0x76,0xeb,0xee,0xb5,
+ 0x21,0x05,0x8c,0x4f,0x31,0x7a,0x80,0xbb};
+
+static AES_PRNG_TV aes_256_tv[] = {
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x88},
+ /* V */
+ {0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x35,0xc7,0xef,0xa7,0x78,0x4d,0x29,0xbc,
+ 0x82,0x79,0x99,0xfb,0xd0,0xb3,0x3b,0x72}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x89},
+ /* V */
+ {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x6c,0xf4,0x42,0x5d,0xc7,0x04,0x1a,0x41,
+ 0x28,0x2a,0x78,0xa9,0xb0,0x12,0xc4,0x95}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8a},
+ /* V */
+ {0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x16,0x90,0xa4,0xff,0x7b,0x7e,0xb9,0x30,
+ 0xdb,0x67,0x4b,0xac,0x2d,0xe1,0xd1,0x75}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8b},
+ /* V */
+ {0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x14,0x6f,0xf5,0x95,0xa1,0x46,0x65,0x30,
+ 0xbc,0x57,0xe2,0x4a,0xf7,0x45,0x62,0x05}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9e,0x8c},
+ /* V */
+ {0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
+ /* R */
+ {0x96,0xe2,0xb4,0x1e,0x66,0x5e,0x0f,0xa4,
+ 0xc5,0xcd,0xa2,0x07,0xcc,0xb7,0x94,0x40}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x06},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe},
+ /* R */
+ {0x61,0xce,0x1d,0x6a,0x48,0x75,0x97,0x28,
+ 0x4b,0x41,0xde,0x18,0x44,0x4f,0x56,0xec}
+ },
+ {
+ /* DT */
+ {0xda,0x3a,0x41,0xec,0x1d,0xa3,0xb0,0xd5,
+ 0xf2,0xa9,0x4e,0x34,0x74,0x8e,0x9f,0x07},
+ /* V */
+ {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
+ /* R */
+ {0x52,0x89,0x59,0x79,0x2d,0xaa,0x28,0xb3,
+ 0xb0,0x8a,0x3e,0x70,0xfa,0x71,0x59,0x84}
+ },
+};
+
+
+void FIPS_corrupt_rng()
+ {
+ aes_192_tv[0].V[0]++;
+ }
+
+#define fips_rand_test(key, tv) \
+ do_rand_test(key, sizeof key, tv, sizeof(tv)/sizeof(AES_PRNG_TV))
+
+static int do_rand_test(unsigned char *key, int keylen,
+ AES_PRNG_TV *tv, int ntv)
+ {
+ unsigned char R[16];
+ int i;
+ if (!FIPS_rand_set_key(key, keylen))
+ return 0;
+ for (i = 0; i < ntv; i++)
+ {
+ FIPS_rand_seed(tv[i].V, 16);
+ FIPS_rand_set_dt(tv[i].DT);
+ FIPS_rand_bytes(R, 16);
+ if (memcmp(R, tv[i].R, 16))
+ return 0;
+ }
+ return 1;
+ }
+
+
+int FIPS_selftest_rng()
+ {
+ FIPS_rand_reset();
+ if (!FIPS_rand_test_mode())
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ if (!fips_rand_test(aes_128_key,aes_128_tv)
+ || !fips_rand_test(aes_192_key, aes_192_tv)
+ || !fips_rand_test(aes_256_key, aes_256_tv))
+ {
+ FIPSerr(FIPS_F_FIPS_SELFTEST_RNG,FIPS_R_SELFTEST_FAILED);
+ return 0;
+ }
+ FIPS_rand_reset();
+ return 1;
+ }
+
+#endif
diff --git a/openssl/fips/rand/fips_randtest.c b/openssl/fips/rand/fips_randtest.c
new file mode 100644
index 000000000..5582941c1
--- /dev/null
+++ b/openssl/fips/rand/fips_randtest.c
@@ -0,0 +1,248 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 2003 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
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+
+#include "e_os.h"
+
+#ifndef OPENSSL_FIPS
+int main(int argc, char *argv[])
+{
+ printf("No FIPS RAND support\n");
+ return(0);
+}
+
+#else
+
+#include "fips_utl.h"
+
+typedef struct
+ {
+ unsigned char DT[16];
+ unsigned char V[16];
+ unsigned char R[16];
+ } AES_PRNG_MCT;
+
+static unsigned char aes_128_mct_key[16] =
+ {0x9f,0x5b,0x51,0x20,0x0b,0xf3,0x34,0xb5,
+ 0xd8,0x2b,0xe8,0xc3,0x72,0x55,0xc8,0x48};
+
+static AES_PRNG_MCT aes_128_mct_tv = {
+ /* DT */
+ {0x63,0x76,0xbb,0xe5,0x29,0x02,0xba,0x3b,
+ 0x67,0xc9,0x25,0xfa,0x70,0x1f,0x11,0xac},
+ /* V */
+ {0x57,0x2c,0x8e,0x76,0x87,0x26,0x47,0x97,
+ 0x7e,0x74,0xfb,0xdd,0xc4,0x95,0x01,0xd1},
+ /* R */
+ {0x48,0xe9,0xbd,0x0d,0x06,0xee,0x18,0xfb,
+ 0xe4,0x57,0x90,0xd5,0xc3,0xfc,0x9b,0x73}
+};
+
+static unsigned char aes_192_mct_key[24] =
+ {0xb7,0x6c,0x34,0xd1,0x09,0x67,0xab,0x73,
+ 0x4d,0x5a,0xd5,0x34,0x98,0x16,0x0b,0x91,
+ 0xbc,0x35,0x51,0x16,0x6b,0xae,0x93,0x8a};
+
+static AES_PRNG_MCT aes_192_mct_tv = {
+ /* DT */
+ {0x84,0xce,0x22,0x7d,0x91,0x5a,0xa3,0xc9,
+ 0x84,0x3c,0x0a,0xb3,0xa9,0x63,0x15,0x52},
+ /* V */
+ {0xb6,0xaf,0xe6,0x8f,0x99,0x9e,0x90,0x64,
+ 0xdd,0xc7,0x7a,0xc1,0xbb,0x90,0x3a,0x6d},
+ /* R */
+ {0xfc,0x85,0x60,0x9a,0x29,0x6f,0xef,0x21,
+ 0xdd,0x86,0x20,0x32,0x8a,0x29,0x6f,0x47}
+};
+
+static unsigned char aes_256_mct_key[32] =
+ {0x9b,0x05,0xc8,0x68,0xff,0x47,0xf8,0x3a,
+ 0xa6,0x3a,0xa8,0xcb,0x4e,0x71,0xb2,0xe0,
+ 0xb8,0x7e,0xf1,0x37,0xb6,0xb4,0xf6,0x6d,
+ 0x86,0x32,0xfc,0x1f,0x5e,0x1d,0x1e,0x50};
+
+static AES_PRNG_MCT aes_256_mct_tv = {
+ /* DT */
+ {0x31,0x6e,0x35,0x9a,0xb1,0x44,0xf0,0xee,
+ 0x62,0x6d,0x04,0x46,0xe0,0xa3,0x92,0x4c},
+ /* V */
+ {0x4f,0xcd,0xc1,0x87,0x82,0x1f,0x4d,0xa1,
+ 0x3e,0x0e,0x56,0x44,0x59,0xe8,0x83,0xca},
+ /* R */
+ {0xc8,0x87,0xc2,0x61,0x5b,0xd0,0xb9,0xe1,
+ 0xe7,0xf3,0x8b,0xd7,0x5b,0xd5,0xf1,0x8d}
+};
+
+static void dump(const unsigned char *b,int n)
+ {
+ while(n-- > 0)
+ {
+ printf(" %02x",*b++);
+ }
+ }
+
+static void compare(const unsigned char *result,const unsigned char *expected,
+ int n)
+ {
+ int i;
+
+ for(i=0 ; i < n ; ++i)
+ if(result[i] != expected[i])
+ {
+ puts("Random test failed, got:");
+ dump(result,n);
+ puts("\n expected:");
+ dump(expected,n);
+ putchar('\n');
+ EXIT(1);
+ }
+ }
+
+
+static void run_test(unsigned char *key, int keylen, AES_PRNG_MCT *tv)
+ {
+ unsigned char buf[16], dt[16];
+ int i, j;
+ FIPS_rand_reset();
+ FIPS_rand_test_mode();
+ FIPS_rand_set_key(key, keylen);
+ FIPS_rand_seed(tv->V, 16);
+ memcpy(dt, tv->DT, 16);
+ for (i = 0; i < 10000; i++)
+ {
+ FIPS_rand_set_dt(dt);
+ FIPS_rand_bytes(buf, 16);
+ /* Increment DT */
+ for (j = 15; j >= 0; j--)
+ {
+ dt[j]++;
+ if (dt[j])
+ break;
+ }
+ }
+
+ compare(buf,tv->R, 16);
+ }
+
+int main()
+ {
+ run_test(aes_128_mct_key, 16, &aes_128_mct_tv);
+ printf("FIPS PRNG test 1 done\n");
+ run_test(aes_192_mct_key, 24, &aes_192_mct_tv);
+ printf("FIPS PRNG test 2 done\n");
+ run_test(aes_256_mct_key, 32, &aes_256_mct_tv);
+ printf("FIPS PRNG test 3 done\n");
+ return 0;
+ }
+
+#endif
diff --git a/openssl/fips/rand/fips_rngvs.c b/openssl/fips/rand/fips_rngvs.c
new file mode 100644
index 000000000..cb904eaf0
--- /dev/null
+++ b/openssl/fips/rand/fips_rngvs.c
@@ -0,0 +1,230 @@
+/*
+ * Crude test driver for processing the VST and MCT testvector files
+ * generated by the CMVP RNGVS product.
+ *
+ * Note the input files are assumed to have a _very_ specific format
+ * as described in the NIST document "The Random Number Generator
+ * Validation System (RNGVS)", May 25, 2004.
+ *
+ */
+#include <openssl/opensslconf.h>
+
+#ifndef OPENSSL_FIPS
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ printf("No FIPS RNG support\n");
+ return 0;
+}
+#else
+
+#include <openssl/bn.h>
+#include <openssl/dsa.h>
+#include <openssl/fips.h>
+#include <openssl/err.h>
+#include <openssl/rand.h>
+#include <openssl/fips_rand.h>
+#include <openssl/x509v3.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "fips_utl.h"
+
+void vst()
+ {
+ unsigned char *key = NULL;
+ unsigned char *v = NULL;
+ unsigned char *dt = NULL;
+ unsigned char ret[16];
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ long i, keylen;
+
+ keylen = 0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if(!strncmp(buf,"[AES 128-Key]", 13))
+ keylen = 16;
+ else if(!strncmp(buf,"[AES 192-Key]", 13))
+ keylen = 24;
+ else if(!strncmp(buf,"[AES 256-Key]", 13))
+ keylen = 32;
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ continue;
+ if(!strcmp(keyword,"Key"))
+ {
+ key=hex2bin_m(value,&i);
+ if (i != keylen)
+ {
+ fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"DT"))
+ {
+ dt=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid DT length\n");
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"V"))
+ {
+ v=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid V length\n");
+ return;
+ }
+
+ if (!key || !dt)
+ {
+ fprintf(stderr, "Missing key or DT\n");
+ return;
+ }
+
+ FIPS_rand_set_key(key, keylen);
+ FIPS_rand_seed(v,16);
+ FIPS_rand_set_dt(dt);
+ if (FIPS_rand_bytes(ret,16) <= 0)
+ {
+ fprintf(stderr, "Error getting PRNG value\n");
+ return;
+ }
+
+ pv("R",ret,16);
+ OPENSSL_free(key);
+ key = NULL;
+ OPENSSL_free(dt);
+ dt = NULL;
+ OPENSSL_free(v);
+ v = NULL;
+ }
+ }
+ }
+
+void mct()
+ {
+ unsigned char *key = NULL;
+ unsigned char *v = NULL;
+ unsigned char *dt = NULL;
+ unsigned char ret[16];
+ char buf[1024];
+ char lbuf[1024];
+ char *keyword, *value;
+ long i, keylen;
+ int j;
+
+ keylen = 0;
+
+ while(fgets(buf,sizeof buf,stdin) != NULL)
+ {
+ fputs(buf,stdout);
+ if(!strncmp(buf,"[AES 128-Key]", 13))
+ keylen = 16;
+ else if(!strncmp(buf,"[AES 192-Key]", 13))
+ keylen = 24;
+ else if(!strncmp(buf,"[AES 256-Key]", 13))
+ keylen = 32;
+ if (!parse_line(&keyword, &value, lbuf, buf))
+ continue;
+ if(!strcmp(keyword,"Key"))
+ {
+ key=hex2bin_m(value,&i);
+ if (i != keylen)
+ {
+ fprintf(stderr, "Invalid key length, expecting %ld\n", keylen);
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"DT"))
+ {
+ dt=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid DT length\n");
+ return;
+ }
+ }
+ else if(!strcmp(keyword,"V"))
+ {
+ v=hex2bin_m(value,&i);
+ if (i != 16)
+ {
+ fprintf(stderr, "Invalid V length\n");
+ return;
+ }
+
+ if (!key || !dt)
+ {
+ fprintf(stderr, "Missing key or DT\n");
+ return;
+ }
+
+ FIPS_rand_set_key(key, keylen);
+ FIPS_rand_seed(v,16);
+ for (i = 0; i < 10000; i++)
+ {
+ FIPS_rand_set_dt(dt);
+ if (FIPS_rand_bytes(ret,16) <= 0)
+ {
+ fprintf(stderr, "Error getting PRNG value\n");
+ return;
+ }
+ /* Increment DT */
+ for (j = 15; j >= 0; j--)
+ {
+ dt[j]++;
+ if (dt[j])
+ break;
+ }
+ }
+
+ pv("R",ret,16);
+ OPENSSL_free(key);
+ key = NULL;
+ OPENSSL_free(dt);
+ dt = NULL;
+ OPENSSL_free(v);
+ v = NULL;
+ }
+ }
+ }
+
+int main(int argc,char **argv)
+ {
+ if(argc != 2)
+ {
+ fprintf(stderr,"%s [mct|vst]\n",argv[0]);
+ exit(1);
+ }
+ if(!FIPS_mode_set(1))
+ {
+ do_print_errors();
+ exit(1);
+ }
+ FIPS_rand_reset();
+ if (!FIPS_rand_test_mode())
+ {
+ fprintf(stderr, "Error setting PRNG test mode\n");
+ do_print_errors();
+ exit(1);
+ }
+ if(!strcmp(argv[1],"mct"))
+ mct();
+ else if(!strcmp(argv[1],"vst"))
+ vst();
+ else
+ {
+ fprintf(stderr,"Don't know how to %s.\n",argv[1]);
+ exit(1);
+ }
+
+ return 0;
+ }
+#endif