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

Line Branch Exec Source
1
/*	$OpenBSD: dh.c,v 1.20 2017/05/21 02:37:52 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 *, 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
const 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_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 },
239
	{ GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 },
240
	{ GROUP_ECP, 27, 224, NULL, NULL, NID_brainpoolP224r1 },
241
	{ GROUP_ECP, 28, 256, NULL, NULL, NID_brainpoolP256r1 },
242
	{ GROUP_ECP, 29, 384, NULL, NULL, NID_brainpoolP384r1 },
243
	{ GROUP_ECP, 30, 512, NULL, NULL, NID_brainpoolP512r1 },
244
245
	/* "Private use" extensions */
246
	{ GROUP_CURVE25519, 1034, CURVE25519_SIZE * 8 }
247
};
248
249
void
250
group_init(void)
251
{
252
	/* currently not used */
253
	return;
254
}
255
256
void
257
group_free(struct group *group)
258
{
259
	if (group == NULL)
260
		return;
261
	if (group->dh != NULL)
262
		DH_free(group->dh);
263
	if (group->ec != NULL)
264
		EC_KEY_free(group->ec);
265
	freezero(group->curve25519, sizeof(struct curve25519_key));
266
	group->spec = NULL;
267
	free(group);
268
}
269
270
struct group *
271
group_get(uint32_t id)
272
{
273
	const struct group_id	*p;
274
	struct group		*group;
275
276
	if ((p = group_getid(id)) == NULL)
277
		return (NULL);
278
279
	if ((group = calloc(1, sizeof(*group))) == NULL)
280
		return (NULL);
281
282
	group->id = id;
283
	group->spec = p;
284
285
	switch (p->type) {
286
	case GROUP_MODP:
287
		group->init = modp_init;
288
		group->getlen = modp_getlen;
289
		group->exchange = modp_create_exchange;
290
		group->shared = modp_create_shared;
291
		break;
292
	case GROUP_EC2N:
293
	case GROUP_ECP:
294
		group->init = ec_init;
295
		group->getlen = ec_getlen;
296
		group->exchange = ec_create_exchange;
297
		group->shared = ec_create_shared;
298
		break;
299
	case GROUP_CURVE25519:
300
		group->init = ec25519_init;
301
		group->getlen = ec25519_getlen;
302
		group->exchange = ec25519_create_exchange;
303
		group->shared = ec25519_create_shared;
304
		break;
305
	default:
306
		group_free(group);
307
		return (NULL);
308
	}
309
310
	if (dh_init(group) != 0) {
311
		group_free(group);
312
		return (NULL);
313
	}
314
315
	return (group);
316
}
317
318
const struct group_id *
319
group_getid(uint32_t id)
320
{
321
	const struct group_id	*p = NULL;
322
	unsigned int		 i, items;
323
324
	items = sizeof(ike_groups) / sizeof(ike_groups[0]);
325
	for (i = 0; i < items; i++) {
326
		if (id == ike_groups[i].id) {
327
			p = &ike_groups[i];
328
			break;
329
		}
330
	}
331
	return (p);
332
}
333
334
int
335
dh_init(struct group *group)
336
{
337
	return (group->init(group));
338
}
339
340
int
341
dh_getlen(struct group *group)
342
{
343
	return (group->getlen(group));
344
}
345
346
int
347
dh_create_exchange(struct group *group, uint8_t *buf)
348
{
349
	return (group->exchange(group, buf));
350
}
351
352
int
353
dh_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange)
354
{
355
	return (group->shared(group, secret, exchange));
356
}
357
358
int
359
modp_init(struct group *group)
360
{
361
	DH	*dh;
362
363
	if ((dh = DH_new()) == NULL)
364
		return (-1);
365
	group->dh = dh;
366
367
	if (!BN_hex2bn(&dh->p, group->spec->prime) ||
368
	    !BN_hex2bn(&dh->g, group->spec->generator))
369
		return (-1);
370
371
	return (0);
372
}
373
374
int
375
modp_getlen(struct group *group)
376
{
377
	if (group->spec == NULL)
378
		return (0);
379
	return (roundup(group->spec->bits, 8) / 8);
380
}
381
382
int
383
modp_create_exchange(struct group *group, uint8_t *buf)
384
{
385
	DH	*dh = group->dh;
386
	int	 len, ret;
387
388
	if (!DH_generate_key(dh))
389
		return (-1);
390
	ret = BN_bn2bin(dh->pub_key, buf);
391
	if (!ret)
392
		return (-1);
393
394
	len = dh_getlen(group);
395
396
	/* add zero padding */
397
	if (ret < len) {
398
		bcopy(buf, buf + (len - ret), ret);
399
		bzero(buf, len - ret);
400
	}
401
402
	return (0);
403
}
404
405
int
406
modp_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange)
407
{
408
	BIGNUM	*ex;
409
	int	 len, ret;
410
411
	len = dh_getlen(group);
412
413
	if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL)
