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