diff options
Diffstat (limited to 'openssl/crypto/ecdsa')
-rw-r--r-- | openssl/crypto/ecdsa/Makefile | 142 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecdsa.h | 271 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecdsatest.c | 500 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_asn1.c | 67 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_err.c | 104 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_lib.c | 261 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_locl.h | 107 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_ossl.c | 478 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_sign.c | 104 | ||||
-rw-r--r-- | openssl/crypto/ecdsa/ecs_vrf.c | 96 |
10 files changed, 2130 insertions, 0 deletions
diff --git a/openssl/crypto/ecdsa/Makefile b/openssl/crypto/ecdsa/Makefile new file mode 100644 index 000000000..4865f3c8d --- /dev/null +++ b/openssl/crypto/ecdsa/Makefile @@ -0,0 +1,142 @@ +# +# crypto/ecdsa/Makefile +# + +DIR= ecdsa +TOP= ../.. +CC= cc +INCLUDES= -I.. -I$(TOP) -I../../include +CFLAG=-g -Wall +MAKEFILE= Makefile +AR= ar r + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=ecdsatest.c +APPS= + +LIB=$(TOP)/libcrypto.a +LIBSRC= ecs_lib.c ecs_asn1.c ecs_ossl.c ecs_sign.c ecs_vrf.c ecs_err.c + +LIBOBJ= ecs_lib.o ecs_asn1.o ecs_ossl.o ecs_sign.o ecs_vrf.o ecs_err.o + +SRC= $(LIBSRC) + +EXHEADER= ecdsa.h +HEADER= ecs_locl.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +top: + (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIBOBJ) + $(ARX) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) || echo Never mind. + @touch lib + +files: + $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO + +links: + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile... + @headerlist="$(EXHEADER)"; for i in $$headerlist; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile... + $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. + +ecs_asn1.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h +ecs_asn1.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h +ecs_asn1.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +ecs_asn1.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +ecs_asn1.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h +ecs_asn1.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +ecs_asn1.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +ecs_asn1.o: ../../include/openssl/symhacks.h ecs_asn1.c ecs_locl.h +ecs_err.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +ecs_err.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +ecs_err.o: ../../include/openssl/ec.h ../../include/openssl/ecdsa.h +ecs_err.o: ../../include/openssl/err.h ../../include/openssl/lhash.h +ecs_err.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +ecs_err.o: ../../include/openssl/ossl_typ.h ../../include/openssl/safestack.h +ecs_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +ecs_err.o: ecs_err.c +ecs_lib.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +ecs_lib.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h +ecs_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h +ecs_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h +ecs_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h +ecs_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h +ecs_lib.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +ecs_lib.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +ecs_lib.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +ecs_lib.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +ecs_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +ecs_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +ecs_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +ecs_lib.o: ecs_lib.c ecs_locl.h +ecs_ossl.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +ecs_ossl.o: ../../include/openssl/bn.h ../../include/openssl/crypto.h +ecs_ossl.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +ecs_ossl.o: ../../include/openssl/ecdsa.h ../../include/openssl/err.h +ecs_ossl.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +ecs_ossl.o: ../../include/openssl/opensslconf.h +ecs_ossl.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +ecs_ossl.o: ../../include/openssl/safestack.h ../../include/openssl/stack.h +ecs_ossl.o: ../../include/openssl/symhacks.h ecs_locl.h ecs_ossl.c +ecs_sign.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +ecs_sign.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +ecs_sign.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +ecs_sign.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +ecs_sign.o: ../../include/openssl/engine.h ../../include/openssl/evp.h +ecs_sign.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +ecs_sign.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +ecs_sign.o: ../../include/openssl/opensslconf.h +ecs_sign.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +ecs_sign.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +ecs_sign.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +ecs_sign.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +ecs_sign.o: ../../include/openssl/x509_vfy.h ecs_locl.h ecs_sign.c +ecs_vrf.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +ecs_vrf.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h +ecs_vrf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +ecs_vrf.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h +ecs_vrf.o: ../../include/openssl/engine.h ../../include/openssl/evp.h +ecs_vrf.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h +ecs_vrf.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +ecs_vrf.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h +ecs_vrf.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pkcs7.h +ecs_vrf.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h +ecs_vrf.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h +ecs_vrf.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h +ecs_vrf.o: ecs_locl.h ecs_vrf.c diff --git a/openssl/crypto/ecdsa/ecdsa.h b/openssl/crypto/ecdsa/ecdsa.h new file mode 100644 index 000000000..f20c8ee73 --- /dev/null +++ b/openssl/crypto/ecdsa/ecdsa.h @@ -0,0 +1,271 @@ +/* crypto/ecdsa/ecdsa.h */ +/** + * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions + * \author Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2003 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDSA_H +#define HEADER_ECDSA_H + +#include <openssl/opensslconf.h> + +#ifdef OPENSSL_NO_ECDSA +#error ECDSA is disabled. +#endif + +#include <openssl/ec.h> +#include <openssl/ossl_typ.h> +#ifndef OPENSSL_NO_DEPRECATED +#include <openssl/bn.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ECDSA_SIG_st + { + BIGNUM *r; + BIGNUM *s; + } ECDSA_SIG; + +/** ECDSA_SIG *ECDSA_SIG_new(void) + * allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** ECDSA_SIG_free + * frees a ECDSA_SIG structure + * \param a pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *a); + +/** i2d_ECDSA_SIG + * DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param a pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *a, unsigned char **pp); + +/** d2i_ECDSA_SIG + * decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param v pointer to ECDSA_SIG pointer (may be NULL) + * \param pp buffer with the DER encoded signature + * \param len bufferlength + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **v, const unsigned char **pp, long len); + +/** ECDSA_do_sign + * computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey pointer to the EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst,int dgst_len,EC_KEY *eckey); + +/** ECDSA_do_sign_ex + * computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv optional pointer to a pre-computed inverse k + * \param rp optional pointer to the pre-computed rp value (see + * ECDSA_sign_setup + * \param eckey pointer to the EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** ECDSA_do_verify + * verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig pointer to the ECDSA_SIG structure + * \param eckey pointer to the EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY* eckey); + +const ECDSA_METHOD *ECDSA_OpenSSL(void); + +/** ECDSA_set_default_method + * sets the default ECDSA method + * \param meth the new default ECDSA_METHOD + */ +void ECDSA_set_default_method(const ECDSA_METHOD *meth); + +/** ECDSA_get_default_method + * returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method + */ +const ECDSA_METHOD *ECDSA_get_default_method(void); + +/** ECDSA_set_method + * sets method to be used for the ECDSA operations + * \param eckey pointer to the EC_KEY object + * \param meth pointer to the new method + * \return 1 on success and 0 otherwise + */ +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); + +/** ECDSA_size + * returns the maximum length of the DER encoded signature + * \param eckey pointer to a EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/** ECDSA_sign_setup + * precompute parts of the signing operation. + * \param eckey pointer to the EC_KEY object containing a private EC key + * \param ctx pointer to a BN_CTX object (may be NULL) + * \param kinv pointer to a BIGNUM pointer for the inverse of k + * \param rp pointer to a BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **rp); + +/** ECDSA_sign + * computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param eckey pointer to the EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + + +/** ECDSA_sign_ex + * computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv optional pointer to a pre-computed inverse k + * \param rp optional pointer to the pre-computed rp value (see + * ECDSA_sign_setup + * \param eckey pointer to the EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, const BIGNUM *kinv, + const BIGNUM *rp, EC_KEY *eckey); + +/** ECDSA_verify + * verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey pointer to the EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/* the standard ex_data functions */ +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDSA_get_ex_data(EC_KEY *d, int idx); + + +/* BEGIN ERROR CODES */ +/* The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDSA_strings(void); + +/* Error codes for the ECDSA functions. */ + +/* Function codes. */ +#define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 +#define ECDSA_F_ECDSA_DO_SIGN 101 +#define ECDSA_F_ECDSA_DO_VERIFY 102 +#define ECDSA_F_ECDSA_SIGN_SETUP 103 + +/* Reason codes. */ +#define ECDSA_R_BAD_SIGNATURE 100 +#define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 +#define ECDSA_R_ERR_EC_LIB 102 +#define ECDSA_R_MISSING_PARAMETERS 103 +#define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +#define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/openssl/crypto/ecdsa/ecdsatest.c b/openssl/crypto/ecdsa/ecdsatest.c new file mode 100644 index 000000000..b07e31252 --- /dev/null +++ b/openssl/crypto/ecdsa/ecdsatest.c @@ -0,0 +1,500 @@ +/* crypto/ecdsa/ecdsatest.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_ECDSA is defined */ + +#ifdef OPENSSL_NO_ECDSA +int main(int argc, char * argv[]) + { + puts("Elliptic curves are disabled."); + return 0; + } +#else + +#include <openssl/crypto.h> +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/ecdsa.h> +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif +#include <openssl/err.h> +#include <openssl/rand.h> + +static const char rnd_seed[] = "string to make the random number generator " + "think it has entropy"; + +/* declaration of the test functions */ +int x9_62_tests(BIO *); +int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s); +int test_builtin(BIO *); + +/* functions to change the RAND_METHOD */ +int change_rand(void); +int restore_rand(void); +int fbytes(unsigned char *buf, int num); + +RAND_METHOD fake_rand; +const RAND_METHOD *old_rand; + +int change_rand(void) + { + /* save old rand method */ + if ((old_rand = RAND_get_rand_method()) == NULL) + return 0; + + fake_rand.seed = old_rand->seed; + fake_rand.cleanup = old_rand->cleanup; + fake_rand.add = old_rand->add; + fake_rand.status = old_rand->status; + /* use own random function */ + fake_rand.bytes = fbytes; + fake_rand.pseudorand = old_rand->bytes; + /* set new RAND_METHOD */ + if (!RAND_set_rand_method(&fake_rand)) + return 0; + return 1; + } + +int restore_rand(void) + { + if (!RAND_set_rand_method(old_rand)) + return 0; + else + return 1; + } + +static int fbytes_counter = 0; +static const char *numbers[8] = { + "651056770906015076056810763456358567190100156695615665659", + "6140507067065001063065065565667405560006161556565665656654", + "8763001015071075675010661307616710783570106710677817767166" + "71676178726717", + "7000000175690566466555057817571571075705015757757057795755" + "55657156756655", + "1275552191113212300012030439187146164646146646466749494799", + "1542725565216523985789236956265265265235675811949404040041", + "1456427555219115346513212300075341203043918714616464614664" + "64667494947990", + "1712787255652165239672857892369562652652652356758119494040" + "40041670216363"}; + +int fbytes(unsigned char *buf, int num) + { + int ret; + BIGNUM *tmp = NULL; + + if (fbytes_counter >= 8) + return 0; + tmp = BN_new(); + if (!tmp) + return 0; + if (!BN_dec2bn(&tmp, numbers[fbytes_counter])) + { + BN_free(tmp); + return 0; + } + fbytes_counter ++; + ret = BN_bn2bin(tmp, buf); + if (ret == 0 || ret != num) + ret = 0; + else + ret = 1; + if (tmp) + BN_free(tmp); + return ret; + } + +/* some tests from the X9.62 draft */ +int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) + { + int ret = 0; + const char message[] = "abc"; + unsigned char digest[20]; + unsigned int dgst_len = 0; + EVP_MD_CTX md_ctx; + EC_KEY *key = NULL; + ECDSA_SIG *signature = NULL; + BIGNUM *r = NULL, *s = NULL; + + EVP_MD_CTX_init(&md_ctx); + /* get the message digest */ + EVP_DigestInit(&md_ctx, EVP_ecdsa()); + EVP_DigestUpdate(&md_ctx, (const void*)message, 3); + EVP_DigestFinal(&md_ctx, digest, &dgst_len); + + BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); + /* create the key */ + if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) + goto x962_int_err; + if (!EC_KEY_generate_key(key)) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + /* create the signature */ + signature = ECDSA_do_sign(digest, 20, key); + if (signature == NULL) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + /* compare the created signature with the expected signature */ + if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) + goto x962_int_err; + if (!BN_dec2bn(&r, r_in) || + !BN_dec2bn(&s, s_in)) + goto x962_int_err; + if (BN_cmp(signature->r ,r) || BN_cmp(signature->s, s)) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + /* verify the signature */ + if (ECDSA_do_verify(digest, 20, signature, key) != 1) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + + BIO_printf(out, " ok\n"); + ret = 1; +x962_int_err: + if (!ret) + BIO_printf(out, " failed\n"); + if (key) + EC_KEY_free(key); + if (signature) + ECDSA_SIG_free(signature); + if (r) + BN_free(r); + if (s) + BN_free(s); + EVP_MD_CTX_cleanup(&md_ctx); + return ret; + } + +int x9_62_tests(BIO *out) + { + int ret = 0; + + BIO_printf(out, "some tests from X9.62:\n"); + + /* set own rand method */ + if (!change_rand()) + goto x962_err; + + if (!x9_62_test_internal(out, NID_X9_62_prime192v1, + "3342403536405981729393488334694600415596881826869351677613", + "5735822328888155254683894997897571951568553642892029982342")) + goto x962_err; + if (!x9_62_test_internal(out, NID_X9_62_prime239v1, + "3086361431751678114926225473006680188549593787585317781474" + "62058306432176", + "3238135532097973577080787768312505059318910517550078427819" + "78505179448783")) + goto x962_err; + if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1, + "87194383164871543355722284926904419997237591535066528048", + "308992691965804947361541664549085895292153777025772063598")) + goto x962_err; + if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1, + "2159633321041961198501834003903461262881815148684178964245" + "5876922391552", + "1970303740007316867383349976549972270528498040721988191026" + "49413465737174")) + goto x962_err; + + ret = 1; +x962_err: + if (!restore_rand()) + ret = 0; + return ret; + } + +int test_builtin(BIO *out) + { + EC_builtin_curve *curves = NULL; + size_t crv_len = 0, n = 0; + EC_KEY *eckey = NULL, *wrong_eckey = NULL; + EC_GROUP *group; + unsigned char digest[20], wrong_digest[20]; + unsigned char *signature = NULL; + unsigned int sig_len; + int nid, ret = 0; + + /* fill digest values with some random data */ + if (!RAND_pseudo_bytes(digest, 20) || + !RAND_pseudo_bytes(wrong_digest, 20)) + { + BIO_printf(out, "ERROR: unable to get random data\n"); + goto builtin_err; + } + + /* create and verify a ecdsa signature with every availble curve + * (with ) */ + BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " + "with some internal curves:\n"); + + /* get a list of all internal curves */ + crv_len = EC_get_builtin_curves(NULL, 0); + + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); + + if (curves == NULL) + { + BIO_printf(out, "malloc error\n"); + goto builtin_err; + } + + if (!EC_get_builtin_curves(curves, crv_len)) + { + BIO_printf(out, "unable to get internal curves\n"); + goto builtin_err; + } + + /* now create and verify a signature for every curve */ + for (n = 0; n < crv_len; n++) + { + unsigned char dirt, offset; + + nid = curves[n].nid; + if (nid == NID_ipsec4) + continue; + /* create new ecdsa key (== EC_KEY) */ + if ((eckey = EC_KEY_new()) == NULL) + goto builtin_err; + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) + goto builtin_err; + if (EC_KEY_set_group(eckey, group) == 0) + goto builtin_err; + EC_GROUP_free(group); + if (EC_GROUP_get_degree(EC_KEY_get0_group(eckey)) < 160) + /* drop the curve */ + { + EC_KEY_free(eckey); + eckey = NULL; + continue; + } + BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); + /* create key */ + if (!EC_KEY_generate_key(eckey)) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + /* create second key */ + if ((wrong_eckey = EC_KEY_new()) == NULL) + goto builtin_err; + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) + goto builtin_err; + if (EC_KEY_set_group(wrong_eckey, group) == 0) + goto builtin_err; + EC_GROUP_free(group); + if (!EC_KEY_generate_key(wrong_eckey)) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + + BIO_printf(out, "."); + (void)BIO_flush(out); + /* check key */ + if (!EC_KEY_check_key(eckey)) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* create signature */ + sig_len = ECDSA_size(eckey); + if ((signature = OPENSSL_malloc(sig_len)) == NULL) + goto builtin_err; + if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* verify signature */ + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* verify signature with the wrong key */ + if (ECDSA_verify(0, digest, 20, signature, sig_len, + wrong_eckey) == 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* wrong digest */ + if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, + eckey) == 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* modify a single byte of the signature */ + offset = signature[10] % sig_len; + dirt = signature[11]; + signature[offset] ^= dirt ? dirt : 1; + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) + { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + + BIO_printf(out, " ok\n"); + /* cleanup */ + OPENSSL_free(signature); + signature = NULL; + EC_KEY_free(eckey); + eckey = NULL; + EC_KEY_free(wrong_eckey); + wrong_eckey = NULL; + } + + ret = 1; +builtin_err: + if (eckey) + EC_KEY_free(eckey); + if (wrong_eckey) + EC_KEY_free(wrong_eckey); + if (signature) + OPENSSL_free(signature); + if (curves) + OPENSSL_free(curves); + + return ret; + } + +int main(void) + { + int ret = 1; + BIO *out; + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + + /* enable memory leak checking unless explicitly disabled */ + if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && + (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) + { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + } + else + { + /* OPENSSL_DEBUG_MEMORY=off */ + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); + } + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + + /* initialize the prng */ + RAND_seed(rnd_seed, sizeof(rnd_seed)); + + /* the tests */ + if (!x9_62_tests(out)) goto err; + if (!test_builtin(out)) goto err; + + ret = 0; +err: + if (ret) + BIO_printf(out, "\nECDSA test failed\n"); + else + BIO_printf(out, "\nECDSA test passed\n"); + if (ret) + ERR_print_errors(out); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_state(0); + ERR_free_strings(); + CRYPTO_mem_leaks(out); + if (out != NULL) + BIO_free(out); + return ret; + } +#endif diff --git a/openssl/crypto/ecdsa/ecs_asn1.c b/openssl/crypto/ecdsa/ecs_asn1.c new file mode 100644 index 000000000..b29548940 --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_asn1.c @@ -0,0 +1,67 @@ +/* crypto/ecdsa/ecs_asn1.c */ +/* ==================================================================== + * Copyright (c) 2000-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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#include <openssl/err.h> +#include <openssl/asn1t.h> + +ASN1_SEQUENCE(ECDSA_SIG) = { + ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), + ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) +} ASN1_SEQUENCE_END(ECDSA_SIG) + +DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) +IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) diff --git a/openssl/crypto/ecdsa/ecs_err.c b/openssl/crypto/ecdsa/ecs_err.c new file mode 100644 index 000000000..d2a53730e --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_err.c @@ -0,0 +1,104 @@ +/* crypto/ecdsa/ecs_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include <stdio.h> +#include <openssl/err.h> +#include <openssl/ecdsa.h> + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0) +#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason) + +static ERR_STRING_DATA ECDSA_str_functs[]= + { +{ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, +{ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, +{ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, +{ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, +{0,NULL} + }; + +static ERR_STRING_DATA ECDSA_str_reasons[]= + { +{ERR_REASON(ECDSA_R_BAD_SIGNATURE) ,"bad signature"}, +{ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE),"data too large for key size"}, +{ERR_REASON(ECDSA_R_ERR_EC_LIB) ,"err ec lib"}, +{ERR_REASON(ECDSA_R_MISSING_PARAMETERS) ,"missing parameters"}, +{ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES),"need new setup values"}, +{ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED),"random number generation failed"}, +{ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED),"signature malloc failed"}, +{0,NULL} + }; + +#endif + +void ERR_load_ECDSA_strings(void) + { +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) + { + ERR_load_strings(0,ECDSA_str_functs); + ERR_load_strings(0,ECDSA_str_reasons); + } +#endif + } diff --git a/openssl/crypto/ecdsa/ecs_lib.c b/openssl/crypto/ecdsa/ecs_lib.c new file mode 100644 index 000000000..85e8a3a7e --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_lib.c @@ -0,0 +1,261 @@ +/* crypto/ecdsa/ecs_lib.c */ +/* ==================================================================== + * Copyright (c) 1998-2005 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include <string.h> +#include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif +#include <openssl/err.h> +#include <openssl/bn.h> + +const char ECDSA_version[]="ECDSA" OPENSSL_VERSION_PTEXT; + +static const ECDSA_METHOD *default_ECDSA_method = NULL; + +static void *ecdsa_data_new(void); +static void *ecdsa_data_dup(void *); +static void ecdsa_data_free(void *); + +void ECDSA_set_default_method(const ECDSA_METHOD *meth) +{ + default_ECDSA_method = meth; +} + +const ECDSA_METHOD *ECDSA_get_default_method(void) +{ + if(!default_ECDSA_method) + default_ECDSA_method = ECDSA_OpenSSL(); + return default_ECDSA_method; +} + +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) +{ + const ECDSA_METHOD *mtmp; + ECDSA_DATA *ecdsa; + + ecdsa = ecdsa_check(eckey); + + if (ecdsa == NULL) + return 0; + + mtmp = ecdsa->meth; +#ifndef OPENSSL_NO_ENGINE + if (ecdsa->engine) + { + ENGINE_finish(ecdsa->engine); + ecdsa->engine = NULL; + } +#endif + ecdsa->meth = meth; + + return 1; +} + +static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) +{ + ECDSA_DATA *ret; + + ret=(ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); + if (ret == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return(NULL); + } + + ret->init = NULL; + + ret->meth = ECDSA_get_default_method(); + ret->engine = engine; +#ifndef OPENSSL_NO_ENGINE + if (!ret->engine) + ret->engine = ENGINE_get_default_ECDSA(); + if (ret->engine) + { + ret->meth = ENGINE_get_ECDSA(ret->engine); + if (!ret->meth) + { + ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->flags = ret->meth->flags; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); +#if 0 + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) + { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret=NULL; + } +#endif + return(ret); +} + +static void *ecdsa_data_new(void) +{ + return (void *)ECDSA_DATA_new_method(NULL); +} + +static void *ecdsa_data_dup(void *data) +{ + ECDSA_DATA *r = (ECDSA_DATA *)data; + + /* XXX: dummy operation */ + if (r == NULL) + return NULL; + + return ecdsa_data_new(); +} + +static void ecdsa_data_free(void *data) +{ + ECDSA_DATA *r = (ECDSA_DATA *)data; + +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); + + OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); + + OPENSSL_free(r); +} + +ECDSA_DATA *ecdsa_check(EC_KEY *key) +{ + ECDSA_DATA *ecdsa_data; + + void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, ecdsa_data_free); + if (data == NULL) + { + ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); + if (ecdsa_data == NULL) + return NULL; + EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, + ecdsa_data_dup, ecdsa_data_free, ecdsa_data_free); + } + else + ecdsa_data = (ECDSA_DATA *)data; + + + return ecdsa_data; +} + +int ECDSA_size(const EC_KEY *r) +{ + int ret,i; + ASN1_INTEGER bs; + BIGNUM *order=NULL; + unsigned char buf[4]; + const EC_GROUP *group; + + if (r == NULL) + return 0; + group = EC_KEY_get0_group(r); + if (group == NULL) + return 0; + + if ((order = BN_new()) == NULL) return 0; + if (!EC_GROUP_get_order(group,order,NULL)) + { + BN_clear_free(order); + return 0; + } + i=BN_num_bits(order); + bs.length=(i+7)/8; + bs.data=buf; + bs.type=V_ASN1_INTEGER; + /* If the top bit is set the asn1 encoding is 1 larger. */ + buf[0]=0xff; + + i=i2d_ASN1_INTEGER(&bs,NULL); + i+=i; /* r and s */ + ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE); + BN_clear_free(order); + return(ret); +} + + +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, + new_func, dup_func, free_func); +} + +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) +{ + ECDSA_DATA *ecdsa; + ecdsa = ecdsa_check(d); + if (ecdsa == NULL) + return 0; + return(CRYPTO_set_ex_data(&ecdsa->ex_data,idx,arg)); +} + +void *ECDSA_get_ex_data(EC_KEY *d, int idx) +{ + ECDSA_DATA *ecdsa; + ecdsa = ecdsa_check(d); + if (ecdsa == NULL) + return NULL; + return(CRYPTO_get_ex_data(&ecdsa->ex_data,idx)); +} diff --git a/openssl/crypto/ecdsa/ecs_locl.h b/openssl/crypto/ecdsa/ecs_locl.h new file mode 100644 index 000000000..3a69a840e --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_locl.h @@ -0,0 +1,107 @@ +/* crypto/ecdsa/ecs_locl.h */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ECS_LOCL_H +#define HEADER_ECS_LOCL_H + +#include <openssl/ecdsa.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct ecdsa_method + { + const char *name; + ECDSA_SIG *(*ecdsa_do_sign)(const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, EC_KEY *eckey); + int (*ecdsa_sign_setup)(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **r); + int (*ecdsa_do_verify)(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); +#if 0 + int (*init)(EC_KEY *eckey); + int (*finish)(EC_KEY *eckey); +#endif + int flags; + char *app_data; + }; + +typedef struct ecdsa_data_st { + /* EC_KEY_METH_DATA part */ + int (*init)(EC_KEY *); + /* method (ECDSA) specific part */ + ENGINE *engine; + int flags; + const ECDSA_METHOD *meth; + CRYPTO_EX_DATA ex_data; +} ECDSA_DATA; + +/** ecdsa_check + * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure + * and if not it removes the old meth_data and creates a ECDSA_DATA structure. + * \param eckey pointer to a EC_KEY object + * \return pointer to a ECDSA_DATA structure + */ +ECDSA_DATA *ecdsa_check(EC_KEY *eckey); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ECS_LOCL_H */ diff --git a/openssl/crypto/ecdsa/ecs_ossl.c b/openssl/crypto/ecdsa/ecs_ossl.c new file mode 100644 index 000000000..3ead1af94 --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_ossl.c @@ -0,0 +1,478 @@ +/* crypto/ecdsa/ecs_ossl.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2004 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#include <openssl/err.h> +#include <openssl/obj_mac.h> +#include <openssl/bn.h> + +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, EC_KEY *eckey); +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +static ECDSA_METHOD openssl_ecdsa_meth = { + "OpenSSL ECDSA method", + ecdsa_do_sign, + ecdsa_sign_setup, + ecdsa_do_verify, +#if 0 + NULL, /* init */ + NULL, /* finish */ +#endif + 0, /* flags */ + NULL /* app_data */ +}; + +const ECDSA_METHOD *ECDSA_OpenSSL(void) +{ + return &openssl_ecdsa_meth; +} + +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + BN_CTX *ctx = NULL; + BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; + EC_POINT *tmp_point=NULL; + const EC_GROUP *group; + int ret = 0; + + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx_in == NULL) + { + if ((ctx = BN_CTX_new()) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_MALLOC_FAILURE); + return 0; + } + } + else + ctx = ctx_in; + + k = BN_new(); /* this value is later returned in *kinvp */ + r = BN_new(); /* this value is later returned in *rp */ + order = BN_new(); + X = BN_new(); + if (!k || !r || !order || !X) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((tmp_point = EC_POINT_new(group)) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (!EC_GROUP_get_order(group, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + + do + { + /* get random k */ + do + if (!BN_rand_range(k, order)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); + goto err; + } + while (BN_is_zero(k)); + + /* compute r the x-coordinate of generator * k */ + if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) + { + if (!EC_POINT_get_affine_coordinates_GFp(group, + tmp_point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); + goto err; + } + } + else /* NID_X9_62_characteristic_two_field */ + { + if (!EC_POINT_get_affine_coordinates_GF2m(group, + tmp_point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP,ERR_R_EC_LIB); + goto err; + } + } + if (!BN_nnmod(r, X, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + } + while (BN_is_zero(r)); + + /* compute the inverse of k */ + if (!BN_mod_inverse(k, k, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + /* clear old values if necessary */ + if (*rp != NULL) + BN_clear_free(*rp); + if (*kinvp != NULL) + BN_clear_free(*kinvp); + /* save the pre-computed values */ + *rp = r; + *kinvp = k; + ret = 1; +err: + if (!ret) + { + if (k != NULL) BN_clear_free(k); + if (r != NULL) BN_clear_free(r); + } + if (ctx_in == NULL) + BN_CTX_free(ctx); + if (order != NULL) + BN_free(order); + if (tmp_point != NULL) + EC_POINT_free(tmp_point); + if (X) + BN_clear_free(X); + return(ret); +} + + +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey) +{ + int ok = 0; + BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL; + const BIGNUM *ckinv; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + ECDSA_SIG *ret; + ECDSA_DATA *ecdsa; + const BIGNUM *priv_key; + + ecdsa = ecdsa_check(eckey); + group = EC_KEY_get0_group(eckey); + priv_key = EC_KEY_get0_private_key(eckey); + + if (group == NULL || priv_key == NULL || ecdsa == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret = ECDSA_SIG_new(); + if (!ret) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } + s = ret->s; + + if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || + (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_GROUP_get_order(group, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); + goto err; + } + if (8 * dgst_len > BN_num_bits(order)) + { + /* XXX + * + * Should provide for optional hash truncation: + * Keep the BN_num_bits(order) leftmost bits of dgst + * (see March 2006 FIPS 186-3 draft, which has a few + * confusing errors in this part though) + */ + + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, + ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + + if (!BN_bin2bn(dgst, dgst_len, m)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + do + { + if (in_kinv == NULL || in_r == NULL) + { + if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN,ERR_R_ECDSA_LIB); + goto err; + } + ckinv = kinv; + } + else + { + ckinv = in_kinv; + if (BN_copy(ret->r, in_r) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_add_quick(s, tmp, m, order)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_mul(s, s, ckinv, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (BN_is_zero(s)) + { + /* if kinv and r have been supplied by the caller + * don't to generate new kinv and r values */ + if (in_kinv != NULL && in_r != NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ECDSA_R_NEED_NEW_SETUP_VALUES); + goto err; + } + } + else + /* s != 0 => we have a valid signature */ + break; + } + while (1); + + ok = 1; +err: + if (!ok) + { + ECDSA_SIG_free(ret); + ret = NULL; + } + if (ctx) + BN_CTX_free(ctx); + if (m) + BN_clear_free(m); + if (tmp) + BN_clear_free(tmp); + if (order) + BN_free(order); + if (kinv) + BN_clear_free(kinv); + return ret; +} + +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + int ret = -1; + BN_CTX *ctx; + BIGNUM *order, *u1, *u2, *m, *X; + EC_POINT *point = NULL; + const EC_GROUP *group; + const EC_POINT *pub_key; + + /* check input values */ + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); + return -1; + } + + ctx = BN_CTX_new(); + if (!ctx) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + return -1; + } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + u1 = BN_CTX_get(ctx); + u2 = BN_CTX_get(ctx); + m = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + if (!X) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + + if (!EC_GROUP_get_order(group, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (8 * dgst_len > BN_num_bits(order)) + { + /* XXX + * + * Should provide for optional hash truncation: + * Keep the BN_num_bits(order) leftmost bits of dgst + * (see March 2006 FIPS 186-3 draft, which has a few + * confusing errors in this part though) + */ + + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, + ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + ret = 0; + goto err; + } + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || + BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); + ret = 0; /* signature is invalid */ + goto err; + } + /* calculate tmp1 = inv(S) mod order */ + if (!BN_mod_inverse(u2, sig->s, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* digest -> m */ + if (!BN_bin2bn(dgst, dgst_len, m)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* u1 = m * tmp mod order */ + if (!BN_mod_mul(u1, m, u2, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* u2 = r * w mod q */ + if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + + if ((point = EC_POINT_new(group)) == NULL) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == NID_X9_62_prime_field) + { + if (!EC_POINT_get_affine_coordinates_GFp(group, + point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + } + else /* NID_X9_62_characteristic_two_field */ + { + if (!EC_POINT_get_affine_coordinates_GF2m(group, + point, X, NULL, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + } + + if (!BN_nnmod(u1, X, order, ctx)) + { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* if the signature is correct u1 is equal to sig->r */ + ret = (BN_ucmp(u1, sig->r) == 0); +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (point) + EC_POINT_free(point); + return ret; +} diff --git a/openssl/crypto/ecdsa/ecs_sign.c b/openssl/crypto/ecdsa/ecs_sign.c new file mode 100644 index 000000000..74b1fe8ca --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_sign.c @@ -0,0 +1,104 @@ +/* crypto/ecdsa/ecdsa_sign.c */ +/* ==================================================================== + * 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif + +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) +{ + return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); +} + +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return NULL; + return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey); +} + +int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, EC_KEY *eckey) +{ + return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); +} + +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, const BIGNUM *kinv, const BIGNUM *r, + EC_KEY *eckey) +{ + ECDSA_SIG *s; + s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); + if (s == NULL) + { + *siglen=0; + return 0; + } + *siglen = i2d_ECDSA_SIG(s, &sig); + ECDSA_SIG_free(s); + return 1; +} + +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return 0; + return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); +} diff --git a/openssl/crypto/ecdsa/ecs_vrf.c b/openssl/crypto/ecdsa/ecs_vrf.c new file mode 100644 index 000000000..ef9acf7b6 --- /dev/null +++ b/openssl/crypto/ecdsa/ecs_vrf.c @@ -0,0 +1,96 @@ +/* crypto/ecdsa/ecdsa_vrf.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * 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 + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +#include <openssl/engine.h> +#endif + +/* returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) + { + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return 0; + return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); + } + +/* returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) + { + ECDSA_SIG *s; + int ret=-1; + + s = ECDSA_SIG_new(); + if (s == NULL) return(ret); + if (d2i_ECDSA_SIG(&s, &sigbuf, sig_len) == NULL) goto err; + ret=ECDSA_do_verify(dgst, dgst_len, s, eckey); +err: + ECDSA_SIG_free(s); + return(ret); + } |