dh.c revision 1.12
1/* $OpenBSD: dh.c,v 1.12 2010/06/29 19:50:16 reyk 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 int codes; 405 DH *dh = group->dh; 406 407 if (!DH_generate_key(dh)) 408 return (-1); 409 if (!DH_check(dh, &codes)) 410 return (-1); 411 if (!BN_bn2bin(dh->pub_key, buf)) 412 return (-1); 413 414 return (0); 415} 416 417int 418modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 419{ 420 BIGNUM *ex; 421 int ret; 422 423 if ((ex = BN_bin2bn(exchange, dh_getlen(group), NULL)) == NULL) 424 return (-1); 425 426 ret = DH_compute_key(secret, ex, group->dh); 427 BN_clear_free(ex); 428 if (!ret) 429 return (-1); 430 431 return (0); 432} 433 434int 435ec_init(struct group *group) 436{ 437 if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL) 438 return (-1); 439 if (!EC_KEY_generate_key(group->ec)) 440 return (-1); 441 return (0); 442} 443 444int 445ec_getlen(struct group *group) 446{ 447 if (group->spec == NULL) 448 return (0); 449 return ((roundup(group->spec->bits, 8) * 2) / 8); 450} 451 452int 453ec_create_exchange(struct group *group, u_int8_t *buf) 454{ 455 size_t len; 456 457 len = ec_getlen(group); 458 bzero(buf, len); 459 460 return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 461 buf, len)); 462} 463 464int 465ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 466{ 467 const EC_GROUP *ecgroup = NULL; 468 const BIGNUM *privkey; 469 EC_POINT *exchangep = NULL, *secretp = NULL; 470 int ret = -1; 471 472 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 473 (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 474 goto done; 475 476 if ((exchangep = 477 ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 478 goto done; 479 480 if ((secretp = EC_POINT_new(ecgroup)) == NULL) 481 goto done; 482 483 if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 484 goto done; 485 486 ret = ec_point2raw(group, secretp, secret, ec_getlen(group)); 487 488 done: 489 if (exchangep != NULL) 490 EC_POINT_clear_free(exchangep); 491 if (secretp != NULL) 492 EC_POINT_clear_free(secretp); 493 494 return (ret); 495} 496 497int 498ec_point2raw(struct group *group, const EC_POINT *point, 499 u_int8_t *buf, size_t len) 500{ 501 const EC_GROUP *ecgroup = NULL; 502 BN_CTX *bnctx = NULL; 503 BIGNUM *x = NULL, *y = NULL; 504 int ret = -1; 505 size_t xlen, ylen; 506 off_t xoff, yoff; 507 508 if ((bnctx = BN_CTX_new()) == NULL) 509 goto done; 510 BN_CTX_start(bnctx); 511 if ((x = BN_CTX_get(bnctx)) == NULL || 512 (y = BN_CTX_get(bnctx)) == NULL) 513 goto done; 514 515 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 516 goto done; 517 518 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 519 NID_X9_62_prime_field) { 520 if (!EC_POINT_get_affine_coordinates_GFp(ecgroup, 521 point, x, y, bnctx)) 522 goto done; 523 } else { 524 if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup, 525 point, x, y, bnctx)) 526 goto done; 527 } 528 529 xlen = roundup(BN_num_bytes(x), 2); 530 xoff = xlen - BN_num_bytes(x); 531 if (!BN_bn2bin(x, buf + xoff)) 532 goto done; 533 534 ylen = roundup(BN_num_bytes(y), 2); 535 yoff = (ylen - BN_num_bytes(y)) + xlen; 536 if (!BN_bn2bin(y, buf + yoff)) 537 goto done; 538 539 ret = 0; 540 done: 541 BN_CTX_end(bnctx); 542 BN_CTX_free(bnctx); 543 544 return (ret); 545} 546 547EC_POINT * 548ec_raw2point(struct group *group, u_int8_t *buf, size_t len) 549{ 550 const EC_GROUP *ecgroup = NULL; 551 EC_POINT *point = NULL; 552 BN_CTX *bnctx = NULL; 553 BIGNUM *x = NULL, *y = NULL; 554 int ret = -1; 555 size_t eclen; 556 size_t xlen, ylen; 557 558 if ((bnctx = BN_CTX_new()) == NULL) 559 goto done; 560 BN_CTX_start(bnctx); 561 if ((x = BN_CTX_get(bnctx)) == NULL || 562 (y = BN_CTX_get(bnctx)) == NULL) 563 goto done; 564 565 eclen = ec_getlen(group); 566 if (len < eclen) 567 goto done; 568 xlen = ylen = eclen / 2; 569 if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 570 (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 571 goto done; 572 573 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 574 goto done; 575 576 if ((point = EC_POINT_new(ecgroup)) == NULL) 577 goto done; 578 579 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 580 NID_X9_62_prime_field) { 581 if (!EC_POINT_set_affine_coordinates_GFp(ecgroup, 582 point, x, y, bnctx)) 583 goto done; 584 } else { 585 if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup, 586 point, x, y, bnctx)) 587 goto done; 588 } 589 590 ret = 0; 591 done: 592 if (ret != 0 && point != NULL) 593 EC_POINT_clear_free(point); 594 BN_CTX_end(bnctx); 595 BN_CTX_free(bnctx); 596 597 return (point); 598} 599