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