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