1/* 2 * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10/* 11 * ECDSA low level APIs are deprecated for public use, but still ok for 12 * internal use. 13 */ 14#include "internal/deprecated.h" 15 16#include <string.h> 17#include <openssl/err.h> 18#include <openssl/obj_mac.h> 19#include <openssl/rand.h> 20#include "crypto/bn.h" 21#include "ec_local.h" 22 23#define MIN_ECDSA_SIGN_ORDERBITS 64 24/* 25 * It is highly unlikely that a retry will happen, 26 * Multiple retries would indicate that something is wrong 27 * with the group parameters (which would normally only happen 28 * with a bad custom group). 29 */ 30#define MAX_ECDSA_SIGN_RETRIES 8 31 32int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 33 BIGNUM **rp) 34{ 35 if (eckey->group->meth->ecdsa_sign_setup == NULL) { 36 ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); 37 return 0; 38 } 39 40 return eckey->group->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); 41} 42 43ECDSA_SIG *ossl_ecdsa_sign_sig(const unsigned char *dgst, int dgst_len, 44 const BIGNUM *in_kinv, const BIGNUM *in_r, 45 EC_KEY *eckey) 46{ 47 if (eckey->group->meth->ecdsa_sign_sig == NULL) { 48 ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); 49 return NULL; 50 } 51 52 return eckey->group->meth->ecdsa_sign_sig(dgst, dgst_len, 53 in_kinv, in_r, eckey); 54} 55 56int ossl_ecdsa_verify_sig(const unsigned char *dgst, int dgst_len, 57 const ECDSA_SIG *sig, EC_KEY *eckey) 58{ 59 if (eckey->group->meth->ecdsa_verify_sig == NULL) { 60 ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA); 61 return 0; 62 } 63 64 return eckey->group->meth->ecdsa_verify_sig(dgst, dgst_len, sig, eckey); 65} 66 67int ossl_ecdsa_sign(int type, const unsigned char *dgst, int dlen, 68 unsigned char *sig, unsigned int *siglen, 69 const BIGNUM *kinv, const BIGNUM *r, EC_KEY *eckey) 70{ 71 ECDSA_SIG *s; 72 73 if (sig == NULL && (kinv == NULL || r == NULL)) { 74 *siglen = ECDSA_size(eckey); 75 return 1; 76 } 77 78 s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); 79 if (s == NULL) { 80 *siglen = 0; 81 return 0; 82 } 83 *siglen = i2d_ECDSA_SIG(s, sig != NULL ? &sig : NULL); 84 ECDSA_SIG_free(s); 85 return 1; 86} 87 88static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, 89 BIGNUM **kinvp, BIGNUM **rp, 90 const unsigned char *dgst, int dlen) 91{ 92 BN_CTX *ctx = NULL; 93 BIGNUM *k = NULL, *r = NULL, *X = NULL; 94 const BIGNUM *order; 95 EC_POINT *tmp_point = NULL; 96 const EC_GROUP *group; 97 int ret = 0; 98 int order_bits; 99 const BIGNUM *priv_key; 100 101 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { 102 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 103 return 0; 104 } 105 if ((priv_key = EC_KEY_get0_private_key(eckey)) == NULL) { 106 ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); 107 return 0; 108 } 109 110 if (!EC_KEY_can_sign(eckey)) { 111 ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); 112 return 0; 113 } 114 115 if ((ctx = ctx_in) == NULL) { 116 if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL) { 117 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 118 return 0; 119 } 120 } 121 122 k = BN_secure_new(); /* this value is later returned in *kinvp */ 123 r = BN_new(); /* this value is later returned in *rp */ 124 X = BN_new(); 125 if (k == NULL || r == NULL || X == NULL) { 126 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 127 goto err; 128 } 129 if ((tmp_point = EC_POINT_new(group)) == NULL) { 130 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 131 goto err; 132 } 133 order = EC_GROUP_get0_order(group); 134 135 /* Preallocate space */ 136 order_bits = BN_num_bits(order); 137 /* Check the number of bits here so that an infinite loop is not possible */ 138 if (order_bits < MIN_ECDSA_SIGN_ORDERBITS 139 || !BN_set_bit(k, order_bits) 140 || !BN_set_bit(r, order_bits) 141 || !BN_set_bit(X, order_bits)) 142 goto err; 143 144 do { 145 /* get random k */ 146 do { 147 if (dgst != NULL) { 148 if (!ossl_bn_gen_dsa_nonce_fixed_top(k, order, priv_key, 149 dgst, dlen, ctx)) { 150 ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); 151 goto err; 152 } 153 } else { 154 if (!ossl_bn_priv_rand_range_fixed_top(k, order, 0, ctx)) { 155 ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED); 156 goto err; 157 } 158 } 159 } while (ossl_bn_is_word_fixed_top(k, 0)); 160 161 /* compute r the x-coordinate of generator * k */ 162 if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { 163 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 164 goto err; 165 } 166 167 if (!EC_POINT_get_affine_coordinates(group, tmp_point, X, NULL, ctx)) { 168 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 169 goto err; 170 } 171 172 if (!BN_nnmod(r, X, order, ctx)) { 173 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 174 goto err; 175 } 176 } while (BN_is_zero(r)); 177 178 /* compute the inverse of k */ 179 if (!ossl_ec_group_do_inverse_ord(group, k, k, ctx)) { 180 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 181 goto err; 182 } 183 184 /* clear old values if necessary */ 185 BN_clear_free(*rp); 186 BN_clear_free(*kinvp); 187 /* save the pre-computed values */ 188 *rp = r; 189 *kinvp = k; 190 ret = 1; 191 err: 192 if (!ret) { 193 BN_clear_free(k); 194 BN_clear_free(r); 195 } 196 if (ctx != ctx_in) 197 BN_CTX_free(ctx); 198 EC_POINT_free(tmp_point); 199 BN_clear_free(X); 200 return ret; 201} 202 203int ossl_ecdsa_simple_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, 204 BIGNUM **rp) 205{ 206 return ecdsa_sign_setup(eckey, ctx_in, kinvp, rp, NULL, 0); 207} 208 209ECDSA_SIG *ossl_ecdsa_simple_sign_sig(const unsigned char *dgst, int dgst_len, 210 const BIGNUM *in_kinv, const BIGNUM *in_r, 211 EC_KEY *eckey) 212{ 213 int ok = 0, i; 214 int retries = 0; 215 BIGNUM *kinv = NULL, *s, *m = NULL; 216 const BIGNUM *order, *ckinv; 217 BN_CTX *ctx = NULL; 218 const EC_GROUP *group; 219 ECDSA_SIG *ret; 220 const BIGNUM *priv_key; 221 222 group = EC_KEY_get0_group(eckey); 223 priv_key = EC_KEY_get0_private_key(eckey); 224 225 if (group == NULL) { 226 ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER); 227 return NULL; 228 } 229 if (priv_key == NULL) { 230 ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); 231 return NULL; 232 } 233 234 if (!EC_KEY_can_sign(eckey)) { 235 ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); 236 return NULL; 237 } 238 239 ret = ECDSA_SIG_new(); 240 if (ret == NULL) { 241 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 242 return NULL; 243 } 244 ret->r = BN_new(); 245 ret->s = BN_new(); 246 if (ret->r == NULL || ret->s == NULL) { 247 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 248 goto err; 249 } 250 s = ret->s; 251 252 if ((ctx = BN_CTX_new_ex(eckey->libctx)) == NULL 253 || (m = BN_new()) == NULL) { 254 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 255 goto err; 256 } 257 258 order = EC_GROUP_get0_order(group); 259 i = BN_num_bits(order); 260 /* 261 * Need to truncate digest if it is too long: first truncate whole bytes. 262 */ 263 if (8 * dgst_len > i) 264 dgst_len = (i + 7) / 8; 265 if (!BN_bin2bn(dgst, dgst_len, m)) { 266 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 267 goto err; 268 } 269 /* If still too long, truncate remaining bits with a shift */ 270 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { 271 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 272 goto err; 273 } 274 do { 275 if (in_kinv == NULL || in_r == NULL) { 276 if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, dgst, dgst_len)) { 277 ERR_raise(ERR_LIB_EC, ERR_R_ECDSA_LIB); 278 goto err; 279 } 280 ckinv = kinv; 281 } else { 282 ckinv = in_kinv; 283 if (BN_copy(ret->r, in_r) == NULL) { 284 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 285 goto err; 286 } 287 } 288 289 /* 290 * With only one multiplicant being in Montgomery domain 291 * multiplication yields real result without post-conversion. 292 * Also note that all operations but last are performed with 293 * zero-padded vectors. Last operation, BN_mod_mul_montgomery 294 * below, returns user-visible value with removed zero padding. 295 */ 296 if (!bn_to_mont_fixed_top(s, ret->r, group->mont_data, ctx) 297 || !bn_mul_mont_fixed_top(s, s, priv_key, group->mont_data, ctx)) { 298 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 299 goto err; 300 } 301 if (!bn_mod_add_fixed_top(s, s, m, order)) { 302 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 303 goto err; 304 } 305 /* 306 * |s| can still be larger than modulus, because |m| can be. In 307 * such case we count on Montgomery reduction to tie it up. 308 */ 309 if (!bn_to_mont_fixed_top(s, s, group->mont_data, ctx) 310 || !BN_mod_mul_montgomery(s, s, ckinv, group->mont_data, ctx)) { 311 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 312 goto err; 313 } 314 315 if (BN_is_zero(s)) { 316 /* 317 * if kinv and r have been supplied by the caller, don't 318 * generate new kinv and r values 319 */ 320 if (in_kinv != NULL && in_r != NULL) { 321 ERR_raise(ERR_LIB_EC, EC_R_NEED_NEW_SETUP_VALUES); 322 goto err; 323 } 324 /* Avoid infinite loops cause by invalid group parameters */ 325 if (retries++ > MAX_ECDSA_SIGN_RETRIES) { 326 ERR_raise(ERR_LIB_EC, EC_R_TOO_MANY_RETRIES); 327 goto err; 328 } 329 } else { 330 /* s != 0 => we have a valid signature */ 331 break; 332 } 333 } while (1); 334 335 ok = 1; 336 err: 337 if (!ok) { 338 ECDSA_SIG_free(ret); 339 ret = NULL; 340 } 341 BN_CTX_free(ctx); 342 BN_clear_free(m); 343 BN_clear_free(kinv); 344 return ret; 345} 346 347/*- 348 * returns 349 * 1: correct signature 350 * 0: incorrect signature 351 * -1: error 352 */ 353int ossl_ecdsa_verify(int type, const unsigned char *dgst, int dgst_len, 354 const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) 355{ 356 ECDSA_SIG *s; 357 const unsigned char *p = sigbuf; 358 unsigned char *der = NULL; 359 int derlen = -1; 360 int ret = -1; 361 362 s = ECDSA_SIG_new(); 363 if (s == NULL) 364 return ret; 365 if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) 366 goto err; 367 /* Ensure signature uses DER and doesn't have trailing garbage */ 368 derlen = i2d_ECDSA_SIG(s, &der); 369 if (derlen != sig_len || memcmp(sigbuf, der, derlen) != 0) 370 goto err; 371 ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); 372 err: 373 OPENSSL_free(der); 374 ECDSA_SIG_free(s); 375 return ret; 376} 377 378int ossl_ecdsa_simple_verify_sig(const unsigned char *dgst, int dgst_len, 379 const ECDSA_SIG *sig, EC_KEY *eckey) 380{ 381 int ret = -1, i; 382 BN_CTX *ctx; 383 const BIGNUM *order; 384 BIGNUM *u1, *u2, *m, *X; 385 EC_POINT *point = NULL; 386 const EC_GROUP *group; 387 const EC_POINT *pub_key; 388 389 /* check input values */ 390 if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || 391 (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { 392 ERR_raise(ERR_LIB_EC, EC_R_MISSING_PARAMETERS); 393 return -1; 394 } 395 396 if (!EC_KEY_can_sign(eckey)) { 397 ERR_raise(ERR_LIB_EC, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING); 398 return -1; 399 } 400 401 ctx = BN_CTX_new_ex(eckey->libctx); 402 if (ctx == NULL) { 403 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 404 return -1; 405 } 406 BN_CTX_start(ctx); 407 u1 = BN_CTX_get(ctx); 408 u2 = BN_CTX_get(ctx); 409 m = BN_CTX_get(ctx); 410 X = BN_CTX_get(ctx); 411 if (X == NULL) { 412 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 413 goto err; 414 } 415 416 order = EC_GROUP_get0_order(group); 417 if (order == NULL) { 418 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 419 goto err; 420 } 421 422 if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || 423 BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || 424 BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { 425 ERR_raise(ERR_LIB_EC, EC_R_BAD_SIGNATURE); 426 ret = 0; /* signature is invalid */ 427 goto err; 428 } 429 /* calculate tmp1 = inv(S) mod order */ 430 if (!ossl_ec_group_do_inverse_ord(group, u2, sig->s, ctx)) { 431 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 432 goto err; 433 } 434 /* digest -> m */ 435 i = BN_num_bits(order); 436 /* 437 * Need to truncate digest if it is too long: first truncate whole bytes. 438 */ 439 if (8 * dgst_len > i) 440 dgst_len = (i + 7) / 8; 441 if (!BN_bin2bn(dgst, dgst_len, m)) { 442 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 443 goto err; 444 } 445 /* If still too long truncate remaining bits with a shift */ 446 if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { 447 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 448 goto err; 449 } 450 /* u1 = m * tmp mod order */ 451 if (!BN_mod_mul(u1, m, u2, order, ctx)) { 452 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 453 goto err; 454 } 455 /* u2 = r * w mod q */ 456 if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { 457 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 458 goto err; 459 } 460 461 if ((point = EC_POINT_new(group)) == NULL) { 462 ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); 463 goto err; 464 } 465 if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { 466 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 467 goto err; 468 } 469 470 if (!EC_POINT_get_affine_coordinates(group, point, X, NULL, ctx)) { 471 ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); 472 goto err; 473 } 474 475 if (!BN_nnmod(u1, X, order, ctx)) { 476 ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB); 477 goto err; 478 } 479 /* if the signature is correct u1 is equal to sig->r */ 480 ret = (BN_ucmp(u1, sig->r) == 0); 481 err: 482 BN_CTX_end(ctx); 483 BN_CTX_free(ctx); 484 EC_POINT_free(point); 485 return ret; 486} 487