fix DH_generate_parameters for general 'generator'
authorBodo Möller <bodo@openssl.org>
Wed, 20 Mar 2002 16:04:04 +0000 (16:04 +0000)
committerBodo Möller <bodo@openssl.org>
Wed, 20 Mar 2002 16:04:04 +0000 (16:04 +0000)
CHANGES
crypto/dh/dh.h
crypto/dh/dh_err.c
crypto/dh/dh_gen.c
crypto/dh/dhtest.c

diff --git a/CHANGES b/CHANGES
index 722c4d8854fd0c79a06cc9f356b4618f670c442a..67aa57833b3c2e90e3f0f72dcc0a2fb01c14675c 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,14 @@
 
  Changes between 0.9.7 and 0.9.8  [xx XXX 2002]
 
+  *) Add a function EC_GROUP_check_discriminant() (defined via
+     EC_METHOD) that verifies that the curve discriminant is non-zero.
+
+     Add a function EC_GROUP_check() that makes some sanity tests
+     on a EC_GROUP, its generator and order.  This includes
+     EC_GROUP_check_discriminant().
+     [Nils Larsch <nla@trustcenter.de>]
+
   *) Add ECDSA in new directory crypto/ecdsa/.
 
      Add applications 'openssl ecdsaparam' and 'openssl ecdsa'
          *) applies to 0.9.6a ... 0.9.6d and 0.9.7
          +) applies to 0.9.7 only
 
+  *) Fix DH_generate_parameters() so that it works for 'non-standard'
+     generators, i.e. generators other than 2 and 5.  (Previously, the
+     code did not properly initialise the 'add' and 'rem' values to
+     BN_generate_prime().)
+
+     In the new general case, we do not insist that 'generator' is
+     actually a primitive root: This requirement is rather pointless;
+     a generator of the order-q subgroup is just as good, if not
+     better.
+     [Bodo Moeller]
+
   *) Map new X509 verification errors to alerts. Discovered and submitted by
      Tom Wu <tom@arcot.com>.
      [Lutz Jaenicke]
index 15cf70de0b6badf3bd3669bcbc0409de8de2142b..05851f84294c3bc53b68793ed69f0c18aacfa80c 100644 (file)
@@ -198,6 +198,7 @@ void ERR_load_DH_strings(void);
 #define DH_F_DH_NEW_METHOD                              105
 
 /* Reason codes. */
+#define DH_R_BAD_GENERATOR                              101
 #define DH_R_NO_PRIVATE_VALUE                           100
 
 #ifdef  __cplusplus
index 225779336cbae22ec7cc1401547d133e974ff22a..d837950aecb3c36d18a3f09e4d647773849c2bd3 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/dh/dh_err.c */
 /* ====================================================================
- * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2002 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
@@ -77,6 +77,7 @@ static ERR_STRING_DATA DH_str_functs[]=
 
 static ERR_STRING_DATA DH_str_reasons[]=
        {
+{DH_R_BAD_GENERATOR                      ,"bad generator"},
 {DH_R_NO_PRIVATE_VALUE                   ,"no private value"},
 {0,NULL}
        };
index 7a6a38fbb4849368beeff620a3611f9d0e6c60ef..06f78b35ab71ced8d0f788325ecef8ea3063c9d7 100644 (file)
  * Since DH should be using a safe prime (both p and q are prime),
  * this generator function can take a very very long time to run.
  */
-
+/* Actually there is no reason to insist that 'generator' be a generator.
+ * It's just as OK (and in some sense better) to use a generator of the
+ * order-q subgroup.
+ */
 DH *DH_generate_parameters(int prime_len, int generator,
             void (*callback)(int,int,void *), void *cb_arg)
        {
@@ -100,30 +103,43 @@ DH *DH_generate_parameters(int prime_len, int generator,
        t2 = BN_CTX_get(ctx);
        if (t1 == NULL || t2 == NULL) goto err;
        
+       if (generator <= 1)
+               {
+               DHerr(DH_F_DH_GENERATE_PARAMETERS, DH_R_BAD_GENERATOR);
+               goto err;
+               }
        if (generator == DH_GENERATOR_2)
                {
-               BN_set_word(t1,24);
-               BN_set_word(t2,11);
+               if (!BN_set_word(t1,24)) goto err;
+               if (!BN_set_word(t2,11)) goto err;
                g=2;
                }
-#ifdef undef  /* does not work for safe primes */
+#if 0 /* does not work for safe primes */
        else if (generator == DH_GENERATOR_3)
                {
-               BN_set_word(t1,12);
-               BN_set_word(t2,5);
+               if (!BN_set_word(t1,12)) goto err;
+               if (!BN_set_word(t2,5)) goto err;
                g=3;
                }
 #endif
        else if (generator == DH_GENERATOR_5)
                {
-               BN_set_word(t1,10);
-               BN_set_word(t2,3);
+               if (!BN_set_word(t1,10)) goto err;
+               if (!BN_set_word(t2,3)) goto err;
                /* BN_set_word(t3,7); just have to miss
                 * out on these ones :-( */
                g=5;
                }
        else
+               {
+               /* in the general case, don't worry if 'generator' is a
+                * generator or not: since we are using safe primes,
+                * it will generate either an order-q or an order-2q group,
+                * which both is OK */
+               if (!BN_set_word(t1,2)) goto err;
+               if (!BN_set_word(t2,1)) goto err;
                g=generator;
+               }
        
        p=BN_generate_prime(NULL,prime_len,1,t1,t2,callback,cb_arg);
        if (p == NULL) goto err;
index 0176436a55026b5305d269192c15c8ea6ce3213b..34894ced73541865041532695e0b720d4cb8a90d 100644 (file)
@@ -117,6 +117,16 @@ int main(int argc, char *argv[])
        a=DH_generate_parameters(64,DH_GENERATOR_5,cb,out);
        if (a == NULL) goto err;
 
+       if (!DH_check(a, &i)) goto err;
+       if (i & DH_CHECK_P_NOT_PRIME)
+               BIO_puts(out, "p value is not prime\n");
+       if (i & DH_CHECK_P_NOT_SAFE_PRIME)
+               BIO_puts(out, "p value is not a safe prime\n");
+       if (i & DH_UNABLE_TO_CHECK_GENERATOR)
+               BIO_puts(out, "unable to check the generator value\n");
+       if (i & DH_NOT_SUITABLE_GENERATOR)
+               BIO_puts(out, "the g value is not a generator\n");
+
        BIO_puts(out,"\np    =");
        BN_print(out,a->p);
        BIO_puts(out,"\ng    =");
@@ -175,6 +185,8 @@ int main(int argc, char *argv[])
        else
                ret=0;
 err:
+       ERR_print_errors_fp(stderr);
+
        if (abuf != NULL) OPENSSL_free(abuf);
        if (bbuf != NULL) OPENSSL_free(bbuf);
        if(b != NULL) DH_free(b);