summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBilly Brumley <bbrumley@gmail.com>2019-02-23 10:12:35 +0200
committerNicola Tuveri <nic.tuv@gmail.com>2019-02-26 17:59:51 +0200
commit1a31d8017ee7e8df0eca76fee601b826699c9ac1 (patch)
tree93d7d0bd2a6215d6a52bda00e0ff36830a346af5
parentb3883f77df33989b0d4298ca9a21d8595dd9a8c9 (diff)
[test] modernize ecdsatest and extend ECDSA sign KATs
Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/8314)
-rw-r--r--test/ecdsatest.c538
-rw-r--r--test/ecdsatest.h10214
2 files changed, 10448 insertions, 304 deletions
diff --git a/test/ecdsatest.c b/test/ecdsatest.c
index bc3adc004c..03327a23dc 100644
--- a/test/ecdsatest.c
+++ b/test/ecdsatest.c
@@ -8,32 +8,27 @@
* https://www.openssl.org/source/license.html
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_EC is defined */
#include "testutil.h"
#ifndef OPENSSL_NO_EC
-# include <openssl/crypto.h>
-# include <openssl/bio.h>
# include <openssl/evp.h>
# include <openssl/bn.h>
# include <openssl/ec.h>
-# ifndef OPENSSL_NO_ENGINE
-# include <openssl/engine.h>
-# endif
-# include <openssl/sha.h>
-# include <openssl/err.h>
# include <openssl/rand.h>
+# include "internal/nelem.h"
+# include "ecdsatest.h"
/* functions to change the RAND_METHOD */
static int fbytes(unsigned char *buf, int num);
static RAND_METHOD fake_rand;
static const RAND_METHOD *old_rand;
+static int use_fake = 0;
+static const char *numbers[2];
+static size_t crv_len = 0;
+static EC_builtin_curve *curves = NULL;
static int change_rand(void)
{
@@ -57,25 +52,10 @@ static int restore_rand(void)
return 1;
}
-static int fbytes_counter = 0, use_fake = 0;
-static const char *numbers[8] = {
- "651056770906015076056810763456358567190100156695615665659",
- "6140507067065001063065065565667405560006161556565665656654",
- "8763001015071075675010661307616710783570106710677817767166"
- "71676178726717",
- "7000000175690566466555057817571571075705015757757057795755"
- "55657156756655",
- "1275552191113212300012030439187146164646146646466749494799",
- "1542725565216523985789236956265265265235675811949404040041",
- "1456427555219115346513212300075341203043918714616464614664"
- "64667494947990",
- "1712787255652165239672857892369562652652652356758119494040"
- "40041670216363"
-};
-
static int fbytes(unsigned char *buf, int num)
{
int ret = 0;
+ static int fbytes_counter = 0;
BIGNUM *tmp = NULL;
if (use_fake == 0)
@@ -83,316 +63,254 @@ static int fbytes(unsigned char *buf, int num)
use_fake = 0;
- if (fbytes_counter >= 8)
- return 0;
- if (!TEST_ptr(tmp = BN_new()))
- return 0;
- if (!TEST_true(BN_dec2bn(&tmp, numbers[fbytes_counter]))) {
- BN_free(tmp);
- return 0;
- }
- fbytes_counter++;
- if (TEST_int_eq(BN_num_bytes(tmp), num)
- && TEST_true(BN_bn2bin(tmp, buf)))
- ret = 1;
+ if (!TEST_ptr(tmp = BN_new())
+ || !TEST_int_lt(fbytes_counter, OSSL_NELEM(numbers))
+ || !TEST_true(BN_hex2bn(&tmp, numbers[fbytes_counter]))
+ /* tmp might need leading zeros so pad it out */
+ || !TEST_int_le(BN_num_bytes(tmp), num)
+ || !TEST_true(BN_bn2binpad(tmp, buf, num)))
+ goto err;
+
+ fbytes_counter = (fbytes_counter + 1) % OSSL_NELEM(numbers);
+ ret = 1;
+ err:
BN_free(tmp);
return ret;
}
-/* some tests from the X9.62 draft */
-static int x9_62_test_internal(int nid, const char *r_in, const char *s_in)
+/*-
+ * This function hijacks the RNG to feed it the chosen ECDSA key and nonce.
+ * The ECDSA KATs are from:
+ * - the X9.62 draft (4)
+ * - NIST CAVP (720)
+ *
+ * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG.
+ * NB: This is not how applications should use ECDSA; this is only for testing.
+ *
+ * Tests the library can successfully:
+ * - generate public keys that matches those KATs
+ * - create ECDSA signatures that match those KATs
+ * - accept those signatures as valid
+ */
+static int x9_62_tests(int n)
{
- int ret = 0;
- const char message[] = "abc";
- unsigned char digest[SHA_DIGEST_LENGTH];
+ int nid, md_nid, ret = 0;
+ const char *r_in = NULL, *s_in = NULL, *tbs = NULL;
+ unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL;
+ unsigned char digest[EVP_MAX_MD_SIZE];
unsigned int dgst_len = 0;
- EVP_MD_CTX *md_ctx;
+ long q_len, msg_len = 0;
+ size_t p_len;
+ EVP_MD_CTX *mctx = NULL;
EC_KEY *key = NULL;
ECDSA_SIG *signature = NULL;
BIGNUM *r = NULL, *s = NULL;
BIGNUM *kinv = NULL, *rp = NULL;
- const BIGNUM *sig_r, *sig_s;
-
- if (!TEST_ptr(md_ctx = EVP_MD_CTX_new()))
- goto x962_int_err;
-
- /* get the message digest */
- if (!TEST_true(EVP_DigestInit(md_ctx, EVP_sha1()))
- || !TEST_true(EVP_DigestUpdate(md_ctx, (const void *)message, 3))
- || !TEST_true(EVP_DigestFinal(md_ctx, digest, &dgst_len)))
- goto x962_int_err;
-
- TEST_info("testing %s", OBJ_nid2sn(nid));
-
- /* create the key */
- if (!TEST_ptr(key = EC_KEY_new_by_curve_name(nid)))
- goto x962_int_err;
+ const BIGNUM *sig_r = NULL, *sig_s = NULL;
+
+ nid = ecdsa_cavs_kats[n].nid;
+ md_nid = ecdsa_cavs_kats[n].md_nid;
+ r_in = ecdsa_cavs_kats[n].r;
+ s_in = ecdsa_cavs_kats[n].s;
+ tbs = ecdsa_cavs_kats[n].msg;
+ numbers[0] = ecdsa_cavs_kats[n].d;
+ numbers[1] = ecdsa_cavs_kats[n].k;
+
+ TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid));
+
+ if (!TEST_ptr(mctx = EVP_MD_CTX_new())
+ /* get the message digest */
+ || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len))
+ || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL))
+ || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len))
+ || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len))
+ /* create the key */
+ || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid))
+ /* load KAT variables */
+ || !TEST_ptr(r = BN_new())
+ || !TEST_ptr(s = BN_new())
+ || !TEST_true(BN_hex2bn(&r, r_in))
+ || !TEST_true(BN_hex2bn(&s, s_in))
+ /* swap the RNG source */
+ || !TEST_true(change_rand()))
+ goto err;
+
+ /* public key must match KAT */
use_fake = 1;
- if (!TEST_true(EC_KEY_generate_key(key)))
- goto x962_int_err;
-
- /* create the signature */
+ if (!TEST_true(EC_KEY_generate_key(key))
+ || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED,
+ &pbuf, NULL))
+ || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len))
+ || !TEST_int_eq(q_len, p_len)
+ || !TEST_mem_eq(qbuf, q_len, pbuf, p_len))
+ goto err;
+
+ /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */
use_fake = 1;
- /* Use ECDSA_sign_setup to avoid use of ECDSA nonces */
- if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp)))
- goto x962_int_err;
- if (!TEST_ptr(signature =
- ECDSA_do_sign_ex(digest, SHA_DIGEST_LENGTH, kinv, rp, key)))
- goto x962_int_err;
+ if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp))
+ || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len,
+ kinv, rp, key))
+ /* verify the signature */
+ || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1))
+ goto err;
/* compare the created signature with the expected signature */
- if (!TEST_ptr(r = BN_new()) || !TEST_ptr(s = BN_new()))
- goto x962_int_err;
- if (!TEST_true(BN_dec2bn(&r, r_in)) || !TEST_true(BN_dec2bn(&s, s_in)))
- goto x962_int_err;
ECDSA_SIG_get0(signature, &sig_r, &sig_s);
if (!TEST_BN_eq(sig_r, r)
- || !TEST_BN_eq(sig_s, s))
- goto x962_int_err;
-
- /* verify the signature */
- if (!TEST_int_eq(ECDSA_do_verify(digest, SHA_DIGEST_LENGTH,
- signature, key), 1))
- goto x962_int_err;
+ || !TEST_BN_eq(sig_s, s))
+ goto err;
ret = 1;
- x962_int_err:
+ err:
+ /* restore the RNG source */
+ if (!TEST_true(restore_rand()))
+ ret = 0;
+
+ OPENSSL_free(message);
+ OPENSSL_free(pbuf);
+ OPENSSL_free(qbuf);
EC_KEY_free(key);
ECDSA_SIG_free(signature);
BN_free(r);
BN_free(s);
- EVP_MD_CTX_free(md_ctx);
+ EVP_MD_CTX_free(mctx);
BN_clear_free(kinv);
BN_clear_free(rp);
return ret;
}
-static int x9_62_tests(void)
-{
- int ret = 0;
-
- /* set own rand method */
- if (!change_rand())
- goto x962_err;
-
- if (!TEST_true(x9_62_test_internal(NID_X9_62_prime192v1,
- "3342403536405981729393488334694600415596881826869351677613",
- "5735822328888155254683894997897571951568553642892029982342")))
- goto x962_err;
- if (!TEST_true(x9_62_test_internal(NID_X9_62_prime239v1,
- "3086361431751678114926225473006680188549593787585317781474"
- "62058306432176",
- "3238135532097973577080787768312505059318910517550078427819"
- "78505179448783")))
- goto x962_err;
-
-# ifndef OPENSSL_NO_EC2M
- if (!TEST_true(x9_62_test_internal(NID_X9_62_c2tnb191v1,
- "87194383164871543355722284926904419997237591535066528048",
- "308992691965804947361541664549085895292153777025772063598")))
- goto x962_err;
- if (!TEST_true(x9_62_test_internal(NID_X9_62_c2tnb239v1,
- "2159633321041961198501834003903461262881815148684178964245"
- "5876922391552",
- "1970303740007316867383349976549972270528498040721988191026"
- "49413465737174")))
- goto x962_err;
-# endif
- ret = 1;
-
- x962_err:
- if (!TEST_true(restore_rand()))
- ret = 0;
- return ret;
-}
-
-static int test_builtin(void)
+/*-
+ * Positive and negative ECDSA testing through EVP interface:
+ * - EVP_DigestSign (this is the one-shot version)
+ * - EVP_DigestVerify
+ *
+ * Tests the library can successfully:
+ * - create a key
+ * - create a signature
+ * - accept that signature
+ * - reject that signature with a different public key
+ * - reject that signature if its length is not correct
+ * - reject that signature after modifying the message
+ * - accept that signature after un-modifying the message
+ * - reject that signature after modifying the signature
+ * - accept that signature after un-modifying the signature
+ */
+static int test_builtin(int n)
{
- EC_builtin_curve *curves = NULL;
- size_t crv_len = 0, n = 0;
- EC_KEY *eckey = NULL, *wrong_eckey = NULL;
- EC_GROUP *group;
- ECDSA_SIG *ecdsa_sig = NULL, *modified_sig = NULL;
- unsigned char digest[SHA512_DIGEST_LENGTH];
- unsigned char wrong_digest[SHA512_DIGEST_LENGTH];
- unsigned char *signature = NULL;
- const unsigned char *sig_ptr;
- unsigned char *sig_ptr2;
- unsigned char *raw_buf = NULL;
- const BIGNUM *sig_r, *sig_s;
- BIGNUM *modified_r = NULL, *modified_s = NULL;
- BIGNUM *unmodified_r = NULL, *unmodified_s = NULL;
- unsigned int sig_len, order, r_len, s_len, bn_len, buf_len;
+ EC_KEY *eckey_neg = NULL, *eckey = NULL;
+ unsigned char dirt, offset, tbs[128];
+ unsigned char *sig = NULL;
+ EVP_PKEY *pkey_neg = NULL, *pkey = NULL;
+ EVP_MD_CTX *mctx = NULL;
+ size_t sig_len;
int nid, ret = 0;
- /* fill digest values with some random data */
- if (!TEST_true(RAND_bytes(digest, SHA512_DIGEST_LENGTH))
- || !TEST_true(RAND_bytes(wrong_digest, SHA512_DIGEST_LENGTH)))
- goto builtin_err;
+ nid = curves[n].nid;
- /* create and verify a ecdsa signature with every available curve */
- /* get a list of all internal curves */
- crv_len = EC_get_builtin_curves(NULL, 0);
- if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
- || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
- 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 || nid == NID_ipsec3)
- continue;
- /* create new ecdsa key (== EC_KEY) */
- if (!TEST_ptr(eckey = EC_KEY_new())
- || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
- || !TEST_true(EC_KEY_set_group(eckey, group)))
- goto builtin_err;
- EC_GROUP_free(group);
- order = EC_GROUP_order_bits(EC_KEY_get0_group(eckey));
-
- TEST_info("testing %s", OBJ_nid2sn(nid));
-
- /* create key */
- if (!TEST_true(EC_KEY_generate_key(eckey)))
- goto builtin_err;
- /* create second key */
- if (!TEST_ptr(wrong_eckey = EC_KEY_new())
- || !TEST_ptr(group = EC_GROUP_new_by_curve_name(nid))
- || !TEST_true(EC_KEY_set_group(wrong_eckey, group)))
- goto builtin_err;
- EC_GROUP_free(group);
- if (!TEST_true(EC_KEY_generate_key(wrong_eckey)))
- goto builtin_err;
-
- /* check key */
- if (!TEST_true(EC_KEY_check_key(eckey)))
- goto builtin_err;
-
- /* create signature */
- sig_len = ECDSA_size(eckey);
- if (!TEST_ptr(signature = OPENSSL_malloc(sig_len))
- || !TEST_true(ECDSA_sign(0, digest, SHA512_DIGEST_LENGTH,
- signature, &sig_len, eckey)))
- goto builtin_err;
-
- /* verify signature */
- if (!TEST_int_eq(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH,
- signature, sig_len, eckey),
- 1))
- goto builtin_err;
-
- /* verify signature with the wrong key */
- if (!TEST_int_ne(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH,
- signature, sig_len, wrong_eckey),
- 1))
- goto builtin_err;
-
- /* wrong digest */
- if (!TEST_int_ne(ECDSA_verify(0, wrong_digest, SHA512_DIGEST_LENGTH,
- signature, sig_len, eckey),
- 1))
- goto builtin_err;
-
- /* wrong length */
- if (!TEST_int_ne(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH,
- signature, sig_len - 1, eckey),
- 1))
- goto builtin_err;
-
- /*
- * 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 (!TEST_ptr(ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)))
- goto builtin_err;
-
- ECDSA_SIG_get0(ecdsa_sig, &sig_r, &sig_s);
-
- /* Store the two BIGNUMs in raw_buf. */
- r_len = BN_num_bytes(sig_r);
- s_len = BN_num_bytes(sig_s);
- bn_len = (order + 7) / 8;
- if (!TEST_false(r_len > bn_len)
- || !TEST_false(s_len > bn_len))
- goto builtin_err;
- buf_len = 2 * bn_len;
- if (!TEST_ptr(raw_buf = OPENSSL_zalloc(buf_len)))
- goto builtin_err;
- BN_bn2bin(sig_r, raw_buf + bn_len - r_len);
- BN_bn2bin(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 (!TEST_ptr(modified_sig = ECDSA_SIG_new()))
- goto builtin_err;
- if (!TEST_ptr(modified_r = BN_bin2bn(raw_buf, bn_len, NULL))
- || !TEST_ptr(modified_s = BN_bin2bn(raw_buf + bn_len,
- bn_len, NULL))
- || !TEST_true(ECDSA_SIG_set0(modified_sig,
- modified_r, modified_s))) {
- BN_free(modified_r);
- BN_free(modified_s);
- goto builtin_err;
- }
- sig_ptr2 = signature;
- sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);
- if (!TEST_false(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH,
- signature, sig_len, eckey)))
- goto builtin_err;
-
- /* Sanity check: undo the modification and verify signature. */
- raw_buf[offset] ^= dirt;
- if (!TEST_ptr(unmodified_r = BN_bin2bn(raw_buf, bn_len, NULL))
- || !TEST_ptr(unmodified_s = BN_bin2bn(raw_buf + bn_len,
- bn_len, NULL))
- || !TEST_true(ECDSA_SIG_set0(modified_sig, unmodified_r,
- unmodified_s))) {
- BN_free(unmodified_r);
- BN_free(unmodified_s);
- goto builtin_err;
- }
-
- sig_ptr2 = signature;
- sig_len = i2d_ECDSA_SIG(modified_sig, &sig_ptr2);
- if (!TEST_true(ECDSA_verify(0, digest, SHA512_DIGEST_LENGTH,
- signature, sig_len, eckey)))
- goto builtin_err;
-
- /* cleanup */
- 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;
- ECDSA_SIG_free(modified_sig);
- modified_sig = NULL;
- OPENSSL_free(raw_buf);
- raw_buf = NULL;
+ /* skip built-in curves where ord(G) is not prime */
+ if (nid == NID_ipsec4 || nid == NID_ipsec3) {
+ TEST_info("skipped: ECDSA unsupported for curve %s", OBJ_nid2sn(nid));
+ return 1;
}
- ret = 1;
- builtin_err:
- EC_KEY_free(eckey);
- EC_KEY_free(wrong_eckey);
- ECDSA_SIG_free(ecdsa_sig);
- ECDSA_SIG_free(modified_sig);
- OPENSSL_free(signature);
- OPENSSL_free(raw_buf);
- OPENSSL_free(curves);
+ TEST_info("testing ECDSA for curve %s", OBJ_nid2sn(nid));
+
+ if (!TEST_ptr(mctx = EVP_MD_CTX_new())
+ /* get some random message data */
+ || !TEST_true(RAND_bytes(tbs, sizeof(tbs)))
+ /* real key */
+ || !TEST_ptr(eckey = EC_KEY_new_by_curve_name(nid))
+ || !TEST_true(EC_KEY_generate_key(eckey))
+ || !TEST_ptr(pkey = EVP_PKEY_new())
+ || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))
+ /* fake key for negative testing */
+ || !TEST_ptr(eckey_neg = EC_KEY_new_by_curve_name(nid))
+ || !TEST_true(EC_KEY_generate_key(eckey_neg))
+ || !TEST_ptr(pkey_neg = EVP_PKEY_new())
+ || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey_neg, eckey_neg)))
+ goto err;
+
+ sig_len = ECDSA_size(eckey);
+
+ if (!TEST_ptr(sig = OPENSSL_malloc(sig_len))
+ /* create a signature */
+ || !TEST_true(EVP_DigestSignInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_true(EVP_DigestSign(mctx, sig, &sig_len, tbs, sizeof(tbs)))
+ || !TEST_int_le(sig_len, ECDSA_size(eckey))
+ /* negative test, verify with wrong key, 0 return */
+ || !TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey_neg))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0)
+ /* negative test, verify with wrong signature length, -1 return */
+ || !TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len - 1, tbs, sizeof(tbs)), -1)
+ /* positive test, verify with correct key, 1 return */
+ || !TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
+ goto err;
+
+ /* muck with the message, test it fails with 0 return */
+ tbs[0] ^= 1;
+ if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0))
+ goto err;
+ /* un-muck and test it verifies */
+ tbs[0] ^= 1;
+ if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
+ goto err;
+
+ /*-
+ * Muck with the ECDSA signature. The DER encoding is one of:
+ * - 30 LL 02 ..
+ * - 30 81 LL 02 ..
+ *
+ * - Sometimes this mucks with the high level DER sequence wrapper:
+ * in that case, DER-parsing of the whole signature should fail.
+ *
+ * - Sometimes this mucks with the DER-encoding of ECDSA.r:
+ * in that case, DER-parsing of ECDSA.r should fail.
+ *
+ * - Sometimes this mucks with the DER-encoding of ECDSA.s:
+ * in that case, DER-parsing of ECDSA.s should fail.
+ *
+ * - Sometimes this mucks with ECDSA.r:
+ * in that case, the signature verification should fail.
+ *
+ * - Sometimes this mucks with ECDSA.s:
+ * in that case, the signature verification should fail.
+ *
+ * The usual case is changing the integer value of ECDSA.r or ECDSA.s.
+ * Because the ratio of DER overhead to signature bytes is small.
+ * So most of the time it will be one of the last two cases.
+ *
+ * In any case, EVP_PKEY_verify should not return 1 for valid.
+ */
+ offset = tbs[0] % sig_len;
+ dirt = tbs[1] ? tbs[1] : 1;
+ sig[offset] ^= dirt;
+ if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
+ goto err;
+ /* un-muck and test it verifies */
+ sig[offset] ^= dirt;
+ if (!TEST_true(EVP_MD_CTX_reset(mctx))
+ || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
+ || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
+ goto err;
+ ret = 1;
+ err:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(pkey_neg);
+ EVP_MD_CTX_free(mctx);
+ OPENSSL_free(sig);
return ret;
}
#endif
@@ -402,8 +320,20 @@ int setup_tests(void)
#ifdef OPENSSL_NO_EC
TEST_note("Elliptic curves are disabled.");
#else
- ADD_TEST(x9_62_tests);
- ADD_TEST(test_builtin);
+ /* get a list of all internal curves */
+ crv_len = EC_get_builtin_curves(NULL, 0);
+ if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
+ || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
+ return 0;
+ ADD_ALL_TESTS(test_builtin, crv_len);
+ ADD_ALL_TESTS(x9_62_tests, OSSL_NELEM(ecdsa_cavs_kats));
#endif
return 1;
}
+
+void cleanup_tests(void)
+{
+#ifndef OPENSSL_NO_EC
+ OPENSSL_free(curves);
+#endif
+}
diff --git a/test/ecdsatest.h b/test/ecdsatest.h
new file mode 100644
index 0000000000..216e66e277
--- /dev/null
+++ b/test/ecdsatest.h
@@ -0,0 +1,10214 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef ECDSATEST_CAVS_H
+# define ECDSATEST_CAVS_H
+
+/*-
+ * NIST CAVP ECDSA KATs:
+ * https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-3ecdsatestvectors.zip
+ *
+ * sha256sum e0d9bee3f760ca3fabb82bd43dd04c13ee64ca9e0b719c6ea64fd52c9f0dd929
+ * 720 KATs from the SigGen.txt file.
+ *
+ * There are also 4 X9.62 KATs; two for prime fields and two for binary fields.
+ */
+
+typedef struct {
+ const int nid; /* curve NID */
+ const int md_nid; /* hash function NID */
+ const char *msg; /* message to sign */
+ const char *d; /* ECDSA private key */
+ const char *Q; /* ECDSA public key: Q = dG */
+ const char *k; /* ECDSA nonce */
+ const char *r; /* ECDSA signature (r,s) */
+ const char *s;
+} ecdsa_cavs_kat_t;
+
+static const ecdsa_cavs_kat_t ecdsa_cavs_kats[] = {
+ /* prime KATs from X9.62 */
+ {NID_X9_62_prime192v1, NID_sha1,
+ "616263", /* "abc" */
+ "1a8d598fc15bf0fd89030b5cb1111aeb92ae8baf5ea475fb",
+ "0462b12d60690cdcf330babab6e69763b471f994dd702d16a563bf5ec08069705ffff65e"
+ "5ca5c0d69716dfcb3474373902",
+ "fa6de29746bbeb7f8bb1e761f85f7dfb2983169d82fa2f4e",
+ "885052380ff147b734c330c43d39b2c4a89f29b0f749fead",
+ "e9ecc78106def82bf1070cf1d4d804c3cb390046951df686"},
+ {NID_X9_62_prime239v1, NID_sha1,
+ "616263", /* "abc" */
+ "7ef7c6fabefffdea864206e80b0b08a9331ed93e698561b64ca0f7777f3d",
+ "045b6dc53bc61a2548ffb0f671472de6c9521a9d2d2534e65abfcbd5fe0c707fd9f1ed2e"
+ "65f09f6ce0893baf5e8e31e6ae82ea8c3592335be906d38dee",
+ "656c7196bf87dcc5d1f1020906df2782360d36b2de7a17ece37d503784af",
+ "2cb7f36803ebb9c427c58d8265f11fc5084747133078fc279de874fbecb0",
+ "2eeae988104e9c2234a3c2beb1f53bfa5dc11ff36a875d1e3ccb1f7e45cf"},
+ /* prime KATs from NIST CAVP */
+ {NID_secp224r1, NID_sha224,
+ "699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc1"
+ "9495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d"
+ "61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a"
+ "22367308036e2070f544ad4fff3d5122c76fad5d",
+ "16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615",
+ "04605495756e6e88f1d07ae5f98787af9b4da8a641d1a9492a12174eabf5cc733b17decc"
+ "806ef1df861a42505d0af9ef7c3df3959b8dfc6669",
+ "d9a5a7328117f48b4b8dd8c17dae722e756b3ff64bd29a527137eec0",
+ "2fc2cff8cdd4866b1d74e45b07d333af46b7af0888049d0fdbc7b0d6",
+ "8d9cc4c8ea93e0fd9d6431b9a1fd99b88f281793396321b11dac41eb"},
+ {NID_secp224r1, NID_sha224,
+ "7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25"
+ "e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5"
+ "e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e"
+ "08821d4fbdd8373517f5b19f9e63b89cfeeeef6f",
+ "cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5",
+ "04fa21f85b99d3dc18c6d53351fbcb1e2d029c00fa7d1663a3dd94695ee9e79578f8988b"
+ "168edff1a8b34a5ed9598cc20acd1f0aed36715d88",
+ "c780d047454824af98677cf310117e5f9e99627d02414f136aed8e83",
+ "45145f06b566ec9fd0fee1b6c6551a4535c7a3bbfc0fede45f4f5038",
+ "7302dff12545b069cf27df49b26e4781270585463656f2834917c3ca"},
+ {NID_secp224r1, NID_sha224,
+ "af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b"
+ "04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c"
+ "2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e826003"
+ "6469d25ab0c8e3643a820b8b3a4d8d43e4b728f9",
+ "dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73",
+ "04fc21a99b060afb0d9dbf3250ea3c4da10be94ce627a65874d8e4a630e8373ab7190890"
+ "326aac4aacca3eba89e15d1086a05434dd033fd3f3",
+ "6629366a156840477df4875cfba4f8faa809e394893e1f5525326d07",
+ "41f8e2b1ae5add7c24da8725a067585a3ad6d5a9ed9580beb226f23a",
+ "a5d71bff02dce997305dd337128046f36714398f4ef6647599712fae"},
+ {NID_secp224r1, NID_sha224,
+ "cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f"
+ "919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac"
+ "0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e0"
+ "59192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c",
+ "aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e",
+ "04fad0a34991bbf89982ad9cf89337b4bd2565f84d5bdd004289fc1cc35d8b6764f28c81"
+ "63a12855a5c266efeb9388df4994b85a8b4f1bd3bc",
+ "1d35d027cd5a569e25c5768c48ed0c2b127c0f99cb4e52ea094fe689",
+ "2258184ef9f0fa698735379972ce9adf034af76017668bfcdab978de",
+ "866fb8e505dea6c909c2c9143ec869d1bac2282cf12366130ff2146c"},
+ {NID_secp224r1, NID_sha224,
+ "c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6"
+ "d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8"
+ "c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283"
+ "c89ef92b13cd0333c4bb70865ae1919bf538ea34",
+ "29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4",
+ "040e0fc15e775a75d45f872e5021b554cc0579da19125e1a49299c7630cb64fe462d025a"
+ "e2a1394746bdbf8251f7ca5a1d6bb13e0edf6b7b09",
+ "39547c10bb947d69f6c3af701f2528e011a1e80a6d04cc5a37466c02",
+ "86622c376d326cdf679bcabf8eb034bf49f0c188f3fc3afd0006325d",
+ "26613d3b33c70e635d7a998f254a5b15d2a3642bf321e8cff08f1e84"},
+ {NID_secp224r1, NID_sha224,
+ "1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd6"
+ "64ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68"
+ "d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a1"
+ "3308e08867565bf2df9d649357a83cdcf18d2cd9",
+ "8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131",
+ "042c070e68e8478341938f3d5026a1fe01e778cdffbebbdd7a4cd29209cde21c9c7c6590"
+ "ba300715a7adac278385a5175b6b4ea749c4b6a681",
+ "509712f9c0f3370f6a09154159975945f0107dd1cee7327c68eaa90b",
+ "57afda5139b180de96373c3d649700682e37efd56ae182335f081013",
+ "eb6cd58650cfb26dfdf21de32fa17464a6efc46830eedc16977342e6"},
+ {NID_secp224r1, NID_sha224,
+ "069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc76005671"
+ "4db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea6"
+ "8421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca1806"
+ "1058043a0e441209c5c594842838a4d9d778a053",
+ "d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974",
+ "043a0d4b8e5fad1ea1abb8d3fb742cd45cd0b76d136e5bbb33206ad120c90ac83276b2fa"
+ "3757b0f226cd7360a313bc96fd8329c76a7306cc7d",
+ "1f1739af68a3cee7c5f09e9e09d6485d9cd64cc4085bc2bc89795aaf",
+ "09bbdd003532d025d7c3204c00747cd52ecdfbc7ce3dde8ffbea23e1",
+ "1e745e80948779a5cc8dc5cb193beebb550ec9c2647f4948bf58ba7d"},
+ {NID_secp224r1, NID_sha224,
+ "d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132"
+ "ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588"
+ "dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d"
+ "45622a2f0e85cba05c567baf1b9862b79a4b244e",
+ "380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8",
+ "044772c27cca3348b1801ae87b01cb564c8cf9b81c23cc74468a907927de9d253935b096"
+ "17a1655c42d385bf48504e06fa386f5fa533a21dcb",
+ "14dbdffa326ba2f3d64f79ff966d9ee6c1aba0d51e9a8e59f5686dc1",
+ "ff6d52a09ca4c3b82da0440864d6717e1be0b50b6dcf5e1d74c0ff56",
+ "09490be77bc834c1efaa23410dcbf800e6fae40d62a737214c5a4418"},
+ {NID_secp224r1, NID_sha224,
+ "79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42"
+ "152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0"
+ "311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601"
+ "dd218fb14c22f57870835b10818369d57d318405",
+ "6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2",
+ "041f249911b125348e6e0a473479105cc4b8cfb4fa32d897810fc69ffea17db03b9877d1"
+ "b6328329061ea67aec5a38a884362e9e5b7d7642dc",
+ "ab3a41fedc77d1f96f3103cc7dce215bf45054a755cf101735fef503",
+ "70ccc0824542e296d17a79320d422f1edcf9253840dafe4427033f40",
+ "e3823699c355b61ab1894be3371765fae2b720405a7ce5e790ca8c00"},
+ {NID_secp224r1, NID_sha224,
+ "8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a6"
+ "3ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd3"
+ "5b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29"
+ "018fc2b1163a22bfbb1de413e8645e871291a9f6",
+ "8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7",
+ "047df67b960ee7a2cb62b22932457360ab1e046c1ec84b91ae65642003c764ca9fc1b0cc"
+ "2233fa57bdcfedaab0131fb7b5f557d6ca57f4afe0",
+ "9ef6ebd178a76402968bc8ec8b257174a04fb5e2d65c1ab34ab039b9",
+ "eef9e8428105704133e0f19636c89e570485e577786df2b09f99602a",
+ "8c01f0162891e4b9536243cb86a6e5c177323cca09777366caf2693c"},
+ {NID_secp224r1, NID_sha224,
+ "c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486"
+ "e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700"
+ "b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a"
+ "2fe7d1dc94f4a0520de73fa72020494d3133ecf7",
+ "3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b",
+ "04b10150fd797eb870d377f1dbfa197f7d0f0ad29965af573ec13cc42a17b63ccefbe27f"
+ "b2a1139e5757b1082aeaa564f478c23a8f631eed5c",
+ "385803b262ee2ee875838b3a645a745d2e199ae112ef73a25d68d15f",
+ "1d293b697f297af77872582eb7f543dc250ec79ad453300d264a3b70",
+ "517a91b89c4859fcc10834242e710c5f0fed90ac938aa5ccdb7c66de"},
+ {NID_secp224r1, NID_sha224,
+ "30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39b"
+ "ec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac5789"
+ "8642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154"
+ "460c3bf12764f3fbf17fcccc82df516a2fbe4ecf",
+ "c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6",
+ "043c9b4ef1748a1925578658d3af51995b989ad760790157b25fe0982655648f4ff4edfb"
+ "899e9a13bd8d20f5c24b35dc6a6a4e42ed5983b4a0",
+ "b04d78d8ac40fefadb99f389a06d93f6b5b72198c1be02dbff6195f0",
+ "4bdd3c84647bad93dcaffd1b54eb87fc61a5704b19d7e6d756d11ad0",
+ "fdd81e5dca54158514f44ba2330271eff4c618330328451e2d93b9fb"},
+ {NID_secp224r1, NID_sha224,
+ "6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf"
+ "5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a4"
+ "9b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7"
+ "640204cd0d9f1e53fc3acf30096cd00fa80b3ae9",
+ "3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc",
+ "04f0acdfbc75a748a4a0ac55281754b5c4a364b7d61c5390b334daae1086587a6768f235"
+ "bf523fbfc6e062c7401ac2b0242cfe4e5fb34f4057",
+ "854b20c61bcdf7a89959dbf0985880bb14b628f01c65ef4f6446f1c1",
+ "a2601fbb9fe89f39814735febb349143baa934170ffb91c6448a7823",
+ "bf90f9305616020a0e34ef30803fc15fa97dffc0948452bbf6cb5f66"},
+ {NID_secp224r1, NID_sha224,
+ "05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359"
+ "cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681c"
+ "b52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b"
+ "0bece10d5ce2744fc7345307dd1b41b6eff0ca89",
+ "2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3",
+ "045fad3c047074b5de1960247d0cc216b4e3fb7f3b9cd960575c8479fce4fc9c7f05ff0b"
+ "040eb171fdd2a1dfe2572c564c2003a08c3179a422",
+ "9267763383f8db55eed5b1ca8f4937dc2e0ca6175066dc3d4a4586af",
+ "422e2e9fe535eb62f11f5f8ce87cf2e9ec65e61c06737cf6a0019ae6",
+ "116cfcf0965b7bc63aecade71d189d7e98a0434b124f2afbe3ccf0a9"},
+ {NID_secp224r1, NID_sha224,
+ "e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609"
+ "f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa"
+ "75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066"
+ "e8994d36a137fdeb9364601daeef09fd174dde4a",
+ "3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912",
+ "046dd84f4d66f362844e41a7913c40b4aad5fa9ba56bb44c2d2ed9efac15f65ebcdf2fd9"
+ "f8035385a330bdabec0f1cd9cc7bc31d2fadbe7cda",
+ "7bb48839d7717bab1fdde89bf4f7b4509d1c2c12510925e13655dead",
+ "127051d85326049115f307af2bc426f6c2d08f4774a0b496fb6982b1",
+ "6857e84418c1d1179333b4e5307e92abade0b74f7521ad78044bf597"},
+ {NID_secp224r1, NID_sha256,
+ "2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd42"
+ "6a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e"
+ "791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff"
+ "410ee411a1b66a516f278327df2462fb5619470e",
+ "888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa",
+ "044c741e4d20103670b7161ae72271082155838418084335338ac38fa4db7919151ac285"
+ "87b72bad7ab180ec8e95ab9e2c8d81d9b9d7e2e383",
+ "06f7a56007825433c4c61153df1a135eee2f38ec687b492ed40d9c90",
+ "0909c9b9cae8d2790e29db6afdb45c04f5b072c4c20410c7dc9b6772",
+ "298f4fcae1fe271da1e0345d11d07a1fca43f58af4c113b909eedea0"},
+ {NID_secp224r1, NID_sha256,
+ "1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea1"
+ "9ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8b"
+ "d37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c"
+ "09ab159f3a00ed7b930f628c3c48257e92fc7407",
+ "5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972",
+ "04897089f4ef05b943eeac06589f0e09ccc571a6add3eb1610a2fc830f62ba3f6b3e6f0f"
+ "062058b93e6f25b6041246c5be13584a41cae7e244",
+ "5b6f7eca2bcc5899fce41b8169d48cd57cf0c4a1b66a30a150072676",
+ "f12c9985d454ffbc899ebbbb6cf43e3debcac7f19029f8f2f35cce31",
+ "12fcb848adbd8b1b4c72b2b54a04d936e4a5f480ae2a3ea2e3c1baae"},
+ {NID_secp224r1, NID_sha256,
+ "74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aae"
+ "e85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b"
+ "4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b"
+ "91dc84bbb59b14ec477a1e9d194c137e21c75bbb",
+ "f60b3