From af28dd6c75cc7abaec8b5df7555f07d143d3a6d1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bodo=20M=C3=B6ller?= Date: Mon, 18 Mar 2002 13:10:45 +0000 Subject: [PATCH] Fix bugs and typos. Add some WTLS curves. New function EC_GROUP_check() (this will probably be implemented differently soon). Submitted by: Nils Larsch Reviewed by: Bodo Moeller --- CHANGES | 5 +- apps/ecdsaparam.c | 114 +++++++++++++++++++++++++--------------- apps/speed.c | 5 +- crypto/conf/conf_mod.c | 2 +- crypto/ec/ec.h | 15 +++++- crypto/ec/ec_curve.c | 31 ++++++++++- crypto/ec/ec_err.c | 8 ++- crypto/ec/ec_lcl.h | 4 ++ crypto/ec/ec_lib.c | 34 ++++++++---- crypto/ec/ecp_mont.c | 1 + crypto/ec/ecp_nist.c | 1 + crypto/ec/ecp_recp.c | 1 + crypto/ec/ecp_smpl.c | 109 +++++++++++++++++++++++++++++++++++++- crypto/ecdsa/ecs_asn1.c | 48 ++++++++++------- 14 files changed, 297 insertions(+), 81 deletions(-) diff --git a/CHANGES b/CHANGES index ba42e28efd..bba9929d66 100644 --- a/CHANGES +++ b/CHANGES @@ -19,8 +19,9 @@ extracted before the specific public key. [Nils Larsch ] - *) 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 diff --git a/apps/ecdsaparam.c b/apps/ecdsaparam.c index 199a363644..10715add80 100644 --- a/apps/ecdsaparam.c +++ b/apps/ecdsaparam.c @@ -133,15 +133,16 @@ * -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 - * -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 @@ -149,21 +150,24 @@ * -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 **); @@ -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 check = 0; 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; + else if (strcmp(*argv,"-check") == 0) + check = 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; + 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 @@ -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," -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," -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"); @@ -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," -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; } @@ -436,9 +453,24 @@ bad: { 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) - { /* 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 || diff --git a/apps/speed.c b/apps/speed.c index 95979e509f..8b837e9964 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -372,8 +372,11 @@ int MAIN(int argc, char **argv) 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; +#if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) + long rsa_count; +#endif #ifndef OPENSSL_NO_RSA unsigned rsa_num; #endif diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index 459a2d7df1..f92babc2e2 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -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) { - char *file; + char *file = NULL; CONF *conf = NULL; int ret = 0; conf = NCONF_new(NULL); diff --git a/crypto/ec/ec.h b/crypto/ec/ec.h index 192ef13f01..f83bacc89b 100644 --- a/crypto/ec/ec.h +++ b/crypto/ec/ec.h @@ -1,6 +1,6 @@ /* 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 @@ -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 *); +/* 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 */ @@ -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_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 *); @@ -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_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 @@ -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_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 @@ -266,6 +275,7 @@ void ERR_load_EC_strings(void); /* 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 @@ -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_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_UNDEFINED_ORDER 122 #define EC_R_UNKNOWN_GROUP 116 #define EC_R_UNKNOWN_NID 117 #define EC_R_UNKNOWN_ORDER 114 diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 8e1f038c3d..132e631a4e 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -60,7 +60,7 @@ #include /* #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 \ @@ -190,6 +190,25 @@ "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, @@ -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; + /* 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) diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c index 2199d92539..e78713bd0b 100644 --- a/crypto/ec/ec_err.c +++ b/crypto/ec/ec_err.c @@ -1,6 +1,6 @@ /* 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 @@ -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_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"}, @@ -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_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"}, @@ -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"}, +{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"}, @@ -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_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_UNDEFINED_ORDER ,"undefined order"}, {EC_R_UNKNOWN_GROUP ,"unknown group"}, {EC_R_UNKNOWN_NID ,"unknown nid"}, {EC_R_UNKNOWN_ORDER ,"unknown order"}, diff --git a/crypto/ec/ec_lcl.h b/crypto/ec/ec_lcl.h index b93825524f..87feb39dea 100644 --- a/crypto/ec/ec_lcl.h +++ b/crypto/ec/ec_lcl.h @@ -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 *); + /* 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 *); @@ -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 *); +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 *); diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 3e372dbed3..1a6aceed82 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -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 *)) @@ -299,17 +322,6 @@ void EC_GROUP_clear_free_extra_data(EC_GROUP *group) 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 */ diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index 7b30d4c38a..1d02661555 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -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_check, ec_GFp_simple_point_init, ec_GFp_simple_point_finish, ec_GFp_simple_point_clear_finish, diff --git a/crypto/ec/ecp_nist.c b/crypto/ec/ecp_nist.c index ed07748675..4d92220670 100644 --- a/crypto/ec/ecp_nist.c +++ b/crypto/ec/ecp_nist.c @@ -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_check, ec_GFp_simple_point_init, ec_GFp_simple_point_finish, ec_GFp_simple_point_clear_finish, diff --git a/crypto/ec/ecp_recp.c b/crypto/ec/ecp_recp.c index fec843b5c8..b251c921ce 100644 --- a/crypto/ec/ecp_recp.c +++ b/crypto/ec/ecp_recp.c @@ -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_check, ec_GFp_simple_point_init, ec_GFp_simple_point_finish, ec_GFp_simple_point_clear_finish, diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 4666a052bf..8e062dc951 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -2,7 +2,7 @@ /* Includes code written by Lenka Fibikova * 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 @@ -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_check, 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); diff --git a/crypto/ecdsa/ecs_asn1.c b/crypto/ecdsa/ecs_asn1.c index 6fa0b3fb7f..b537de6600 100644 --- a/crypto/ecdsa/ecs_asn1.c +++ b/crypto/ecdsa/ecs_asn1.c @@ -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; + unsigned char char_buf = 0; 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 ((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) - 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) { -- 2.34.1