414
		return (-1);
415
416
	ret = DH_compute_key(secret, ex, group->dh);
417
	BN_clear_free(ex);
418
	if (ret <= 0)
419
		return (-1);
420
421
	/* add zero padding */
422
	if (ret < len) {
423
		bcopy(secret, secret + (len - ret), ret);
424
		bzero(secret, len - ret);
425
	}
426
427
	return (0);
428
}
429
430
int
431
ec_init(struct group *group)
432
{
433
	if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL)
434
		return (-1);
435
	if (!EC_KEY_generate_key(group->ec))
436
		return (-1);
437
	if (!EC_KEY_check_key(group->ec)) {
438
		EC_KEY_free(group->ec);
439
		return (-1);
440
	}
441
	return (0);
442
}
443
444
int
445
ec_getlen(struct group *group)
446
{
447
	if (group->spec == NULL)
448
		return (0);
449
	/* NB:  Return value will always be even */
450
	return ((roundup(group->spec->bits, 8) * 2) / 8);
451
}
452
453
int
454
ec_create_exchange(struct group *group, uint8_t *buf)
455
{
456
	size_t	 len;
457
458
	len = ec_getlen(group);
459
	bzero(buf, len);
460
461
	return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec),
462
	    buf, len));
463
}
464
465
int
466
ec_create_shared(struct group *group, uint8_t *secret, uint8_t *exchange)
467
{
468
	const EC_GROUP	*ecgroup = NULL;
469
	const BIGNUM	*privkey;
470
	EC_KEY		*exkey = NULL;
471
	EC_POINT	*exchangep = NULL, *secretp = NULL;
472
	int		 ret = -1;
473
474
	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL ||
475
	    (privkey = EC_KEY_get0_private_key(group->ec)) == NULL)
476
		goto done;
477
478
	if ((exchangep =
479
	    ec_raw2point(group, exchange, ec_getlen(group))) == NULL)
480
		goto done;
481
482
	if ((exkey = EC_KEY_new()) == NULL)
483
		goto done;
484
	if (!EC_KEY_set_group(exkey, ecgroup))
485
		goto done;
486
	if (!EC_KEY_set_public_key(exkey, exchangep))
487
		goto done;
488
489
	/* validate exchangep */
490
	if (!EC_KEY_check_key(exkey))
491
		goto done;
492
493
	if ((secretp = EC_POINT_new(ecgroup)) == NULL)
494
		goto done;
495
496
	if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL))
497
		goto done;
498
499
	ret = ec_point2raw(group, secretp, secret, ec_getlen(group));
500
501
 done:
502
	if (exkey != NULL)
503
		EC_KEY_free(exkey);
504
	if (exchangep != NULL)
505
		EC_POINT_clear_free(exchangep);
506
	if (secretp != NULL)
507
		EC_POINT_clear_free(secretp);
508
509
	return (ret);
510
}
511
512
int
513
ec_point2raw(struct group *group, const EC_POINT *point,
514
    uint8_t *buf, size_t len)
515
{
516
	const EC_GROUP	*ecgroup = NULL;
517
	BN_CTX		*bnctx = NULL;
518
	BIGNUM		*x = NULL, *y = NULL;
519
	int		 ret = -1;
520
	size_t		 eclen, xlen, ylen;
521
	off_t		 xoff, yoff;
522
523
	if ((bnctx = BN_CTX_new()) == NULL)
524
		goto done;
525
	BN_CTX_start(bnctx);
526
	if ((x = BN_CTX_get(bnctx)) == NULL ||
527
	    (y = BN_CTX_get(bnctx)) == NULL)
528
		goto done;
529
530
	eclen = ec_getlen(group);
531
	if (len < eclen)
532
		goto done;
533
	xlen = ylen = eclen / 2;
534
535
	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
536
		goto done;
537
538
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
539
	    NID_X9_62_prime_field) {
540
		if (!EC_POINT_get_affine_coordinates_GFp(ecgroup,
541
		    point, x, y, bnctx))
542
			goto done;
543
	} else {
544
		if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup,
545
		    point, x, y, bnctx))
