dh.c revision 1.15
1/* $OpenBSD: dh.c,v 1.15 2012/06/04 09:14:29 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 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 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 424int 425modp_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 449int 450ec_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 459int 460ec_getlen(struct group *group) 461{ 462 if (group->spec == NULL) 463 return (0); 464 /* NB: Return value will always be even */ 465 return ((roundup(group->spec->bits, 8) * 2) / 8); 466} 467 468int 469ec_create_exchange(struct group *group, u_int8_t *buf) 470{ 471 size_t len; 472 473 len = ec_getlen(group); 474 bzero(buf, len); 475 476 return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec), 477 buf, len)); 478} 479 480int 481ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange) 482{ 483 const EC_GROUP *ecgroup = NULL; 484 const BIGNUM *privkey; 485 EC_POINT *exchangep = NULL, *secretp = NULL; 486 int ret = -1; 487 488 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL || 489 (privkey = EC_KEY_get0_private_key(group->ec)) == NULL) 490 goto done; 491 492 if ((exchangep = 493 ec_raw2point(group, exchange, ec_getlen(group))) == NULL) 494 goto done; 495 496 if ((secretp = EC_POINT_new(ecgroup)) == NULL) 497 goto done; 498 499 if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL)) 500 goto done; 501 502 ret = ec_point2raw(group, secretp, secret, ec_getlen(group)); 503 504 done: 505 if (exchangep != NULL) 506 EC_POINT_clear_free(exchangep); 507 if (secretp != NULL) 508 EC_POINT_clear_free(secretp); 509 510 return (ret); 511} 512 513int 514ec_point2raw(struct group *group, const EC_POINT *point, 515 u_int8_t *buf, size_t len) 516{ 517 const EC_GROUP *ecgroup = NULL; 518 BN_CTX *bnctx = NULL; 519 BIGNUM *x = NULL, *y = NULL; 520 int ret = -1; 521 size_t eclen, xlen, ylen; 522 off_t xoff, yoff; 523 524 if ((bnctx = BN_CTX_new()) == NULL) 525 goto done; 526 BN_CTX_start(bnctx); 527 if ((x = BN_CTX_get(bnctx)) == NULL || 528 (y = BN_CTX_get(bnctx)) == NULL) 529 goto done; 530 531 eclen = ec_getlen(group); 532 if (len < eclen) 533 goto done; 534 xlen = ylen = eclen / 2; 535 536 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 537 goto done; 538 539 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 540 NID_X9_62_prime_field) { 541 if (!EC_POINT_get_affine_coordinates_GFp(ecgroup, 542 point, x, y, bnctx)) 543 goto done; 544 } else { 545 if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup, 546 point, x, y, bnctx)) 547 goto done; 548 } 549 550 xoff = xlen - BN_num_bytes(x); 551 bzero(buf, xoff); 552 if (!BN_bn2bin(x, buf + xoff)) 553 goto done; 554 555 yoff = (ylen - BN_num_bytes(y)) + xlen; 556 bzero(buf + xlen, yoff - xlen); 557 if (!BN_bn2bin(y, buf + yoff)) 558 goto done; 559 560 ret = 0; 561 done: 562 BN_CTX_end(bnctx); 563 BN_CTX_free(bnctx); 564 565 return (ret); 566} 567 568EC_POINT * 569ec_raw2point(struct group *group, u_int8_t *buf, size_t len) 570{ 571 const EC_GROUP *ecgroup = NULL; 572 EC_POINT *point = NULL; 573 BN_CTX *bnctx = NULL; 574 BIGNUM *x = NULL, *y = NULL; 575 int ret = -1; 576 size_t eclen; 577 size_t xlen, ylen; 578 579 if ((bnctx = BN_CTX_new()) == NULL) 580 goto done; 581 BN_CTX_start(bnctx); 582 if ((x = BN_CTX_get(bnctx)) == NULL || 583 (y = BN_CTX_get(bnctx)) == NULL) 584 goto done; 585 586 eclen = ec_getlen(group); 587 if (len < eclen) 588 goto done; 589 xlen = ylen = eclen / 2; 590 if ((x = BN_bin2bn(buf, xlen, x)) == NULL || 591 (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL) 592 goto done; 593 594 if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL) 595 goto done; 596 597 if ((point = EC_POINT_new(ecgroup)) == NULL) 598 goto done; 599 600 if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) == 601 NID_X9_62_prime_field) { 602 if (!EC_POINT_set_affine_coordinates_GFp(ecgroup, 603 point, x, y, bnctx)) 604 goto done; 605 } else { 606 if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup, 607 point, x, y, bnctx)) 608 goto done; 609 } 610 611 ret = 0; 612 done: 613 if (ret != 0 && point != NULL) 614 EC_POINT_clear_free(point); 615 BN_CTX_end(bnctx); 616 BN_CTX_free(bnctx); 617 618 return (point); 619} 620