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