GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: sbin/iked/dh.c Lines: 0 207 0.0 %
Date: 2016-12-06 Branches: 0 130 0.0 %

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