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