-/* $OpenBSD: ecs_ossl.c,v 1.68 2023/07/04 10:53:42 tb Exp $ */
+/* $OpenBSD: ecs_ossl.c,v 1.69 2023/07/04 14:57:05 tb Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project
*/
return ret;
}
+/*
+ * FIPS 186-5, section 6.4.1, steps 3-8 and 11: Generate k, calculate r and
+ * kinv, and clear it. If r == 0, try again with a new random k.
+ */
+
int
ossl_ecdsa_sign_setup(EC_KEY *key, BN_CTX *in_ctx, BIGNUM **out_kinv,
BIGNUM **out_r)
!BN_set_bit(x, order_bits))
goto err;
+ /* Step 11: repeat until r != 0. */
do {
+ /* Step 3: generate random k. */
if (!bn_rand_interval(k, BN_value_one(), order)) {
ECDSAerror(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
BN_set_flags(k, BN_FLG_CONSTTIME);
- /* Compute r, the x-coordinate of G * k. */
+ /* Step 5: P = k * G. */
if (!EC_POINT_mul(group, point, k, NULL, NULL, ctx)) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
+ /* Steps 6 (and 7): from P = (x, y) retain the x-coordinate. */
if (!EC_POINT_get_affine_coordinates(group, point, x, NULL,
ctx)) {
ECDSAerror(ERR_R_EC_LIB);
goto err;
}
+ /* Step 8: r = x (mod order). */
if (!BN_nnmod(r, x, order, ctx)) {
ECDSAerror(ERR_R_BN_LIB);
goto err;
}
} while (BN_is_zero(r));
+ /* Step 4: calculate kinv. */
if (BN_mod_inverse_ct(k, k, order, ctx) == NULL) {
ECDSAerror(ERR_R_BN_LIB);
goto err;
goto err;
}
+ /* Step 11: if s == 0 start over. */
if (!BN_is_zero(s)) {
*out_s = s;
s = NULL;
*/
#define ECDSA_MAX_SIGN_ITERATIONS 32
+/*
+ * FIPS 186-5: Section 6.4.1: ECDSA signature generation, steps 2-12.
+ * The caller provides the hash of the message, thus performs step 1.
+ * Step 10, zeroing k and kinv, is done by BN_free().
+ */
+
ECDSA_SIG *
ossl_ecdsa_sign_sig(const unsigned char *digest, int digest_len,
const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *key)
if ((e = BN_CTX_get(ctx)) == NULL)
goto err;
+ /* Step 2: convert hash into an integer. */
if (!ecdsa_prepare_digest(digest, digest_len, key, e))
goto err;
}
do {
+ /* Steps 3-8: calculate kinv and r. */
if (!caller_supplied_values) {
if (!ECDSA_sign_setup(key, ctx, &kinv, &r)) {
ECDSAerror(ERR_R_ECDSA_LIB);
}
}
- /* If s is non-NULL, we have a valid signature. */
+ /*
+ * Steps 9 and 11: if s is non-NULL, we have a valid signature.
+ */
if (!ecdsa_compute_s(&s, e, kinv, r, key, ctx))
goto err;
if (s != NULL)
}
} while (1);
+ /* Step 12: output (r, s). */
if ((sig = ECDSA_SIG_new()) == NULL) {
ECDSAerror(ERR_R_MALLOC_FAILURE);
goto err;