dh.c revision 1.13
1/* $OpenBSD: dh.c,v 1.13 2010/11/29 22:49:26 markus 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 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}; 283 284void 285group_init(void) 286{ 287 /* currently not used */ 288 return; 289} 290 291void 292group_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 303struct group * 304group_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 353int 354dh_init(struct group *group) 355{ 356 return (group->init(group)); 357} 358 359int 360dh_getlen(struct group *group) 361{ 362 return (group->getlen(group)); 363} 364 365int 366dh_create_exchange(struct group *group, u_int8_t *buf) 367{ 368 return (group->exchange(group, buf)); 369} 370 371int 372dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 373{ 374 return (group->shared(group, secret, exchange)); 375} 376 377int 378modp_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 393int 394modp_getlen(struct group *group) 395{ 396 if (group->spec == NULL) 397 return (0); 398 return (roundup(group->spec->bits, 8) / 8); 399} 400 401int 402modp_create_exchange(struct group *group, u_int8_t *buf) 403{ 404 DH *dh = group->dh; 405 406 if (!DH_generate_key(dh)) 407 return (-1); 408 if (!BN_bn2bin(dh->pub_key, buf)) 409 return (-1); 410 411 return (0); 412} 413 414int 415modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 416{ 417 BIGNUM *ex; 418 int ret; 419 420 if ((ex = BN_bin2bn(exchange, dh_getlen(group), NULL)) == NULL) 421 return (-1); 422 423 ret = DH_compute_key(secret, ex, group->dh); 424 BN_clear_free(ex); 425 if (!ret) 426 return (-1); 427 428 return (0); 429} 430 431int 432ec_init(struct group *group) 433{ 434 if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL) 435 return (-1); 436 if (!EC_KEY_generate_key(group->ec)) 437 return (-1); 438 return (0); 439} 440 441int 442ec_getlen(struct group *group) 443{ 444 if (group->spec == NULL) 445 return (0); 446 return ((roundup(group->spec->bits, 8) * 2) / 8); 447} 448 449int 450ec_create_exchange(struct group *group, u_int8_t *buf) 451{ 452 size_t len; 453 454 len = ec_getlen(group); 455 bzero(buf, len); 456 457 return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 458 buf, len)); 459} 460 461int 462ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 463{ 464 const EC_GROUP *ecgroup = NULL; 465 const BIGNUM *privkey; 466 EC_POINT *exchangep = NULL, *secretp = NULL; 467 int ret = -1; 468 469 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 470 (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 471 goto done; 472 473 if ((exchangep = 474 ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 475 goto done; 476 477 if ((secretp = EC_POINT_new(ecgroup)) == NULL) 478 goto done; 479 480 if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 481 goto done; 482 483 ret = ec_point2raw(group, secretp, secret, ec_getlen(group)); 484 485 done: 486 if (exchangep != NULL) 487 EC_POINT_clear_free(exchangep); 488 if (secretp != NULL) 489 EC_POINT_clear_free(secretp); 490 491 return (ret); 492} 493 494int 495ec_point2raw(struct group *group, const EC_POINT *point, 496 u_int8_t *buf, size_t len) 497{ 498 const EC_GROUP *ecgroup = NULL; 499 BN_CTX *bnctx = NULL; 500 BIGNUM *x = NULL, *y = NULL; 501 int ret = -1; 502 size_t xlen, ylen; 503 off_t xoff, yoff; 504 505 if ((bnctx = BN_CTX_new()) == NULL) 506 goto done; 507 BN_CTX_start(bnctx); 508 if ((x = BN_CTX_get(bnctx)) == NULL || 509 (y = BN_CTX_get(bnctx)) == NULL) 510 goto done; 511 512 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 513 goto done; 514 515 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 516 NID_X9_62_prime_field) { 517 if (!EC_POINT_get_affine_coordinates_GFp(ecgroup, 518 point, x, y, bnctx)) 519 goto done; 520 } else { 521 if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup, 522 point, x, y, bnctx)) 523 goto done; 524 } 525 526 xlen = roundup(BN_num_bytes(x), 2); 527 xoff = xlen - BN_num_bytes(x); 528 if (!BN_bn2bin(x, buf + xoff)) 529 goto done; 530 531 ylen = roundup(BN_num_bytes(y), 2); 532 yoff = (ylen - BN_num_bytes(y)) + xlen; 533 if (!BN_bn2bin(y, buf + yoff)) 534 goto done; 535 536 ret = 0; 537 done: 538 BN_CTX_end(bnctx); 539 BN_CTX_free(bnctx); 540 541 return (ret); 542} 543 544EC_POINT * 545ec_raw2point(struct group *group, u_int8_t *buf, size_t len) 546{ 547 const EC_GROUP *ecgroup = NULL; 548 EC_POINT *point = NULL; 549 BN_CTX *bnctx = NULL; 550 BIGNUM *x = NULL, *y = NULL; 551 int ret = -1; 552 size_t eclen; 553 size_t xlen, ylen; 554 555 if ((bnctx = BN_CTX_new()) == NULL) 556 goto done; 557 BN_CTX_start(bnctx); 558 if ((x = BN_CTX_get(bnctx)) == NULL || 559 (y = BN_CTX_get(bnctx)) == NULL) 560 goto done; 561 562 eclen = ec_getlen(group); 563 if (len < eclen) 564 goto done; 565 xlen = ylen = eclen / 2; 566 if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 567 (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 568 goto done; 569 570 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 571 goto done; 572 573 if ((point = EC_POINT_new(ecgroup)) == NULL) 574 goto done; 575 576 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 577 NID_X9_62_prime_field) { 578 if (!EC_POINT_set_affine_coordinates_GFp(ecgroup, 579 point, x, y, bnctx)) 580 goto done; 581 } else { 582 if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup, 583 point, x, y, bnctx)) 584 goto done; 585 } 586 587 ret = 0; 588 done: 589 if (ret != 0 && point != NULL) 590 EC_POINT_clear_free(point); 591 BN_CTX_end(bnctx); 592 BN_CTX_free(bnctx); 593 594 return (point); 595} 596