Fix bugs and typos.
authorBodo Möller <bodo@openssl.org>
Mon, 18 Mar 2002 13:10:45 +0000 (13:10 +0000)
committerBodo Möller <bodo@openssl.org>
Mon, 18 Mar 2002 13:10:45 +0000 (13:10 +0000)
Add some WTLS curves.
New function EC_GROUP_check() (this will probably
be implemented differently soon).

Submitted by: Nils Larsch
Reviewed by: Bodo Moeller

14 files changed:
CHANGES
apps/ecdsaparam.c
apps/speed.c
crypto/conf/conf_mod.c
crypto/ec/ec.h
crypto/ec/ec_curve.c
crypto/ec/ec_err.c
crypto/ec/ec_lcl.h
crypto/ec/ec_lib.c
crypto/ec/ecp_mont.c
crypto/ec/ecp_nist.c
crypto/ec/ecp_recp.c
crypto/ec/ecp_smpl.c
crypto/ecdsa/ecs_asn1.c

diff --git a/CHANGES b/CHANGES
index ba42e28..bba9929 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -19,8 +19,9 @@
        extracted before the specific public key.
      [Nils Larsch <nla@trustcenter.de>]
 
        extracted before the specific public key.
      [Nils Larsch <nla@trustcenter.de>]
 
-  *) Include some named elliptic curves, and add OIDs from X9.62 and SECG.
-     The curves can be obtained from the new functions
+  *) Include some named elliptic curves, and add OIDs from X9.62,
+     SECG, and WAP/WTLS.  The curves can be obtained from the new
+     functions
           EC_GROUP_new_by_nid()
           EC_GROUP_new_by_name()
      Also add a 'nid' field to EC_GROUP objects, which can be accessed
           EC_GROUP_new_by_nid()
           EC_GROUP_new_by_name()
      Also add a 'nid' field to EC_GROUP objects, which can be accessed
index 199a363..10715ad 100644 (file)
  * -out arg            - output file - default stdout
  * -noout
  * -text
  * -out arg            - output file - default stdout
  * -noout
  * -text
+ * -check               - validate the ec parameters
  * -C
  * -noout
  * -genkey             - generate a private public keypair based on the supplied curve
  * -named_curve                - use the curve oid instead of the parameters
  * -C
  * -noout
  * -genkey             - generate a private public keypair based on the supplied curve
  * -named_curve                - use the curve oid instead of the parameters
- * -NIST_192           - use the NIST recommeded curve parameters over a 192 bit prime field
- * -NIST_224           - use the NIST recommeded curve parameters over a 224 bit prime field
- * -NIST_256           - use the NIST recommeded curve parameters over a 256 bit prime field
- * -NIST_384           - use the NIST recommeded curve parameters over a 384 bit prime field
- * -NIST_521           - use the NIST recommeded curve parameters over a 521 bit prime field
+ * -NIST_192           - use the NIST recommended curve parameters over a 192 bit prime field
+ * -NIST_224           - use the NIST recommended curve parameters over a 224 bit prime field
+ * -NIST_256           - use the NIST recommended curve parameters over a 256 bit prime field
+ * -NIST_384           - use the NIST recommended curve parameters over a 384 bit prime field
+ * -NIST_521           - use the NIST recommended curve parameters over a 521 bit prime field
  * -X9_62_192v1                - use the X9_62 192v1 example curve over a 192 bit prime field
  * -X9_62_192v2                - use the X9_62 192v2 example curve over a 192 bit prime field
  * -X9_62_192v3                - use the X9_62 192v3 example curve over a 192 bit prime field
  * -X9_62_192v1                - use the X9_62 192v1 example curve over a 192 bit prime field
  * -X9_62_192v2                - use the X9_62 192v2 example curve over a 192 bit prime field
  * -X9_62_192v3                - use the X9_62 192v3 example curve over a 192 bit prime field
  * -X9_62_239v2                - use the X9_62 239v2 example curve over a 239 bit prime field
  * -X9_62_239v3                - use the X9_62 239v3 example curve over a 239 bit prime field
  * -X9_62_256v1                - use the X9_62 239v1 example curve over a 256 bit prime field
  * -X9_62_239v2                - use the X9_62 239v2 example curve over a 239 bit prime field
  * -X9_62_239v3                - use the X9_62 239v3 example curve over a 239 bit prime field
  * -X9_62_256v1                - use the X9_62 239v1 example curve over a 256 bit prime field
