1 /* Originally written by Bodo Moeller for the OpenSSL project. 2 * ==================================================================== 3 * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in 14 * the documentation and/or other materials provided with the 15 * distribution. 16 * 17 * 3. All advertising materials mentioning features or use of this 18 * software must display the following acknowledgment: 19 * "This product includes software developed by the OpenSSL Project 20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 21 * 22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 23 * endorse or promote products derived from this software without 24 * prior written permission. For written permission, please contact 25 * openssl-core (at) openssl.org. 26 * 27 * 5. Products derived from this software may not be called "OpenSSL" 28 * nor may "OpenSSL" appear in their names without prior written 29 * permission of the OpenSSL Project. 30 * 31 * 6. Redistributions of any form whatsoever must retain the following 32 * acknowledgment: 33 * "This product includes software developed by the OpenSSL Project 34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 35 * 36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 47 * OF THE POSSIBILITY OF SUCH DAMAGE. 48 * ==================================================================== 49 * 50 * This product includes cryptographic software written by Eric Young 51 * (eay (at) cryptsoft.com). This product includes software written by Tim 52 * Hudson (tjh (at) cryptsoft.com). 53 * 54 */ 55 /* ==================================================================== 56 * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 57 * 58 * Portions of the attached software ("Contribution") are developed by 59 * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. 60 * 61 * The Contribution is licensed pursuant to the OpenSSL open source 62 * license provided above. 63 * 64 * The elliptic curve binary polynomial software is originally written by 65 * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems 66 * Laboratories. */ 67 68 #include <openssl/ec.h> 69 70 #include <assert.h> 71 #include <string.h> 72 73 #include <openssl/bn.h> 74 #include <openssl/err.h> 75 #include <openssl/mem.h> 76 #include <openssl/nid.h> 77 78 #include "internal.h" 79 #include "../../internal.h" 80 #include "../bn/internal.h" 81 #include "../delocate.h" 82 83 84 static void ec_point_free(EC_POINT *point, int free_group); 85 86 static const uint8_t kP224Params[6 * 28] = { 87 // p 88 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 89 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 90 0x00, 0x00, 0x00, 0x01, 91 // a 92 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 93 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 94 0xFF, 0xFF, 0xFF, 0xFE, 95 // b 96 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, 97 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, 98 0x23, 0x55, 0xFF, 0xB4, 99 // x 100 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, 101 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, 102 0x11, 0x5C, 0x1D, 0x21, 103 // y 104 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, 105 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, 106 0x85, 0x00, 0x7e, 0x34, 107 // order 108 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 109 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, 110 0x5C, 0x5C, 0x2A, 0x3D, 111 }; 112 113 static const uint8_t kP256Params[6 * 32] = { 114 // p 115 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 117 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 118 // a 119 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 121 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 122 // b 123 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, 124 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, 125 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, 126 // x 127 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, 128 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, 129 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, 130 // y 131 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 132 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 133 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, 134 // order 135 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 136 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 137 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51, 138 }; 139 140 static const uint8_t kP384Params[6 * 48] = { 141 // p 142 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 143 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 144 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 146 // a 147 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 148 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 149 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, 151 // b 152 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, 153 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, 154 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, 155 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, 156 // x 157 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, 158 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, 159 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, 160 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, 161 // y 162 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, 163 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, 164 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, 165 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, 166 // order 167 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 168 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 169 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, 170 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73, 171 }; 172 173 static const uint8_t kP521Params[6 * 66] = { 174 // p 175 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 176 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 177 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 178 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 179 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 180 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 181 // a 182 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 183 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 184 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 185 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 186 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 187 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 188 // b 189 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, 190 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, 191 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, 192 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, 193 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, 194 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, 195 // x 196 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, 197 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, 198 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, 199 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, 200 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, 201 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, 202 // y 203 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, 204 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, 205 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, 206 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, 207 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, 208 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, 209 // order 210 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 211 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 212 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, 213 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, 214 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, 215 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09, 216 }; 217 218 DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) { 219 // 1.3.132.0.35 220 static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; 221 out->curves[0].nid = NID_secp521r1; 222 out->curves[0].oid = kOIDP521; 223 out->curves[0].oid_len = sizeof(kOIDP521); 224 out->curves[0].comment = "NIST P-521"; 225 out->curves[0].param_len = 66; 226 out->curves[0].params = kP521Params; 227 out->curves[0].method = EC_GFp_mont_method(); 228 229 // 1.3.132.0.34 230 static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; 231 out->curves[1].nid = NID_secp384r1; 232 out->curves[1].oid = kOIDP384; 233 out->curves[1].oid_len = sizeof(kOIDP384); 234 out->curves[1].comment = "NIST P-384"; 235 out->curves[1].param_len = 48; 236 out->curves[1].params = kP384Params; 237 out->curves[1].method = EC_GFp_mont_method(); 238 239 // 1.2.840.10045.3.1.7 240 static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce, 241 0x3d, 0x03, 0x01, 0x07}; 242 out->curves[2].nid = NID_X9_62_prime256v1; 243 out->curves[2].oid = kOIDP256; 244 out->curves[2].oid_len = sizeof(kOIDP256); 245 out->curves[2].comment = "NIST P-256"; 246 out->curves[2].param_len = 32; 247 out->curves[2].params = kP256Params; 248 out->curves[2].method = 249 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ 250 !defined(OPENSSL_SMALL) 251 EC_GFp_nistz256_method(); 252 #else 253 EC_GFp_nistp256_method(); 254 #endif 255 256 // 1.3.132.0.33 257 static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21}; 258 out->curves[3].nid = NID_secp224r1; 259 out->curves[3].oid = kOIDP224; 260 out->curves[3].oid_len = sizeof(kOIDP224); 261 out->curves[3].comment = "NIST P-224"; 262 out->curves[3].param_len = 28; 263 out->curves[3].params = kP224Params; 264 out->curves[3].method = 265 #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) 266 EC_GFp_nistp224_method(); 267 #else 268 EC_GFp_mont_method(); 269 #endif 270 } 271 272 EC_GROUP *ec_group_new(const EC_METHOD *meth) { 273 EC_GROUP *ret; 274 275 if (meth == NULL) { 276 OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL); 277 return NULL; 278 } 279 280 if (meth->group_init == 0) { 281 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 282 return NULL; 283 } 284 285 ret = OPENSSL_malloc(sizeof(EC_GROUP)); 286 if (ret == NULL) { 287 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 288 return NULL; 289 } 290 OPENSSL_memset(ret, 0, sizeof(EC_GROUP)); 291 292 ret->references = 1; 293 ret->meth = meth; 294 BN_init(&ret->order); 295 296 if (!meth->group_init(ret)) { 297 OPENSSL_free(ret); 298 return NULL; 299 } 300 301 return ret; 302 } 303 304 static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) { 305 assert(group->generator == NULL); 306 assert(group == generator->group); 307 308 // Avoid a reference cycle. |group->generator| does not maintain an owning 309 // pointer to |group|. 310 group->generator = generator; 311 int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references); 312 313 assert(!is_zero); 314 (void)is_zero; 315 } 316 317 EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, 318 const BIGNUM *b, BN_CTX *ctx) { 319 if (BN_num_bytes(p) > EC_MAX_SCALAR_BYTES) { 320 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); 321 return NULL; 322 } 323 324 EC_GROUP *ret = ec_group_new(EC_GFp_mont_method()); 325 if (ret == NULL) { 326 return NULL; 327 } 328 329 if (ret->meth->group_set_curve == NULL) { 330 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 331 EC_GROUP_free(ret); 332 return NULL; 333 } 334 if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) { 335 EC_GROUP_free(ret); 336 return NULL; 337 } 338 return ret; 339 } 340 341 int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, 342 const BIGNUM *order, const BIGNUM *cofactor) { 343 if (group->curve_name != NID_undef || group->generator != NULL || 344 generator->group != group) { 345 // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by 346 // |EC_GROUP_new_curve_GFp| and may only used once on each group. 347 // Additionally, |generator| must been created from 348 // |EC_GROUP_new_curve_GFp|, not a copy, so that 349 // |generator->group->generator| is set correctly. 350 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 351 return 0; 352 } 353 354 if (BN_num_bytes(order) > EC_MAX_SCALAR_BYTES) { 355 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); 356 return 0; 357 } 358 359 // Require a cofactor of one for custom curves, which implies prime order. 360 if (!BN_is_one(cofactor)) { 361 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR); 362 return 0; 363 } 364 365 // Require that p < 2order. This simplifies some ECDSA operations. 366 // 367 // Note any curve which did not satisfy this must have been invalid or use a 368 // tiny prime (less than 17). See the proof in |field_element_to_scalar| in 369 // the ECDSA implementation. 370 BIGNUM *tmp = BN_new(); 371 if (tmp == NULL || 372 !BN_lshift1(tmp, order)) { 373 BN_free(tmp); 374 return 0; 375 } 376 int ok = BN_cmp(tmp, &group->field) > 0; 377 BN_free(tmp); 378 if (!ok) { 379 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); 380 return 0; 381 } 382 383 EC_POINT *copy = EC_POINT_new(group); 384 if (copy == NULL || 385 !EC_POINT_copy(copy, generator) || 386 !BN_copy(&group->order, order)) { 387 EC_POINT_free(copy); 388 return 0; 389 } 390 391 BN_MONT_CTX_free(group->order_mont); 392 group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL); 393 if (group->order_mont == NULL) { 394 return 0; 395 } 396 397 ec_group_set0_generator(group, copy); 398 return 1; 399 } 400 401 static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { 402 EC_GROUP *group = NULL; 403 EC_POINT *P = NULL; 404 BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; 405 int ok = 0; 406 407 BN_CTX *ctx = BN_CTX_new(); 408 if (ctx == NULL) { 409 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 410 goto err; 411 } 412 413 const unsigned param_len = curve->param_len; 414 const uint8_t *params = curve->params; 415 416 if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) || 417 !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) || 418 !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { 419 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 420 goto err; 421 } 422 423 group = ec_group_new(curve->method); 424 if (group == NULL || 425 !group->meth->group_set_curve(group, p, a, b, ctx)) { 426 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 427 goto err; 428 } 429 430 if ((P = EC_POINT_new(group)) == NULL) { 431 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 432 goto err; 433 } 434 435 if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) || 436 !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { 437 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 438 goto err; 439 } 440 441 if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { 442 OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); 443 goto err; 444 } 445 if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) { 446 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 447 goto err; 448 } 449 450 group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx); 451 if (group->order_mont == NULL) { 452 OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); 453 goto err; 454 } 455 456 ec_group_set0_generator(group, P); 457 P = NULL; 458 ok = 1; 459 460 err: 461 if (!ok) { 462 EC_GROUP_free(group); 463 group = NULL; 464 } 465 EC_POINT_free(P); 466 BN_CTX_free(ctx); 467 BN_free(p); 468 BN_free(a); 469 BN_free(b); 470 BN_free(x); 471 BN_free(y); 472 return group; 473 } 474 475 // Built-in groups are allocated lazily and static once allocated. 476 // TODO(davidben): Make these actually static. https://crbug.com/boringssl/20. 477 struct built_in_groups_st { 478 EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES]; 479 }; 480 DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups); 481 DEFINE_STATIC_MUTEX(built_in_groups_lock); 482 483 EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { 484 struct built_in_groups_st *groups = built_in_groups_bss_get(); 485 EC_GROUP **group_ptr = NULL; 486 const struct built_in_curves *const curves = OPENSSL_built_in_curves(); 487 const struct built_in_curve *curve = NULL; 488 for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { 489 if (curves->curves[i].nid == nid) { 490 curve = &curves->curves[i]; 491 group_ptr = &groups->groups[i]; 492 break; 493 } 494 } 495 496 if (curve == NULL) { 497 OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); 498 return NULL; 499 } 500 501 CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get()); 502 EC_GROUP *ret = *group_ptr; 503 CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get()); 504 if (ret != NULL) { 505 return ret; 506 } 507 508 ret = ec_group_new_from_data(curve); 509 if (ret == NULL) { 510 return NULL; 511 } 512 513 EC_GROUP *to_free = NULL; 514 CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get()); 515 if (*group_ptr == NULL) { 516 *group_ptr = ret; 517 // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup| 518 // into no-ops. At this point, |ret| is considered static. 519 ret->curve_name = nid; 520 } else { 521 to_free = ret; 522 ret = *group_ptr; 523 } 524 CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get()); 525 526 EC_GROUP_free(to_free); 527 return ret; 528 } 529 530 void EC_GROUP_free(EC_GROUP *group) { 531 if (group == NULL || 532 // Built-in curves are static. 533 group->curve_name != NID_undef || 534 !CRYPTO_refcount_dec_and_test_zero(&group->references)) { 535 return; 536 } 537 538 if (group->meth->group_finish != NULL) { 539 group->meth->group_finish(group); 540 } 541 542 ec_point_free(group->generator, 0 /* don't free group */); 543 BN_free(&group->order); 544 BN_MONT_CTX_free(group->order_mont); 545 546 OPENSSL_free(group); 547 } 548 549 EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { 550 if (a == NULL || 551 // Built-in curves are static. 552 a->curve_name != NID_undef) { 553 return (EC_GROUP *)a; 554 } 555 556 // Groups are logically immutable (but for |EC_GROUP_set_generator| which must 557 // be called early on), so we simply take a reference. 558 EC_GROUP *group = (EC_GROUP *)a; 559 CRYPTO_refcount_inc(&group->references); 560 return group; 561 } 562 563 int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { 564 // Note this function returns 0 if equal and non-zero otherwise. 565 if (a == b) { 566 return 0; 567 } 568 if (a->curve_name != b->curve_name) { 569 return 1; 570 } 571 if (a->curve_name != NID_undef) { 572 // Built-in curves may be compared by curve name alone. 573 return 0; 574 } 575 576 // |a| and |b| are both custom curves. We compare the entire curve 577 // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes, 578 // custom curve construction is sadly done in two parts) but otherwise not the 579 // same object, we consider them always unequal. 580 return a->generator == NULL || 581 b->generator == NULL || 582 BN_cmp(&a->order, &b->order) != 0 || 583 BN_cmp(&a->field, &b->field) != 0 || 584 BN_cmp(&a->a, &b->a) != 0 || 585 BN_cmp(&a->b, &b->b) != 0 || 586 ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0; 587 } 588 589 const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { 590 return group->generator; 591 } 592 593 const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) { 594 assert(!BN_is_zero(&group->order)); 595 return &group->order; 596 } 597 598 int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { 599 if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) { 600 return 0; 601 } 602 return 1; 603 } 604 605 int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, 606 BN_CTX *ctx) { 607 // All |EC_GROUP|s have cofactor 1. 608 return BN_set_word(cofactor, 1); 609 } 610 611 int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, 612 BIGNUM *out_b, BN_CTX *ctx) { 613 return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx); 614 } 615 616 int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } 617 618 unsigned EC_GROUP_get_degree(const EC_GROUP *group) { 619 return ec_GFp_simple_group_get_degree(group); 620 } 621 622 EC_POINT *EC_POINT_new(const EC_GROUP *group) { 623 EC_POINT *ret; 624 625 if (group == NULL) { 626 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 627 return NULL; 628 } 629 630 ret = OPENSSL_malloc(sizeof *ret); 631 if (ret == NULL) { 632 OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); 633 return NULL; 634 } 635 636 ret->group = EC_GROUP_dup(group); 637 if (ret->group == NULL || 638 !ec_GFp_simple_point_init(ret)) { 639 OPENSSL_free(ret); 640 return NULL; 641 } 642 643 return ret; 644 } 645 646 static void ec_point_free(EC_POINT *point, int free_group) { 647 if (!point) { 648 return; 649 } 650 ec_GFp_simple_point_finish(point); 651 if (free_group) { 652 EC_GROUP_free(point->group); 653 } 654 OPENSSL_free(point); 655 } 656 657 void EC_POINT_free(EC_POINT *point) { 658 ec_point_free(point, 1 /* free group */); 659 } 660 661 void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); } 662 663 int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { 664 if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) { 665 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 666 return 0; 667 } 668 if (dest == src) { 669 return 1; 670 } 671 return ec_GFp_simple_point_copy(dest, src); 672 } 673 674 EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { 675 if (a == NULL) { 676 return NULL; 677 } 678 679 EC_POINT *ret = EC_POINT_new(group); 680 if (ret == NULL || 681 !EC_POINT_copy(ret, a)) { 682 EC_POINT_free(ret); 683 return NULL; 684 } 685 686 return ret; 687 } 688 689 int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { 690 if (EC_GROUP_cmp(group, point->group, NULL) != 0) { 691 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 692 return 0; 693 } 694 return ec_GFp_simple_point_set_to_infinity(group, point); 695 } 696 697 int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { 698 if (EC_GROUP_cmp(group, point->group, NULL) != 0) { 699 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 700 return 0; 701 } 702 return ec_GFp_simple_is_at_infinity(group, point); 703 } 704 705 int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, 706 BN_CTX *ctx) { 707 if (EC_GROUP_cmp(group, point->group, NULL) != 0) { 708 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 709 return 0; 710 } 711 return ec_GFp_simple_is_on_curve(group, point, ctx); 712 } 713 714 int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, 715 BN_CTX *ctx) { 716 if (EC_GROUP_cmp(group, a->group, NULL) != 0 || 717 EC_GROUP_cmp(group, b->group, NULL) != 0) { 718 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 719 return -1; 720 } 721 return ec_GFp_simple_cmp(group, a, b, ctx); 722 } 723 724 int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { 725 if (EC_GROUP_cmp(group, point->group, NULL) != 0) { 726 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 727 return 0; 728 } 729 return ec_GFp_simple_make_affine(group, point, ctx); 730 } 731 732 int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], 733 BN_CTX *ctx) { 734 for (size_t i = 0; i < num; i++) { 735 if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) { 736 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 737 return 0; 738 } 739 } 740 return ec_GFp_simple_points_make_affine(group, num, points, ctx); 741 } 742 743 int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, 744 const EC_POINT *point, BIGNUM *x, 745 BIGNUM *y, BN_CTX *ctx) { 746 if (group->meth->point_get_affine_coordinates == 0) { 747 OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 748 return 0; 749 } 750 if (EC_GROUP_cmp(group, point->group, NULL) != 0) { 751 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 752 return 0; 753 } 754 return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); 755 } 756 757 int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point, 758 const BIGNUM *x, const BIGNUM *y, 759 BN_CTX *ctx) { 760 if (EC_GROUP_cmp(group, point->group, NULL) != 0) { 761 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 762 return 0; 763 } 764 if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) { 765 return 0; 766 } 767 768 if (!EC_POINT_is_on_curve(group, point, ctx)) { 769 // In the event of an error, defend against the caller not checking the 770 // return value by setting a known safe value: the base point. 771 const EC_POINT *generator = EC_GROUP_get0_generator(group); 772 // The generator can be missing if the caller is in the process of 773 // constructing an arbitrary group. In this, we give up and hope they're 774 // checking the return value. 775 if (generator) { 776 EC_POINT_copy(point, generator); 777 } 778 OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); 779 return 0; 780 } 781 782 return 1; 783 } 784 785 int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 786 const EC_POINT *b, BN_CTX *ctx) { 787 if (EC_GROUP_cmp(group, r->group, NULL) != 0 || 788 EC_GROUP_cmp(group, a->group, NULL) != 0 || 789 EC_GROUP_cmp(group, b->group, NULL) != 0) { 790 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 791 return 0; 792 } 793 return ec_GFp_simple_add(group, r, a, b, ctx); 794 } 795 796 797 int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, 798 BN_CTX *ctx) { 799 if (EC_GROUP_cmp(group, r->group, NULL) != 0 || 800 EC_GROUP_cmp(group, a->group, NULL) != 0) { 801 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 802 return 0; 803 } 804 return ec_GFp_simple_dbl(group, r, a, ctx); 805 } 806 807 808 int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { 809 if (EC_GROUP_cmp(group, a->group, NULL) != 0) { 810 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 811 return 0; 812 } 813 return ec_GFp_simple_invert(group, a, ctx); 814 } 815 816 static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, 817 const BIGNUM *in, BN_CTX *ctx) { 818 if (ec_bignum_to_scalar(group, out, in)) { 819 return 1; 820 } 821 822 ERR_clear_error(); 823 824 // This is an unusual input, so we do not guarantee constant-time 825 // processing, even ignoring |bn_correct_top|. 826 const BIGNUM *order = &group->order; 827 BN_CTX_start(ctx); 828 BIGNUM *tmp = BN_CTX_get(ctx); 829 int ok = tmp != NULL && 830 BN_nnmod(tmp, in, order, ctx) && 831 ec_bignum_to_scalar_unchecked(group, out, tmp); 832 BN_CTX_end(ctx); 833 return ok; 834 } 835 836 int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, 837 const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { 838 // Previously, this function set |r| to the point at infinity if there was 839 // nothing to multiply. But, nobody should be calling this function with 840 // nothing to multiply in the first place. 841 if ((g_scalar == NULL && p_scalar == NULL) || 842 (p == NULL) != (p_scalar == NULL)) { 843 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 844 return 0; 845 } 846 847 int ret = 0; 848 EC_SCALAR g_scalar_storage, p_scalar_storage; 849 EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL; 850 BN_CTX *new_ctx = NULL; 851 if (ctx == NULL) { 852 new_ctx = BN_CTX_new(); 853 if (new_ctx == NULL) { 854 goto err; 855 } 856 ctx = new_ctx; 857 } 858 859 if (g_scalar != NULL) { 860 if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) { 861 goto err; 862 } 863 g_scalar_arg = &g_scalar_storage; 864 } 865 866 if (p_scalar != NULL) { 867 if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) { 868 goto err; 869 } 870 p_scalar_arg = &p_scalar_storage; 871 } 872 873 ret = ec_point_mul_scalar(group, r, g_scalar_arg, p, p_scalar_arg, ctx); 874 875 err: 876 BN_CTX_free(new_ctx); 877 OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage)); 878 OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage)); 879 return ret; 880 } 881 882 int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r, 883 const EC_SCALAR *g_scalar, const EC_POINT *p, 884 const EC_SCALAR *p_scalar, BN_CTX *ctx) { 885 if ((g_scalar == NULL && p_scalar == NULL) || 886 (p == NULL) != (p_scalar == NULL)) { 887 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 888 return 0; 889 } 890 891 if (EC_GROUP_cmp(group, r->group, NULL) != 0 || 892 (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { 893 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 894 return 0; 895 } 896 897 return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx); 898 } 899 900 int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r, 901 const EC_SCALAR *g_scalar, const EC_POINT *p, 902 const EC_SCALAR *p_scalar, BN_CTX *ctx) { 903 if ((g_scalar == NULL && p_scalar == NULL) || 904 (p == NULL) != (p_scalar == NULL)) { 905 OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); 906 return 0; 907 } 908 909 if (EC_GROUP_cmp(group, r->group, NULL) != 0 || 910 (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { 911 OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); 912 return 0; 913 } 914 915 return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx); 916 } 917 918 void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} 919 920 const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { 921 return NULL; 922 } 923 924 int EC_METHOD_get_field_type(const EC_METHOD *meth) { 925 return NID_X9_62_prime_field; 926 } 927 928 void EC_GROUP_set_point_conversion_form(EC_GROUP *group, 929 point_conversion_form_t form) { 930 if (form != POINT_CONVERSION_UNCOMPRESSED) { 931 abort(); 932 } 933 } 934 935 size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, 936 size_t max_num_curves) { 937 const struct built_in_curves *const curves = OPENSSL_built_in_curves(); 938 939 for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES; 940 i++) { 941 out_curves[i].comment = curves->curves[i].comment; 942 out_curves[i].nid = curves->curves[i].nid; 943 } 944 945 return OPENSSL_NUM_BUILT_IN_CURVES; 946 } 947 948 int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, 949 const BIGNUM *in) { 950 if (!ec_bignum_to_scalar_unchecked(group, out, in)) { 951 return 0; 952 } 953 if (!bn_less_than_words(out->words, group->order.d, group->order.top)) { 954 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); 955 return 0; 956 } 957 return 1; 958 } 959 960 int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out, 961 const BIGNUM *in) { 962 if (!bn_copy_words(out->words, group->order.top, in)) { 963 OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); 964 return 0; 965 } 966 return 1; 967 } 968 969 int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, 970 const uint8_t additional_data[32]) { 971 return bn_rand_range_words(out->words, 1, group->order.d, group->order.top, 972 additional_data); 973 } 974