dh.c revision 1.23
1/* $OpenBSD: dh.c,v 1.23 2021/11/29 06:42:13 deraadt Exp $ */ 2 3/* 4 * Copyright (c) 2010-2014 Reyk Floeter <reyk@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <string.h> 20 21#include <openssl/obj_mac.h> 22#include <openssl/dh.h> 23#include <openssl/ec.h> 24#include <openssl/ecdh.h> 25#include <openssl/bn.h> 26 27#include "dh.h" 28 29#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) 30 31int dh_init(struct group *); 32 33int modp_init(struct group *); 34int modp_getlen(struct group *); 35int modp_create_exchange(struct group *, u_int8_t *); 36int modp_create_shared(struct group *, u_int8_t *, u_int8_t *); 37 38int ec_init(struct group *); 39int ec_getlen(struct group *); 40int ec_secretlen(struct group *); 41int ec_create_exchange(struct group *, u_int8_t *); 42int ec_create_shared(struct group *, u_int8_t *, u_int8_t *); 43 44#define EC_POINT2RAW_FULL 0 45#define EC_POINT2RAW_XONLY 1 46int ec_point2raw(struct group *, const EC_POINT *, uint8_t *, size_t, int); 47EC_POINT * 48 ec_raw2point(struct group *, u_int8_t *, size_t); 49 50struct group_id ike_groups[] = { 51 { GROUP_MODP, 1, 768, 52 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 53 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 54 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 55 "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF", 56 "02" 57 }, 58 { GROUP_MODP, 2, 1024, 59 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 60 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 61 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 62 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 63 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" 64 "FFFFFFFFFFFFFFFF", 65 "02" 66 }, 67 { GROUP_EC2N, 3, 155, NULL, NULL, NID_ipsec3 }, 68 { GROUP_EC2N, 4, 185, NULL, NULL, NID_ipsec4 }, 69 { GROUP_MODP, 5, 1536, 70 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 71 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 72 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 73 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 74 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 75 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 76 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 77 "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF", 78 "02" 79 }, 80 { GROUP_MODP, 14, 2048, 81 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 82 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 83 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 84 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 85 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 86 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 87 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 88 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 89 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 90 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 91 "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 92 "02" 93 }, 94 { GROUP_MODP, 15, 3072, 95 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 96 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 97 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 98 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 99 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 100 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 101 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 102 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 103 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 104 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 105 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 106 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 107 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 108 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 109 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 110 "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF", 111 "02" 112 }, 113 { GROUP_MODP, 16, 4096, 114 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 115 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 116 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 117 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 118 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 119 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 120 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 121 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 122 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 123 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 124 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 125 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 126 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 127 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 128 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 129 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 130 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 131 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 132 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 133 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 134 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199" 135 "FFFFFFFFFFFFFFFF", 136 "02" 137 }, 138 { GROUP_MODP, 17, 6144, 139 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 140 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 141 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 142 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 143 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 144 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 145 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 146 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 147 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 148 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 149 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 150 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 151 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 152 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 153 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 154 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 155 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 156 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 157 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 158 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 159 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" 160 "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" 161 "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" 162 "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" 163 "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" 164 "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" 165 "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" 166 "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" 167 "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" 168 "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" 169 "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" 170 "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF", 171 "02" 172 }, 173 { GROUP_MODP, 18, 8192, 174 "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" 175 "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" 176 "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" 177 "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" 178 "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" 179 "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" 180 "83655D23DCA3AD961C62F356208552BB9ED529077096966D" 181 "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" 182 "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" 183 "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" 184 "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64" 185 "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7" 186 "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B" 187 "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C" 188 "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31" 189 "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7" 190 "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA" 191 "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6" 192 "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED" 193 "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9" 194 "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492" 195 "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD" 196 "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831" 197 "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B" 198 "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF" 199 "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6" 200 "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3" 201 "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA" 202 "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328" 203 "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C" 204 "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE" 205 "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4" 206 "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300" 207 "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568" 208 "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9" 209 "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B" 210 "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A" 211 "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36" 212 "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1" 213 "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92" 214 "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47" 215 "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71" 216 "60C980DD98EDD3DFFFFFFFFFFFFFFFFF", 217 "02" 218 }, 219 { GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 }, 220 { GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 }, 221 { GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 }, 222 { GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 }, 223 { GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 }, 224 { GROUP_ECP, 27, 224, NULL, NULL, NID_brainpoolP224r1 }, 225 { GROUP_ECP, 28, 256, NULL, NULL, NID_brainpoolP256r1 }, 226 { GROUP_ECP, 29, 384, NULL, NULL, NID_brainpoolP384r1 }, 227 { GROUP_ECP, 30, 512, NULL, NULL, NID_brainpoolP512r1 } 228}; 229 230void 231group_init(void) 232{ 233 /* currently not used */ 234 return; 235} 236 237void 238group_free(struct group *group) 239{ 240 if (group == NULL) 241 return; 242 if (group->dh != NULL) 243 DH_free(group->dh); 244 if (group->ec != NULL) 245 EC_KEY_free(group->ec); 246 group->spec = NULL; 247 free(group); 248} 249 250struct group * 251group_get(u_int32_t id) 252{ 253 struct group_id *p = NULL; 254 struct group *group; 255 u_int i, items; 256 257 items = sizeof(ike_groups) / sizeof(ike_groups[0]); 258 for (i = 0; i < items; i++) { 259 if (id == ike_groups[i].id) { 260 p = &ike_groups[i]; 261 break; 262 } 263 } 264 if (p == NULL) 265 return (NULL); 266 267 if ((group = calloc(1, sizeof(*group))) == NULL) 268 return (NULL); 269 270 group->id = id; 271 group->spec = p; 272 273 switch (p->type) { 274 case GROUP_MODP: 275 group->init = modp_init; 276 group->getlen = modp_getlen; 277 group->exchange = modp_create_exchange; 278 group->shared = modp_create_shared; 279 break; 280 case GROUP_EC2N: 281 case GROUP_ECP: 282 group->init = ec_init; 283 group->getlen = ec_getlen; 284 group->secretlen = ec_secretlen; 285 group->exchange = ec_create_exchange; 286 group->shared = ec_create_shared; 287 break; 288 default: 289 group_free(group); 290 return (NULL); 291 } 292 293 if (dh_init(group) != 0) { 294 group_free(group); 295 return (NULL); 296 } 297 298 return (group); 299} 300 301int 302dh_init(struct group *group) 303{ 304 return (group->init(group)); 305} 306 307int 308dh_getlen(struct group *group) 309{ 310 return (group->getlen(group)); 311} 312 313int 314dh_secretlen(struct group *group) 315{ 316 if (group->secretlen) 317 return (group->secretlen(group)); 318 else 319 return (group->getlen(group)); 320} 321 322int 323dh_create_exchange(struct group *group, u_int8_t *buf) 324{ 325 return (group->exchange(group, buf)); 326} 327 328int 329dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 330{ 331 return (group->shared(group, secret, exchange)); 332} 333 334int 335modp_init(struct group *group) 336{ 337 DH *dh; 338 339 if ((dh = DH_new()) == NULL) 340 return (-1); 341 group->dh = dh; 342 343 if (!BN_hex2bn(&dh->p, group->spec->prime) || 344 !BN_hex2bn(&dh->g, group->spec->generator)) 345 return (-1); 346 347 return (0); 348} 349 350int 351modp_getlen(struct group *group) 352{ 353 if (group->spec == NULL) 354 return (0); 355 return (roundup(group->spec->bits, 8) / 8); 356} 357 358int 359modp_create_exchange(struct group *group, u_int8_t *buf) 360{ 361 DH *dh = group->dh; 362 int len, ret; 363 364 if (!DH_generate_key(dh)) 365 return (-1); 366 ret = BN_bn2bin(dh->pub_key, buf); 367 if (!ret) 368 return (-1); 369 370 len = dh_getlen(group); 371 372 /* add zero padding */ 373 if (ret < len) { 374 bcopy(buf, buf + (len - ret), ret); 375 bzero(buf, len - ret); 376 } 377 378 return (0); 379} 380 381int 382modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 383{ 384 BIGNUM *ex; 385 int len, ret; 386 387 len = dh_getlen(group); 388 389 if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL) 390 return (-1); 391 392 ret = DH_compute_key(secret, ex, group->dh); 393 BN_clear_free(ex); 394 if (ret <= 0) 395 return (-1); 396 397 /* add zero padding */ 398 if (ret < len) { 399 bcopy(secret, secret + (len - ret), ret); 400 bzero(secret, len - ret); 401 } 402 403 return (0); 404} 405 406int 407ec_init(struct group *group) 408{ 409 if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL) 410 return (-1); 411 if (!EC_KEY_generate_key(group->ec)) 412 return (-1); 413 if (!EC_KEY_check_key(group->ec)) { 414 EC_KEY_free(group->ec); 415 return (-1); 416 } 417 return (0); 418} 419 420int 421ec_getlen(struct group *group) 422{ 423 if (group->spec == NULL) 424 return (0); 425 /* NB: Return value will always be even */ 426 return ((roundup(group->spec->bits, 8) * 2) / 8); 427} 428 429/* 430 * Note that the shared secret only includes the x value: 431 * 432 * See RFC 5903, 7. ECP Key Exchange Data Formats: 433 * The Diffie-Hellman shared secret value consists of the x value of the 434 * Diffie-Hellman common value. 435 * See also RFC 5903, 9. Changes from RFC 4753. 436 */ 437int 438ec_secretlen(struct group *group) 439{ 440 return (ec_getlen(group) / 2); 441} 442 443int 444ec_create_exchange(struct group *group, u_int8_t *buf) 445{ 446 size_t len; 447 448 len = ec_getlen(group); 449 bzero(buf, len); 450 451 return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 452 buf, len, EC_POINT2RAW_FULL)); 453} 454 455int 456ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 457{ 458 const EC_GROUP *ecgroup = NULL; 459 const BIGNUM *privkey; 460 EC_KEY *exkey = NULL; 461 EC_POINT *exchangep = NULL, *secretp = NULL; 462 int ret = -1; 463 464 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 465 (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 466 goto done; 467 468 if ((exchangep = 469 ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 470 goto done; 471 472 if ((exkey = EC_KEY_new()) == NULL) 473 goto done; 474 if (!EC_KEY_set_group(exkey, ecgroup)) 475 goto done; 476 if (!EC_KEY_set_public_key(exkey, exchangep)) 477 goto done; 478 479 /* validate exchangep */ 480 if (!EC_KEY_check_key(exkey)) 481 goto done; 482 483 if ((secretp = EC_POINT_new(ecgroup)) == NULL) 484 goto done; 485 486 if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 487 goto done; 488 489 ret = ec_point2raw(group, secretp, secret, ec_secretlen(group), 490 EC_POINT2RAW_XONLY); 491 492 done: 493 if (exkey != NULL) 494 EC_KEY_free(exkey); 495 if (exchangep != NULL) 496 EC_POINT_clear_free(exchangep); 497 if (secretp != NULL) 498 EC_POINT_clear_free(secretp); 499 500 return (ret); 501} 502 503int 504ec_point2raw(struct group *group, const EC_POINT *point, 505 u_int8_t *buf, size_t len, int mode) 506{ 507 const EC_GROUP *ecgroup = NULL; 508 BN_CTX *bnctx = NULL; 509 BIGNUM *x = NULL, *y = NULL; 510 int ret = -1; 511 size_t eclen, xlen, ylen; 512 off_t xoff, yoff; 513 514 if ((bnctx = BN_CTX_new()) == NULL) 515 goto done; 516 BN_CTX_start(bnctx); 517 if ((x = BN_CTX_get(bnctx)) == NULL || 518 (y = BN_CTX_get(bnctx)) == NULL) 519 goto done; 520 521 eclen = ec_getlen(group); 522 switch (mode) { 523 case EC_POINT2RAW_XONLY: 524 xlen = eclen / 2; 525 ylen = 0; 526 break; 527 case EC_POINT2RAW_FULL: 528 xlen = ylen = eclen / 2; 529 break; 530 default: 531 goto done; 532 } 533 if (len < xlen + ylen) 534 goto done; 535 536 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 537 goto done; 538 539 if (!EC_POINT_get_affine_coordinates(ecgroup, point, x, y, bnctx)) 540 goto done; 541 542 xoff = xlen - BN_num_bytes(x); 543 bzero(buf, xoff); 544 if (!BN_bn2bin(x, buf + xoff)) 545 goto done; 546 547 if (ylen > 0) { 548 yoff = (ylen - BN_num_bytes(y)) + xlen; 549 bzero(buf + xlen, yoff - xlen); 550 if (!BN_bn2bin(y, buf + yoff)) 551 goto done; 552 } 553 554 ret = 0; 555 done: 556 /* Make sure to erase sensitive data */ 557 if (x != NULL) 558 BN_clear(x); 559 if (y != NULL) 560 BN_clear(y); 561 BN_CTX_end(bnctx); 562 BN_CTX_free(bnctx); 563 564 return (ret); 565} 566 567EC_POINT * 568ec_raw2point(struct group *group, u_int8_t *buf, size_t len) 569{ 570 const EC_GROUP *ecgroup = NULL; 571 EC_POINT *point = NULL; 572 BN_CTX *bnctx = NULL; 573 BIGNUM *x = NULL, *y = NULL; 574 int ret = -1; 575 size_t eclen; 576 size_t xlen, ylen; 577 578 if ((bnctx = BN_CTX_new()) == NULL) 579 goto done; 580 BN_CTX_start(bnctx); 581 if ((x = BN_CTX_get(bnctx)) == NULL || 582 (y = BN_CTX_get(bnctx)) == NULL) 583 goto done; 584 585 eclen = ec_getlen(group); 586 if (len < eclen) 587 goto done; 588 xlen = ylen = eclen / 2; 589 if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 590 (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 591 goto done; 592 593 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 594 goto done; 595 596 if ((point = EC_POINT_new(ecgroup)) == NULL) 597 goto done; 598 599 if (!EC_POINT_set_affine_coordinates(ecgroup, point, x, y, bnctx)) 600 goto done; 601 602 ret = 0; 603 done: 604 if (ret != 0 && point != NULL) 605 EC_POINT_clear_free(point); 606 /* Make sure to erase sensitive data */ 607 if (x != NULL) 608 BN_clear(x); 609 if (y != NULL) 610 BN_clear(y); 611 BN_CTX_end(bnctx); 612 BN_CTX_free(bnctx); 613 614 return (point); 615} 616