- * -SECG_PRIME_112R1    - use the SECG 112r1 recommeded curve over a 112 bit prime field
- * -SECG_PRIME_112R2    - use the SECG 112r2 recommeded curve over a 112 bit prime field
- * -SECG_PRIME_128R1    - use the SECG 128r1 recommeded curve over a 128 bit prime field
- * -SECG_PRIME_128R2    - use the SECG 128r2 recommeded curve over a 128 bit prime field
- * -SECG_PRIME_160K1    - use the SECG 160k1 recommeded curve over a 160 bit prime field
- * -SECG_PRIME_160R1    - use the SECG 160r1 recommeded curve over a 160 bit prime field
- * -SECG_PRIME_160R2    - use the SECG 160r2 recommeded curve over a 160 bit prime field
- * -SECG_PRIME_192K1    - use the SECG 192k1 recommeded curve over a 192 bit prime field
- * -SECG_PRIME_192R1    - use the SECG 192r1 recommeded curve over a 192 bit prime field
- * -SECG_PRIME_224K1    - use the SECG 224k1 recommeded curve over a 224 bit prime field
- * -SECG_PRIME_224R1    - use the SECG 224r1 recommeded curve over a 224 bit prime field
- * -SECG_PRIME_256K1    - use the SECG 256k1 recommeded curve over a 256 bit prime field
- * -SECG_PRIME_256R1    - use the SECG 256r1 recommeded curve over a 256 bit prime field
- * -SECG_PRIME_384R1    - use the SECG 384r1 recommeded curve over a 384 bit prime field
- * -SECG_PRIME_521R1    - use the SECG 521r1 recommeded curve over a 521 bit prime field
+ * -SECG_PRIME_112R1    - use the SECG 112r1 recommended curve over a 112 bit prime field
+ * -SECG_PRIME_112R2    - use the SECG 112r2 recommended curve over a 112 bit prime field
+ * -SECG_PRIME_128R1    - use the SECG 128r1 recommended curve over a 128 bit prime field
+ * -SECG_PRIME_128R2    - use the SECG 128r2 recommended curve over a 128 bit prime field
+ * -SECG_PRIME_160K1    - use the SECG 160k1 recommended curve over a 160 bit prime field
+ * -SECG_PRIME_160R1    - use the SECG 160r1 recommended curve over a 160 bit prime field
+ * -SECG_PRIME_160R2    - use the SECG 160r2 recommended curve over a 160 bit prime field
+ * -SECG_PRIME_192K1    - use the SECG 192k1 recommended curve over a 192 bit prime field
+ * -SECG_PRIME_192R1    - use the SECG 192r1 recommended curve over a 192 bit prime field
+ * -SECG_PRIME_224K1    - use the SECG 224k1 recommended curve over a 224 bit prime field
+ * -SECG_PRIME_224R1    - use the SECG 224r1 recommended curve over a 224 bit prime field
+ * -SECG_PRIME_256K1    - use the SECG 256k1 recommended curve over a 256 bit prime field
+ * -SECG_PRIME_256R1    - use the SECG 256r1 recommended curve over a 256 bit prime field
+ * -SECG_PRIME_384R1    - use the SECG 384r1 recommended curve over a 384 bit prime field
+ * -SECG_PRIME_521R1    - use the SECG 521r1 recommended curve over a 521 bit prime field
+ * -WTLS_6              - use the WAP/WTLS recommended curve number 6 over a 112 bit field
+ * -WTLS_8              - use the WAP/WTLS recommended curve number 8 over a 112 bit field
+ * -WTLS_9              - use the WAP/WTLS recommended curve number 9 over a 160 bit field
  */
 
 int MAIN(int, char **);
  */
 
 int MAIN(int, char **);
@@ -177,6 +181,7 @@ int MAIN(int argc, char **argv)
        int     informat, outformat, noout = 0, C = 0, ret = 1;
        char    *infile, *outfile, *prog, *inrand = NULL;
        int     genkey = 0;
        int     informat, outformat, noout = 0, C = 0, ret = 1;
        char    *infile, *outfile, *prog, *inrand = NULL;
        int     genkey = 0;
+       int     check = 0;
        int     need_rand = 0;
        char    *engine=NULL;
        int     curve_type = EC_GROUP_NO_CURVE;
        int     need_rand = 0;
        char    *engine=NULL;
        int     curve_type = EC_GROUP_NO_CURVE;
@@ -235,6 +240,8 @@ int MAIN(int argc, char **argv)
                        text = 1;
                else if (strcmp(*argv,"-C") == 0)
                        C = 1;
                        text = 1;
                else if (strcmp(*argv,"-C") == 0)
                        C = 1;
