xref: /openbsd/sbin/iked/dh.c (revision fc61954a)
1 /*	$OpenBSD: dh.c,v 1.17 2015/08/21 11:59:27 reyk Exp $	*/
2 
3 /*
4  * Copyright (c) 2010-2014 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>	/* roundup */
20 #include <string.h>
21 
22 #include <openssl/obj_mac.h>
23 #include <openssl/dh.h>
24 #include <openssl/ec.h>
25 #include <openssl/ecdh.h>
26 #include <openssl/bn.h>
27 
28 #include "dh.h"
29 
30 int	dh_init(struct group *);
31 
32 /* MODP */
33 int	modp_init(struct group *);
34 int	modp_getlen(struct group *);
35 int	modp_create_exchange(struct group *, uint8_t *);
36 int	modp_create_shared(struct group *, uint8_t *, uint8_t *);
37 
38 /* EC2N/ECP */
39 int	ec_init(struct group *);
40 int	ec_getlen(struct group *);
41 int	ec_create_exchange(struct group *, uint8_t *);
42 int	ec_create_shared(struct group *, uint8_t *, uint8_t *);
43 
44 int	ec_point2raw(struct group *, const EC_POINT *, uint8_t *, size_t);
45 EC_POINT *
46 	ec_raw2point(struct group *, uint8_t *, size_t);
47 
48 /* curve25519 */
49 int	ec25519_init(struct group *);
50 int	ec25519_getlen(struct group *);
51 int	ec25519_create_exchange(struct group *, uint8_t *);
52 int	ec25519_create_shared(struct group *, uint8_t *, uint8_t *);
53 
54 #define CURVE25519_SIZE 32	/* 256 bits */
55 struct curve25519_key {
56 	uint8_t		 secret[CURVE25519_SIZE];
57 	uint8_t		 public[CURVE25519_SIZE];
58 };
59 extern int crypto_scalarmult_curve25519(unsigned char a[CURVE25519_SIZE],
60     const unsigned char b[CURVE25519_SIZE],
61     const unsigned char c[CURVE25519_SIZE])
62 	__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
63 	__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)))
64 	__attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE)));
65 
66 struct group_id ike_groups[] = {
67 	{ GROUP_MODP, 1, 768,
68 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
69 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
70 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
71 	    "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF",
72 	    "02"
73 	},
74 	{ GROUP_MODP, 2, 1024,
75 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
76 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
77 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
78 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
79 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
80 	    "FFFFFFFFFFFFFFFF",
81 	    "02"
82 	},
83 	{ GROUP_EC2N, 3, 155, NULL, NULL, NID_ipsec3 },
84 	{ GROUP_EC2N, 4, 185, NULL, NULL, NID_ipsec4 },
85 	{ GROUP_MODP, 5, 1536,
86 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
87 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
88 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
89 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
90 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
91 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
92 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
93 	    "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
94 	    "02"
95 	},
96 	{ GROUP_MODP, 14, 2048,
97 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
98 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
99 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
100 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
101 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
102 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
103 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
104 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
105 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
106 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
107 	    "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
108 	    "02"
109 	},
110 	{ GROUP_MODP, 15, 3072,
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 	    "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
127 	    "02"
128 	},
129 	{ GROUP_MODP, 16, 4096,
130 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
131 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
132 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
133 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
134 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
135 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
136 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
137 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
138 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
139 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
140 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
141 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
142 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
143 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
144 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
145 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
146 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
147 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
148 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
149 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
150 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
151 	    "FFFFFFFFFFFFFFFF",
152 	    "02"
153 	},
154 	{ GROUP_MODP, 17, 6144,
155 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
156 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
157 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
158 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
159 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
160 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
161 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
162 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
163 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
164 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
165 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
166 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
167 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
168 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
169 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
170 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
171 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
172 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
173 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
174 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
175 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
176 	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
177 	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
178 	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
179 	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
180 	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
181 	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
182 	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
183 	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
184 	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
185 	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
186 	    "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF",
187 	    "02"
188 	},
189 	{ GROUP_MODP, 18, 8192,
190 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
191 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
192 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
193 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
194 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
195 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
196 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
197 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
198 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
199 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
200 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
201 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
202 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
203 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
204 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
205 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
206 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
207 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
208 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
209 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
210 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
211 	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
212 	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
213 	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
214 	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
215 	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
216 	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
217 	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
218 	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
219 	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
220 	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
221 	    "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
222 	    "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
223 	    "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
224 	    "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
225 	    "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
226 	    "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
227 	    "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
228 	    "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
229 	    "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
230 	    "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
231 	    "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
232 	    "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
233 	    "02"
234 	},
235 	{ GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 },
236 	{ GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 },
237 	{ GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 },
238 	{ GROUP_MODP, 22, 1024,
239 	    "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
240 	    "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
241 	    "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
242 	    "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
243 	    "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
244 	    "DF1FB2BC2E4A4371",
245 	    "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
246 	    "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
247 	    "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
248 	    "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
249 	    "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
250 	    "855E6EEB22B3B2E5"
251 	},
252 	{ GROUP_MODP, 23, 2048,
253 	    "AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1"
254 	    "B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15"
255 	    "EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC212"
256 	    "9037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207"
257 	    "C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708"
258 	    "B3BF8A317091883681286130BC8985DB1602E714415D9330"
259 	    "278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486D"
260 	    "CDF93ACC44328387315D75E198C641A480CD86A1B9E587E8"
261 	    "BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763"
262 	    "C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71"
263 	    "CF9DE5384E71B81C0AC4DFFE0C10E64F",
264 	    "AC4032EF4F2D9AE39DF30B5C8FFDAC506CDEBE7B89998CAF"
265 	    "74866A08CFE4FFE3A6824A4E10B9A6F0DD921F01A70C4AFA"
266 	    "AB739D7700C29F52C57DB17C620A8652BE5E9001A8D66AD7"
267 	    "C17669101999024AF4D027275AC1348BB8A762D0521BC98A"
268 	    "E247150422EA1ED409939D54DA7460CDB5F6C6B250717CBE"
269 	    "F180EB34118E98D119529A45D6F834566E3025E316A330EF"
270 	    "BB77A86F0C1AB15B051AE3D428C8F8ACB70A8137150B8EEB"
271 	    "10E183EDD19963DDD9E263E4770589EF6AA21E7F5F2FF381"
272 	    "B539CCE3409D13CD566AFBB48D6C019181E1BCFE94B30269"
273 	    "EDFE72FE9B6AA4BD7B5A0F1C71CFFF4C19C418E1F6EC0179"
274 	    "81BC087F2A7065B384B890D3191F2BFA"
275 	},
276 	{ GROUP_MODP, 24, 2048,
277 	    "87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F2"
278 	    "5D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA30"
279 	    "16C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD"
280 	    "5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B"
281 	    "6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C"
282 	    "4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0E"
283 	    "F13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D9"
284 	    "67E144E5140564251CCACB83E6B486F6B3CA3F7971506026"
285 	    "C0B857F689962856DED4010ABD0BE621C3A3960A54E710C3"
286 	    "75F26375D7014103A4B54330C198AF126116D2276E11715F"
287 	    "693877FAD7EF09CADB094AE91E1A1597",
288 	    "3FB32C9B73134D0B2E77506660EDBD484CA7B18F21EF2054"
289 	    "07F4793A1A0BA12510DBC15077BE463FFF4FED4AAC0BB555"
290 	    "BE3A6C1B0C6B47B1BC3773BF7E8C6F62901228F8C28CBB18"
291 	    "A55AE31341000A650196F931C77A57F2DDF463E5E9EC144B"
292 	    "777DE62AAAB8A8628AC376D282D6ED3864E67982428EBC83"
293 	    "1D14348F6F2F9193B5045AF2767164E1DFC967C1FB3F2E55"
294 	    "A4BD1BFFE83B9C80D052B985D182EA0ADB2A3B7313D3FE14"
295 	    "C8484B1E052588B9B7D2BBD2DF016199ECD06E1557CD0915"
296 	    "B3353BBB64E0EC377FD028370DF92B52C7891428CDC67EB6"
297 	    "184B523D1DB246C32F63078490F00EF8D647D148D4795451"
298 	    "5E2327CFEF98C582664B4C0F6CC41659"
299 	},
300 	{ GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 },
301 	{ GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 },
302 	{ GROUP_ECP, 27, 224, NULL, NULL, NID_brainpoolP224r1 },
303 	{ GROUP_ECP, 28, 256, NULL, NULL, NID_brainpoolP256r1 },
304 	{ GROUP_ECP, 29, 384, NULL, NULL, NID_brainpoolP384r1 },
305 	{ GROUP_ECP, 30, 512, NULL, NULL, NID_brainpoolP512r1 },
306 
307 	/* "Private use" extensions */
308 	{ GROUP_CURVE25519, 1034, CURVE25519_SIZE * 8 }
309 };
310 
311 void
312 group_init(void)
313 {
314 	/* currently not used */
315 	return;
316 }
317 
318 void
319 group_free(struct group *group)
320 {
321 	if (group == NULL)
322 		return;
323 	if (group->dh != NULL)
324 		DH_free(group->dh);
325 	if (group->ec != NULL)
326 		EC_KEY_free(group->ec);
327 	if (group->curve25519 != NULL) {
328 		explicit_bzero(group->curve25519,
329 		    sizeof(struct curve25519_key));
330 		free(group->curve25519);
331 	}
332 	group->spec = NULL;
333 	free(group);
334 }
335 
336 struct group *
337 group_get(uint32_t id)
338 {
339 	struct group_id	*p = NULL;
340 	struct group	*group;
341 	unsigned int	 i, items;
342 
343 	items = sizeof(ike_groups) / sizeof(ike_groups[0]);
344 	for (i = 0; i < items; i++) {
345 		if (id == ike_groups[i].id) {
346 			p = &ike_groups[i];
347 			break;
348 		}
349 	}
350 	if (p == NULL)
351 		return (NULL);
352 
353 	if ((group = calloc(1, sizeof(*group))) == NULL)
354 		return (NULL);
355 
356 	group->id = id;
357 	group->spec = p;
358 
359 	switch (p->type) {
360 	case GROUP_MODP:
361 		group->init = modp_init;
362 		group->getlen = modp_getlen;
363 		group->exchange = modp_create_exchange;
364 		group->shared = modp_create_shared;
365 		break;
366 	case GROUP_EC2N:
367 	case GROUP_ECP:
368 		group->init = ec_init;
369 		group->getlen = ec_getlen;
370 		group->exchange = ec_create_exchange;
371 		group->shared = ec_create_shared;
372 		break;
373 	case GROUP_CURVE25519:
374 		group->init = ec25519_init;
375 		group->getlen = ec25519_getlen;
376 		group->exchange = ec25519_create_exchange;
377 		group->shared = ec25519_create_shared;
378 		break;
379 	default:
380 		group_free(group);
381 		return (NULL);
382 	}
383 
384 	if (dh_init(group) != 0) {
385 		group_free(group);
386 		return (NULL);
387 	}
388 
389 	return (group);
390 }
391 
392 int
393 dh_init(struct group *group)
394 {
395 	return (group->init(group));
396 }
397 
398 int
399 dh_getlen(struct group *group)
400 {
401 	return (group->getlen(group));
402 }
403 
404 int
405 dh_create_exchange(struct group *group, uint8_t *buf)
406 {
407 	return (group->exchange(group, buf));
408 }
409 
410 int
411 dh_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange)
412 {
413 	return (group->shared(group, secret, exchange));
414 }
415 
416 int
417 modp_init(struct group *group)
418 {
419 	DH	*dh;
420 
421 	if ((dh = DH_new()) == NULL)
422 		return (-1);
423 	group->dh = dh;
424 
425 	if (!BN_hex2bn(&dh->p, group->spec->prime) ||
426 	    !BN_hex2bn(&dh->g, group->spec->generator))
427 		return (-1);
428 
429 	return (0);
430 }
431 
432 int
433 modp_getlen(struct group *group)
434 {
435 	if (group->spec == NULL)
436 		return (0);
437 	return (roundup(group->spec->bits, 8) / 8);
438 }
439 
440 int
441 modp_create_exchange(struct group *group, uint8_t *buf)
442 {
443 	DH	*dh = group->dh;
444 	int	 len, ret;
445 
446 	if (!DH_generate_key(dh))
447 		return (-1);
448 	ret = BN_bn2bin(dh->pub_key, buf);
449 	if (!ret)
450 		return (-1);
451 
452 	len = dh_getlen(group);
453 
454 	/* add zero padding */
455 	if (ret < len) {
456 		bcopy(buf, buf + (len - ret), ret);
457 		bzero(buf, len - ret);
458 	}
459 
460 	return (0);
461 }
462 
463 int
464 modp_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange)
465 {
466 	BIGNUM	*ex;
467 	int	 len, ret;
468 
469 	len = dh_getlen(group);
470 
471 	if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL)
472 		return (-1);
473 
474 	ret = DH_compute_key(secret, ex, group->dh);
475 	BN_clear_free(ex);
476 	if (ret <= 0)
477 		return (-1);
478 
479 	/* add zero padding */
480 	if (ret < len) {
481 		bcopy(secret, secret + (len - ret), ret);
482 		bzero(secret, len - ret);
483 	}
484 
485 	return (0);
486 }
487 
488 int
489 ec_init(struct group *group)
490 {
491 	if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL)
492 		return (-1);
493 	if (!EC_KEY_generate_key(group->ec))
494 		return (-1);
495 	if (!EC_KEY_check_key(group->ec)) {
496 		EC_KEY_free(group->ec);
497 		return (-1);
498 	}
499 	return (0);
500 }
501 
502 int
503 ec_getlen(struct group *group)
504 {
505 	if (group->spec == NULL)
506 		return (0);
507 	/* NB:  Return value will always be even */
508 	return ((roundup(group->spec->bits, 8) * 2) / 8);
509 }
510 
511 int
512 ec_create_exchange(struct group *group, uint8_t *buf)
513 {
514 	size_t	 len;
515 
516 	len = ec_getlen(group);
517 	bzero(buf, len);
518 
519 	return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec),
520 	    buf, len));
521 }
522 
523 int
524 ec_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange)
525 {
526 	const EC_GROUP	*ecgroup = NULL;
527 	const BIGNUM	*privkey;
528 	EC_KEY		*exkey = NULL;
529 	EC_POINT	*exchangep = NULL, *secretp = NULL;
530 	int		 ret = -1;
531 
532 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL ||
533 	    (privkey = EC_KEY_get0_private_key(group->ec)) == NULL)
534 		goto done;
535 
536 	if ((exchangep =
537 	    ec_raw2point(group, exchange, ec_getlen(group))) == NULL)
538 		goto done;
539 
540 	if ((exkey = EC_KEY_new()) == NULL)
541 		goto done;
542 	if (!EC_KEY_set_group(exkey, ecgroup))
543 		goto done;
544 	if (!EC_KEY_set_public_key(exkey, exchangep))
545 		goto done;
546 
547 	/* validate exchangep */
548 	if (!EC_KEY_check_key(exkey))
549 		goto done;
550 
551 	if ((secretp = EC_POINT_new(ecgroup)) == NULL)
552 		goto done;
553 
554 	if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL))
555 		goto done;
556 
557 	ret = ec_point2raw(group, secretp, secret, ec_getlen(group));
558 
559  done:
560 	if (exkey != NULL)
561 		EC_KEY_free(exkey);
562 	if (exchangep != NULL)
563 		EC_POINT_clear_free(exchangep);
564 	if (secretp != NULL)
565 		EC_POINT_clear_free(secretp);
566 
567 	return (ret);
568 }
569 
570 int
571 ec_point2raw(struct group *group, const EC_POINT *point,
572     uint8_t *buf, size_t len)
573 {
574 	const EC_GROUP	*ecgroup = NULL;
575 	BN_CTX		*bnctx = NULL;
576 	BIGNUM		*x = NULL, *y = NULL;
577 	int		 ret = -1;
578 	size_t		 eclen, xlen, ylen;
579 	off_t		 xoff, yoff;
580 
581 	if ((bnctx = BN_CTX_new()) == NULL)
582 		goto done;
583 	BN_CTX_start(bnctx);
584 	if ((x = BN_CTX_get(bnctx)) == NULL ||
585 	    (y = BN_CTX_get(bnctx)) == NULL)
586 		goto done;
587 
588 	eclen = ec_getlen(group);
589 	if (len < eclen)
590 		goto done;
591 	xlen = ylen = eclen / 2;
592 
593 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
594 		goto done;
595 
596 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
597 	    NID_X9_62_prime_field) {
598 		if (!EC_POINT_get_affine_coordinates_GFp(ecgroup,
599 		    point, x, y, bnctx))
600 			goto done;
601 	} else {
602 		if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup,
603 		    point, x, y, bnctx))
604 			goto done;
605 	}
606 
607 	xoff = xlen - BN_num_bytes(x);
608 	bzero(buf, xoff);
609 	if (!BN_bn2bin(x, buf + xoff))
610 		goto done;
611 
612 	yoff = (ylen - BN_num_bytes(y)) + xlen;
613 	bzero(buf + xlen, yoff - xlen);
614 	if (!BN_bn2bin(y, buf + yoff))
615 		goto done;
616 
617 	ret = 0;
618  done:
619 	/* Make sure to erase sensitive data */
620 	if (x != NULL)
621 		BN_clear(x);
622 	if (y != NULL)
623 		BN_clear(y);
624 	BN_CTX_end(bnctx);
625 	BN_CTX_free(bnctx);
626 
627 	return (ret);
628 }
629 
630 EC_POINT *
631 ec_raw2point(struct group *group, uint8_t *buf, size_t len)
632 {
633 	const EC_GROUP	*ecgroup = NULL;
634 	EC_POINT	*point = NULL;
635 	BN_CTX		*bnctx = NULL;
636 	BIGNUM		*x = NULL, *y = NULL;
637 	int		 ret = -1;
638 	size_t		 eclen;
639 	size_t		 xlen, ylen;
640 
641 	if ((bnctx = BN_CTX_new()) == NULL)
642 		goto done;
643 	BN_CTX_start(bnctx);
644 	if ((x = BN_CTX_get(bnctx)) == NULL ||
645 	    (y = BN_CTX_get(bnctx)) == NULL)
646 		goto done;
647 
648 	eclen = ec_getlen(group);
649 	if (len < eclen)
650 		goto done;
651 	xlen = ylen = eclen / 2;
652 	if ((x = BN_bin2bn(buf, xlen, x)) == NULL ||
653 	    (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL)
654 		goto done;
655 
656 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
657 		goto done;
658 
659 	if ((point = EC_POINT_new(ecgroup)) == NULL)
660 		goto done;
661 
662 	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
663 	    NID_X9_62_prime_field) {
664 		if (!EC_POINT_set_affine_coordinates_GFp(ecgroup,
665 		    point, x, y, bnctx))
666 			goto done;
667 	} else {
668 		if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup,
669 		    point, x, y, bnctx))
670 			goto done;
671 	}
672 
673 	ret = 0;
674  done:
675 	if (ret != 0 && point != NULL)
676 		EC_POINT_clear_free(point);
677 	/* Make sure to erase sensitive data */
678 	if (x != NULL)
679 		BN_clear(x);
680 	if (y != NULL)
681 		BN_clear(y);
682 	BN_CTX_end(bnctx);
683 	BN_CTX_free(bnctx);
684 
685 	return (point);
686 }
687 
688 int
689 ec25519_init(struct group *group)
690 {
691 	static const uint8_t	 basepoint[CURVE25519_SIZE] = { 9 };
692 	struct curve25519_key	*curve25519;
693 
694 	if ((curve25519 = calloc(1, sizeof(*curve25519))) == NULL)
695 		return (-1);
696 
697 	group->curve25519 = curve25519;
698 
699 	arc4random_buf(curve25519->secret, CURVE25519_SIZE);
700 	crypto_scalarmult_curve25519(curve25519->public,
701 	    curve25519->secret, basepoint);
702 
703 	return (0);
704 }
705 
706 int
707 ec25519_getlen(struct group *group)
708 {
709 	if (group->spec == NULL)
710 		return (0);
711 	return (CURVE25519_SIZE);
712 }
713 
714 int
715 ec25519_create_exchange(struct group *group, uint8_t *buf)
716 {
717 	struct curve25519_key	*curve25519 = group->curve25519;
718 
719 	memcpy(buf, curve25519->public, ec25519_getlen(group));
720 	return (0);
721 }
722 
723 int
724 ec25519_create_shared(struct group *group, uint8_t *shared, uint8_t *public)
725 {
726 	struct curve25519_key	*curve25519 = group->curve25519;
727 
728 	crypto_scalarmult_curve25519(shared, curve25519->secret, public);
729 	return (0);
730 }
731