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