xref: /third_party/openssl/crypto/ec/ecp_nist.c (revision e1051a39)
1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4e1051a39Sopenharmony_ci *
5e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
6e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
7e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
8e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
9e1051a39Sopenharmony_ci */
10e1051a39Sopenharmony_ci
11e1051a39Sopenharmony_ci/*
12e1051a39Sopenharmony_ci * ECDSA low level APIs are deprecated for public use, but still ok for
13e1051a39Sopenharmony_ci * internal use.
14e1051a39Sopenharmony_ci */
15e1051a39Sopenharmony_ci#include "internal/deprecated.h"
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_ci#include <limits.h>
18e1051a39Sopenharmony_ci
19e1051a39Sopenharmony_ci#include <openssl/err.h>
20e1051a39Sopenharmony_ci#include <openssl/obj_mac.h>
21e1051a39Sopenharmony_ci#include "ec_local.h"
22e1051a39Sopenharmony_ci
23e1051a39Sopenharmony_ciconst EC_METHOD *EC_GFp_nist_method(void)
24e1051a39Sopenharmony_ci{
25e1051a39Sopenharmony_ci    static const EC_METHOD ret = {
26e1051a39Sopenharmony_ci        EC_FLAGS_DEFAULT_OCT,
27e1051a39Sopenharmony_ci        NID_X9_62_prime_field,
28e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_group_init,
29e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_group_finish,
30e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_group_clear_finish,
31e1051a39Sopenharmony_ci        ossl_ec_GFp_nist_group_copy,
32e1051a39Sopenharmony_ci        ossl_ec_GFp_nist_group_set_curve,
33e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_group_get_curve,
34e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_group_get_degree,
35e1051a39Sopenharmony_ci        ossl_ec_group_simple_order_bits,
36e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_group_check_discriminant,
37e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_init,
38e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_finish,
39e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_clear_finish,
40e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_copy,
41e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_set_to_infinity,
42e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_set_affine_coordinates,
43e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_point_get_affine_coordinates,
44e1051a39Sopenharmony_ci        0, 0, 0,
45e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_add,
46e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_dbl,
47e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_invert,
48e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_is_at_infinity,
49e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_is_on_curve,
50e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_cmp,
51e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_make_affine,
52e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_points_make_affine,
53e1051a39Sopenharmony_ci        0 /* mul */ ,
54e1051a39Sopenharmony_ci        0 /* precompute_mult */ ,
55e1051a39Sopenharmony_ci        0 /* have_precompute_mult */ ,
56e1051a39Sopenharmony_ci        ossl_ec_GFp_nist_field_mul,
57e1051a39Sopenharmony_ci        ossl_ec_GFp_nist_field_sqr,
58e1051a39Sopenharmony_ci        0 /* field_div */ ,
59e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_field_inv,
60e1051a39Sopenharmony_ci        0 /* field_encode */ ,
61e1051a39Sopenharmony_ci        0 /* field_decode */ ,
62e1051a39Sopenharmony_ci        0,                      /* field_set_to_one */
63e1051a39Sopenharmony_ci        ossl_ec_key_simple_priv2oct,
64e1051a39Sopenharmony_ci        ossl_ec_key_simple_oct2priv,
65e1051a39Sopenharmony_ci        0, /* set private */
66e1051a39Sopenharmony_ci        ossl_ec_key_simple_generate_key,
67e1051a39Sopenharmony_ci        ossl_ec_key_simple_check_key,
68e1051a39Sopenharmony_ci        ossl_ec_key_simple_generate_public_key,
69e1051a39Sopenharmony_ci        0, /* keycopy */
70e1051a39Sopenharmony_ci        0, /* keyfinish */
71e1051a39Sopenharmony_ci        ossl_ecdh_simple_compute_key,
72e1051a39Sopenharmony_ci        ossl_ecdsa_simple_sign_setup,
73e1051a39Sopenharmony_ci        ossl_ecdsa_simple_sign_sig,
74e1051a39Sopenharmony_ci        ossl_ecdsa_simple_verify_sig,
75e1051a39Sopenharmony_ci        0, /* field_inverse_mod_ord */
76e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_blind_coordinates,
77e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_ladder_pre,
78e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_ladder_step,
79e1051a39Sopenharmony_ci        ossl_ec_GFp_simple_ladder_post
80e1051a39Sopenharmony_ci    };
81e1051a39Sopenharmony_ci
82e1051a39Sopenharmony_ci    return &ret;
83e1051a39Sopenharmony_ci}
84e1051a39Sopenharmony_ci
85e1051a39Sopenharmony_ciint ossl_ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
86e1051a39Sopenharmony_ci{
87e1051a39Sopenharmony_ci    dest->field_mod_func = src->field_mod_func;
88e1051a39Sopenharmony_ci
89e1051a39Sopenharmony_ci    return ossl_ec_GFp_simple_group_copy(dest, src);
90e1051a39Sopenharmony_ci}
91e1051a39Sopenharmony_ci
92e1051a39Sopenharmony_ciint ossl_ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
93e1051a39Sopenharmony_ci                                     const BIGNUM *a, const BIGNUM *b,
94e1051a39Sopenharmony_ci                                     BN_CTX *ctx)
95e1051a39Sopenharmony_ci{
96e1051a39Sopenharmony_ci    int ret = 0;
97e1051a39Sopenharmony_ci    BN_CTX *new_ctx = NULL;
98e1051a39Sopenharmony_ci
99e1051a39Sopenharmony_ci    if (ctx == NULL)
100e1051a39Sopenharmony_ci        if ((ctx = new_ctx = BN_CTX_new_ex(group->libctx)) == NULL)
101e1051a39Sopenharmony_ci            return 0;
102e1051a39Sopenharmony_ci
103e1051a39Sopenharmony_ci    BN_CTX_start(ctx);
104e1051a39Sopenharmony_ci
105e1051a39Sopenharmony_ci    if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
106e1051a39Sopenharmony_ci        group->field_mod_func = BN_nist_mod_192;
107e1051a39Sopenharmony_ci    else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
108e1051a39Sopenharmony_ci        group->field_mod_func = BN_nist_mod_224;
109e1051a39Sopenharmony_ci    else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
110e1051a39Sopenharmony_ci        group->field_mod_func = BN_nist_mod_256;
111e1051a39Sopenharmony_ci    else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
112e1051a39Sopenharmony_ci        group->field_mod_func = BN_nist_mod_384;
113e1051a39Sopenharmony_ci    else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
114e1051a39Sopenharmony_ci        group->field_mod_func = BN_nist_mod_521;
115e1051a39Sopenharmony_ci    else {
116e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EC, EC_R_NOT_A_NIST_PRIME);
117e1051a39Sopenharmony_ci        goto err;
118e1051a39Sopenharmony_ci    }
119e1051a39Sopenharmony_ci
120e1051a39Sopenharmony_ci    ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
121e1051a39Sopenharmony_ci
122e1051a39Sopenharmony_ci err:
123e1051a39Sopenharmony_ci    BN_CTX_end(ctx);
124e1051a39Sopenharmony_ci    BN_CTX_free(new_ctx);
125e1051a39Sopenharmony_ci    return ret;
126e1051a39Sopenharmony_ci}
127e1051a39Sopenharmony_ci
128e1051a39Sopenharmony_ciint ossl_ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
129e1051a39Sopenharmony_ci                               const BIGNUM *b, BN_CTX *ctx)
130e1051a39Sopenharmony_ci{
131e1051a39Sopenharmony_ci    int ret = 0;
132e1051a39Sopenharmony_ci    BN_CTX *ctx_new = NULL;
133e1051a39Sopenharmony_ci
134e1051a39Sopenharmony_ci    if (!group || !r || !a || !b) {
135e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
136e1051a39Sopenharmony_ci        goto err;
137e1051a39Sopenharmony_ci    }
138e1051a39Sopenharmony_ci    if (!ctx)
139e1051a39Sopenharmony_ci        if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL)
140e1051a39Sopenharmony_ci            goto err;
141e1051a39Sopenharmony_ci
142e1051a39Sopenharmony_ci    if (!BN_mul(r, a, b, ctx))
143e1051a39Sopenharmony_ci        goto err;
144e1051a39Sopenharmony_ci    if (!group->field_mod_func(r, r, group->field, ctx))
145e1051a39Sopenharmony_ci        goto err;
146e1051a39Sopenharmony_ci
147e1051a39Sopenharmony_ci    ret = 1;
148e1051a39Sopenharmony_ci err:
149e1051a39Sopenharmony_ci    BN_CTX_free(ctx_new);
150e1051a39Sopenharmony_ci    return ret;
151e1051a39Sopenharmony_ci}
152e1051a39Sopenharmony_ci
153e1051a39Sopenharmony_ciint ossl_ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
154e1051a39Sopenharmony_ci                               BN_CTX *ctx)
155e1051a39Sopenharmony_ci{
156e1051a39Sopenharmony_ci    int ret = 0;
157e1051a39Sopenharmony_ci    BN_CTX *ctx_new = NULL;
158e1051a39Sopenharmony_ci
159e1051a39Sopenharmony_ci    if (!group || !r || !a) {
160e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_EC, EC_R_PASSED_NULL_PARAMETER);
161e1051a39Sopenharmony_ci        goto err;
162e1051a39Sopenharmony_ci    }
163e1051a39Sopenharmony_ci    if (!ctx)
164e1051a39Sopenharmony_ci        if ((ctx_new = ctx = BN_CTX_new_ex(group->libctx)) == NULL)
165e1051a39Sopenharmony_ci            goto err;
166e1051a39Sopenharmony_ci
167e1051a39Sopenharmony_ci    if (!BN_sqr(r, a, ctx))
168e1051a39Sopenharmony_ci        goto err;
169e1051a39Sopenharmony_ci    if (!group->field_mod_func(r, r, group->field, ctx))
170e1051a39Sopenharmony_ci        goto err;
171e1051a39Sopenharmony_ci
172e1051a39Sopenharmony_ci    ret = 1;
173e1051a39Sopenharmony_ci err:
174e1051a39Sopenharmony_ci    BN_CTX_free(ctx_new);
175e1051a39Sopenharmony_ci    return ret;
176e1051a39Sopenharmony_ci}
177