1 /* 2 * Copyright 2001-2018 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_lcl.h" 16 17 const 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 0 /* field_encode */ , 56 0 /* field_decode */ , 57 0, /* field_set_to_one */ 58 ec_key_simple_priv2oct, 59 ec_key_simple_oct2priv, 60 0, /* set private */ 61 ec_key_simple_generate_key, 62 ec_key_simple_check_key, 63 ec_key_simple_generate_public_key, 64 0, /* keycopy */ 65 0, /* keyfinish */ 66 ecdh_simple_compute_key, 67 0, /* field_inverse_mod_ord */ 68 ec_GFp_simple_blind_coordinates, 69 ec_GFp_simple_ladder_pre, 70 ec_GFp_simple_ladder_step, 71 ec_GFp_simple_ladder_post 72 }; 73 74 return &ret; 75 } 76 77 int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) 78 { 79 dest->field_mod_func = src->field_mod_func; 80 81 return ec_GFp_simple_group_copy(dest, src); 82 } 83 84 int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, 85 const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) 86 { 87 int ret = 0; 88 BN_CTX *new_ctx = NULL; 89 90 if (ctx == NULL) 91 if ((ctx = new_ctx = BN_CTX_new()) == NULL) 92 return 0; 93 94 BN_CTX_start(ctx); 95 96 if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) 97 group->field_mod_func = BN_nist_mod_192; 98 else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) 99 group->field_mod_func = BN_nist_mod_224; 100 else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) 101 group->field_mod_func = BN_nist_mod_256; 102 else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) 103 group->field_mod_func = BN_nist_mod_384; 104 else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) 105 group->field_mod_func = BN_nist_mod_521; 106 else { 107 ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME); 108 goto err; 109 } 110 111 ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); 112 113 err: 114 BN_CTX_end(ctx); 115 BN_CTX_free(new_ctx); 116 return ret; 117 } 118 119 int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, 120 const BIGNUM *b, BN_CTX *ctx) 121 { 122 int ret = 0; 123 BN_CTX *ctx_new = NULL; 124 125 if (!group || !r || !a || !b) { 126 ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER); 127 goto err; 128 } 129 if (!ctx) 130 if ((ctx_new = ctx = BN_CTX_new()) == NULL) 131 goto err; 132 133 if (!BN_mul(r, a, b, ctx)) 134 goto err; 135 if (!group->field_mod_func(r, r, group->field, ctx)) 136 goto err; 137 138 ret = 1; 139 err: 140 BN_CTX_free(ctx_new); 141 return ret; 142 } 143 144 int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, 145 BN_CTX *ctx) 146 { 147 int ret = 0; 148 BN_CTX *ctx_new = NULL; 149 150 if (!group || !r || !a) { 151 ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); 152 goto err; 153 } 154 if (!ctx) 155 if ((ctx_new = ctx = BN_CTX_new()) == NULL) 156 goto err; 157 158 if (!BN_sqr(r, a, ctx)) 159 goto err; 160 if (!group->field_mod_func(r, r, group->field, ctx)) 161 goto err; 162 163 ret = 1; 164 err: 165 BN_CTX_free(ctx_new); 166 return ret; 167 } 168