+               else if (strcmp(*argv,"-check") == 0)
+                       check = 1;
                else if (strcmp(*argv,"-genkey") == 0)
                {
                        genkey = 1;
                else if (strcmp(*argv,"-genkey") == 0)
                {
                        genkey = 1;
@@ -302,6 +309,12 @@ int MAIN(int argc, char **argv)
                        curve_type = EC_GROUP_SECG_PRIME_384R1;
                else if (strcmp(*argv, "-SECG_PRIME_521R1") == 0)
                        curve_type = EC_GROUP_SECG_PRIME_521R1;
                        curve_type = EC_GROUP_SECG_PRIME_384R1;
                else if (strcmp(*argv, "-SECG_PRIME_521R1") == 0)
                        curve_type = EC_GROUP_SECG_PRIME_521R1;
+               else if (strcmp(*argv, "-WTLS_6") == 0)
+                       curve_type = EC_GROUP_WTLS_6;
+               else if (strcmp(*argv, "-WTLS_8") == 0)
+                       curve_type = EC_GROUP_WTLS_8;
+               else if (strcmp(*argv, "-WTLS_9") == 0)
+                       curve_type = EC_GROUP_WTLS_9;
                else if (strcmp(*argv, "-noout") == 0)
                        noout=1;
                else
                else if (strcmp(*argv, "-noout") == 0)
                        noout=1;
                else
@@ -325,15 +338,16 @@ bad:
                BIO_printf(bio_err," -out arg           output file\n");
                BIO_printf(bio_err," -text              print the key in text\n");
                BIO_printf(bio_err," -C                 Output C code\n");
                BIO_printf(bio_err," -out arg           output file\n");
                BIO_printf(bio_err," -text              print the key in text\n");
                BIO_printf(bio_err," -C                 Output C code\n");
+               BIO_printf(bio_err," -check             validate the ec parameters\n");
                BIO_printf(bio_err," -noout             no output\n");
                BIO_printf(bio_err," -rand              files to use for random number input\n");
                BIO_printf(bio_err," -engine e          use engine e, possibly a hardware device.\n");
                BIO_printf(bio_err," -named_curve       use the curve oid instead of the parameters\n");
                BIO_printf(bio_err," -noout             no output\n");
                BIO_printf(bio_err," -rand              files to use for random number input\n");
                BIO_printf(bio_err," -engine e          use engine e, possibly a hardware device.\n");
                BIO_printf(bio_err," -named_curve       use the curve oid instead of the parameters\n");
-               BIO_printf(bio_err," -NIST_192          use the NIST recommeded curve parameters over a 192 bit prime field\n");
-               BIO_printf(bio_err," -NIST_224          use the NIST recommeded curve parameters over a 224 bit prime field\n");
-               BIO_printf(bio_err," -NIST_256          use the NIST recommeded curve parameters over a 256 bit prime field\n");
-               BIO_printf(bio_err," -NIST_384          use the NIST recommeded curve parameters over a 384 bit prime field\n");
-               BIO_printf(bio_err," -NIST_521          use the NIST recommeded curve parameters over a 521 bit prime field\n");
+               BIO_printf(bio_err," -NIST_192          use the NIST recommended curve parameters over a 192 bit prime field\n");
+               BIO_printf(bio_err," -NIST_224          use the NIST recommended curve parameters over a 224 bit prime field\n");
+               BIO_printf(bio_err," -NIST_256          use the NIST recommended curve parameters over a 256 bit prime field\n");
+               BIO_printf(bio_err," -NIST_384          use the NIST recommended curve parameters over a 384 bit prime field\n");
+               BIO_printf(bio_err," -NIST_521          use the NIST recommended curve parameters over a 521 bit prime field\n");
                BIO_printf(bio_err," -X9_62_192v1       use the X9_62 192v1 example curve over a 192 bit prime field\n");
                BIO_printf(bio_err," -X9_62_192v2       use the X9_62 192v2 example curve over a 192 bit prime field\n");
                BIO_printf(bio_err," -X9_62_192v3       use the X9_62 192v3 example curve over a 192 bit prime field\n");
                BIO_printf(bio_err," -X9_62_192v1       use the X9_62 192v1 example curve over a 192 bit prime field\n");
                BIO_printf(bio_err," -X9_62_192v2       use the X9_62 192v2 example curve over a 192 bit prime field\n");
                BIO_printf(bio_err," -X9_62_192v3       use the X9_62 192v3 example curve over a 192 bit prime field\n");
@@ -341,21 +355,24 @@ bad:
                BIO_printf(bio_err," -X9_62_239v2       use the X9_62 239v2 example curve over a 239 bit prime field\n");
                BIO_printf(bio_err," -X9_62_239v3       use the X9_62 239v3 example curve over a 239 bit prime field\n");
                BIO_printf(bio_err," -X9_62_256v1       use the X9_62 239v1 example curve over a 256 bit prime field\n");
                BIO_printf(bio_err," -X9_62_239v2       use the X9_62 239v2 example curve over a 239 bit prime field\n");
                BIO_printf(bio_err," -X9_62_239v3       use the X9_62 239v3 example curve over a 239 bit prime field\n");
                BIO_printf(bio_err," -X9_62_256v1       use the X9_62 239v1 example curve over a 256 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_112R1  use the SECG 112r1 recommeded curve over a 112 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_112R2  use the SECG 112r2 recommeded curve over a 112 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_128R1  use the SECG 128r1 recommeded curve over a 128 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_128R2  use the SECG 128r2 recommeded curve over a 128 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_160K1  use the SECG 160k1 recommeded curve over a 160 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_160R1  use the SECG 160r1 recommeded curve over a 160 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_160R2  use the SECG 160r2 recommeded curve over a 160 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_192K1  use the SECG 192k1 recommeded curve over a 192 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_192R1  use the SECG 192r1 recommeded curve over a 192 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_224K1  use the SECG 224k1 recommeded curve over a 224 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_224R1  use the SECG 224r1 recommeded curve over a 224 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_256K1  use the SECG 256k1 recommeded curve over a 256 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_256R1  use the SECG 256r1 recommeded curve over a 256 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_384R1  use the SECG 384r1 recommeded curve over a 384 bit prime field\n");
-               BIO_printf(bio_err," -SECG_PRIME_521R1  use the SECG 521r1 recommeded curve over a 521 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_112R1  use the SECG 112r1 recommended curve over a 112 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_112R2  use the SECG 112r2 recommended curve over a 112 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_128R1  use the SECG 128r1 recommended curve over a 128 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_128R2  use the SECG 128r2 recommended curve over a 128 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_160K1  use the SECG 160k1 recommended curve over a 160 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_160R1  use the SECG 160r1 recommended curve over a 160 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_160R2  use the SECG 160r2 recommended curve over a 160 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_192K1  use the SECG 192k1 recommended curve over a 192 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_192R1  use the SECG 192r1 recommended curve over a 192 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_224K1  use the SECG 224k1 recommended curve over a 224 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_224R1  use the SECG 224r1 recommended curve over a 224 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_256K1  use the SECG 256k1 recommended curve over a 256 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_256R1  use the SECG 256r1 recommended curve over a 256 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_384R1  use the SECG 384r1 recommended curve over a 384 bit prime field\n");
+               BIO_printf(bio_err," -SECG_PRIME_521R1  use the SECG 521r1 recommended curve over a 521 bit prime field\n");
+               BIO_printf(bio_err," -WTLS_6            use the WAP/WTLS recommended curve number 6 over a 112 bit field\n");
+               BIO_printf(bio_err," -WTLS_8            use the WAP/WTLS recommended curve number 8 over a 112 bit field\n");
+               BIO_printf(bio_err," -WTLS_9            use the WAP/WTLS recommended curve number 9 over a 112 bit field\n");
                goto end;
        }
 
                goto end;
        }
 
@@ -436,9 +453,24 @@ bad:
        {
                ECDSAParameters_print(out, ecdsa);
        }
        {
                ECDSAParameters_print(out, ecdsa);
        }
+
+       if (check)
+       {
+               if (ecdsa == NULL)
+                       BIO_printf(bio_err, "no elliptic curve parameters\n");
+               BIO_printf(bio_err, "checking elliptic curve parameters: ");
+               if (!EC_GROUP_check(ecdsa->group, NULL))
+               {
+                       BIO_printf(bio_err, "failed\n");
+                       ERR_print_errors(bio_err);
+               }
+               else
+                       BIO_printf(bio_err, "ok\n");
+                       
+       }
        
        if (C)
        
        if (C)
