summaryrefslogtreecommitdiffstats
path: root/lib/libcrypto/ecdsa
diff options
context:
space:
mode:
authordjm <djm@openbsd.org>2010-10-01 22:54:00 +0000
committerdjm <djm@openbsd.org>2010-10-01 22:54:00 +0000
commitf1535dc82c407426dcbc37ddee0ceff3f0c94865 (patch)
treef73777171acb436d21ef5cb0f2cd241a939ab7f8 /lib/libcrypto/ecdsa
parent- document new MODCPAN_MODULES (diff)
downloadwireguard-openbsd-f1535dc82c407426dcbc37ddee0ceff3f0c94865.tar.xz
wireguard-openbsd-f1535dc82c407426dcbc37ddee0ceff3f0c94865.zip
import OpenSSL-1.0.0a
Diffstat (limited to 'lib/libcrypto/ecdsa')
-rw-r--r--lib/libcrypto/ecdsa/ecdsa.h193
-rw-r--r--lib/libcrypto/ecdsa/ecdsatest.c2
-rw-r--r--lib/libcrypto/ecdsa/ecs_err.c2
-rw-r--r--lib/libcrypto/ecdsa/ecs_ossl.c54
-rw-r--r--lib/libcrypto/ecdsa/ecs_sign.c2
5 files changed, 118 insertions, 135 deletions
diff --git a/lib/libcrypto/ecdsa/ecdsa.h b/lib/libcrypto/ecdsa/ecdsa.h
index f20c8ee7381..e61c539812a 100644
--- a/lib/libcrypto/ecdsa/ecdsa.h
+++ b/lib/libcrypto/ecdsa/ecdsa.h
@@ -4,7 +4,7 @@
* \author Written by Nils Larsch for the OpenSSL project
*/
/* ====================================================================
- * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved.
+ * 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
@@ -81,156 +81,143 @@ typedef struct ECDSA_SIG_st
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
+/** 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
+/** frees a ECDSA_SIG structure
+ * \param sig pointer to the ECDSA_SIG structure
*/
-void ECDSA_SIG_free(ECDSA_SIG *a);
+void ECDSA_SIG_free(ECDSA_SIG *sig);
-/** 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
+/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
+ * (*pp += length of the DER encoded signature)).
+ * \param sig 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);
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, 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)
+/** Decodes a DER encoded ECDSA signature (note: this function changes *pp
+ * (*pp += len)).
+ * \param sig pointer to ECDSA_SIG pointer (may be NULL)
+ * \param pp memory buffer with the DER encoded signature
+ * \param len length of the buffer
+ * \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_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, 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
+/** 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 EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
*/
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
+/** 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 BIGNUM with a pre-computed inverse k (optional)
+ * \param rp BIGNUM with a pre-computed rp value (optioanl),
+ * see ECDSA_sign_setup
+ * \param eckey EC_KEY object containing a private EC key
+ * \return pointer to a ECDSA_SIG structure or NULL if an error occurred
*/
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
+/** 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 ECDSA_SIG structure
+ * \param eckey 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
+/** Sets the default ECDSA method
+ * \param meth 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
+/** 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
+/** Sets method to be used for the ECDSA operations
+ * \param eckey EC_KEY object
+ * \param meth 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
+/** Returns the maximum length of the DER encoded signature
+ * \param eckey 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
+/** Precompute parts of the signing operation
+ * \param eckey EC_KEY object containing a private EC key
+ * \param ctx BN_CTX object (optional)
+ * \param kinv BIGNUM pointer for the inverse of k
+ * \param rp 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
+/** 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 memory for the DER encoded created signature
+ * \param siglen pointer to the length of the returned signature
+ * \param eckey 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
+/** 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 BIGNUM with a pre-computed inverse k (optional)
+ * \param rp BIGNUM with a pre-computed rp value (optioanl),
+ * see ECDSA_sign_setup
+ * \param eckey 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
+/** 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 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);
diff --git a/lib/libcrypto/ecdsa/ecdsatest.c b/lib/libcrypto/ecdsa/ecdsatest.c
index b07e31252b9..aa4e1481a8f 100644
--- a/lib/libcrypto/ecdsa/ecdsatest.c
+++ b/lib/libcrypto/ecdsa/ecdsatest.c
@@ -490,7 +490,7 @@ err:
if (ret)
ERR_print_errors(out);
CRYPTO_cleanup_all_ex_data();
- ERR_remove_state(0);
+ ERR_remove_thread_state(NULL);
ERR_free_strings();
CRYPTO_mem_leaks(out);
if (out != NULL)
diff --git a/lib/libcrypto/ecdsa/ecs_err.c b/lib/libcrypto/ecdsa/ecs_err.c
index d2a53730ea5..98e38d537f2 100644
--- a/lib/libcrypto/ecdsa/ecs_err.c
+++ b/lib/libcrypto/ecdsa/ecs_err.c
@@ -1,6 +1,6 @@
/* crypto/ecdsa/ecs_err.c */
/* ====================================================================
- * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2006 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
diff --git a/lib/libcrypto/ecdsa/ecs_ossl.c b/lib/libcrypto/ecdsa/ecs_ossl.c
index 3ead1af94e7..551cf5068fa 100644
--- a/lib/libcrypto/ecdsa/ecs_ossl.c
+++ b/lib/libcrypto/ecdsa/ecs_ossl.c
@@ -212,7 +212,7 @@ err:
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;
+ int ok = 0, i;
BIGNUM *kinv=NULL, *s, *m=NULL,*tmp=NULL,*order=NULL;
const BIGNUM *ckinv;
BN_CTX *ctx = NULL;
@@ -251,22 +251,19 @@ static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len,
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB);
goto err;
}
- if (8 * dgst_len > BN_num_bits(order))
+ i = BN_num_bits(order);
+ /* Need to truncate digest if it is too long: first truncate whole
+ * bytes.
+ */
+ if (8 * dgst_len > i)
+ dgst_len = (i + 7)/8;
+ if (!BN_bin2bn(dgst, dgst_len, m))
{
- /* 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);
+ ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
}
-
- if (!BN_bin2bn(dgst, dgst_len, m))
+ /* If still too long truncate remaining bits with a shift */
+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
{
ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB);
goto err;
@@ -346,7 +343,7 @@ err:
static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
const ECDSA_SIG *sig, EC_KEY *eckey)
{
- int ret = -1;
+ int ret = -1, i;
BN_CTX *ctx;
BIGNUM *order, *u1, *u2, *m, *X;
EC_POINT *point = NULL;
@@ -384,21 +381,6 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
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) ||
@@ -415,11 +397,23 @@ static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len,
goto err;
}
/* digest -> m */
+ i = BN_num_bits(order);
+ /* Need to truncate digest if it is too long: first truncate whole
+ * bytes.
+ */
+ if (8 * dgst_len > i)
+ dgst_len = (i + 7)/8;
if (!BN_bin2bn(dgst, dgst_len, m))
{
ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB);
goto err;
}
+ /* If still too long truncate remaining bits with a shift */
+ if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7)))
+ {
+ 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))
{
diff --git a/lib/libcrypto/ecdsa/ecs_sign.c b/lib/libcrypto/ecdsa/ecs_sign.c
index 74b1fe8caff..353d5af5146 100644
--- a/lib/libcrypto/ecdsa/ecs_sign.c
+++ b/lib/libcrypto/ecdsa/ecs_sign.c
@@ -57,6 +57,7 @@
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
+#include <openssl/rand.h>
ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey)
{
@@ -83,6 +84,7 @@ int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char
EC_KEY *eckey)
{
ECDSA_SIG *s;
+ RAND_seed(dgst, dlen);
s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey);
if (s == NULL)
{