From 7f1288da939d17136c2c70af0e3a7d7fe57a07ce Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Mon, 13 Aug 2007 18:02:52 +0000 Subject: [PATCH] Enforce minimum key sizes in FIPS mode. --- crypto/dh/dh.h | 3 +++ crypto/dh/dh_err.c | 3 ++- crypto/dsa/dsa.h | 4 ++++ crypto/dsa/dsa_err.c | 2 ++ crypto/rsa/rsa.h | 2 ++ fips-1.0/dh/fips_dh_gen.c | 6 ++++++ fips-1.0/dh/fips_dh_key.c | 8 +++++++- fips-1.0/dsa/fips_dsa_gen.c | 6 ++++++ fips-1.0/dsa/fips_dsa_ossl.c | 12 ++++++++++++ fips-1.0/rsa/fips_rsa_eay.c | 24 ++++++++++++++++++++++++ fips-1.0/rsa/fips_rsa_gen.c | 8 ++++---- 11 files changed, 72 insertions(+), 6 deletions(-) diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h index 809de46f8d..10475ac4b3 100644 --- a/crypto/dh/dh.h +++ b/crypto/dh/dh.h @@ -77,6 +77,8 @@ # define OPENSSL_DH_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DH_FIPS_MIN_MODULUS_BITS 1024 + #define DH_FLAG_CACHE_MONT_P 0x01 #define DH_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DH * implementation now uses constant time @@ -233,6 +235,7 @@ void ERR_load_DH_strings(void); /* Reason codes. */ #define DH_R_BAD_GENERATOR 101 #define DH_R_INVALID_PUBKEY 102 +#define DH_R_KEY_SIZE_TOO_SMALL 104 #define DH_R_MODULUS_TOO_LARGE 103 #define DH_R_NO_PRIVATE_VALUE 100 diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c index 4595a2adf7..13263c81c1 100644 --- a/crypto/dh/dh_err.c +++ b/crypto/dh/dh_err.c @@ -1,6 +1,6 @@ /* crypto/dh/dh_err.c */ /* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-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 @@ -87,6 +87,7 @@ static ERR_STRING_DATA DH_str_reasons[]= { {ERR_REASON(DH_R_BAD_GENERATOR) ,"bad generator"}, {ERR_REASON(DH_R_INVALID_PUBKEY) ,"invalid public key"}, +{ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(DH_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DH_R_NO_PRIVATE_VALUE) ,"no private value"}, {0,NULL} diff --git a/crypto/dsa/dsa.h b/crypto/dsa/dsa.h index 914f6c7195..6a9e732dea 100644 --- a/crypto/dsa/dsa.h +++ b/crypto/dsa/dsa.h @@ -88,6 +88,8 @@ # define OPENSSL_DSA_MAX_MODULUS_BITS 10000 #endif +#define OPENSSL_DSA_FIPS_MIN_MODULUS_BITS 1024 + #define DSA_FLAG_CACHE_MONT_P 0x01 #define DSA_FLAG_NO_EXP_CONSTTIME 0x02 /* new with 0.9.7h; the built-in DSA * implementation now uses constant time @@ -292,6 +294,7 @@ void ERR_load_DSA_strings(void); #define DSA_F_DSAPARAMS_PRINT_FP 101 #define DSA_F_DSA_DO_SIGN 112 #define DSA_F_DSA_DO_VERIFY 113 +#define DSA_F_DSA_GENERATE_PARAMETERS 117 #define DSA_F_DSA_NEW_METHOD 103 #define DSA_F_DSA_PRINT 104 #define DSA_F_DSA_PRINT_FP 105 @@ -307,6 +310,7 @@ void ERR_load_DSA_strings(void); /* Reason codes. */ #define DSA_R_BAD_Q_VALUE 102 #define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +#define DSA_R_KEY_SIZE_TOO_SMALL 106 #define DSA_R_MISSING_PARAMETERS 101 #define DSA_R_MODULUS_TOO_LARGE 103 #define DSA_R_NON_FIPS_METHOD 104 diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c index 68663d85fd..e41619c5c1 100644 --- a/crypto/dsa/dsa_err.c +++ b/crypto/dsa/dsa_err.c @@ -75,6 +75,7 @@ static ERR_STRING_DATA DSA_str_functs[]= {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, +{ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS), "DSA_generate_parameters"}, {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, {ERR_FUNC(DSA_F_DSA_PRINT), "DSA_print"}, {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, @@ -93,6 +94,7 @@ static ERR_STRING_DATA DSA_str_reasons[]= { {ERR_REASON(DSA_R_BAD_Q_VALUE) ,"bad q value"}, {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, +{ERR_REASON(DSA_R_KEY_SIZE_TOO_SMALL) ,"key size too small"}, {ERR_REASON(DSA_R_MISSING_PARAMETERS) ,"missing parameters"}, {ERR_REASON(DSA_R_MODULUS_TOO_LARGE) ,"modulus too large"}, {ERR_REASON(DSA_R_NON_FIPS_METHOD) ,"non fips method"}, diff --git a/crypto/rsa/rsa.h b/crypto/rsa/rsa.h index 464b295f0d..068f613b28 100644 --- a/crypto/rsa/rsa.h +++ b/crypto/rsa/rsa.h @@ -182,6 +182,8 @@ struct rsa_st # define OPENSSL_RSA_MAX_MODULUS_BITS 16384 #endif +#define OPENSSL_RSA_FIPS_MIN_MODULUS_BITS 1024 + #ifndef OPENSSL_RSA_SMALL_MODULUS_BITS # define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 #endif diff --git a/fips-1.0/dh/fips_dh_gen.c b/fips-1.0/dh/fips_dh_gen.c index a12423c0e7..3f852f1af9 100644 --- a/fips-1.0/dh/fips_dh_gen.c +++ b/fips-1.0/dh/fips_dh_gen.c @@ -115,6 +115,12 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB return 0; } + if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_GENERATE_PARAMETERS, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } + ctx=BN_CTX_new(); if (ctx == NULL) goto err; BN_CTX_start(ctx); diff --git a/fips-1.0/dh/fips_dh_key.c b/fips-1.0/dh/fips_dh_key.c index b30a85f2e4..6c590d0e98 100644 --- a/fips-1.0/dh/fips_dh_key.c +++ b/fips-1.0/dh/fips_dh_key.c @@ -194,7 +194,13 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) DHerr(DH_F_COMPUTE_KEY,DH_R_MODULUS_TOO_LARGE); goto err; } - + + if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS)) + { + DHerr(DH_F_COMPUTE_KEY, DH_R_KEY_SIZE_TOO_SMALL); + goto err; + } + if (dh->priv_key == NULL) { DHerr(DH_F_DH_COMPUTE_KEY,DH_R_NO_PRIVATE_VALUE); diff --git a/fips-1.0/dsa/fips_dsa_gen.c b/fips-1.0/dsa/fips_dsa_gen.c index 9e05ed2071..e0a0e1c56b 100644 --- a/fips-1.0/dsa/fips_dsa_gen.c +++ b/fips-1.0/dsa/fips_dsa_gen.c @@ -124,6 +124,12 @@ static int dsa_builtin_paramgen(DSA *ret, int bits, goto err; } + if (FIPS_mode() && (bits < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_GENERATE_PARAMETERS, DSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + if (bits < 512) bits=512; bits=(bits+63)/64*64; diff --git a/fips-1.0/dsa/fips_dsa_ossl.c b/fips-1.0/dsa/fips_dsa_ossl.c index a29be0f7fc..18e14691a5 100644 --- a/fips-1.0/dsa/fips_dsa_ossl.c +++ b/fips-1.0/dsa/fips_dsa_ossl.c @@ -132,6 +132,12 @@ static DSA_SIG *dsa_do_sign(const unsigned char *dgst, FIPS_DSA_SIZE_T dlen, DSA return NULL; } + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); + return NULL; + } + BN_init(&m); BN_init(&xr); @@ -309,6 +315,12 @@ static int dsa_do_verify(const unsigned char *dgst, FIPS_DSA_SIZE_T dgst_len, DS return -1; } + if (FIPS_mode() && (BN_num_bits(dsa->p) < OPENSSL_DSA_FIPS_MIN_MODULUS_BITS)) + { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + BN_init(&u1); BN_init(&u2); BN_init(&t1); diff --git a/fips-1.0/rsa/fips_rsa_eay.c b/fips-1.0/rsa/fips_rsa_eay.c index 69170b16b3..69015f82a0 100644 --- a/fips-1.0/rsa/fips_rsa_eay.c +++ b/fips-1.0/rsa/fips_rsa_eay.c @@ -175,6 +175,12 @@ static int RSA_eay_public_encrypt(int flen, const unsigned char *from, goto err; } + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); @@ -374,6 +380,12 @@ static int RSA_eay_private_encrypt(int flen, const unsigned char *from, goto err; } + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if ((ctx=BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -511,6 +523,12 @@ static int RSA_eay_private_decrypt(int flen, const unsigned char *from, goto err; } + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if((ctx = BN_CTX_new()) == NULL) goto err; BN_CTX_start(ctx); f = BN_CTX_get(ctx); @@ -644,6 +662,12 @@ static int RSA_eay_public_decrypt(int flen, const unsigned char *from, goto err; } + if (FIPS_mode() && (BN_num_bits(rsa->n) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) + { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); diff --git a/fips-1.0/rsa/fips_rsa_gen.c b/fips-1.0/rsa/fips_rsa_gen.c index 7c23ef8357..7dab88b2d0 100644 --- a/fips-1.0/rsa/fips_rsa_gen.c +++ b/fips-1.0/rsa/fips_rsa_gen.c @@ -116,15 +116,15 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) int bitsp,bitsq,ok= -1,n=0; BN_CTX *ctx=NULL; - if (bits < 512) + if(FIPS_selftest_failed()) { - FIPSerr(FIPS_F_RSA_GENERATE_KEY,FIPS_R_KEY_TOO_SHORT); + FIPSerr(FIPS_F_RSA_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED); return 0; } - if(FIPS_selftest_failed()) + if (FIPS_mode() && (bits < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS)) { - FIPSerr(FIPS_F_RSA_GENERATE_KEY,FIPS_R_FIPS_SELFTEST_FAILED); + FIPSerr(FIPS_F_RSA_GENERATE_KEY,FIPS_R_KEY_TOO_SHORT); return 0; } -- 2.25.1