-       {       /* TODO : characteristic two */
+       {       /* TODO: characteristic two */
                int     l, len, bits_p;
                if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL ||
                    (tmp_3 = BN_new()) == NULL || (tmp_4 = BN_new()) == NULL ||
                int     l, len, bits_p;
                if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL ||
                    (tmp_3 = BN_new()) == NULL || (tmp_4 = BN_new()) == NULL ||
index 95979e5..8b837e9 100644 (file)
@@ -372,8 +372,11 @@ int MAIN(int argc, char **argv)
        ENGINE *e = NULL;
        unsigned char *buf=NULL,*buf2=NULL;
        int mret=1;
        ENGINE *e = NULL;
        unsigned char *buf=NULL,*buf2=NULL;
        int mret=1;
-       long count=0,save_count=0, rsa_count;
+       long count=0,save_count=0;
        int i,j,k;
        int i,j,k;
+#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA)
+       long rsa_count;
+#endif
 #ifndef OPENSSL_NO_RSA
        unsigned rsa_num;
 #endif
 #ifndef OPENSSL_NO_RSA
        unsigned rsa_num;
 #endif
index 459a2d7..f92babc 100644 (file)
@@ -165,7 +165,7 @@ int CONF_modules_load(const CONF *cnf, const char *appname,
 int CONF_modules_load_file(const char *filename, const char *appname,
                           unsigned long flags)
        {
 int CONF_modules_load_file(const char *filename, const char *appname,
                           unsigned long flags)
        {
-       char *file;
+       char *file = NULL;
        CONF *conf = NULL;
        int ret = 0;
        conf = NCONF_new(NULL);
        CONF *conf = NULL;
        int ret = 0;
        conf = NCONF_new(NULL);
index 192ef13..f83bacc 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/ec/ec.h */
 /* ====================================================================
 /* crypto/ec/ec.h */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -125,6 +125,8 @@ EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *);
 int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
 int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
 
 int EC_GROUP_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
 int EC_GROUP_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
 
+/* EC_GROUP_check() returns 1 if 'group' defines a valid group, 0 otherwise */
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx);
 
 /* EC_GROUP_new_GFp() calls EC_GROUP_new() and EC_GROUP_set_GFp()
  * after choosing an appropriate EC_METHOD */
 
 /* EC_GROUP_new_GFp() calls EC_GROUP_new() and EC_GROUP_set_GFp()
  * after choosing an appropriate EC_METHOD */
@@ -163,6 +165,11 @@ EC_GROUP *EC_GROUP_new_by_name(int name);
 #define EC_GROUP_SECG_PRIME_256R1      NID_secp256r1
 #define EC_GROUP_SECG_PRIME_384R1      NID_secp384r1
 #define EC_GROUP_SECG_PRIME_521R1      NID_secp521r1
 #define EC_GROUP_SECG_PRIME_256R1      NID_secp256r1
 #define EC_GROUP_SECG_PRIME_384R1      NID_secp384r1
 #define EC_GROUP_SECG_PRIME_521R1      NID_secp521r1
+#define EC_GROUP_WTLS_6                        NID_wap_wsg_idm_ecid_wtls6
+#define EC_GROUP_WTLS_7                        NID_secp160r1
+#define EC_GROUP_WTLS_8                        NID_wap_wsg_idm_ecid_wtls8
+#define EC_GROUP_WTLS_9                        NID_wap_wsg_idm_ecid_wtls9
+#define EC_GROUP_WTLS_12               NID_secp224r1
 
 EC_POINT *EC_POINT_new(const EC_GROUP *);
 void EC_POINT_free(EC_POINT *);
 
 EC_POINT *EC_POINT_new(const EC_GROUP *);
 void EC_POINT_free(EC_POINT *);
@@ -220,6 +227,7 @@ void ERR_load_EC_strings(void);
 #define EC_F_EC_GFP_MONT_FIELD_ENCODE                   134
 #define EC_F_EC_GFP_MONT_FIELD_MUL                      131
 #define EC_F_EC_GFP_MONT_FIELD_SQR                      132
 #define EC_F_EC_GFP_MONT_FIELD_ENCODE                   134
 #define EC_F_EC_GFP_MONT_FIELD_MUL                      131
 #define EC_F_EC_GFP_MONT_FIELD_SQR                      132
+#define EC_F_EC_GFP_SIMPLE_GROUP_CHECK                  151
 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP          100
 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR          101
 #define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE                  102
 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP          100
 #define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR          101
 #define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE                  102
@@ -229,6 +237,7 @@ void ERR_load_EC_strings(void);
 #define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
 #define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
 #define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
 #define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105
 #define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128
 #define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129
+#define EC_F_EC_GROUP_CHECK                             150
 #define EC_F_EC_GROUP_COPY                              106
 #define EC_F_EC_GROUP_GET0_GENERATOR                    139
 #define EC_F_EC_GROUP_GET_COFACTOR                      140
 #define EC_F_EC_GROUP_COPY                              106
 #define EC_F_EC_GROUP_GET0_GENERATOR                    139
 #define EC_F_EC_GROUP_GET_COFACTOR                      140
@@ -266,6 +275,7 @@ void ERR_load_EC_strings(void);
 
 /* Reason codes. */
 #define EC_R_BUFFER_TOO_SMALL                           100
 
 /* Reason codes. */
 #define EC_R_BUFFER_TOO_SMALL                           100
+#define EC_R_DISCRIMINANT_IS_ZERO                       118
 #define EC_R_INCOMPATIBLE_OBJECTS                       101
 #define EC_R_INVALID_ARGUMENT                           112
 #define EC_R_INVALID_COMPRESSED_POINT                   110
 #define EC_R_INCOMPATIBLE_OBJECTS                       101
 #define EC_R_INVALID_ARGUMENT                           112
 #define EC_R_INVALID_COMPRESSED_POINT                   110
@@ -273,13 +283,14 @@ void ERR_load_EC_strings(void);
 #define EC_R_INVALID_ENCODING                           102
 #define EC_R_INVALID_FIELD                              103
 #define EC_R_INVALID_FORM                               104
 #define EC_R_INVALID_ENCODING                           102
 #define EC_R_INVALID_FIELD                              103
 #define EC_R_INVALID_FORM                               104
-#define EC_R_MISSING_PARAMETERS                                 115
+#define EC_R_INVALID_GROUP_ORDER                        119
 #define EC_R_NOT_INITIALIZED                            111
 #define EC_R_NO_SUCH_EXTRA_DATA                                 105
 #define EC_R_POINT_AT_INFINITY                          106
 #define EC_R_POINT_IS_NOT_ON_CURVE                      107
 #define EC_R_SLOT_FULL                                  108
 #define EC_R_UNDEFINED_GENERATOR                        113
 #define EC_R_NOT_INITIALIZED                            111
 #define EC_R_NO_SUCH_EXTRA_DATA                                 105
 #define EC_R_POINT_AT_INFINITY                          106
 #define EC_R_POINT_IS_NOT_ON_CURVE                      107
 #define EC_R_SLOT_FULL                                  108
 #define EC_R_UNDEFINED_GENERATOR                        113
+#define EC_R_UNDEFINED_ORDER                            122
 #define EC_R_UNKNOWN_GROUP                              116
 #define EC_R_UNKNOWN_NID                                117
 #define EC_R_UNKNOWN_ORDER                              114
 #define EC_R_UNKNOWN_GROUP                              116
 #define EC_R_UNKNOWN_NID                                117
 #define EC_R_UNKNOWN_ORDER                              114
index 8e1f038..132e631 100644 (file)
@@ -60,7 +60,7 @@
 #include <openssl/asn1t.h>
 
 /* #define _EC_GROUP_EXAMPLE_PRIME_CURVE       \
 #include <openssl/asn1t.h>
 
 /* #define _EC_GROUP_EXAMPLE_PRIME_CURVE       \
- *             "the prime number p", "a", "b", "the compressed base point", "y-bit", "order", "cofacor"
+ *             "the prime number p", "a", "b", "the compressed base point", "y-bit", "order", "cofactor"
  */
 /* the nist prime curves */
 #define _EC_GROUP_NIST_PRIME_192       \
  */
 /* the nist prime curves */
 #define _EC_GROUP_NIST_PRIME_192       \
                "7",\
                "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",0,\
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1
                "7",\
                "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",0,\
                "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",1
+/* some wap/wtls curves */
+#define _EC_GROUP_WTLS_6       \
+               "DB7C2ABF62E35E668076BEAD208B",\
+               "DB7C2ABF62E35E668076BEAD2088",\
+               "659EF8BA043916EEDE8911702B22",\
+               "09487239995A5EE76B55F9C2F098",0,\
+               "DB7C2ABF62E35E7628DFAC6561C5",1
+#define _EC_GROUP_WTLS_8       \
+               "FFFFFFFFFFFFFFFFFFFFFFFFFDE7",\
+               "0",\
+               "3",\
+               "1",0,\
+               "0100000000000001ECEA551AD837E9",1
+#define _EC_GROUP_WTLS_9       \
+               "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC808F",\
+               "0",\
+               "3",\
+               "1",0,\
+               "0100000000000000000001CDC98AE0E2DE574ABF33",1
 
 static EC_GROUP *ec_group_new_GFp_from_hex(const char *prime_in,
            const char *a_in, const char *b_in,
 
 static EC_GROUP *ec_group_new_GFp_from_hex(const char *prime_in,
            const char *a_in, const char *b_in,
@@ -317,6 +336,16 @@ EC_GROUP *EC_GROUP_new_by_name(int name)
        case EC_GROUP_SECG_PRIME_256K1:
                ret = ec_group_new_GFp_from_hex(_EC_GROUP_SECG_PRIME_256K1);
                break;
        case EC_GROUP_SECG_PRIME_256K1:
                ret = ec_group_new_GFp_from_hex(_EC_GROUP_SECG_PRIME_256K1);
                break;
+       /* some wap/wtls curves */
+       case EC_GROUP_WTLS_6:
+               ret = ec_group_new_GFp_from_hex(_EC_GROUP_WTLS_6);
+               break;
+       case EC_GROUP_WTLS_8:
+               ret = ec_group_new_GFp_from_hex(_EC_GROUP_WTLS_8);
+               break;
+       case EC_GROUP_WTLS_9:
+               ret = ec_group_new_GFp_from_hex(_EC_GROUP_WTLS_9);
+               break;
 
                }
        if (ret == NULL)
 
                }
        if (ret == NULL)
index 2199d92..e78713b 100644 (file)
@@ -1,6 +1,6 @@
 /* crypto/ec/ec_err.c */
 /* ====================================================================
 /* crypto/ec/ec_err.c */
 /* ====================================================================
- * Copyright (c) 2001 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
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -71,6 +71,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_ENCODE,0),  "ec_GFp_mont_field_encode"},
 {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_MUL,0),     "ec_GFp_mont_field_mul"},
 {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_SQR,0),     "ec_GFp_mont_field_sqr"},
 {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_ENCODE,0),  "ec_GFp_mont_field_encode"},
 {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_MUL,0),     "ec_GFp_mont_field_mul"},
 {ERR_PACK(0,EC_F_EC_GFP_MONT_FIELD_SQR,0),     "ec_GFp_mont_field_sqr"},
+{ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_CHECK,0), "ec_GFp_simple_group_check"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "ec_GFp_simple_group_set_curve_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR,0), "ec_GFp_simple_group_set_generator"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_MAKE_AFFINE,0), "ec_GFp_simple_make_affine"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP,0), "ec_GFp_simple_group_set_curve_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR,0), "ec_GFp_simple_group_set_generator"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_MAKE_AFFINE,0), "ec_GFp_simple_make_affine"},
@@ -80,6 +81,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP,0),    "ec_GFp_simple_point_get_affine_coordinates_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP,0),    "ec_GFp_simple_point_set_affine_coordinates_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP,0),      "ec_GFp_simple_set_compressed_coordinates_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP,0),    "ec_GFp_simple_point_get_affine_coordinates_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP,0),    "ec_GFp_simple_point_set_affine_coordinates_GFp"},
 {ERR_PACK(0,EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP,0),      "ec_GFp_simple_set_compressed_coordinates_GFp"},
+{ERR_PACK(0,EC_F_EC_GROUP_CHECK,0),    "EC_GROUP_check"},
 {ERR_PACK(0,EC_F_EC_GROUP_COPY,0),     "EC_GROUP_copy"},
 {ERR_PACK(0,EC_F_EC_GROUP_GET0_GENERATOR,0),   "EC_GROUP_get0_generator"},
 {ERR_PACK(0,EC_F_EC_GROUP_GET_COFACTOR,0),     "EC_GROUP_get_cofactor"},
 {ERR_PACK(0,EC_F_EC_GROUP_COPY,0),     "EC_GROUP_copy"},
 {ERR_PACK(0,EC_F_EC_GROUP_GET0_GENERATOR,0),   "EC_GROUP_get0_generator"},
 {ERR_PACK(0,EC_F_EC_GROUP_GET_COFACTOR,0),     "EC_GROUP_get_cofactor"},
@@ -120,6 +122,7 @@ static ERR_STRING_DATA EC_str_functs[]=
 static ERR_STRING_DATA EC_str_reasons[]=
        {
 {EC_R_BUFFER_TOO_SMALL                   ,"buffer too small"},
 static ERR_STRING_DATA EC_str_reasons[]=
        {
 {EC_R_BUFFER_TOO_SMALL                   ,"buffer too small"},
+{EC_R_DISCRIMINANT_IS_ZERO               ,"discriminant is zero"},
 {EC_R_INCOMPATIBLE_OBJECTS               ,"incompatible objects"},
 {EC_R_INVALID_ARGUMENT                   ,"invalid argument"},
 {EC_R_INVALID_COMPRESSED_POINT           ,"invalid compressed point"},
 {EC_R_INCOMPATIBLE_OBJECTS               ,"incompatible objects"},
 {EC_R_INVALID_ARGUMENT                   ,"invalid argument"},
 {EC_R_INVALID_COMPRESSED_POINT           ,"invalid compressed point"},
@@ -127,13 +130,14 @@ static ERR_STRING_DATA EC_str_reasons[]=
 {EC_R_INVALID_ENCODING                   ,"invalid encoding"},
 {EC_R_INVALID_FIELD                      ,"invalid field"},
 {EC_R_INVALID_FORM                       ,"invalid form"},
 {EC_R_INVALID_ENCODING                   ,"invalid encoding"},
 {EC_R_INVALID_FIELD                      ,"invalid field"},
 {EC_R_INVALID_FORM                       ,"invalid form"},
-{EC_R_MISSING_PARAMETERS                 ,"missing parameters"},
+{EC_R_INVALID_GROUP_ORDER                ,"invalid group order"},
 {EC_R_NOT_INITIALIZED                    ,"not initialized"},
 {EC_R_NO_SUCH_EXTRA_DATA                 ,"no such extra data"},
 {EC_R_POINT_AT_INFINITY                  ,"point at infinity"},
 {EC_R_POINT_IS_NOT_ON_CURVE              ,"point is not on curve"},
 {EC_R_SLOT_FULL                          ,"slot full"},
 {EC_R_UNDEFINED_GENERATOR                ,"undefined generator"},
 {EC_R_NOT_INITIALIZED                    ,"not initialized"},
 {EC_R_NO_SUCH_EXTRA_DATA                 ,"no such extra data"},
 {EC_R_POINT_AT_INFINITY                  ,"point at infinity"},
 {EC_R_POINT_IS_NOT_ON_CURVE              ,"point is not on curve"},
 {EC_R_SLOT_FULL                          ,"slot full"},
 {EC_R_UNDEFINED_GENERATOR                ,"undefined generator"},
+{EC_R_UNDEFINED_ORDER                    ,"undefined order"},
 {EC_R_UNKNOWN_GROUP                      ,"unknown group"},
 {EC_R_UNKNOWN_NID                        ,"unknown nid"},
 {EC_R_UNKNOWN_ORDER                      ,"unknown order"},
 {EC_R_UNKNOWN_GROUP                      ,"unknown group"},
 {EC_R_UNKNOWN_NID                        ,"unknown nid"},
 {EC_R_UNKNOWN_ORDER                      ,"unknown order"},
index b938255..87feb39 100644 (file)
@@ -82,6 +82,9 @@ struct ec_method_st {
        int (*group_get_order)(const EC_GROUP *, BIGNUM *order, BN_CTX *);
        int (*group_get_cofactor)(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
 
        int (*group_get_order)(const EC_GROUP *, BIGNUM *order, BN_CTX *);
        int (*group_get_cofactor)(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
 
+       /* used by EC_GROUP_check: */
+       int (*group_check)(const EC_GROUP *, BN_CTX *);
+
        /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
        int (*point_init)(EC_POINT *);
        void (*point_finish)(EC_POINT *);
        /* used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, EC_POINT_copy: */
        int (*point_init)(EC_POINT *);
        void (*point_finish)(EC_POINT *);
@@ -215,6 +218,7 @@ int ec_GFp_simple_group_set_generator(EC_GROUP *, const EC_POINT *generator,
 EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *);
 int ec_GFp_simple_group_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
 int ec_GFp_simple_group_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
 EC_POINT *ec_GFp_simple_group_get0_generator(const EC_GROUP *);
 int ec_GFp_simple_group_get_order(const EC_GROUP *, BIGNUM *order, BN_CTX *);
 int ec_GFp_simple_group_get_cofactor(const EC_GROUP *, BIGNUM *cofactor, BN_CTX *);
+int ec_GFp_simple_group_check(const EC_GROUP *, BN_CTX *);
 int ec_GFp_simple_point_init(EC_POINT *);
 void ec_GFp_simple_point_finish(EC_POINT *);
 void ec_GFp_simple_point_clear_finish(EC_POINT *);
 int ec_GFp_simple_point_init(EC_POINT *);
 void ec_GFp_simple_point_finish(EC_POINT *);
 void ec_GFp_simple_point_clear_finish(EC_POINT *);
index 3e372db..1a6acee 100644 (file)
@@ -237,6 +237,29 @@ int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx)
        }
 
 
        }
 
 
