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

Line Branch Exec Source
1
/*	$OpenBSD: dh.c,v 1.20 2017/01/04 12:31:01 mikeb 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
int	modp_init(struct group *);
33
int	modp_getlen(struct group *);
34
int	modp_create_exchange(struct group *, u_int8_t *);
35
int	modp_create_shared(struct group *, u_int8_t *, u_int8_t *);
36
37
int	ec_init(struct group *);
38
int	ec_getlen(struct group *);
39
int	ec_create_exchange(struct group *, u_int8_t *);
40
int	ec_create_shared(struct group *, u_int8_t *, u_int8_t *);
41
42
int	ec_point2raw(struct group *, const EC_POINT *, u_int8_t *, size_t);
43
EC_POINT *
44
	ec_raw2point(struct group *, u_int8_t *, size_t);
45
46
struct group_id ike_groups[] = {
47
	{ GROUP_MODP, 1, 768,
48
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
49
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
50
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
51
	    "E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF",
52
	    "02"
53
	},
54
	{ GROUP_MODP, 2, 1024,
55
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
56
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
57
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
58
	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
59
	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
60
	    "FFFFFFFFFFFFFFFF",
61
	    "02"
62
	},
63
	{ GROUP_EC2N, 3, 155, NULL, NULL, NID_ipsec3 },
64
	{ GROUP_EC2N, 4, 185, NULL, NULL, NID_ipsec4 },
65
	{ GROUP_MODP, 5, 1536,
66
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
67
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
68
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
69
	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
70
	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
71
	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
72
	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
73
	    "670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF",
74
	    "02"
75
	},
76
	{ GROUP_MODP, 14, 2048,
77
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
78
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
79
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
80
	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
81
	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
82
	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
83
	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
84
	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
85
	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
86
	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
87
	    "15728E5A8AACAA68FFFFFFFFFFFFFFFF",
88
	    "02"
89
	},
90
	{ GROUP_MODP, 15, 3072,
91
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
92
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
93
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
94
	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
95
	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
96
	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
97
	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
98
	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
99
	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
100
	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
101
	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
102
	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
103
	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
104
	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
105
	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
106
	    "43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF",
107
	    "02"
108
	},
109
	{ GROUP_MODP, 16, 4096,
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
	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
126
	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
127
	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
128
	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
129
	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
130
	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
131
	    "FFFFFFFFFFFFFFFF",
132
	    "02"
133
	},
134
	{ GROUP_MODP, 17, 6144,
135
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
136
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
137
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
138
	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
139
	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
140
	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
141
	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
142
	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
143
	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
144
	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
145
	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
146
	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
147
	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
148
	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
149
	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
150
	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
151
	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
152
	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
153
	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
154
	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
155
	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
156
	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
157
	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
158
	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
159
	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
160
	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
161
	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
162
	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
163
	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
164
	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
165
	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
166
	    "12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF",
167
	    "02"
168
	},
169
	{ GROUP_MODP, 18, 8192,
170
	    "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
171
	    "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
172
	    "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
173
	    "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
174
	    "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
175
	    "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
176
	    "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
177
	    "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
178
	    "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
179
	    "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
180
	    "15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
181
	    "ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
182
	    "ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
183
	    "F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
184
	    "BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
185
	    "43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
186
	    "88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
187
	    "2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
188
	    "287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
189
	    "1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
190
	    "93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
191
	    "36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
192
	    "F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
193
	    "179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
194
	    "DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
195
	    "5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
196
	    "D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
197
	    "23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
198
	    "CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
199
	    "06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
200
	    "DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
201
	    "12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
202
	    "38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
203
	    "741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
204
	    "3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
205
	    "22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
206
	    "4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
207
	    "062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
208
	    "4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
209
	    "B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
210
	    "4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
211
	    "9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
212
	    "60C980DD98EDD3DFFFFFFFFFFFFFFFFF",
213
	    "02"
214
	},
215
	{ GROUP_ECP, 19, 256, NULL, NULL, NID_X9_62_prime256v1 },
216
	{ GROUP_ECP, 20, 384, NULL, NULL, NID_secp384r1 },
217
	{ GROUP_ECP, 21, 521, NULL, NULL, NID_secp521r1 },
218
	{ GROUP_ECP, 25, 192, NULL, NULL, NID_X9_62_prime192v1 },
219
	{ GROUP_ECP, 26, 224, NULL, NULL, NID_secp224r1 },
220
	{ GROUP_ECP, 27, 224, NULL, NULL, NID_brainpoolP224r1 },
221
	{ GROUP_ECP, 28, 256, NULL, NULL, NID_brainpoolP256r1 },
222
	{ GROUP_ECP, 29, 384, NULL, NULL, NID_brainpoolP384r1 },
223
	{ GROUP_ECP, 30, 512, NULL, NULL, NID_brainpoolP512r1 }
224
};
225
226
void
227
group_init(void)
228
{
229
	/* currently not used */
