1/*
2 * Copyright 2001-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 <limits.h>
12
13#include <openssl/err.h>
14#include <openssl/obj_mac.h>
15#include "ec_local.h"
16
17const EC_METHOD *EC_GFp_nist_method(void)
18{
19    static const EC_METHOD ret = {
20        EC_FLAGS_DEFAULT_OCT,
21        NID_X9_62_prime_field,
22        ec_GFp_simple_group_init,
23        ec_GFp_simple_group_finish,
24        ec_GFp_simple_group_clear_finish,
25        ec_GFp_nist_group_copy,
26        ec_GFp_nist_group_set_curve,
27        ec_GFp_simple_group_get_curve,
28        ec_GFp_simple_group_get_degree,
29        ec_group_simple_order_bits,
30        ec_GFp_simple_group_check_discriminant,
31        ec_GFp_simple_point_init,
32        ec_GFp_simple_point_finish,
33        ec_GFp_simple_point_clear_finish,
34        ec_GFp_simple_point_copy,
35        ec_GFp_simple_point_set_to_infinity,
36        ec_GFp_simple_set_Jprojective_coordinates_GFp,
37        ec_GFp_simple_get_Jprojective_coordinates_GFp,
38        ec_GFp_simple_point_set_affine_coordinates,
39        ec_GFp_simple_point_get_affine_coordinates,
40        0, 0, 0,
41        ec_GFp_simple_add,
42        ec_GFp_simple_dbl,
43        ec_GFp_simple_invert,
44        ec_GFp_simple_is_at_infinity,
45        ec_GFp_simple_is_on_curve,
46        ec_GFp_simple_cmp,
47        ec_GFp_simple_make_affine,
48        ec_GFp_simple_points_make_affine,
49        0 /* mul */ ,
50        0 /* precompute_mult */ ,
51        0 /* have_precompute_mult */ ,
52        ec_GFp_nist_field_mul,
53        ec_GFp_nist_field_sqr,
54        0 /* field_div */ ,
55        ec_GFp_simple_field_inv,
56        0 /* field_encode */ ,
57        0 /* field_decode */ ,
58        0,                      /* field_set_to_one */
59        ec_key_simple_priv2oct,
60        ec_key_simple_oct2priv,
61        0, /* set private */
62        ec_key_simple_generate_key,
63        ec_key_simple_check_key,
64        ec_key_simple_generate_public_key,
65        0, /* keycopy */
66        0, /* keyfinish */
67        ecdh_simple_compute_key,
68        0, /* field_inverse_mod_ord */
69        ec_GFp_simple_blind_coordinates,
70        ec_GFp_simple_ladder_pre,
71        ec_GFp_simple_ladder_step,
72        ec_GFp_simple_ladder_post
73    };
74
75    return &ret;
76}
77
78int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src)
79{
80    dest->field_mod_func = src->field_mod_func;
81
82    return ec_GFp_simple_group_copy(dest, src);
83}
84
85int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p,
86                                const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
87{
88    int ret = 0;
89    BN_CTX *new_ctx = NULL;
90
91    if (ctx == NULL)
92        if ((ctx = new_ctx = BN_CTX_new()) == NULL)
93            return 0;
94
95    BN_CTX_start(ctx);
96
97    if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0)
98        group->field_mod_func = BN_nist_mod_192;
99    else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0)
100        group->field_mod_func = BN_nist_mod_224;
101    else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0)
102        group->field_mod_func = BN_nist_mod_256;
103    else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0)
104        group->field_mod_func = BN_nist_mod_384;
105    else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0)
106        group->field_mod_func = BN_nist_mod_521;
107    else {
108        ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME);
109        goto err;
110    }
111
112    ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
113
114 err:
115    BN_CTX_end(ctx);
116    BN_CTX_free(new_ctx);
117    return ret;
118}
119
120int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
121                          const BIGNUM *b, BN_CTX *ctx)
122{
123    int ret = 0;
124    BN_CTX *ctx_new = NULL;
125
126    if (!group || !r || !a || !b) {
127        ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER);
128        goto err;
129    }
130    if (!ctx)
131        if ((ctx_new = ctx = BN_CTX_new()) == NULL)
132            goto err;
133
134    if (!BN_mul(r, a, b, ctx))
135        goto err;
136    if (!group->field_mod_func(r, r, group->field, ctx))
137        goto err;
138
139    ret = 1;
140 err:
141    BN_CTX_free(ctx_new);
142    return ret;
143}
144
145int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
146                          BN_CTX *ctx)
147{
148    int ret = 0;
149    BN_CTX *ctx_new = NULL;
150
151    if (!group || !r || !a) {
152        ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER);
153        goto err;
154    }
155    if (!ctx)
156        if ((ctx_new = ctx = BN_CTX_new()) == NULL)
157            goto err;
158
159    if (!BN_sqr(r, a, ctx))
160        goto err;
161    if (!group->field_mod_func(r, r, group->field, ctx))
162        goto err;
163
164    ret = 1;
165 err:
166    BN_CTX_free(ctx_new);
167    return ret;
168}
169