+int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx)
+       {
+       if (group->meth->group_check == 0)
+               {
+               ECerr(EC_F_EC_GROUP_CHECK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+               return 0;
+               }
+       return group->meth->group_check(group, ctx);
+       }
+
+
+void EC_GROUP_set_nid(EC_GROUP *group, int nid)
+       {
+       group->nid = nid;
+       }
+
+
+int EC_GROUP_get_nid(const EC_GROUP *group)
+       {
+       return group->nid;
+       }
+
+
 /* this has 'package' visibility */
 int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *),
        void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
 /* this has 'package' visibility */
 int EC_GROUP_set_extra_data(EC_GROUP *group, void *extra_data, void *(*extra_data_dup_func)(void *),
        void (*extra_data_free_func)(void *), void (*extra_data_clear_free_func)(void *))
@@ -299,17 +322,6 @@ void EC_GROUP_clear_free_extra_data(EC_GROUP *group)
        group->extra_data_clear_free_func = 0;
        }
 
        group->extra_data_clear_free_func = 0;
        }
 
-void EC_GROUP_set_nid(EC_GROUP *group, int nid)
-       {
-       group->nid = nid;
-       }
-
-int EC_GROUP_get_nid(const EC_GROUP *group)
-       {
-       return group->nid;
-       }
-
-
 
 /* functions for EC_POINT objects */
 
 
 /* functions for EC_POINT objects */
 
