Home | History | Annotate | Line # | Download | only in test
ecdsatest.c revision 1.6
      1  1.2  christos /*
      2  1.5  christos  * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
      3  1.3  christos  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
      4  1.2  christos  *
      5  1.2  christos  * Licensed under the OpenSSL license (the "License").  You may not use
      6  1.2  christos  * this file except in compliance with the License.  You can obtain a copy
      7  1.2  christos  * in the file LICENSE in the source distribution or at
      8  1.2  christos  * https://www.openssl.org/source/license.html
      9  1.2  christos  */
     10  1.2  christos 
     11  1.2  christos #include <openssl/opensslconf.h> /* To see if OPENSSL_NO_EC is defined */
     12  1.4  christos #include "testutil.h"
     13  1.2  christos 
     14  1.3  christos #ifndef OPENSSL_NO_EC
     15  1.2  christos 
     16  1.2  christos # include <openssl/evp.h>
     17  1.2  christos # include <openssl/bn.h>
     18  1.2  christos # include <openssl/ec.h>
     19  1.2  christos # include <openssl/rand.h>
     20  1.6  christos # include "internal/nelem.h"
     21  1.6  christos # include "ecdsatest.h"
     22  1.2  christos 
     23  1.2  christos /* functions to change the RAND_METHOD */
     24  1.3  christos static int fbytes(unsigned char *buf, int num);
     25  1.2  christos 
     26  1.2  christos static RAND_METHOD fake_rand;
     27  1.2  christos static const RAND_METHOD *old_rand;
     28  1.6  christos static int use_fake = 0;
     29  1.6  christos static const char *numbers[2];
     30  1.6  christos static size_t crv_len = 0;
     31  1.6  christos static EC_builtin_curve *curves = NULL;
     32  1.2  christos 
     33  1.3  christos static int change_rand(void)
     34  1.2  christos {
     35  1.2  christos     /* save old rand method */
     36  1.3  christos     if (!TEST_ptr(old_rand = RAND_get_rand_method()))
     37  1.2  christos         return 0;
     38  1.2  christos 
     39  1.3  christos     fake_rand = *old_rand;
     40  1.2  christos     /* use own random function */
     41  1.2  christos     fake_rand.bytes = fbytes;
     42  1.2  christos     /* set new RAND_METHOD */
     43  1.3  christos     if (!TEST_true(RAND_set_rand_method(&fake_rand)))
     44  1.2  christos         return 0;
     45  1.2  christos     return 1;
     46  1.2  christos }
     47  1.2  christos 
     48  1.3  christos static int restore_rand(void)
     49  1.2  christos {
     50  1.3  christos     if (!TEST_true(RAND_set_rand_method(old_rand)))
     51  1.2  christos         return 0;
     52  1.3  christos     return 1;
     53  1.2  christos }
     54  1.2  christos 
     55  1.3  christos static int fbytes(unsigned char *buf, int num)
     56  1.2  christos {
     57  1.3  christos     int ret = 0;
     58  1.6  christos     static int fbytes_counter = 0;
     59  1.2  christos     BIGNUM *tmp = NULL;
     60  1.2  christos 
     61  1.2  christos     if (use_fake == 0)
     62  1.2  christos         return old_rand->bytes(buf, num);
     63  1.2  christos 
     64  1.2  christos     use_fake = 0;
     65  1.2  christos 
     66  1.6  christos     if (!TEST_ptr(tmp = BN_new())
     67  1.6  christos         || !TEST_int_lt(fbytes_counter, OSSL_NELEM(numbers))
     68  1.6  christos         || !TEST_true(BN_hex2bn(&tmp, numbers[fbytes_counter]))
     69  1.6  christos         /* tmp might need leading zeros so pad it out */
     70  1.6  christos         || !TEST_int_le(BN_num_bytes(tmp), num)
     71  1.6  christos         || !TEST_true(BN_bn2binpad(tmp, buf, num)))
     72  1.6  christos         goto err;
     73  1.6  christos 
     74  1.6  christos     fbytes_counter = (fbytes_counter + 1) % OSSL_NELEM(numbers);
     75  1.6  christos     ret = 1;
     76  1.6  christos  err:
     77  1.2  christos     BN_free(tmp);
     78  1.2  christos     return ret;
     79  1.2  christos }
     80  1.2  christos 
     81  1.6  christos /*-
     82  1.6  christos  * This function hijacks the RNG to feed it the chosen ECDSA key and nonce.
     83  1.6  christos  * The ECDSA KATs are from:
     84  1.6  christos  * - the X9.62 draft (4)
     85  1.6  christos  * - NIST CAVP (720)
     86  1.6  christos  *
     87  1.6  christos  * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG.
     88  1.6  christos  * NB: This is not how applications should use ECDSA; this is only for testing.
     89  1.6  christos  *
     90  1.6  christos  * Tests the library can successfully:
     91  1.6  christos  * - generate public keys that matches those KATs
     92  1.6  christos  * - create ECDSA signatures that match those KATs
     93  1.6  christos  * - accept those signatures as valid
     94  1.6  christos  */
     95  1.6  christos static int x9_62_tests(int n)
     96  1.2  christos {
     97  1.6  christos     int nid, md_nid, ret = 0;
     98  1.6  christos     const char *r_in = NULL, *s_in = NULL, *tbs = NULL;
     99  1.6  christos     unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL;
    100  1.6  christos     unsigned char digest[EVP_MAX_MD_SIZE];
    101  1.2  christos     unsigned int dgst_len = 0;
    102  1.6  christos     long q_len, msg_len = 0;
    103  1.6  christos     size_t p_len;
    104  1.6  christos     EVP_MD_CTX *mctx = NULL;
    105  1.2  christos     EC_KEY *key = NULL;
    106  1.2  christos     ECDSA_SIG *signature = NULL;
    107  1.2  christos     BIGNUM *r = NULL, *s = NULL;
    108  1.2  christos     BIGNUM *kinv = NULL, *rp = NULL;
    109  1.6  christos     const BIGNUM *sig_r = NULL, *sig_s = NULL;
    110  1.2  christos 
    111  1.6  christos     nid = ecdsa_cavs_kats[n].nid;
    112  1.6  christos     md_nid = ecdsa_cavs_kats[n].md_nid;
    113  1.6  christos     r_in = ecdsa_cavs_kats[n].r;
    114  1.6  christos     s_in = ecdsa_cavs_kats[n].s;
    115  1.6  christos     tbs = ecdsa_cavs_kats[n].msg;
    116  1.6  christos     numbers[0] = ecdsa_cavs_kats[n].d;
    117  1.6  christos     numbers[1] = ecdsa_cavs_kats[n].k;
    118  1.6  christos 
    119  1.6  christos     TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid));
    120  1.6  christos 
    121  1.6  christos     if (!TEST_ptr(mctx = EVP_MD_CTX_new())
    122  1.6  christos         /* get the message digest */
    123  1.6  christos         || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len))
    124  1.6  christos         || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL))
    125  1.6  christos         || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len))
    126  1.6  christos         || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len))
    127  1.6  christos         /* create the key */
    128  1.6  christos         || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid))
    129  1.6  christos         /* load KAT variables */
    130  1.6  christos         || !TEST_ptr(r = BN_new())
    131  1.6  christos         || !TEST_ptr(s = BN_new())
    132  1.6  christos         || !TEST_true(BN_hex2bn(&r, r_in))
    133  1.6  christos         || !TEST_true(BN_hex2bn(&s, s_in))
    134  1.6  christos         /* swap the RNG source */
    135  1.6  christos         || !TEST_true(change_rand()))
    136  1.6  christos         goto err;
    137  1.2  christos 
    138  1.6  christos     /* public key must match KAT */
    139  1.2  christos     use_fake = 1;
    140  1.6  christos     if (!TEST_true(EC_KEY_generate_key(key))
    141  1.6  christos         || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED,
    142  1.6  christos                                              &pbuf, NULL))
    143  1.6  christos         || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len))
    144  1.6  christos         || !TEST_int_eq(q_len, p_len)
    145  1.6  christos         || !TEST_mem_eq(qbuf, q_len, pbuf, p_len))
    146  1.6  christos         goto err;
    147  1.3  christos 
    148  1.6  christos     /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */
    149  1.2  christos     use_fake = 1;
    150  1.6  christos     if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp))
    151  1.6  christos         || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len,
    152  1.6  christos                                                   kinv, rp, key))
    153  1.6  christos         /* verify the signature */
    154  1.6  christos         || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1))
    155  1.6  christos         goto err;
    156  1.3  christos 
    157  1.2  christos     /* compare the created signature with the expected signature */
    158  1.2  christos     ECDSA_SIG_get0(signature, &sig_r, &sig_s);
    159  1.3  christos     if (!TEST_BN_eq(sig_r, r)
    160  1.6  christos         || !TEST_BN_eq(sig_s, s))
    161  1.6  christos         goto err;
    162  1.3  christos 
    163  1.6  christos     ret = 1;
    164  1.2  christos 
    165  1.6  christos  err:
    166  1.6  christos     /* restore the RNG source */
    167  1.6  christos     if (!TEST_true(restore_rand()))
    168  1.6  christos         ret = 0;
    169  1.3  christos 
    170  1.6  christos     OPENSSL_free(message);
    171  1.6  christos     OPENSSL_free(pbuf);
    172  1.6  christos     OPENSSL_free(qbuf);
    173  1.2  christos     EC_KEY_free(key);
    174  1.2  christos     ECDSA_SIG_free(signature);
    175  1.2  christos     BN_free(r);
    176  1.2  christos     BN_free(s);
    177  1.6  christos     EVP_MD_CTX_free(mctx);
    178  1.2  christos     BN_clear_free(kinv);
    179  1.2  christos     BN_clear_free(rp);
    180  1.2  christos     return ret;
    181  1.2  christos }
    182  1.2  christos 
    183  1.6  christos /*-
    184  1.6  christos  * Positive and negative ECDSA testing through EVP interface:
    185  1.6  christos  * - EVP_DigestSign (this is the one-shot version)
    186  1.6  christos  * - EVP_DigestVerify
    187  1.6  christos  *
    188  1.6  christos  * Tests the library can successfully:
    189  1.6  christos  * - create a key
    190  1.6  christos  * - create a signature
    191  1.6  christos  * - accept that signature
    192  1.6  christos  * - reject that signature with a different public key
    193  1.6  christos  * - reject that signature if its length is not correct
    194  1.6  christos  * - reject that signature after modifying the message
    195  1.6  christos  * - accept that signature after un-modifying the message
    196  1.6  christos  * - reject that signature after modifying the signature
    197  1.6  christos  * - accept that signature after un-modifying the signature
    198  1.6  christos  */
    199  1.6  christos static int test_builtin(int n)
    200  1.2  christos {
    201  1.6  christos     EC_KEY *eckey_neg = NULL, *eckey = NULL;
    202  1.6  christos     unsigned char dirt, offset, tbs[128];
    203  1.6  christos     unsigned char *sig = NULL;
    204  1.6  christos     EVP_PKEY *pkey_neg = NULL, *pkey = NULL;
    205  1.6  christos     EVP_MD_CTX *mctx = NULL;
    206  1.6  christos     size_t sig_len;
    207  1.6  christos     int nid, ret = 0;
    208  1.2  christos 
    209  1.6  christos     nid = curves[n].nid;
    210  1.3  christos 
    211  1.6  christos     /* skip built-in curves where ord(G) is not prime */
    212  1.6  christos     if (nid == NID_ipsec4 || nid == NID_ipsec3) {
    213  1.6  christos         TEST_info("skipped: ECDSA unsupported for curve %s", OBJ_nid2sn(nid));
    214  1.6  christos         return 1;
    215  1.6  christos     }
    216  1.2  christos 
    217  1.6  christos     TEST_info("testing ECDSA for curve %s", OBJ_nid2sn(nid));
    218  1.2  christos 
    219  1.6  christos     if (!TEST_ptr(mctx = EVP_MD_CTX_new())
    220  1.6  christos         /* get some random message data */
    221  1.6  christos         || !TEST_true(RAND_bytes(tbs, sizeof(tbs)))
    222  1.6  christos         /* real key */
    223  1.6  christos         || !TEST_ptr(eckey = EC_KEY_new_by_curve_name(nid))
    224  1.6  christos         || !TEST_true(EC_KEY_generate_key(eckey))
    225  1.6  christos         || !TEST_ptr(pkey = EVP_PKEY_new())
    226  1.6  christos         || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))
    227  1.6  christos         /* fake key for negative testing */
    228  1.6  christos         || !TEST_ptr(eckey_neg = EC_KEY_new_by_curve_name(nid))
    229  1.6  christos         || !TEST_true(EC_KEY_generate_key(eckey_neg))
    230  1.6  christos         || !TEST_ptr(pkey_neg = EVP_PKEY_new())
    231  1.6  christos         || !TEST_true(EVP_PKEY_assign_EC_KEY(pkey_neg, eckey_neg)))
    232  1.6  christos         goto err;
    233  1.6  christos 
    234  1.6  christos     sig_len = ECDSA_size(eckey);
    235  1.6  christos 
    236  1.6  christos     if (!TEST_ptr(sig = OPENSSL_malloc(sig_len))
    237  1.6  christos         /* create a signature */
    238  1.6  christos         || !TEST_true(EVP_DigestSignInit(mctx, NULL, NULL, NULL, pkey))
    239  1.6  christos         || !TEST_true(EVP_DigestSign(mctx, sig, &sig_len, tbs, sizeof(tbs)))
    240  1.6  christos         || !TEST_int_le(sig_len, ECDSA_size(eckey))
    241  1.6  christos         /* negative test, verify with wrong key, 0 return */
    242  1.6  christos         || !TEST_true(EVP_MD_CTX_reset(mctx))
    243  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey_neg))
    244  1.6  christos         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0)
    245  1.6  christos         /* negative test, verify with wrong signature length, -1 return */
    246  1.6  christos         || !TEST_true(EVP_MD_CTX_reset(mctx))
    247  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
    248  1.6  christos         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len - 1, tbs, sizeof(tbs)), -1)
    249  1.6  christos         /* positive test, verify with correct key, 1 return */
    250  1.6  christos         || !TEST_true(EVP_MD_CTX_reset(mctx))
    251  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
    252  1.6  christos         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
    253  1.6  christos         goto err;
    254  1.6  christos 
    255  1.6  christos     /* muck with the message, test it fails with 0 return */
    256  1.6  christos     tbs[0] ^= 1;
    257  1.6  christos     if (!TEST_true(EVP_MD_CTX_reset(mctx))
    258  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
    259  1.6  christos         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 0))
    260  1.6  christos         goto err;
    261  1.6  christos     /* un-muck and test it verifies */
    262  1.6  christos     tbs[0] ^= 1;
    263  1.6  christos     if (!TEST_true(EVP_MD_CTX_reset(mctx))
    264  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
    265  1.6  christos         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
    266  1.6  christos         goto err;
    267  1.6  christos 
    268  1.6  christos     /*-
    269  1.6  christos      * Muck with the ECDSA signature. The DER encoding is one of:
    270  1.6  christos      * - 30 LL 02 ..
    271  1.6  christos      * - 30 81 LL 02 ..
    272  1.6  christos      *
    273  1.6  christos      * - Sometimes this mucks with the high level DER sequence wrapper:
    274  1.6  christos      *   in that case, DER-parsing of the whole signature should fail.
    275  1.6  christos      *
    276  1.6  christos      * - Sometimes this mucks with the DER-encoding of ECDSA.r:
    277  1.6  christos      *   in that case, DER-parsing of ECDSA.r should fail.
    278  1.6  christos      *
    279  1.6  christos      * - Sometimes this mucks with the DER-encoding of ECDSA.s:
    280  1.6  christos      *   in that case, DER-parsing of ECDSA.s should fail.
    281  1.6  christos      *
    282  1.6  christos      * - Sometimes this mucks with ECDSA.r:
    283  1.6  christos      *   in that case, the signature verification should fail.
    284  1.6  christos      *
    285  1.6  christos      * - Sometimes this mucks with ECDSA.s:
    286  1.6  christos      *   in that case, the signature verification should fail.
    287  1.6  christos      *
    288  1.6  christos      * The usual case is changing the integer value of ECDSA.r or ECDSA.s.
    289  1.6  christos      * Because the ratio of DER overhead to signature bytes is small.
    290  1.6  christos      * So most of the time it will be one of the last two cases.
    291  1.6  christos      *
    292  1.6  christos      * In any case, EVP_PKEY_verify should not return 1 for valid.
    293  1.6  christos      */
    294  1.6  christos     offset = tbs[0] % sig_len;
    295  1.6  christos     dirt = tbs[1] ? tbs[1] : 1;
    296  1.6  christos     sig[offset] ^= dirt;
    297  1.6  christos     if (!TEST_true(EVP_MD_CTX_reset(mctx))
    298  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
    299  1.6  christos         || !TEST_int_ne(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
    300  1.6  christos         goto err;
    301  1.6  christos     /* un-muck and test it verifies */
    302  1.6  christos     sig[offset] ^= dirt;
    303  1.6  christos     if (!TEST_true(EVP_MD_CTX_reset(mctx))
    304  1.6  christos         || !TEST_true(EVP_DigestVerifyInit(mctx, NULL, NULL, NULL, pkey))
    305  1.6  christos         || !TEST_int_eq(EVP_DigestVerify(mctx, sig, sig_len, tbs, sizeof(tbs)), 1))
    306  1.6  christos         goto err;
    307  1.2  christos 
    308  1.2  christos     ret = 1;
    309  1.6  christos  err:
    310  1.6  christos     EVP_PKEY_free(pkey);
    311  1.6  christos     EVP_PKEY_free(pkey_neg);
    312  1.6  christos     EVP_MD_CTX_free(mctx);
    313  1.6  christos     OPENSSL_free(sig);
    314  1.2  christos     return ret;
    315  1.2  christos }
    316  1.3  christos #endif
    317  1.2  christos 
    318  1.3  christos int setup_tests(void)
    319  1.2  christos {
    320  1.3  christos #ifdef OPENSSL_NO_EC
    321  1.3  christos     TEST_note("Elliptic curves are disabled.");
    322  1.3  christos #else
    323  1.6  christos     /* get a list of all internal curves */
    324  1.6  christos     crv_len = EC_get_builtin_curves(NULL, 0);
    325  1.6  christos     if (!TEST_ptr(curves = OPENSSL_malloc(sizeof(*curves) * crv_len))
    326  1.6  christos         || !TEST_true(EC_get_builtin_curves(curves, crv_len)))
    327  1.6  christos         return 0;
    328  1.6  christos     ADD_ALL_TESTS(test_builtin, crv_len);
    329  1.6  christos     ADD_ALL_TESTS(x9_62_tests, OSSL_NELEM(ecdsa_cavs_kats));
    330  1.2  christos #endif
    331  1.3  christos     return 1;
    332  1.2  christos }
    333  1.6  christos 
    334  1.6  christos void cleanup_tests(void)
    335  1.6  christos {
    336  1.6  christos #ifndef OPENSSL_NO_EC
    337  1.6  christos     OPENSSL_free(curves);
    338  1.6  christos #endif
    339  1.6  christos }
    340