546
			goto done;
547
	}
548
549
	xoff = xlen - BN_num_bytes(x);
550
	bzero(buf, xoff);
551
	if (!BN_bn2bin(x, buf + xoff))
552
		goto done;
553
554
	yoff = (ylen - BN_num_bytes(y)) + xlen;
555
	bzero(buf + xlen, yoff - xlen);
556
	if (!BN_bn2bin(y, buf + yoff))
557
		goto done;
558
559
	ret = 0;
560
 done:
561
	/* Make sure to erase sensitive data */
562
	if (x != NULL)
563
		BN_clear(x);
564
	if (y != NULL)
565
		BN_clear(y);
566
	BN_CTX_end(bnctx);
567
	BN_CTX_free(bnctx);
568
569
	return (ret);
570
}
571
572
EC_POINT *
573
ec_raw2point(struct group *group, uint8_t *buf, size_t len)
574
{
575
	const EC_GROUP	*ecgroup = NULL;
576
	EC_POINT	*point = NULL;
577
	BN_CTX		*bnctx = NULL;
578
	BIGNUM		*x = NULL, *y = NULL;
579
	int		 ret = -1;
580
	size_t		 eclen;
581
	size_t		 xlen, ylen;
582
583
	if ((bnctx = BN_CTX_new()) == NULL)
584
		goto done;
585
	BN_CTX_start(bnctx);
586
	if ((x = BN_CTX_get(bnctx)) == NULL ||
587
	    (y = BN_CTX_get(bnctx)) == NULL)
588
		goto done;
589
590
	eclen = ec_getlen(group);
591
	if (len < eclen)
592
		goto done;
593
	xlen = ylen = eclen / 2;
594
	if ((x = BN_bin2bn(buf, xlen, x)) == NULL ||
595
	    (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL)
596
		goto done;
597
598
	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
599
		goto done;
600
601
	if ((point = EC_POINT_new(ecgroup)) == NULL)
602
		goto done;
603
604
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
605
	    NID_X9_62_prime_field) {
606
		if (!EC_POINT_set_affine_coordinates_GFp(ecgroup,
607
		    point, x, y, bnctx))
608
			goto done;
609
	} else {
610
		if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup,
611
		    point, x, y, bnctx))
612
			goto done;
613
	}
614
615
	ret = 0;
616
 done:
617
	if (ret != 0 && point != NULL)
618
		EC_POINT_clear_free(point);
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 (point);
628
}
629
630
int
631
ec25519_init(struct group *group)
632
{
633
	static const uint8_t	 basepoint[CURVE25519_SIZE] = { 9 };
634
	struct curve25519_key	*curve25519;
635
636
	if ((curve25519 = calloc(1, sizeof(*curve25519))) == NULL)
637
		return (-1);
638
639
	group->curve25519 = curve25519;
640
641
	arc4random_buf(curve25519->secret, CURVE25519_SIZE);
642
	crypto_scalarmult_curve25519(curve25519->public,
643
	    curve25519->secret, basepoint);
644
645
	return (0);
646
}
647
648
int
649
ec25519_getlen(struct group *group)
650
{
651
	if (group->spec == NULL)
652
		return (0);
653
	return (CURVE25519_SIZE);
654
}
655
656
int
657
ec25519_create_exchange(struct group *group, uint8_t *buf)
658
{
659
	struct curve25519_key	*curve25519 = group->curve25519;
660
661
	memcpy(buf, curve25519->public, ec25519_getlen(group));
662
	return (0);
663
}
664
665
int
666
ec25519_create_shared(struct group *group, uint8_t *shared, uint8_t *public)
667
{
668
	struct curve25519_key	*curve25519 = group->curve25519;
669
670
	crypto_scalarmult_curve25519(shared, curve25519->secret, public);
671
	return (0);
672
}