FIPS DH changes: selftest checks and key range checks.
authorDr. Stephen Henson <steve@openssl.org>
Wed, 26 Jan 2011 15:47:19 +0000 (15:47 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 26 Jan 2011 15:47:19 +0000 (15:47 +0000)
crypto/dh/Makefile
crypto/dh/dh.h
crypto/dh/dh_err.c
crypto/dh/dh_gen.c
crypto/dh/dh_key.c

index f23b4f7..173bf09 100644 (file)
@@ -35,7 +35,7 @@ top:
 all:   lib
 
 lib:   $(LIBOBJ)
-       $(AR) $(LIB) $(LIBOBJ)
+       $(ARX) $(LIB) $(LIBOBJ)
        $(RANLIB) $(LIB) || echo Never mind.
        @touch lib
 
index 849309a..084dc08 100644 (file)
@@ -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
@@ -168,6 +170,11 @@ DH *DHparams_dup(DH *);
 
 const DH_METHOD *DH_OpenSSL(void);
 
+#ifdef OPENSSL_FIPS
+DH *   FIPS_dh_new(void);
+void   FIPS_dh_free(DH *dh);
+#endif
+
 void DH_set_default_method(const DH_METHOD *meth);
 const DH_METHOD *DH_get_default_method(void);
 int DH_set_method(DH *dh, const DH_METHOD *meth);
@@ -249,6 +256,7 @@ void ERR_load_DH_strings(void);
 #define DH_R_DECODE_ERROR                               104
 #define DH_R_INVALID_PUBKEY                             102
 #define DH_R_KEYS_NOT_SET                               108
+#define DH_R_KEY_SIZE_TOO_SMALL                                 110
 #define DH_R_MODULUS_TOO_LARGE                          103
 #define DH_R_NO_PARAMETERS_SET                          107
 #define DH_R_NO_PRIVATE_VALUE                           100
index d5cf0c2..a4c30b7 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/dh/dh_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2006 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2010 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
@@ -95,6 +95,7 @@ static ERR_STRING_DATA DH_str_reasons[]=
 {ERR_REASON(DH_R_DECODE_ERROR)           ,"decode error"},
 {ERR_REASON(DH_R_INVALID_PUBKEY)         ,"invalid public key"},
 {ERR_REASON(DH_R_KEYS_NOT_SET)           ,"keys not set"},
+{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_PARAMETERS_SET)      ,"no parameters set"},
 {ERR_REASON(DH_R_NO_PRIVATE_VALUE)       ,"no private value"},
index cfd5b11..82e5600 100644 (file)
@@ -65,6 +65,9 @@
 #include "cryptlib.h"
 #include <openssl/bn.h>
 #include <openssl/dh.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 
 static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB *cb);
 
@@ -106,6 +109,20 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator, BN_GENCB
        int g,ok= -1;
        BN_CTX *ctx=NULL;
 
+#ifdef OPENSSL_FIPS
+       if(FIPS_selftest_failed())
+               {
+               FIPSerr(FIPS_F_DH_BUILTIN_GENPARAMS,FIPS_R_FIPS_SELFTEST_FAILED);
+               return 0;
+               }
+
+       if (FIPS_mode() && (prime_len < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
+               {
+               DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_KEY_SIZE_TOO_SMALL);
+               goto err;
+               }
+#endif
+
        ctx=BN_CTX_new();
        if (ctx == NULL) goto err;
        BN_CTX_start(ctx);
index e7db440..99c722b 100644 (file)
@@ -61,6 +61,9 @@
 #include <openssl/bn.h>
 #include <openssl/rand.h>
 #include <openssl/dh.h>
+#ifdef OPENSSL_FIPS
+#include <openssl/fips.h>
+#endif
 
 static int generate_key(DH *dh);
 static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
@@ -107,6 +110,14 @@ static int generate_key(DH *dh)
        BN_MONT_CTX *mont=NULL;
        BIGNUM *pub_key=NULL,*priv_key=NULL;
 
+#ifdef OPENSSL_FIPS
+       if (FIPS_mode() && (BN_num_bits(dh->p) < OPENSSL_DH_FIPS_MIN_MODULUS_BITS))
+               {
+               DHerr(DH_F_GENERATE_KEY, DH_R_KEY_SIZE_TOO_SMALL);
+               return 0;
+               }
+#endif
+
        ctx = BN_CTX_new();
        if (ctx == NULL) goto err;
 
@@ -185,6 +196,14 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
                goto err;
                }
 
+#ifdef OPENSSL_FIPS
+       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;
+               }
+#endif
+
        ctx = BN_CTX_new();
        if (ctx == NULL) goto err;
        BN_CTX_start(ctx);
@@ -251,6 +270,9 @@ static int dh_bn_mod_exp(const DH *dh, BIGNUM *r,
 
 static int dh_init(DH *dh)
        {
+#ifdef OPENSSL_FIPS
+       FIPS_selftest_check();
+#endif
        dh->flags |= DH_FLAG_CACHE_MONT_P;
        return(1);
        }