xref: /openbsd-src/sbin/iked/dh.c (revision a699afcae2000f690cec89a958b9e8fc6350ddce)
1 /*	$OpenBSD: dh.c,v 1.33 2023/07/28 07:31:38 claudio 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/types.h>
20 
21 #include <sys/queue.h>
22 #include <sys/socket.h>
23 #include <sys/uio.h>
24 #include <string.h>
25 #include <event.h>
26 #include <imsg.h>
27 
28 #include <openssl/evp.h>
29 #include <openssl/sha.h>
30 #include <openssl/obj_mac.h>
31 #include <openssl/dh.h>
32 #include <openssl/ec.h>
33 #include <openssl/ecdh.h>
34 #include <openssl/bn.h>
35 
36 #include "dh.h"
37 #include "iked.h"
38 #include "crypto_api.h"
39 
40 int	dh_init(struct dh_group *);
41 int	dh_getlen(struct dh_group *);
42 int	dh_secretlen(struct dh_group *);
43 
44 /* MODP */
45 int	modp_init(struct dh_group *);
46 int	modp_getlen(struct dh_group *);
47 int	modp_create_exchange(struct dh_group *, uint8_t *);
48 int	modp_create_shared(struct dh_group *, uint8_t *, uint8_t *);
49 
50 /* ECP */
51 int	ec_init(struct dh_group *);
52 int	ec_getlen(struct dh_group *);
53 int	ec_secretlen(struct dh_group *);
54 int	ec_create_exchange(struct dh_group *, uint8_t *);
55 int	ec_create_shared(struct dh_group *, uint8_t *, uint8_t *);
56 
57 #define EC_POINT2RAW_FULL	0
58 #define EC_POINT2RAW_XONLY	1
59 int	ec_point2raw(struct dh_group *, const EC_POINT *, uint8_t *, size_t, int);
60 EC_POINT *
61 	ec_raw2point(struct dh_group *, uint8_t *, size_t);
62 
63 /* curve25519 */
64 int	ec25519_init(struct dh_group *);
65 int	ec25519_getlen(struct dh_group *);
66 int	ec25519_create_exchange(struct dh_group *, uint8_t *);
67 int	ec25519_create_shared(struct dh_group *, uint8_t *, uint8_t *);
68 
69 #define CURVE25519_SIZE 32	/* 256 bits */
70 struct curve25519_key {
71 	uint8_t		 secret[CURVE25519_SIZE];
72 	uint8_t		 public[CURVE25519_SIZE];
73 };
74 extern int crypto_scalarmult_curve25519(unsigned char a[CURVE25519_SIZE],
75     const unsigned char b[CURVE25519_SIZE],
76     const unsigned char c[CURVE25519_SIZE])
77 	__attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
78 	__attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)))
79 	__attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE)));
80 
81 /* SNTRUP761 with X25519 */
82 int	kemsx_init(struct dh_group *);
83 int	kemsx_getlen(struct dh_group *);
84 int	kemsx_create_exchange2(struct dh_group *, struct ibuf **, struct ibuf *);
85 int	kemsx_create_shared2(struct dh_group *, struct ibuf **, struct ibuf *);
86 
87 struct kemsx_key {
88 	uint8_t		kemkey[crypto_kem_sntrup761_BYTES];
89 	uint8_t		secret[crypto_kem_sntrup761_SECRETKEYBYTES];
90 	uint8_t		public[crypto_kem_sntrup761_PUBLICKEYBYTES];
91 	uint8_t		initiator;
92 };
93 
94 const struct group_id ike_groups[] = {
95 	{ GROUP_MODP, 1, 768,
96 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
97 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
98 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
99 	    "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF",
100 	    "02"
101 	},
102 	{ GROUP_MODP, 2, 1024,
103 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
104 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
105 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
106 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
107 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
108 	    "FFFFFFFFFFFFFFFF",
109 	    "02"
110 	},
111 	{ GROUP_MODP, 5, 1536,
112 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
113 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
114 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
115 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
116 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
117 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
118 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
119 	    "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
120 	    "02"
121 	},
122 	{ GROUP_MODP, 14, 2048,
123 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
124 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
125 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
126 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
127 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
128 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
129 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
130 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
131 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
132 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
133 	    "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
134 	    "02"
135 	},
136 	{ GROUP_MODP, 15, 3072,
137 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
138 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
139 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
140 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
141 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
142 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
143 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
144 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
145 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
146 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
147 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
148 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
149 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
150 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
151 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
152 	    "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
153 	    "02"
154 	},
155 	{ GROUP_MODP, 16, 4096,
156 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
157 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
158 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
159 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
160 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
161 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
162 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
163 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
164 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
165 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
166 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
167 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
168 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
169 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
170 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
171 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
172 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
173 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
174 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
175 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
176 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
177 	    "FFFFFFFFFFFFFFFF",
178 	    "02"
179 	},
180 	{ GROUP_MODP, 17, 6144,
181 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
182 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
183 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
184 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
185 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
186 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
187 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
188 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
189 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
190 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
191 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
192 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
193 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
194 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
195 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
196 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
197 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
198 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
199 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
200 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
201 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
202 	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
203 	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
204 	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
205 	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
206 	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
207 	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
208 	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
209 	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
210 	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
211 	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
212 	    "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF",
213 	    "02"
214 	},
215 	{ GROUP_MODP, 18, 8192,
216 	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
217 	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
218 	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
219 	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
220 	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
221 	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
222 	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
223 	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
224 	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
225 	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
226 	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
227 	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
228 	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
229 	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
230 	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
231 	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
232 	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
233 	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
234 	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
235 	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
236 	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
237 	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
238 	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
239 	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
240 	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
241 	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
242 	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
243 	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
244 	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
245 	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
246 	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
247 	    "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
248 	    "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
249 	    "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
250 	    "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
251 	    "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
252 	    "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
253 	    "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
254 	    "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
255 	    "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
256 	    "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
257 	    "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
258 	    "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
259 	    "02"
260 	},
261 	{ GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 },
262 	{ GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 },
263 	{ GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 },
264 	{ GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 },
265 	{ GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 },
266 	{ GROUP_ECP, 27, 224, NULL, NULL, NID_brainpoolP224r1 },
267 	{ GROUP_ECP, 28, 256, NULL, NULL, NID_brainpoolP256r1 },
268 	{ GROUP_ECP, 29, 384, NULL, NULL, NID_brainpoolP384r1 },
269 	{ GROUP_ECP, 30, 512, NULL, NULL, NID_brainpoolP512r1 },
270 	{ GROUP_CURVE25519, 31, CURVE25519_SIZE * 8 },
271 	/* "Private use" extensions */
272 	/* PQC KEM */
273 	{ GROUP_SNTRUP761X25519, 1035,
274 	   (MAXIMUM(crypto_kem_sntrup761_PUBLICKEYBYTES,
275 	        crypto_kem_sntrup761_CIPHERTEXTBYTES) +
276 	    CURVE25519_SIZE) * 8 }
277 };
278 
279 void
group_init(void)280 group_init(void)
281 {
282 	/* currently not used */
283 	return;
284 }
285 
286 void
group_free(struct dh_group * group)287 group_free(struct dh_group *group)
288 {
289 	if (group == NULL)
290 		return;
291 	if (group->dh != NULL)
292 		DH_free(group->dh);
293 	if (group->ec != NULL)
294 		EC_KEY_free(group->ec);
295 	freezero(group->curve25519, sizeof(struct curve25519_key));
296 	freezero(group->kemsx, sizeof(struct kemsx_key));
297 	group->spec = NULL;
298 	free(group);
299 }
300 
301 struct dh_group *
group_get(uint32_t id)302 group_get(uint32_t id)
303 {
304 	const struct group_id	*p;
305 	struct dh_group		*group;
306 
307 	if ((p = group_getid(id)) == NULL)
308 		return (NULL);
309 
310 	if ((group = calloc(1, sizeof(*group))) == NULL)
311 		return (NULL);
312 
313 	group->id = id;
314 	group->spec = p;
315 
316 	switch (p->type) {
317 	case GROUP_MODP:
318 		group->init = modp_init;
319 		group->getlen = modp_getlen;
320 		group->exchange = modp_create_exchange;
321 		group->shared = modp_create_shared;
322 		break;
323 	case GROUP_ECP:
324 		group->init = ec_init;
325 		group->getlen = ec_getlen;
326 		group->secretlen = ec_secretlen;
327 		group->exchange = ec_create_exchange;
328 		group->shared = ec_create_shared;
329 		break;
330 	case GROUP_CURVE25519:
331 		group->init = ec25519_init;
332 		group->getlen = ec25519_getlen;
333 		group->exchange = ec25519_create_exchange;
334 		group->shared = ec25519_create_shared;
335 		break;
336 	case GROUP_SNTRUP761X25519:
337 		group->init = kemsx_init;
338 		group->getlen = kemsx_getlen;
339 		group->exchange2 = kemsx_create_exchange2;
340 		group->shared2 = kemsx_create_shared2;
341 		break;
342 	default:
343 		group_free(group);
344 		return (NULL);
345 	}
346 
347 	if (dh_init(group) != 0) {
348 		group_free(group);
349 		return (NULL);
350 	}
351 
352 	return (group);
353 }
354 
355 const struct group_id *
group_getid(uint32_t id)356 group_getid(uint32_t id)
357 {
358 	const struct group_id	*p = NULL;
359 	unsigned int		 i, items;
360 
361 	items = sizeof(ike_groups) / sizeof(ike_groups[0]);
362 	for (i = 0; i < items; i++) {
363 		if (id == ike_groups[i].id) {
364 			p = &ike_groups[i];
365 			break;
366 		}
367 	}
368 	return (p);
369 }
370 
371 int
dh_init(struct dh_group * group)372 dh_init(struct dh_group *group)
373 {
374 	return (group->init(group));
375 }
376 
377 int
dh_getlen(struct dh_group * group)378 dh_getlen(struct dh_group *group)
379 {
380 	return (group->getlen(group));
381 }
382 
383 int
dh_secretlen(struct dh_group * group)384 dh_secretlen(struct dh_group *group)
385 {
386 	if (group->secretlen)
387 		return (group->secretlen(group));
388 	else
389 		return (group->getlen(group));
390 }
391 
392 int
dh_create_exchange(struct dh_group * group,struct ibuf ** bufp,struct ibuf * iexchange)393 dh_create_exchange(struct dh_group *group, struct ibuf **bufp, struct ibuf *iexchange)
394 {
395 	struct ibuf *buf;
396 
397 	*bufp = NULL;
398 	if (group->exchange2)
399 		return (group->exchange2(group, bufp, iexchange));
400 	buf = ibuf_new(NULL, dh_getlen(group));
401 	if (buf == NULL)
402 		return -1;
403 	*bufp = buf;
404 	return (group->exchange(group, ibuf_data(buf)));
405 }
406 
407 int
dh_create_shared(struct dh_group * group,struct ibuf ** secretp,struct ibuf * exchange)408 dh_create_shared(struct dh_group *group, struct ibuf **secretp, struct ibuf *exchange)
409 {
410 	struct ibuf *buf;
411 
412 	*secretp = NULL;
413 	if (group->shared2)
414 		return (group->shared2(group, secretp, exchange));
415 	if (exchange == NULL ||
416 	    (ssize_t)ibuf_size(exchange) != dh_getlen(group))
417 		return -1;
418 	buf = ibuf_new(NULL, dh_secretlen(group));
419 	if (buf == NULL)
420 		return -1;
421 	*secretp = buf;
422 	return (group->shared(group, ibuf_data(buf), ibuf_data(exchange)));
423 }
424 
425 int
modp_init(struct dh_group * group)426 modp_init(struct dh_group *group)
427 {
428 	BIGNUM	*g = NULL, *p = NULL;
429 	DH	*dh;
430 	int	 ret = -1;
431 
432 	if ((dh = DH_new()) == NULL)
433 		return (-1);
434 
435 	if (!BN_hex2bn(&p, group->spec->prime) ||
436 	    !BN_hex2bn(&g, group->spec->generator) ||
437 	    DH_set0_pqg(dh, p, NULL, g) == 0)
438 		goto done;
439 
440 	p = g = NULL;
441 	group->dh = dh;
442 
443 	ret = 0;
444  done:
445 	BN_clear_free(g);
446 	BN_clear_free(p);
447 
448 	return (ret);
449 }
450 
451 int
modp_getlen(struct dh_group * group)452 modp_getlen(struct dh_group *group)
453 {
454 	if (group->spec == NULL)
455 		return (0);
456 	return (roundup(group->spec->bits, 8) / 8);
457 }
458 
459 int
modp_create_exchange(struct dh_group * group,uint8_t * buf)460 modp_create_exchange(struct dh_group *group, uint8_t *buf)
461 {
462 	const BIGNUM	*pub;
463 	DH		*dh = group->dh;
464 	int		 len, ret;
465 
466 	if (!DH_generate_key(dh))
467 		return (-1);
468 	DH_get0_key(group->dh, &pub, NULL);
469 	ret = BN_bn2bin(pub, buf);
470 	if (!ret)
471 		return (-1);
472 
473 	len = dh_getlen(group);
474 
475 	/* add zero padding */
476 	if (ret < len) {
477 		bcopy(buf, buf + (len - ret), ret);
478 		bzero(buf, len - ret);
479 	}
480 
481 	return (0);
482 }
483 
484 int
modp_create_shared(struct dh_group * group,uint8_t * secret,uint8_t * exchange)485 modp_create_shared(struct dh_group *group, uint8_t *secret, uint8_t *exchange)
486 {
487 	BIGNUM	*ex;
488 	int	 len, ret;
489 
490 	len = dh_getlen(group);
491 
492 	if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL)
493 		return (-1);
494 
495 	ret = DH_compute_key(secret, ex, group->dh);
496 	BN_clear_free(ex);
497 	if (ret <= 0)
498 		return (-1);
499 
500 	/* add zero padding */
501 	if (ret < len) {
502 		bcopy(secret, secret + (len - ret), ret);
503 		bzero(secret, len - ret);
504 	}
505 
506 	return (0);
507 }
508 
509 int
ec_init(struct dh_group * group)510 ec_init(struct dh_group *group)
511 {
512 	if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL)
513 		return (-1);
514 	if (!EC_KEY_generate_key(group->ec))
515 		return (-1);
516 	if (!EC_KEY_check_key(group->ec))
517 		return (-1);
518 	return (0);
519 }
520 
521 int
ec_getlen(struct dh_group * group)522 ec_getlen(struct dh_group *group)
523 {
524 	if (group->spec == NULL)
525 		return (0);
526 	/* NB:  Return value will always be even */
527 	return ((roundup(group->spec->bits, 8) * 2) / 8);
528 }
529 
530 /*
531  * Note that the shared secret only includes the x value:
532  *
533  * See RFC 5903, 7. ECP Key Exchange Data Formats:
534  *   The Diffie-Hellman shared secret value consists of the x value of the
535  *   Diffie-Hellman common value.
536  * See also RFC 5903, 9. Changes from RFC 4753.
537  */
538 int
ec_secretlen(struct dh_group * group)539 ec_secretlen(struct dh_group *group)
540 {
541 	return (ec_getlen(group) / 2);
542 }
543 
544 int
ec_create_exchange(struct dh_group * group,uint8_t * buf)545 ec_create_exchange(struct dh_group *group, uint8_t *buf)
546 {
547 	size_t	 len;
548 
549 	len = ec_getlen(group);
550 	bzero(buf, len);
551 
552 	return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec),
553 	    buf, len, EC_POINT2RAW_FULL));
554 }
555 
556 int
ec_create_shared(struct dh_group * group,uint8_t * secret,uint8_t * exchange)557 ec_create_shared(struct dh_group *group, uint8_t *secret, uint8_t *exchange)
558 {
559 	const EC_GROUP	*ecgroup = NULL;
560 	const BIGNUM	*privkey;
561 	EC_KEY		*exkey = NULL;
562 	EC_POINT	*exchangep = NULL, *secretp = NULL;
563 	int		 ret = -1;
564 
565 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL ||
566 	    (privkey = EC_KEY_get0_private_key(group->ec)) == NULL)
567 		goto done;
568 
569 	if ((exchangep =
570 	    ec_raw2point(group, exchange, ec_getlen(group))) == NULL)
571 		goto done;
572 
573 	if ((exkey = EC_KEY_new()) == NULL)
574 		goto done;
575 	if (!EC_KEY_set_group(exkey, ecgroup))
576 		goto done;
577 	if (!EC_KEY_set_public_key(exkey, exchangep))
578 		goto done;
579 
580 	/* validate exchangep */
581 	if (!EC_KEY_check_key(exkey))
582 		goto done;
583 
584 	if ((secretp = EC_POINT_new(ecgroup)) == NULL)
585 		goto done;
586 
587 	if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL))
588 		goto done;
589 
590 	ret = ec_point2raw(group, secretp, secret, ec_secretlen(group),
591 	    EC_POINT2RAW_XONLY);
592 
593  done:
594 	if (exkey != NULL)
595 		EC_KEY_free(exkey);
596 	if (exchangep != NULL)
597 		EC_POINT_clear_free(exchangep);
598 	if (secretp != NULL)
599 		EC_POINT_clear_free(secretp);
600 
601 	return (ret);
602 }
603 
604 int
ec_point2raw(struct dh_group * group,const EC_POINT * point,uint8_t * buf,size_t len,int mode)605 ec_point2raw(struct dh_group *group, const EC_POINT *point,
606     uint8_t *buf, size_t len, int mode)
607 {
608 	const EC_GROUP	*ecgroup = NULL;
609 	BN_CTX		*bnctx = NULL;
610 	BIGNUM		*x = NULL, *y = NULL;
611 	int		 ret = -1;
612 	size_t		 eclen, xlen, ylen;
613 	off_t		 xoff, yoff;
614 
615 	if ((bnctx = BN_CTX_new()) == NULL)
616 		goto done;
617 	BN_CTX_start(bnctx);
618 	if ((x = BN_CTX_get(bnctx)) == NULL ||
619 	    (y = BN_CTX_get(bnctx)) == NULL)
620 		goto done;
621 
622 	eclen = ec_getlen(group);
623 	switch (mode) {
624 	case EC_POINT2RAW_XONLY:
625 		xlen = eclen / 2;
626 		ylen = 0;
627 		break;
628 	case EC_POINT2RAW_FULL:
629 		xlen = ylen = eclen / 2;
630 		break;
631 	default:
632 		goto done;
633 	}
634 	if (len < xlen + ylen)
635 		goto done;
636 
637 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
638 		goto done;
639 
640 	if (!EC_POINT_get_affine_coordinates(ecgroup, point, x, y, bnctx))
641 		goto done;
642 
643 	xoff = xlen - BN_num_bytes(x);
644 	bzero(buf, xoff);
645 	if (!BN_bn2bin(x, buf + xoff))
646 		goto done;
647 
648 	if (ylen > 0) {
649 		yoff = (ylen - BN_num_bytes(y)) + xlen;
650 		bzero(buf + xlen, yoff - xlen);
651 		if (!BN_bn2bin(y, buf + yoff))
652 			goto done;
653 	}
654 
655 	ret = 0;
656  done:
657 	/* Make sure to erase sensitive data */
658 	if (x != NULL)
659 		BN_clear(x);
660 	if (y != NULL)
661 		BN_clear(y);
662 	BN_CTX_end(bnctx);
663 	BN_CTX_free(bnctx);
664 
665 	return (ret);
666 }
667 
668 EC_POINT *
ec_raw2point(struct dh_group * group,uint8_t * buf,size_t len)669 ec_raw2point(struct dh_group *group, uint8_t *buf, size_t len)
670 {
671 	const EC_GROUP	*ecgroup = NULL;
672 	EC_POINT	*point = NULL;
673 	BN_CTX		*bnctx = NULL;
674 	BIGNUM		*x = NULL, *y = NULL;
675 	int		 ret = -1;
676 	size_t		 eclen;
677 	size_t		 xlen, ylen;
678 
679 	if ((bnctx = BN_CTX_new()) == NULL)
680 		goto done;
681 	BN_CTX_start(bnctx);
682 	if ((x = BN_CTX_get(bnctx)) == NULL ||
683 	    (y = BN_CTX_get(bnctx)) == NULL)
684 		goto done;
685 
686 	eclen = ec_getlen(group);
687 	if (len < eclen)
688 		goto done;
689 	xlen = ylen = eclen / 2;
690 	if ((x = BN_bin2bn(buf, xlen, x)) == NULL ||
691 	    (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL)
692 		goto done;
693 
694 	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
695 		goto done;
696 
697 	if ((point = EC_POINT_new(ecgroup)) == NULL)
698 		goto done;
699 
700 	if (!EC_POINT_set_affine_coordinates(ecgroup, point, x, y, bnctx))
701 		goto done;
702 
703 	ret = 0;
704  done:
705 	if (ret != 0 && point != NULL)
706 		EC_POINT_clear_free(point);
707 	/* Make sure to erase sensitive data */
708 	if (x != NULL)
709 		BN_clear(x);
710 	if (y != NULL)
711 		BN_clear(y);
712 	BN_CTX_end(bnctx);
713 	BN_CTX_free(bnctx);
714 
715 	return (point);
716 }
717 
718 int
ec25519_init(struct dh_group * group)719 ec25519_init(struct dh_group *group)
720 {
721 	static const uint8_t	 basepoint[CURVE25519_SIZE] = { 9 };
722 	struct curve25519_key	*curve25519;
723 
724 	if ((curve25519 = calloc(1, sizeof(*curve25519))) == NULL)
725 		return (-1);
726 
727 	group->curve25519 = curve25519;
728 
729 	arc4random_buf(curve25519->secret, CURVE25519_SIZE);
730 	crypto_scalarmult_curve25519(curve25519->public,
731 	    curve25519->secret, basepoint);
732 
733 	return (0);
734 }
735 
736 int
ec25519_getlen(struct dh_group * group)737 ec25519_getlen(struct dh_group *group)
738 {
739 	if (group->spec == NULL)
740 		return (0);
741 	return (CURVE25519_SIZE);
742 }
743 
744 int
ec25519_create_exchange(struct dh_group * group,uint8_t * buf)745 ec25519_create_exchange(struct dh_group *group, uint8_t *buf)
746 {
747 	struct curve25519_key	*curve25519 = group->curve25519;
748 
749 	memcpy(buf, curve25519->public, ec25519_getlen(group));
750 	return (0);
751 }
752 
753 int
ec25519_create_shared(struct dh_group * group,uint8_t * shared,uint8_t * public)754 ec25519_create_shared(struct dh_group *group, uint8_t *shared, uint8_t *public)
755 {
756 	struct curve25519_key	*curve25519 = group->curve25519;
757 
758 	crypto_scalarmult_curve25519(shared, curve25519->secret, public);
759 	return (0);
760 }
761 
762 /* combine sntrup761 with curve25519 */
763 
764 int
kemsx_init(struct dh_group * group)765 kemsx_init(struct dh_group *group)
766 {
767 	/* delayed until kemsx_create_exchange2 */
768 	return (0);
769 }
770 
771 int
kemsx_getlen(struct dh_group * group)772 kemsx_getlen(struct dh_group *group)
773 {
774 	return (0);
775 }
776 
777 int
kemsx_create_exchange2(struct dh_group * group,struct ibuf ** bufp,struct ibuf * iexchange)778 kemsx_create_exchange2(struct dh_group *group, struct ibuf **bufp,
779     struct ibuf *iexchange)
780 {
781 	struct kemsx_key	*kemsx;
782 	struct curve25519_key	*curve25519;
783 	struct ibuf		*buf = NULL;
784 	u_char *cp, *pk;
785 	size_t have, need;
786 
787 	if (ec25519_init(group) == -1)
788 		return (-1);
789 	if (group->curve25519 == NULL)
790 		return (-1);
791 	if ((kemsx = calloc(1, sizeof(*kemsx))) == NULL)
792 		return (-1);
793 	group->kemsx = kemsx;
794 
795 	if (iexchange == NULL) {
796 		kemsx->initiator = 1;
797 		crypto_kem_sntrup761_keypair(kemsx->public, kemsx->secret);
798 		/* output */
799 		need = crypto_kem_sntrup761_PUBLICKEYBYTES +
800 		    CURVE25519_SIZE;
801 		buf = ibuf_new(NULL, need);
802 		if (buf == NULL)
803 			return -1;
804 		cp = ibuf_data(buf);
805 		memcpy(cp, kemsx->public,
806 		    crypto_kem_sntrup761_PUBLICKEYBYTES);
807 		cp += crypto_kem_sntrup761_PUBLICKEYBYTES;
808 	} else {
809 		kemsx->initiator = 0;
810 		/* input */
811 		have = ibuf_size(iexchange);
812 		need = crypto_kem_sntrup761_PUBLICKEYBYTES +
813 		    CURVE25519_SIZE;
814 		if (have != need)
815 			return -1;
816 		/* output */
817 		need = crypto_kem_sntrup761_CIPHERTEXTBYTES +
818 		    CURVE25519_SIZE;
819 		buf = ibuf_new(NULL, need);
820 		if (buf == NULL)
821 			return -1;
822 		cp = ibuf_data(buf);
823 		pk = ibuf_data(iexchange);
824 		crypto_kem_sntrup761_enc(cp, kemsx->kemkey, pk);
825 		cp += crypto_kem_sntrup761_CIPHERTEXTBYTES;
826 	}
827 	curve25519 = group->curve25519;
828 	memcpy(cp, curve25519->public, CURVE25519_SIZE);
829 	*bufp = buf;
830 	return (0);
831 }
832 
833 int
kemsx_create_shared2(struct dh_group * group,struct ibuf ** sharedp,struct ibuf * exchange)834 kemsx_create_shared2(struct dh_group *group, struct ibuf **sharedp,
835     struct ibuf *exchange)
836 {
837 	struct curve25519_key	*curve25519 = group->curve25519;
838 	struct kemsx_key	*kemsx = group->kemsx;
839 	struct ibuf		*buf = NULL;
840 	EVP_MD_CTX		*ctx = NULL;
841 	uint8_t			*cp;
842 	uint8_t			 shared[CURVE25519_SIZE];
843 	size_t			 have, need;
844 	u_int			 len;
845 
846 	*sharedp = NULL;
847 	if (kemsx == NULL)
848 		return (-1);
849 	if (exchange == NULL)
850 		return (-1);
851 
852 	have = ibuf_size(exchange);
853 	cp = ibuf_data(exchange);
854 	if (kemsx->initiator) {
855 		/* input */
856 		need = crypto_kem_sntrup761_CIPHERTEXTBYTES +
857 		    CURVE25519_SIZE;
858 		if (have != need)
859 			return (-1);
860 		crypto_kem_sntrup761_dec(kemsx->kemkey, cp, kemsx->secret);
861 		cp += crypto_kem_sntrup761_CIPHERTEXTBYTES;
862 	} else {
863 		/* input, should have been checked before */
864 		need = crypto_kem_sntrup761_PUBLICKEYBYTES +
865 		    CURVE25519_SIZE;
866 		if (have != need)
867 			return (-1);
868 		cp += crypto_kem_sntrup761_PUBLICKEYBYTES;
869 	}
870 	crypto_scalarmult_curve25519(shared, curve25519->secret, cp);
871 
872 	/* result is hash of concatenation of KEM key and DH shared secret */
873 	len = SHA512_DIGEST_LENGTH;
874 	buf = ibuf_new(NULL, len);
875 	if (buf == NULL)
876 		return (-1);
877 	if ((ctx = EVP_MD_CTX_new()) == NULL ||
878 	    EVP_DigestInit_ex(ctx, EVP_sha512(), NULL) != 1 ||
879 	    EVP_DigestUpdate(ctx, kemsx->kemkey, sizeof(kemsx->kemkey)) != 1 ||
880 	    EVP_DigestUpdate(ctx, shared, sizeof(shared)) != 1 ||
881 	    EVP_DigestFinal_ex(ctx, ibuf_data(buf), &len) != 1) {
882 		EVP_MD_CTX_free(ctx);
883 		ibuf_free(buf);
884 		return (-1);
885 	}
886 	EVP_MD_CTX_free(ctx);
887 	*sharedp = buf;
888 	return (0);
889 }
890