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