1 /* $OpenBSD: dh.c,v 1.14 2011/06/15 10:35:47 mikeb Exp $ */ 2 /* $vantronix: dh.c,v 1.13 2010/05/28 15:34:35 reyk Exp $ */ 3 4 /* 5 * Copyright (c) 2010 Reyk Floeter <reyk@vantronix.net> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/param.h> 21 #include <string.h> 22 23 #include <openssl/obj_mac.h> 24 #include <openssl/dh.h> 25 #include <openssl/ec.h> 26 #include <openssl/ecdh.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_create_exchange(struct group *, u_int8_t *); 40 int ec_create_shared(struct group *, u_int8_t *, u_int8_t *); 41 42 int ec_point2raw(struct group *, const EC_POINT *, u_int8_t *, size_t); 43 EC_POINT * 44 ec_raw2point(struct group *, u_int8_t *, size_t); 45 46 struct 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 }; 283 284 void 285 group_init(void) 286 { 287 /* currently not used */ 288 return; 289 } 290 291 void 292 group_free(struct group *group) 293 { 294 if (group == NULL) 295 return; 296 if (group->dh != NULL) 297 DH_free(group->dh); 298 if (group->ec != NULL) 299 EC_KEY_free(group->ec); 300 group->spec = NULL; 301 } 302 303 struct group * 304 group_get(u_int32_t id) 305 { 306 struct group_id *p = NULL; 307 struct group *group; 308 u_int i, items; 309 310 items = sizeof(ike_groups) / sizeof(ike_groups[0]); 311 for (i = 0; i < items; i++) { 312 if (id == ike_groups[i].id) { 313 p = &ike_groups[i]; 314 break; 315 } 316 } 317 if (p == NULL) 318 return (NULL); 319 320 if ((group = calloc(1, sizeof(*group))) == NULL) 321 return (NULL); 322 323 group->id = id; 324 group->spec = p; 325 326 switch (p->type) { 327 case GROUP_MODP: 328 group->init = modp_init; 329 group->getlen = modp_getlen; 330 group->exchange = modp_create_exchange; 331 group->shared = modp_create_shared; 332 break; 333 case GROUP_EC2N: 334 case GROUP_ECP: 335 group->init = ec_init; 336 group->getlen = ec_getlen; 337 group->exchange = ec_create_exchange; 338 group->shared = ec_create_shared; 339 break; 340 default: 341 group_free(group); 342 return (NULL); 343 } 344 345 if (dh_init(group) != 0) { 346 group_free(group); 347 return (NULL); 348 } 349 350 return (group); 351 } 352 353 int 354 dh_init(struct group *group) 355 { 356 return (group->init(group)); 357 } 358 359 int 360 dh_getlen(struct group *group) 361 { 362 return (group->getlen(group)); 363 } 364 365 int 366 dh_create_exchange(struct group *group, u_int8_t *buf) 367 { 368 return (group->exchange(group, buf)); 369 } 370 371 int 372 dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 373 { 374 return (group->shared(group, secret, exchange)); 375 } 376 377 int 378 modp_init(struct group *group) 379 { 380 DH *dh; 381 382 if ((dh = DH_new()) == NULL) 383 return (-1); 384 group->dh = dh; 385 386 if (!BN_hex2bn(&dh->p, group->spec->prime) || 387 !BN_hex2bn(&dh->g, group->spec->generator)) 388 return (-1); 389 390 return (0); 391 } 392 393 int 394 modp_getlen(struct group *group) 395 { 396 if (group->spec == NULL) 397 return (0); 398 return (roundup(group->spec->bits, 8) / 8); 399 } 400 401 int 402 modp_create_exchange(struct group *group, u_int8_t *buf) 403 { 404 DH *dh = group->dh; 405 int len, ret; 406 407 if (!DH_generate_key(dh)) 408 return (-1); 409 ret = BN_bn2bin(dh->pub_key, buf); 410 if (!ret) 411 return (-1); 412 413 len = dh_getlen(group); 414 415 /* add zero padding */ 416 if (ret < len) { 417 bcopy(buf, buf + (len - ret), ret); 418 bzero(buf, len - ret); 419 } 420 421 return (0); 422 } 423 424 int 425 modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 426 { 427 BIGNUM *ex; 428 int len, ret; 429 430 len = dh_getlen(group); 431 432 if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL) 433 return (-1); 434 435 ret = DH_compute_key(secret, ex, group->dh); 436 BN_clear_free(ex); 437 if (!ret) 438 return (-1); 439 440 /* add zero padding */ 441 if (ret < len) { 442 bcopy(secret, secret + (len - ret), ret); 443 bzero(secret, len - ret); 444 } 445 446 return (0); 447 } 448 449 int 450 ec_init(struct group *group) 451 { 452 if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL) 453 return (-1); 454 if (!EC_KEY_generate_key(group->ec)) 455 return (-1); 456 return (0); 457 } 458 459 int 460 ec_getlen(struct group *group) 461 { 462 if (group->spec == NULL) 463 return (0); 464 return ((roundup(group->spec->bits, 8) * 2) / 8); 465 } 466 467 int 468 ec_create_exchange(struct group *group, u_int8_t *buf) 469 { 470 size_t len; 471 472 len = ec_getlen(group); 473 bzero(buf, len); 474 475 return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 476 buf, len)); 477 } 478 479 int 480 ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 481 { 482 const EC_GROUP *ecgroup = NULL; 483 const BIGNUM *privkey; 484 EC_POINT *exchangep = NULL, *secretp = NULL; 485 int ret = -1; 486 487 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 488 (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 489 goto done; 490 491 if ((exchangep = 492 ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 493 goto done; 494 495 if ((secretp = EC_POINT_new(ecgroup)) == NULL) 496 goto done; 497 498 if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 499 goto done; 500 501 ret = ec_point2raw(group, secretp, secret, ec_getlen(group)); 502 503 done: 504 if (exchangep != NULL) 505 EC_POINT_clear_free(exchangep); 506 if (secretp != NULL) 507 EC_POINT_clear_free(secretp); 508 509 return (ret); 510 } 511 512 int 513 ec_point2raw(struct group *group, const EC_POINT *point, 514 u_int8_t *buf, size_t len) 515 { 516 const EC_GROUP *ecgroup = NULL; 517 BN_CTX *bnctx = NULL; 518 BIGNUM *x = NULL, *y = NULL; 519 int ret = -1; 520 size_t xlen, ylen; 521 off_t xoff, yoff; 522 523 if ((bnctx = BN_CTX_new()) == NULL) 524 goto done; 525 BN_CTX_start(bnctx); 526 if ((x = BN_CTX_get(bnctx)) == NULL || 527 (y = BN_CTX_get(bnctx)) == NULL) 528 goto done; 529 530 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 531 goto done; 532 533 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 534 NID_X9_62_prime_field) { 535 if (!EC_POINT_get_affine_coordinates_GFp(ecgroup, 536 point, x, y, bnctx)) 537 goto done; 538 } else { 539 if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup, 540 point, x, y, bnctx)) 541 goto done; 542 } 543 544 xlen = roundup(BN_num_bytes(x), 2); 545 xoff = xlen - BN_num_bytes(x); 546 if (!BN_bn2bin(x, buf + xoff)) 547 goto done; 548 549 ylen = roundup(BN_num_bytes(y), 2); 550 yoff = (ylen - BN_num_bytes(y)) + xlen; 551 if (!BN_bn2bin(y, buf + yoff)) 552 goto done; 553 554 ret = 0; 555 done: 556 BN_CTX_end(bnctx); 557 BN_CTX_free(bnctx); 558 559 return (ret); 560 } 561 562 EC_POINT * 563 ec_raw2point(struct group *group, u_int8_t *buf, size_t len) 564 { 565 const EC_GROUP *ecgroup = NULL; 566 EC_POINT *point = NULL; 567 BN_CTX *bnctx = NULL; 568 BIGNUM *x = NULL, *y = NULL; 569 int ret = -1; 570 size_t eclen; 571 size_t xlen, ylen; 572 573 if ((bnctx = BN_CTX_new()) == NULL) 574 goto done; 575 BN_CTX_start(bnctx); 576 if ((x = BN_CTX_get(bnctx)) == NULL || 577 (y = BN_CTX_get(bnctx)) == NULL) 578 goto done; 579 580 eclen = ec_getlen(group); 581 if (len < eclen) 582 goto done; 583 xlen = ylen = eclen / 2; 584 if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 585 (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 586 goto done; 587 588 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 589 goto done; 590 591 if ((point = EC_POINT_new(ecgroup)) == NULL) 592 goto done; 593 594 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 595 NID_X9_62_prime_field) { 596 if (!EC_POINT_set_affine_coordinates_GFp(ecgroup, 597 point, x, y, bnctx)) 598 goto done; 599 } else { 600 if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup, 601 point, x, y, bnctx)) 602 goto done; 603 } 604 605 ret = 0; 606 done: 607 if (ret != 0 && point != NULL) 608 EC_POINT_clear_free(point); 609 BN_CTX_end(bnctx); 610 BN_CTX_free(bnctx); 611 612 return (point); 613 } 614