From 868f12988c7397fa6466a4fbc7269cd6de99ec1b Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 6 Mar 2011 12:35:09 +0000 Subject: [PATCH] Updates to DRBG: fix bugs in infrastructure. Add initial experimental algorithm test generator. --- fips/rand/Makefile | 2 +- fips/rand/fips_drbg_lib.c | 31 +++- fips/rand/fips_drbgvs.c | 304 ++++++++++++++++++++++++++++++++++++++ fips/rand/fips_rand.h | 13 ++ fips/rand/fips_rand_lcl.h | 6 +- test/Makefile | 15 +- 6 files changed, 359 insertions(+), 12 deletions(-) create mode 100644 fips/rand/fips_drbgvs.c diff --git a/fips/rand/Makefile b/fips/rand/Makefile index 580d6df777..0aade52d68 100644 --- a/fips/rand/Makefile +++ b/fips/rand/Makefile @@ -18,7 +18,7 @@ AR= ar r CFLAGS= $(INCLUDES) $(CFLAG) GENERAL=Makefile -TEST= fips_randtest.c fips_rngvs.c +TEST= fips_randtest.c fips_rngvs.c fips_drbgvs.c APPS= LIB=$(TOP)/libcrypto.a diff --git a/fips/rand/fips_drbg_lib.c b/fips/rand/fips_drbg_lib.c index da9fb37dd9..9b497b54cc 100644 --- a/fips/rand/fips_drbg_lib.c +++ b/fips/rand/fips_drbg_lib.c @@ -134,6 +134,8 @@ int FIPS_drbg_instantiate(DRBG_CTX *dctx, dctx->status = DRBG_STATUS_READY; dctx->reseed_counter = 1; + /* Initial test value for reseed interval */ + dctx->reseed_interval = 1<<24; end: @@ -160,7 +162,7 @@ int FIPS_drbg_reseed(DRBG_CTX *dctx, if (!adin) adinlen = 0; - else if (adinlen > dctx->max_adin); + else if (adinlen > dctx->max_adin) { /* error */ return 0; @@ -223,4 +225,31 @@ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, } +int FIPS_drbg_set_test_mode(DRBG_CTX *dctx, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out, + int entropy, size_t min_len, size_t max_len), + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out, + int entropy, size_t min_len, size_t max_len)) + { + if (dctx->status != DRBG_STATUS_UNINITIALISED) + return 0; + dctx->flags |= DRBG_FLAG_TEST; + dctx->get_entropy = get_entropy; + dctx->get_nonce = get_nonce; + return 1; + } +void *FIPS_drbg_get_app_data(DRBG_CTX *dctx) + { + return dctx->app_data; + } + +void FIPS_drbg_set_app_data(DRBG_CTX *dctx, void *app_data) + { + dctx->app_data = app_data; + } + +size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx) + { + return dctx->blocklength; + } diff --git a/fips/rand/fips_drbgvs.c b/fips/rand/fips_drbgvs.c new file mode 100644 index 0000000000..a599233908 --- /dev/null +++ b/fips/rand/fips_drbgvs.c @@ -0,0 +1,304 @@ +/* fips/rand/fips_drbgvs.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * 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 + * 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 + * licensing@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. + * ==================================================================== + */ + + +#define OPENSSL_FIPSAPI +#include + +#ifndef OPENSSL_FIPS +#include + +int main(int argc, char **argv) +{ + printf("No FIPS GCM support\n"); + return(0); +} +#else + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "fips_utl.h" + +static int parse_md(char *str) + { + switch(atoi(str + 5)) + { + case 1: + return NID_sha1; + + case 224: + return NID_sha224; + + case 256: + return NID_sha256; + + case 384: + return NID_sha384; + + case 512: + return NID_sha512; + + } + + return NID_undef; + } + +static int parse_aes(char *str, int *pdf) + { + + if (!strncmp(str + 9, "no", 2)) + *pdf = 0; + else + *pdf = DRBG_FLAG_CTR_USE_DF; + + switch(atoi(str + 5)) + { + case 128: + return NID_aes_128_ctr; + + case 192: + return NID_aes_192_ctr; + + case 256: + return NID_aes_256_ctr; + + default: + return NID_undef; + + } + + return NID_undef; + } + +typedef struct + { + unsigned char *ent; + size_t entlen; + unsigned char *nonce; + size_t noncelen; + } TEST_ENT; + +static size_t test_entropy(DRBG_CTX *dctx, unsigned char *out, + int entropy, size_t min_len, size_t max_len) + { + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + memcpy(out, t->ent, t->entlen); + return t->entlen; + } + +static size_t test_nonce(DRBG_CTX *dctx, unsigned char *out, + int entropy, size_t min_len, size_t max_len) + { + TEST_ENT *t = FIPS_drbg_get_app_data(dctx); + memcpy(out, t->nonce, t->noncelen); + return t->noncelen; + } + + + +int main(int argc,char **argv) + { + DRBG_CTX *dctx; + TEST_ENT t; + int r, nid; + int pr = 0; + char buf[2048], lbuf[2048]; + unsigned char out[2048]; + char *keyword = NULL, *value = NULL; + + unsigned char *ent = NULL, *nonce = NULL, *pers = NULL, *adin = NULL; + long entlen, noncelen, perslen, adinlen; + int df; + + int outlen = 0; + + int gen = 0; + + fips_set_error_print(); + + while (fgets(buf, sizeof(buf), stdin) != NULL) + { + fputs(buf, stdout); + if (strlen(buf) > 4 && !strncmp(buf, "[SHA-", 5)) + { + nid = parse_md(buf); + if (nid == NID_undef) + exit(1); + } + if (strlen(buf) > 12 && !strncmp(buf, "[AES-", 5)) + { + nid = parse_aes(buf, &df); + if (nid == NID_undef) + exit(1); + } + if (!parse_line(&keyword, &value, lbuf, buf)) + continue; + + if (!strcmp(keyword, "[PredictionResistance")) + { + if (!strcmp(value, "True]")) + pr = 1; + else if (!strcmp(value, "False]")) + pr = 0; + else + exit(1); + } + + if (!strcmp(keyword, "EntropyInput")) + { + ent = hex2bin_m(value, &entlen); + t.ent = ent; + t.entlen = entlen; + } + + if (!strcmp(keyword, "Nonce")) + { + nonce = hex2bin_m(value, &noncelen); + t.nonce = nonce; + t.noncelen = noncelen; + } + + if (!strcmp(keyword, "PersonalizationString")) + { + pers = hex2bin_m(value, &perslen); + dctx = FIPS_drbg_new(nid, df); + if (!dctx) + exit (1); + FIPS_drbg_set_test_mode(dctx, test_entropy, test_nonce); + FIPS_drbg_set_app_data(dctx, &t); + outlen = (int)FIPS_drbg_get_blocklength(dctx); + r = FIPS_drbg_instantiate(dctx, 0, pers, perslen); + if (!r) + { + fprintf(stderr, "Error instantiating DRBG\n"); + exit(1); + } + OPENSSL_free(pers); + OPENSSL_free(ent); + OPENSSL_free(nonce); + ent = nonce = pers = NULL; + gen = 0; + } + + if (!strcmp(keyword, "AdditionalInput")) + { + adin = hex2bin_m(value, &adinlen); + if (pr) + continue; + r = FIPS_drbg_generate(dctx, out, outlen, 0, + adin, adinlen); + if (!r) + { + fprintf(stderr, "Error generating DRBG bits\n"); + exit(1); + } + if (!r) + exit(1); + OPENSSL_free(adin); + adin = NULL; + gen++; + } + + if (pr) + { + if (!strcmp(keyword, "EntropyInputPR")) + { + ent = hex2bin_m(value, &entlen); + t.ent = ent; + t.entlen = entlen; + r = FIPS_drbg_generate(dctx, out, outlen, 1, + adin, adinlen); + if (!r) + { + fprintf(stderr, + "Error generating DRBG bits\n"); + exit(1); + } + OPENSSL_free(adin); + OPENSSL_free(ent); + adin = ent = NULL; + gen++; + } + } + if (!strcmp(keyword, "EntropyInputReseed")) + { + ent = hex2bin_m(value, &entlen); + t.ent = ent; + t.entlen = entlen; + } + if (!strcmp(keyword, "AdditionalInputReseed")) + { + adin = hex2bin_m(value, &adinlen); + FIPS_drbg_reseed(dctx, adin, adinlen); + OPENSSL_free(ent); + OPENSSL_free(adin); + ent = adin = NULL; + } + if (gen == 2) + { + OutputValue("ReturnedBits", out, outlen, stdout, 0); + gen = 0; + } + + } + return 0; + } + +#endif diff --git a/fips/rand/fips_rand.h b/fips/rand/fips_rand.h index 27eb8f7c2b..e0cc8c9da5 100644 --- a/fips/rand/fips_rand.h +++ b/fips/rand/fips_rand.h @@ -72,6 +72,9 @@ const RAND_METHOD *FIPS_rand_method(void); typedef struct drbg_ctx_st DRBG_CTX; +/* Flag for CTR mode only: use derivation function ctr_df */ +#define DRBG_FLAG_CTR_USE_DF 0x1 + DRBG_CTX *FIPS_drbg_new(int type, unsigned int flags); int FIPS_drbg_instantiate(DRBG_CTX *dctx, int strength, const unsigned char *pers, size_t perslen); @@ -80,6 +83,16 @@ int FIPS_drbg_generate(DRBG_CTX *dctx, unsigned char *out, size_t outlen, int prediction_resistance, const unsigned char *adin, size_t adinlen); +int FIPS_drbg_set_test_mode(DRBG_CTX *dctx, + size_t (*get_entropy)(DRBG_CTX *ctx, unsigned char *out, + int entropy, size_t min_len, size_t max_len), + size_t (*get_nonce)(DRBG_CTX *ctx, unsigned char *out, + int entropy, size_t min_len, size_t max_len)); + +void *FIPS_drbg_get_app_data(DRBG_CTX *ctx); +void FIPS_drbg_set_app_data(DRBG_CTX *ctx, void *app_data); +size_t FIPS_drbg_get_blocklength(DRBG_CTX *dctx); + #ifdef __cplusplus } #endif diff --git a/fips/rand/fips_rand_lcl.h b/fips/rand/fips_rand_lcl.h index 72820bf784..34f1c59991 100644 --- a/fips/rand/fips_rand_lcl.h +++ b/fips/rand/fips_rand_lcl.h @@ -84,12 +84,8 @@ struct drbg_ctr_ctx_st /* DRBG flags */ -/* Enable prediction resistance */ -#define DRBG_FLAG_PREDICTION_RESISTANCE 0x1 -/* CTR only: use derivation function */ -#define DRBG_FLAG_CTR_USE_DF 0x2 /* PRNG is in test state */ -#define DRBG_FLAG_TEST 0x4 +#define DRBG_FLAG_TEST 0x2 /* DRBG status values */ /* not initialised */ diff --git a/test/Makefile b/test/Makefile index c1a05c327b..3e26dfcbfb 100644 --- a/test/Makefile +++ b/test/Makefile @@ -74,6 +74,7 @@ FIPS_RSAGTEST= fips_rsagtest FIPS_DSATEST= fips_dsatest FIPS_DSSVS= fips_dssvs FIPS_RNGVS= fips_rngvs +FIPS_DRBGVS= fips_drbgvs FIPS_ECDSAVS= fips_ecdsavs FIPS_TEST_SUITE=fips_test_suite @@ -94,7 +95,8 @@ FIPSEXE=$(FIPS_SHATEST)$(EXE_EXT) $(FIPS_DESTEST)$(EXE_EXT) \ $(FIPS_HMACTEST)$(EXE_EXT) $(FIPS_RSAVTEST)$(EXE_EXT) \ $(FIPS_RSASTEST)$(EXE_EXT) $(FIPS_RSAGTEST)$(EXE_EXT) \ $(FIPS_DSSVS)$(EXE_EXT) $(FIPS_DSATEST)$(EXE_EXT) \ - $(FIPS_RNGVS)$(EXE_EXT) $(FIPS_TEST_SUITE)$(EXE_EXT) \ + $(FIPS_RNGVS)$(EXE_EXT) $(FIPS_DRBGVS)$(EXE_EXT) \ + $(FIPS_TEST_SUITE)$(EXE_EXT) \ $(FIPS_GCMTEST)$(EXE_EXT) $(FIPS_ECDSAVS)$(EXE_EXT) # $(METHTEST)$(EXE_EXT) @@ -110,8 +112,8 @@ OBJ= $(BNTEST).o $(ECTEST).o $(ECDSATEST).o $(ECDHTEST).o $(IDEATEST).o \ $(FIPS_SHATEST).o $(FIPS_DESTEST).o $(FIPS_RANDTEST).o \ $(FIPS_AESTEST).o $(FIPS_HMACTEST).o $(FIPS_RSAVTEST).o \ $(FIPS_RSASTEST).o $(FIPS_RSAGTEST).o $(FIPS_GCMTEST).o \ - $(FIPS_DSSVS).o $(FIPS_DSATEST).o $(FIPS_RNGVS).o $(FIPS_TEST_SUITE).o \ - $(FIPS_ECDSAVS).o \ + $(FIPS_DSSVS).o $(FIPS_DSATEST).o $(FIPS_RNGVS).o $(FIPS_DRBGVS).o \ + $(FIPS_TEST_SUITE).o $(FIPS_ECDSAVS).o \ $(EVPTEST).o $(IGETEST).o $(JPAKETEST).o SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \ $(MD2TEST).c $(MD4TEST).c $(MD5TEST).c \ @@ -123,8 +125,8 @@ SRC= $(BNTEST).c $(ECTEST).c $(ECDSATEST).c $(ECDHTEST).c $(IDEATEST).c \ $(FIPS_SHATEST).c $(FIPS_DESTEST).c $(FIPS_RANDTEST).c \ $(FIPS_AESTEST).c $(FIPS_HMACTEST).c $(FIPS_RSAVTEST).c \ $(FIPS_RSASTEST).c $(FIPS_RSAGTEST).c $(FIPS_GCMTEST).c \ - $(FIPS_DSSVS).c $(FIPS_DSATEST).c $(FIPS_RNGVS).c $(FIPS_TEST_SUITE).c \ - $(FIPS_ECDSAVS).c \ + $(FIPS_DSSVS).c $(FIPS_DSATEST).c $(FIPS_RNGVS).c $(FIPS_DRBGVS).c \ + $(FIPS_TEST_SUITE).c $(FIPS_ECDSAVS).c \ $(EVPTEST).c $(IGETEST).c $(JPAKETEST).c EXHEADER= @@ -476,6 +478,9 @@ $(FIPS_ECDSAVS)$(EXE_EXT): $(FIPS_ECDSAVS).o $(DLIBCRYPTO) $(FIPS_RNGVS)$(EXE_EXT): $(FIPS_RNGVS).o $(DLIBCRYPTO) @target=$(FIPS_RNGVS); $(FIPS_BUILD_CMD) +$(FIPS_DRBGVS)$(EXE_EXT): $(FIPS_DRBGVS).o $(DLIBCRYPTO) + @target=$(FIPS_DRBGVS); $(FIPS_BUILD_CMD) + $(FIPS_TEST_SUITE)$(EXE_EXT): $(FIPS_TEST_SUITE).o $(DLIBCRYPTO) @target=$(FIPS_TEST_SUITE); $(FIPS_BUILD_CMD)