summaryrefslogtreecommitdiffstats
path: root/crypto/ecdsa
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2012-06-27 16:44:58 +0000
committerjkim <jkim@FreeBSD.org>2012-06-27 16:44:58 +0000
commit1554498e64df093a519f9074c3412047f398aa17 (patch)
treecc5cd6657453d80b7eafb3ba5cc4ef4fd66c176f /crypto/ecdsa
parentae03beb758270fb19d741c93f7bfde88a6635612 (diff)
downloadFreeBSD-src-1554498e64df093a519f9074c3412047f398aa17.zip
FreeBSD-src-1554498e64df093a519f9074c3412047f398aa17.tar.gz
Import OpenSSL 0.9.8x.
Diffstat (limited to 'crypto/ecdsa')
-rw-r--r--crypto/ecdsa/ecdsatest.c91
-rw-r--r--crypto/ecdsa/ecs_ossl.c8
2 files changed, 89 insertions, 10 deletions
diff --git a/crypto/ecdsa/ecdsatest.c b/crypto/ecdsa/ecdsatest.c
index b07e312..1ad507d 100644
--- a/crypto/ecdsa/ecdsatest.c
+++ b/crypto/ecdsa/ecdsatest.c
@@ -168,10 +168,9 @@ int fbytes(unsigned char *buf, int num)
return 0;
}
fbytes_counter ++;
- ret = BN_bn2bin(tmp, buf);
- if (ret == 0 || ret != num)
+ if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf))
ret = 0;
- else
+ else
ret = 1;
if (tmp)
BN_free(tmp);
@@ -287,9 +286,13 @@ int test_builtin(BIO *out)
size_t crv_len = 0, n = 0;
EC_KEY *eckey = NULL, *wrong_eckey = NULL;
EC_GROUP *group;
+ ECDSA_SIG *ecdsa_sig = NULL;
unsigned char digest[20], wrong_digest[20];
- unsigned char *signature = NULL;
- unsigned int sig_len;
+ unsigned char *signature = NULL;
+ const unsigned char *sig_ptr;
+ unsigned char *sig_ptr2;
+ unsigned char *raw_buf = NULL;
+ unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len;
int nid, ret = 0;
/* fill digest values with some random data */
@@ -339,7 +342,8 @@ int test_builtin(BIO *out)
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)
+ degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey));
+ if (degree < 160)
/* drop the curve */
{
EC_KEY_free(eckey);
@@ -415,26 +419,89 @@ int test_builtin(BIO *out)
}
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;
+ /* wrong length */
+ if (ECDSA_verify(0, digest, 20, signature, sig_len - 1,
+ eckey) == 1)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ BIO_printf(out, ".");
+ (void)BIO_flush(out);
+
+ /* Modify a single byte of the signature: to ensure we don't
+ * garble the ASN1 structure, we read the raw signature and
+ * modify a byte in one of the bignums directly. */
+ sig_ptr = signature;
+ if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL)
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+
+ /* Store the two BIGNUMs in raw_buf. */
+ r_len = BN_num_bytes(ecdsa_sig->r);
+ s_len = BN_num_bytes(ecdsa_sig->s);
+ bn_len = (degree + 7) / 8;
+ if ((r_len > bn_len) || (s_len > bn_len))
+ {
+ BIO_printf(out, " failed\n");
+ goto builtin_err;
+ }
+ buf_len = 2 * bn_len;
+ if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL)
+ goto builtin_err;
+ /* Pad the bignums with leading zeroes. */
+ memset(raw_buf, 0, buf_len);
+ BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len);
+ BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len);
+
+ /* Modify a single byte in the buffer. */
+ offset = raw_buf[10] % buf_len;
+ dirt = raw_buf[11] ? raw_buf[11] : 1;
+ raw_buf[offset] ^= dirt;
+ /* Now read the BIGNUMs back in from raw_buf. */
+ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+ (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+ goto builtin_err;
+
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1)
{
BIO_printf(out, " failed\n");
goto builtin_err;
}
+ /* Sanity check: undo the modification and verify signature. */
+ raw_buf[offset] ^= dirt;
+ if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) ||
+ (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL))
+ goto builtin_err;
+
+ sig_ptr2 = signature;
+ sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2);
+ 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 */
+ /* clean bogus errors */
+ ERR_clear_error();
OPENSSL_free(signature);
signature = NULL;
EC_KEY_free(eckey);
eckey = NULL;
EC_KEY_free(wrong_eckey);
wrong_eckey = NULL;
+ ECDSA_SIG_free(ecdsa_sig);
+ ecdsa_sig = NULL;
+ OPENSSL_free(raw_buf);
+ raw_buf = NULL;
}
ret = 1;
@@ -443,8 +510,12 @@ builtin_err:
EC_KEY_free(eckey);
if (wrong_eckey)
EC_KEY_free(wrong_eckey);
+ if (ecdsa_sig)
+ ECDSA_SIG_free(ecdsa_sig);
if (signature)
OPENSSL_free(signature);
+ if (raw_buf)
+ OPENSSL_free(raw_buf);
if (curves)
OPENSSL_free(curves);
diff --git a/crypto/ecdsa/ecs_ossl.c b/crypto/ecdsa/ecs_ossl.c
index 551cf50..1bbf328 100644
--- a/crypto/ecdsa/ecs_ossl.c
+++ b/crypto/ecdsa/ecs_ossl.c
@@ -144,6 +144,14 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
}
while (BN_is_zero(k));
+ /* We do not want timing information to leak the length of k,
+ * so we compute G*k using an equivalent scalar of fixed
+ * bit-length. */
+
+ if (!BN_add(k, k, order)) goto err;
+ if (BN_num_bits(k) <= BN_num_bits(order))
+ if (!BN_add(k, k, order)) goto err;
+
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx))
{
OpenPOWER on IntegriCloud