Test ECDSA_do_sign/ECDSA_do_verify like ECDSA_sign/ECDSA_verify.

Change-Id: I6f2b685f9a2c7a921bc0705e0b9ff3dba38fdeab
Reviewed-on: https://boringssl-review.googlesource.com/3935
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
Brian Smith 2015-03-14 18:42:41 -10:00 committed by Adam Langley
parent 1f0d2ef3c4
commit 655764a22a

View File

@ -60,41 +60,53 @@
#include <openssl/obj.h>
#include <openssl/rand.h>
typedef enum api_t {
encoded_api,
raw_api,
};
/* verify_ecdsa_sig returns 1 on success, 0 on failure. */
static int verify_ecdsa_sig(const uint8_t *digest, size_t digest_len,
const ECDSA_SIG *ecdsa_sig, EC_KEY *eckey,
int expected_result) {
int ret = 0;
static int verify_ecdsa_sig(enum api_t api, const uint8_t *digest,
size_t digest_len, const ECDSA_SIG *ecdsa_sig,
EC_KEY *eckey, int expected_result) {
int actual_result;
int sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL);
if (sig_len <= 0) {
return 0;
}
uint8_t *signature = OPENSSL_malloc(sig_len);
if (signature == NULL) {
return 0;
}
uint8_t *sig_ptr = signature;
sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
if (sig_len <= 0) {
goto err;
}
int actual_result = ECDSA_verify(0, digest, digest_len, signature, sig_len,
switch (api) {
case encoded_api: {
int sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL);
if (sig_len <= 0) {
return 0;
}
uint8_t *signature = OPENSSL_malloc(sig_len);
if (signature == NULL) {
return 0;
}
uint8_t *sig_ptr = signature;
sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
if (sig_len <= 0) {
OPENSSL_free(signature);
return 0;
}
actual_result = ECDSA_verify(0, digest, digest_len, signature, sig_len,
eckey);
if (expected_result != actual_result) {
goto err;
}
OPENSSL_free(signature);
break;
}
ret = 1;
err:
OPENSSL_free(signature);
return ret;
case raw_api:
actual_result = ECDSA_do_verify(digest, digest_len, ecdsa_sig, eckey);
break;
default:
return 0;
}
return expected_result == actual_result;
}
/* test_tampered_sig verifies that signature verification fails when a valid
* signature is tampered with. |ecdsa_sig| must be a valid signature, which
* will be modified. test_tampered_sig returns 1 on success, 0 on failure. */
static int test_tampered_sig(FILE *out, const uint8_t *digest,
static int test_tampered_sig(FILE *out, enum api_t api, const uint8_t *digest,
size_t digest_len, ECDSA_SIG *ecdsa_sig,
EC_KEY *eckey, const BIGNUM *order) {
int ret = 0;
@ -128,7 +140,7 @@ static int test_tampered_sig(FILE *out, const uint8_t *digest,
/* 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 ||
!verify_ecdsa_sig(digest, digest_len, ecdsa_sig, eckey, 0)) {
!verify_ecdsa_sig(api, digest, digest_len, ecdsa_sig, eckey, 0)) {
goto err;
}
@ -136,7 +148,7 @@ static int test_tampered_sig(FILE *out, const uint8_t *digest,
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 ||
!verify_ecdsa_sig(digest, digest_len, ecdsa_sig, eckey, 1)) {
!verify_ecdsa_sig(api, digest, digest_len, ecdsa_sig, eckey, 1)) {
goto err;
}
@ -156,8 +168,6 @@ static int test_builtin(FILE *out) {
ECDSA_SIG *ecdsa_sig = NULL;
uint8_t digest[20], wrong_digest[20];
uint8_t *signature = NULL;
const uint8_t *sig_ptr;
unsigned sig_len;
int nid, ret = 0;
/* fill digest values with some random data */
@ -171,10 +181,9 @@ static int test_builtin(FILE *out) {
goto builtin_err;
}
/* create and verify a ecdsa signature with every availble curve
* (with ) */
fprintf(out, "\ntesting ECDSA_sign() and ECDSA_verify() "
"with some internal curves:\n");
/* Create and verify ecdsa signatures with every available curve. */
fputs("\ntesting ECDSA_sign(), ECDSA_verify(), ECDSA_do_sign(), and "
"ECDSA_do_verify() with some internal curves:\n", out);
static const struct
{
@ -248,8 +257,10 @@ static int test_builtin(FILE *out) {
}
fprintf(out, ".");
fflush(out);
/* create signature */
sig_len = ECDSA_size(eckey);
/* Test ASN.1-encoded signatures. */
/* Create a signature. */
unsigned sig_len = ECDSA_size(eckey);
signature = OPENSSL_malloc(sig_len);
if (signature == NULL) {
goto builtin_err;
@ -288,14 +299,55 @@ static int test_builtin(FILE *out) {
}
fprintf(out, ".");
fflush(out);
/* Tampering with a signature causes verification to fail. */
sig_ptr = signature;
/* Verify a tampered signature. */
const uint8_t *sig_ptr = signature;
ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len);
if (ecdsa_sig == NULL) {
fprintf(out, " failed\n");
goto builtin_err;
}
if (!test_tampered_sig(out, digest, 20, ecdsa_sig, eckey, order)) {
if (!test_tampered_sig(out, encoded_api, digest, 20, ecdsa_sig, eckey,
order)) {
fprintf(out, " failed\n");
goto builtin_err;
}
fprintf(out, ".");
fflush(out);
OPENSSL_free(signature);
signature = NULL;
/* Test ECDSA_SIG signing and verification. */
/* Create a signature. */
ecdsa_sig = ECDSA_do_sign(digest, 20, eckey);
if (!ecdsa_sig) {
fprintf(out, " failed\n");
goto builtin_err;
}
fprintf(out, ".");
fflush(out);
/* Verify the signature using the correct key. */
if (!ECDSA_do_verify(digest, 20, ecdsa_sig, eckey)) {
fprintf(out, " failed\n");
goto builtin_err;
}
fprintf(out, ".");
fflush(out);
/* Verify the signature with the wrong key. */
if (ECDSA_do_verify(digest, 20, ecdsa_sig, wrong_eckey)) {
fprintf(out, " failed\n");
goto builtin_err;
}
fprintf(out, ".");
fflush(out);
/* Verify the signature using the wrong digest. */
if (ECDSA_do_verify(wrong_digest, 20, ecdsa_sig, eckey)) {
fprintf(out, " failed\n");
goto builtin_err;
}
fprintf(out, ".");
fflush(out);
/* Verify a tampered signature. */
if (!test_tampered_sig(out, raw_api, digest, 20, ecdsa_sig, eckey, order)) {
fprintf(out, " failed\n");
goto builtin_err;
}
@ -306,8 +358,6 @@ static int test_builtin(FILE *out) {
/* cleanup */
/* clean bogus errors */
ERR_clear_error();
OPENSSL_free(signature);
signature = NULL;
EC_KEY_free(eckey);
eckey = NULL;
EC_KEY_free(wrong_eckey);