GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/iked/dh.c Lines: 0 180 0.0 %
Date: 2017-11-13 Branches: 0 136 0.0 %

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