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