index 7b30d4c..1d02661 100644 (file)
@@ -71,6 +71,7 @@ const EC_METHOD *EC_GFp_mont_method(void)
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
+               ec_GFp_simple_group_check,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
index ed07748..4d92220 100644 (file)
@@ -69,6 +69,7 @@ const EC_METHOD *EC_GFp_nist_method(void)
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
+               ec_GFp_simple_group_check,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
index fec843b..b251c92 100644 (file)
@@ -69,6 +69,7 @@ const EC_METHOD *EC_GFp_recp_method(void)
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
+               ec_GFp_simple_group_check,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
index 4666a05..8e062dc 100644 (file)
@@ -2,7 +2,7 @@
 /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
  * for the OpenSSL project. */
 /* ====================================================================
 /* Includes code written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
  * for the OpenSSL project. */
 /* ====================================================================
- * Copyright (c) 1998-2001 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -73,6 +73,7 @@ const EC_METHOD *EC_GFp_simple_method(void)
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
                ec_GFp_simple_group_get0_generator,
                ec_GFp_simple_group_get_order,
                ec_GFp_simple_group_get_cofactor,
+               ec_GFp_simple_group_check,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
                ec_GFp_simple_point_init,
                ec_GFp_simple_point_finish,
                ec_GFp_simple_point_clear_finish,
@@ -338,6 +339,112 @@ int ec_GFp_simple_group_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN
        }
 
 
        }
 
 
+int ec_GFp_simple_group_check(const EC_GROUP *group, BN_CTX *ctx)
+       {
+       int ret = 0;
+       BIGNUM *a,*b,*order,*tmp_1,*tmp_2;
+       const BIGNUM *p = &group->field;
+       BN_CTX *new_ctx = NULL;
+       EC_POINT *point = NULL;
+
+       if (ctx == NULL)
+               {
+               ctx = new_ctx = BN_CTX_new();
+               if (ctx == NULL)
+                       {
+                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, ERR_R_MALLOC_FAILURE);
+                       goto err;
+                       }
+               }
+       BN_CTX_start(ctx);
+       a = BN_CTX_get(ctx);
+       b = BN_CTX_get(ctx);
+       tmp_1 = BN_CTX_get(ctx);
+       tmp_2 = BN_CTX_get(ctx);
+       order = BN_CTX_get(ctx);
+       if (order == NULL) goto err;
+
+       if (group->meth->field_decode)
+               {
+               if (!group->meth->field_decode(group, a, &group->a, ctx)) goto err;
+               if (!group->meth->field_decode(group, b, &group->b, ctx)) goto err;
+               }
+       else
+               {
+               if (!BN_copy(a, &group->a)) goto err;
+               if (!BN_copy(b, &group->b)) goto err;
+               }
+       
+       /* check the discriminant:
+        * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) 
+         * 0 =< a, b < p */
+       if (BN_is_zero(a))
+               {
+               if (BN_is_zero(b))
+                       {
+                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+                       goto err;
+                       }
+               }
+       else if (!BN_is_zero(b))
+               {
+               if (!BN_mod_sqr(tmp_1, a, p, ctx)) goto err;
+               if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) goto err;
+               if (!BN_lshift(tmp_1, tmp_2, 2)) goto err;
+               /* tmp_1 = 4*a^3 */
+
+               if (!BN_mod_sqr(tmp_2, b, p, ctx)) goto err;
+               if (!BN_mul_word(tmp_2, 27)) goto err;
+               /* tmp_2 = 27*b^2 */
+
+               if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) goto err;
+               if (BN_is_zero(a))
+                       {
+                       ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO);
+                       goto err;
+                       }
+               }
+       
+       /* check the generator */
+       if (group->generator == NULL)
+               {
+               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR);
+               goto err;
+               }
+       if (!ec_GFp_simple_is_on_curve(group, group->generator, ctx))
+               {
+               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE);
+               goto err;
+               }
+
+       /* check the order of the generator */
+       if ((point = EC_POINT_new(group)) == NULL) goto err;
+       if (!EC_GROUP_get_order(group, order, ctx)) goto err; 
+       if (BN_is_zero(order))
+               {
+               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_UNDEFINED_ORDER);
+               goto err;
+               }
+       
+       if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) goto err;
+       if (!EC_POINT_is_at_infinity(group, point))
+               {
+               ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER);
+               goto err;
+               }
+
+       ret = 1;
+
+err:
+       BN_CTX_end(ctx);
+       if (new_ctx != NULL)
+               BN_CTX_free(new_ctx);
+       if (point)
+               EC_POINT_free(point);
+       return ret;
+       }
+
+
 int ec_GFp_simple_point_init(EC_POINT *point)
        {
        BN_init(&point->X);
 int ec_GFp_simple_point_init(EC_POINT *point)
        {
        BN_init(&point->X);
index 6fa0b3f..b537de6 100644 (file)
@@ -170,6 +170,7 @@ X9_62_CURVE   *ECDSA_get_X9_62_CURVE(const ECDSA *ecdsa, X9_62_CURVE *curve)
        X9_62_CURVE *ret=NULL;
        BIGNUM      *tmp1=NULL, *tmp2=NULL;
        unsigned char *buffer=NULL;
        X9_62_CURVE *ret=NULL;
        BIGNUM      *tmp1=NULL, *tmp2=NULL;
        unsigned char *buffer=NULL;
+       unsigned char char_buf = 0;
 
        if (!ecdsa || !ecdsa->group)
                OPENSSL_ECDSA_ABORT(ECDSA_R_MISSING_PARAMETERS)
 
        if (!ecdsa || !ecdsa->group)
                OPENSSL_ECDSA_ABORT(ECDSA_R_MISSING_PARAMETERS)
@@ -189,29 +190,38 @@ X9_62_CURVE   *ECDSA_get_X9_62_CURVE(const ECDSA *ecdsa, X9_62_CURVE *curve)
        if (!EC_GROUP_get_curve_GFp(ecdsa->group, NULL, tmp1, tmp2, NULL))
                OPENSSL_ECDSA_ABORT(ERR_R_EC_LIB)
 
        if (!EC_GROUP_get_curve_GFp(ecdsa->group, NULL, tmp1, tmp2, NULL))
                OPENSSL_ECDSA_ABORT(ERR_R_EC_LIB)
 
-       if ((len1 = BN_num_bytes(tmp1)) == 0)
-               OPENSSL_ECDSA_ABORT(ECDSA_R_UNEXPECTED_PARAMETER_LENGTH)
-       if ((buffer = OPENSSL_malloc(len1)) == NULL)
-               OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE)
-       if ((len1 = BN_bn2bin(tmp1, buffer)) == 0) goto err;
-       if ((ret->a = M_ASN1_OCTET_STRING_new()) == NULL)
-               OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
-       if (!M_ASN1_OCTET_STRING_set(ret->a, buffer, len1))
+       if ((ret->a = M_ASN1_OCTET_STRING_new()) == NULL || 
+           (ret->b = M_ASN1_OCTET_STRING_new()) == NULL )
                OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
 
                OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
 
-       if ((len2 = BN_num_bytes(tmp2)) == 0)
-               OPENSSL_ECDSA_ABORT(ECDSA_R_UNEXPECTED_PARAMETER_LENGTH)
-       if (len1 < len2)
+       len1 = BN_num_bytes(tmp1);
+       len2 = BN_num_bytes(tmp2);
+
+       if ((buffer = OPENSSL_malloc(len1 > len2 ? len1 : len2)) == NULL)
+               OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE)
+
+       if (len1 == 0) /* => a == 0 */
        {
        {
-               OPENSSL_free(buffer);
-               if ((buffer = OPENSSL_malloc(len2)) == NULL)
-                       OPENSSL_ECDSA_ABORT(ERR_R_MALLOC_FAILURE)
+               if (!M_ASN1_OCTET_STRING_set(ret->a, char_buf, 1))
+                       OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
+       }
+       else
+       {
+               if ((len1 = BN_bn2bin(tmp1, buffer)) == 0) goto err;
+               if (!M_ASN1_OCTET_STRING_set(ret->a, buffer, len1))
+                       OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
+       }
+       if (len2 == 0) /* => b == 0 */
+       {
+               if (!M_ASN1_OCTET_STRING_set(ret->a, char_buf, 1))
+                       OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
+       }
+       else
+       {
+               if ((len2 = BN_bn2bin(tmp2, buffer)) == 0) goto err;
+               if (!M_ASN1_OCTET_STRING_set(ret->b, buffer, len2))
+                       OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
        }
        }
-       if ((len2 = BN_bn2bin(tmp2, buffer)) == 0) goto err;
-       if ((ret->b = M_ASN1_OCTET_STRING_new()) == NULL)
-               OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
-       if (!M_ASN1_OCTET_STRING_set(ret->b, buffer, len2))
-               OPENSSL_ECDSA_ABORT(ERR_R_ASN1_LIB)
 
        if (ecdsa->seed)
        {       
 
        if (ecdsa->seed)
        {