230
	return;
231
}
232
233
void
234
group_free(struct group *group)
235
{
236
	if (group == NULL)
237
		return;
238
	if (group->dh != NULL)
239
		DH_free(group->dh);
240
	if (group->ec != NULL)
241
		EC_KEY_free(group->ec);
242
	group->spec = NULL;
243
	free(group);
244
}
245
246
struct group *
247
group_get(u_int32_t id)
248
{
249
	struct group_id	*p = NULL;
250
	struct group	*group;
251
	u_int		 i, items;
252
253
	items = sizeof(ike_groups) / sizeof(ike_groups[0]);
254
	for (i = 0; i < items; i++) {
255
		if (id == ike_groups[i].id) {
256
			p = &ike_groups[i];
257
			break;
258
		}
259
	}
260
	if (p == NULL)
261
		return (NULL);
262
263
	if ((group = calloc(1, sizeof(*group))) == NULL)
264
		return (NULL);
265
266
	group->id = id;
267
	group->spec = p;
268
269
	switch (p->type) {
270
	case GROUP_MODP:
271
		group->init = modp_init;
272
		group->getlen = modp_getlen;
273
		group->exchange = modp_create_exchange;
274
		group->shared = modp_create_shared;
275
		break;
276
	case GROUP_EC2N:
277
	case GROUP_ECP:
278
		group->init = ec_init;
279
		group->getlen = ec_getlen;
280
		group->exchange = ec_create_exchange;
281
		group->shared = ec_create_shared;
282
		break;
283
	default:
284
		group_free(group);
285
		return (NULL);
286
	}
287
288
	if (dh_init(group) != 0) {
289
		group_free(group);
290
		return (NULL);
291
	}
292
293
	return (group);
294
}
295
296
int
297
dh_init(struct group *group)
298
{
299
	return (group->init(group));
300
}
301
302
int
303
dh_getlen(struct group *group)
304
{
305
	return (group->getlen(group));
306
}
307
308
int
309
dh_create_exchange(struct group *group, u_int8_t *buf)
310
{
311
	return (group->exchange(group, buf));
312
}
313
314
int
315
dh_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
316
{
317
	return (group->shared(group, secret, exchange));
318
}
319
320
int
321
modp_init(struct group *group)
322
{
323
	DH	*dh;
324
325
	if ((dh = DH_new()) == NULL)
326
		return (-1);
327
	group->dh = dh;
328
329
	if (!BN_hex2bn(&dh->p, group->spec->prime) ||
330
	    !BN_hex2bn(&dh->g, group->spec->generator))
331
		return (-1);
332
333
	return (0);
334
}
335
336
int
337
modp_getlen(struct group *group)
338
{
339
	if (group->spec == NULL)
340
		return (0);
341
	return (roundup(group->spec->bits, 8) / 8);
342
}
343
344
int
345
modp_create_exchange(struct group *group, u_int8_t *buf)
346
{
347
	DH	*dh = group->dh;
348
	int	 len, ret;
349
350
	if (!DH_generate_key(dh))
351
		return (-1);
352
	ret = BN_bn2bin(dh->pub_key, buf);
353
	if (!ret)
354
		return (-1);
355
356
	len = dh_getlen(group);
357
358
	/* add zero padding */
359
	if (ret < len) {
360
		bcopy(buf, buf + (len - ret), ret);
361
		bzero(buf, len - ret);
362
	}
363
364
	return (0);
365
}
366
367
int
368
modp_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
369
{
370
	BIGNUM	*ex;
371
	int	 len, ret;
372
373
	len = dh_getlen(group);
374
375
	if ((ex = BN_bin2bn(exchange, len, NULL)) == NULL)
376
		return (-1);
377
378
	ret = DH_compute_key(secret, ex, group->dh);
379
	BN_clear_free(ex);
380
	if (ret <= 0)
381
		return (-1);
382
383
	/* add zero padding */
384
	if (ret < len) {
385
		bcopy(secret, secret + (len - ret), ret);
386
		bzero(secret, len - ret);
387
	}
388
389
	return (0);
390
}
391
392
int
393
ec_init(struct group *group)
394
{
395
	if ((group->ec = EC_KEY_new_by_curve_name(group->spec->nid)) == NULL)
396
		return (-1);
397
	if (!EC_KEY_generate_key(group->ec))
398
		return (-1);
399
	if (!EC_KEY_check_key(group->ec)) {
400
		EC_KEY_free(group->ec);
401
		return (-1);
402
	}
403
	return (0);
404
}
405
406
int
407
ec_getlen(struct group *group)
408
{
409
	if (group->spec == NULL)
410
		return (0);
411
	/* NB:  Return value will always be even */
412
	return ((roundup(group->spec->bits, 8) * 2) / 8);
413
}
414
415
int
416
ec_create_exchange(struct group *group, u_int8_t *buf)
417
{
418
	size_t	 len;
419
420
	len = ec_getlen(group);
421
	bzero(buf, len);
422
423
	return (ec_point2raw(group, EC_KEY_get0_public_key(group->ec),
424
	    buf, len));
425
}
426
427
int
428
ec_create_shared(struct group *group, u_int8_t *secret, u_int8_t *exchange)
429
{
430
	const EC_GROUP	*ecgroup = NULL;
431
	const BIGNUM	*privkey;
432
	EC_KEY		*exkey = NULL;
433
	EC_POINT	*exchangep = NULL, *secretp = NULL;
434
	int		 ret = -1;
435
436
	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL ||
437
	    (privkey = EC_KEY_get0_private_key(group->ec)) == NULL)
438
		goto done;
439
440
	if ((exchangep =
441
	    ec_raw2point(group, exchange, ec_getlen(group))) == NULL)
442
		goto done;
443
444
	if ((exkey = EC_KEY_new()) == NULL)
445
		goto done;
446
	if (!EC_KEY_set_group(exkey, ecgroup))
447
		goto done;
448
	if (!EC_KEY_set_public_key(exkey, exchangep))
449
		goto done;
450
451
	/* validate exchangep */
452
	if (!EC_KEY_check_key(exkey))
453
		goto done;
454
455
	if ((secretp = EC_POINT_new(ecgroup)) == NULL)
456
		goto done;
457
458
	if (!EC_POINT_mul(ecgroup, secretp, NULL, exchangep, privkey, NULL))
459
		goto done;
460
461
	ret = ec_point2raw(group, secretp, secret, ec_getlen(group));
462
463
 done:
464
	if (exkey != NULL)
465
		EC_KEY_free(exkey);
466
	if (exchangep != NULL)
467
		EC_POINT_clear_free(exchangep);
468
	if (secretp != NULL)
469
		EC_POINT_clear_free(secretp);
470
471
	return (ret);
472
}
473
474
int
475
ec_point2raw(struct group *group, const EC_POINT *point,
476
    u_int8_t *buf, size_t len)
477
{
478
	const EC_GROUP	*ecgroup = NULL;
479
	BN_CTX		*bnctx = NULL;
480
	BIGNUM		*x = NULL, *y = NULL;
481
	int		 ret = -1;
482
	size_t		 eclen, xlen, ylen;
483
	off_t		 xoff, yoff;
484
485
	if ((bnctx = BN_CTX_new()) == NULL)
486
		goto done;
487
	BN_CTX_start(bnctx);
488
	if ((x = BN_CTX_get(bnctx)) == NULL ||
489
	    (y = BN_CTX_get(bnctx)) == NULL)
490
		goto done;
491
492
	eclen = ec_getlen(group);
493
	if (len < eclen)
494
		goto done;
495
	xlen = ylen = eclen / 2;
496
497
	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
498
		goto done;
499
500
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
501
	    NID_X9_62_prime_field) {
502
		if (!EC_POINT_get_affine_coordinates_GFp(ecgroup,
503
		    point, x, y, bnctx))
504
			goto done;
505
	} else {
506
		if (!EC_POINT_get_affine_coordinates_GF2m(ecgroup,
507
		    point, x, y, bnctx))
508
			goto done;
509
	}
510
511
	xoff = xlen - BN_num_bytes(x);
512
	bzero(buf, xoff);
513
	if (!BN_bn2bin(x, buf + xoff))
514
		goto done;
515
516
	yoff = (ylen - BN_num_bytes(y)) + xlen;
517
	bzero(buf + xlen, yoff - xlen);
518
	if (!BN_bn2bin(y, buf + yoff))
519
		goto done;
520
521
	ret = 0;
522
 done:
523
	/* Make sure to erase sensitive data */
524
	if (x != NULL)
525
		BN_clear(x);
526
	if (y != NULL)
527
		BN_clear(y);
528
	BN_CTX_end(bnctx);
529
	BN_CTX_free(bnctx);
530
531
	return (ret);
532
}
533
534
EC_POINT *
535
ec_raw2point(struct group *group, u_int8_t *buf, size_t len)
536
{
537
	const EC_GROUP	*ecgroup = NULL;
538
	EC_POINT	*point = NULL;
539
	BN_CTX		*bnctx = NULL;
540
	BIGNUM		*x = NULL, *y = NULL;
541
	int		 ret = -1;
542
	size_t		 eclen;
543
	size_t		 xlen, ylen;
544
545
	if ((bnctx = BN_CTX_new()) == NULL)
546
		goto done;
547
	BN_CTX_start(bnctx);
548
	if ((x = BN_CTX_get(bnctx)) == NULL ||
549
	    (y = BN_CTX_get(bnctx)) == NULL)
550
		goto done;
551
552
	eclen = ec_getlen(group);
553
	if (len < eclen)
554
		goto done;
555
	xlen = ylen = eclen / 2;
556
	if ((x = BN_bin2bn(buf, xlen, x)) == NULL ||
557
	    (y = BN_bin2bn(buf + xlen, ylen, y)) == NULL)
558
		goto done;
559
560
	if ((ecgroup = EC_KEY_get0_group(group->ec)) == NULL)
561
		goto done;
562
563
	if ((point = EC_POINT_new(ecgroup)) == NULL)
564
		goto done;
565
566
	if (EC_METHOD_get_field_type(EC_GROUP_method_of(ecgroup)) ==
567
	    NID_X9_62_prime_field) {
568
		if (!EC_POINT_set_affine_coordinates_GFp(ecgroup,
569
		    point, x, y, bnctx))
570
			goto done;
571
	} else {
572
		if (!EC_POINT_set_affine_coordinates_GF2m(ecgroup,
573
		    point, x, y, bnctx))
574
			goto done;
575
	}
576
577
	ret = 0;
578
 done:
579
	if (ret != 0 && point != NULL)
580
		EC_POINT_clear_free(point);
581
	/* Make sure to erase sensitive data */
582
	if (x != NULL)
583
		BN_clear(x);
584
	if (y != NULL)
585
		BN_clear(y);
586
	BN_CTX_end(bnctx);
587
	BN_CTX_free(bnctx);
588
589
	return (point);
590
}