1*a1157835SDaniel Fojt /*
2*a1157835SDaniel Fojt  * Wrapper functions for libnettle and libgmp
3*a1157835SDaniel Fojt  * Copyright (c) 2017, Jouni Malinen <j@w1.fi>
4*a1157835SDaniel Fojt  *
5*a1157835SDaniel Fojt  * This software may be distributed under the terms of the BSD license.
6*a1157835SDaniel Fojt  * See README for more details.
7*a1157835SDaniel Fojt  */
8*a1157835SDaniel Fojt 
9*a1157835SDaniel Fojt #include "includes.h"
10*a1157835SDaniel Fojt #include <nettle/nettle-meta.h>
11*a1157835SDaniel Fojt #include <nettle/des.h>
12*a1157835SDaniel Fojt #undef des_encrypt
13*a1157835SDaniel Fojt #include <nettle/hmac.h>
14*a1157835SDaniel Fojt #include <nettle/aes.h>
15*a1157835SDaniel Fojt #undef aes_encrypt
16*a1157835SDaniel Fojt #undef aes_decrypt
17*a1157835SDaniel Fojt #include <nettle/arcfour.h>
18*a1157835SDaniel Fojt #include <nettle/bignum.h>
19*a1157835SDaniel Fojt 
20*a1157835SDaniel Fojt #include "common.h"
21*a1157835SDaniel Fojt #include "md5.h"
22*a1157835SDaniel Fojt #include "sha1.h"
23*a1157835SDaniel Fojt #include "sha256.h"
24*a1157835SDaniel Fojt #include "sha384.h"
25*a1157835SDaniel Fojt #include "sha512.h"
26*a1157835SDaniel Fojt #include "crypto.h"
27*a1157835SDaniel Fojt 
28*a1157835SDaniel Fojt 
des_encrypt(const u8 * clear,const u8 * key,u8 * cypher)29*a1157835SDaniel Fojt int des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
30*a1157835SDaniel Fojt {
31*a1157835SDaniel Fojt 	struct des_ctx ctx;
32*a1157835SDaniel Fojt 	u8 pkey[8], next, tmp;
33*a1157835SDaniel Fojt 	int i;
34*a1157835SDaniel Fojt 
35*a1157835SDaniel Fojt 	/* Add parity bits to the key */
36*a1157835SDaniel Fojt 	next = 0;
37*a1157835SDaniel Fojt 	for (i = 0; i < 7; i++) {
38*a1157835SDaniel Fojt 		tmp = key[i];
39*a1157835SDaniel Fojt 		pkey[i] = (tmp >> i) | next | 1;
40*a1157835SDaniel Fojt 		next = tmp << (7 - i);
41*a1157835SDaniel Fojt 	}
42*a1157835SDaniel Fojt 	pkey[i] = next | 1;
43*a1157835SDaniel Fojt 
44*a1157835SDaniel Fojt 	nettle_des_set_key(&ctx, pkey);
45*a1157835SDaniel Fojt 	nettle_des_encrypt(&ctx, DES_BLOCK_SIZE, cypher, clear);
46*a1157835SDaniel Fojt 	os_memset(&ctx, 0, sizeof(ctx));
47*a1157835SDaniel Fojt 	return 0;
48*a1157835SDaniel Fojt }
49*a1157835SDaniel Fojt 
50*a1157835SDaniel Fojt 
nettle_digest_vector(const struct nettle_hash * alg,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)51*a1157835SDaniel Fojt static int nettle_digest_vector(const struct nettle_hash *alg, size_t num_elem,
52*a1157835SDaniel Fojt 				const u8 *addr[], const size_t *len, u8 *mac)
53*a1157835SDaniel Fojt {
54*a1157835SDaniel Fojt 	void *ctx;
55*a1157835SDaniel Fojt 	size_t i;
56*a1157835SDaniel Fojt 
57*a1157835SDaniel Fojt 	if (TEST_FAIL())
58*a1157835SDaniel Fojt 		return -1;
59*a1157835SDaniel Fojt 
60*a1157835SDaniel Fojt 	ctx = os_malloc(alg->context_size);
61*a1157835SDaniel Fojt 	if (!ctx)
62*a1157835SDaniel Fojt 		return -1;
63*a1157835SDaniel Fojt 	alg->init(ctx);
64*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++)
65*a1157835SDaniel Fojt 		alg->update(ctx, len[i], addr[i]);
66*a1157835SDaniel Fojt 	alg->digest(ctx, alg->digest_size, mac);
67*a1157835SDaniel Fojt 	bin_clear_free(ctx, alg->context_size);
68*a1157835SDaniel Fojt 	return 0;
69*a1157835SDaniel Fojt }
70*a1157835SDaniel Fojt 
71*a1157835SDaniel Fojt 
md4_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)72*a1157835SDaniel Fojt int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
73*a1157835SDaniel Fojt {
74*a1157835SDaniel Fojt 	return nettle_digest_vector(&nettle_md4, num_elem, addr, len, mac);
75*a1157835SDaniel Fojt }
76*a1157835SDaniel Fojt 
77*a1157835SDaniel Fojt 
md5_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)78*a1157835SDaniel Fojt int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
79*a1157835SDaniel Fojt {
80*a1157835SDaniel Fojt 	return nettle_digest_vector(&nettle_md5, num_elem, addr, len, mac);
81*a1157835SDaniel Fojt }
82*a1157835SDaniel Fojt 
83*a1157835SDaniel Fojt 
sha1_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)84*a1157835SDaniel Fojt int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
85*a1157835SDaniel Fojt {
86*a1157835SDaniel Fojt 	return nettle_digest_vector(&nettle_sha1, num_elem, addr, len, mac);
87*a1157835SDaniel Fojt }
88*a1157835SDaniel Fojt 
89*a1157835SDaniel Fojt 
sha256_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)90*a1157835SDaniel Fojt int sha256_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
91*a1157835SDaniel Fojt {
92*a1157835SDaniel Fojt 	return nettle_digest_vector(&nettle_sha256, num_elem, addr, len, mac);
93*a1157835SDaniel Fojt }
94*a1157835SDaniel Fojt 
95*a1157835SDaniel Fojt 
sha384_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)96*a1157835SDaniel Fojt int sha384_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
97*a1157835SDaniel Fojt {
98*a1157835SDaniel Fojt 	return nettle_digest_vector(&nettle_sha384, num_elem, addr, len, mac);
99*a1157835SDaniel Fojt }
100*a1157835SDaniel Fojt 
101*a1157835SDaniel Fojt 
sha512_vector(size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)102*a1157835SDaniel Fojt int sha512_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
103*a1157835SDaniel Fojt {
104*a1157835SDaniel Fojt 	return nettle_digest_vector(&nettle_sha512, num_elem, addr, len, mac);
105*a1157835SDaniel Fojt }
106*a1157835SDaniel Fojt 
107*a1157835SDaniel Fojt 
hmac_md5_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)108*a1157835SDaniel Fojt int hmac_md5_vector(const u8 *key, size_t key_len, size_t num_elem,
109*a1157835SDaniel Fojt 		    const u8 *addr[], const size_t *len, u8 *mac)
110*a1157835SDaniel Fojt {
111*a1157835SDaniel Fojt 	struct hmac_md5_ctx ctx;
112*a1157835SDaniel Fojt 	size_t i;
113*a1157835SDaniel Fojt 
114*a1157835SDaniel Fojt 	if (TEST_FAIL())
115*a1157835SDaniel Fojt 		return -1;
116*a1157835SDaniel Fojt 
117*a1157835SDaniel Fojt 	hmac_md5_set_key(&ctx, key_len, key);
118*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++)
119*a1157835SDaniel Fojt 		hmac_md5_update(&ctx, len[i], addr[i]);
120*a1157835SDaniel Fojt 	hmac_md5_digest(&ctx, MD5_DIGEST_SIZE, mac);
121*a1157835SDaniel Fojt 	os_memset(&ctx, 0, sizeof(ctx));
122*a1157835SDaniel Fojt 	return 0;
123*a1157835SDaniel Fojt }
124*a1157835SDaniel Fojt 
125*a1157835SDaniel Fojt 
hmac_md5(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)126*a1157835SDaniel Fojt int hmac_md5(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
127*a1157835SDaniel Fojt 	     u8 *mac)
128*a1157835SDaniel Fojt {
129*a1157835SDaniel Fojt 	return hmac_md5_vector(key, key_len, 1, &data, &data_len, mac);
130*a1157835SDaniel Fojt }
131*a1157835SDaniel Fojt 
132*a1157835SDaniel Fojt 
hmac_sha1_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)133*a1157835SDaniel Fojt int hmac_sha1_vector(const u8 *key, size_t key_len, size_t num_elem,
134*a1157835SDaniel Fojt 		     const u8 *addr[], const size_t *len, u8 *mac)
135*a1157835SDaniel Fojt {
136*a1157835SDaniel Fojt 	struct hmac_sha1_ctx ctx;
137*a1157835SDaniel Fojt 	size_t i;
138*a1157835SDaniel Fojt 
139*a1157835SDaniel Fojt 	if (TEST_FAIL())
140*a1157835SDaniel Fojt 		return -1;
141*a1157835SDaniel Fojt 
142*a1157835SDaniel Fojt 	hmac_sha1_set_key(&ctx, key_len, key);
143*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++)
144*a1157835SDaniel Fojt 		hmac_sha1_update(&ctx, len[i], addr[i]);
145*a1157835SDaniel Fojt 	hmac_sha1_digest(&ctx, SHA1_DIGEST_SIZE, mac);
146*a1157835SDaniel Fojt 	os_memset(&ctx, 0, sizeof(ctx));
147*a1157835SDaniel Fojt 	return 0;
148*a1157835SDaniel Fojt }
149*a1157835SDaniel Fojt 
150*a1157835SDaniel Fojt 
hmac_sha1(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)151*a1157835SDaniel Fojt int hmac_sha1(const u8 *key, size_t key_len, const u8 *data, size_t data_len,
152*a1157835SDaniel Fojt 	       u8 *mac)
153*a1157835SDaniel Fojt {
154*a1157835SDaniel Fojt 	return hmac_sha1_vector(key, key_len, 1, &data, &data_len, mac);
155*a1157835SDaniel Fojt }
156*a1157835SDaniel Fojt 
157*a1157835SDaniel Fojt 
158*a1157835SDaniel Fojt #ifdef CONFIG_SHA256
159*a1157835SDaniel Fojt 
hmac_sha256_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)160*a1157835SDaniel Fojt int hmac_sha256_vector(const u8 *key, size_t key_len, size_t num_elem,
161*a1157835SDaniel Fojt 		       const u8 *addr[], const size_t *len, u8 *mac)
162*a1157835SDaniel Fojt {
163*a1157835SDaniel Fojt 	struct hmac_sha256_ctx ctx;
164*a1157835SDaniel Fojt 	size_t i;
165*a1157835SDaniel Fojt 
166*a1157835SDaniel Fojt 	if (TEST_FAIL())
167*a1157835SDaniel Fojt 		return -1;
168*a1157835SDaniel Fojt 
169*a1157835SDaniel Fojt 	hmac_sha256_set_key(&ctx, key_len, key);
170*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++)
171*a1157835SDaniel Fojt 		hmac_sha256_update(&ctx, len[i], addr[i]);
172*a1157835SDaniel Fojt 	hmac_sha256_digest(&ctx, SHA256_DIGEST_SIZE, mac);
173*a1157835SDaniel Fojt 	os_memset(&ctx, 0, sizeof(ctx));
174*a1157835SDaniel Fojt 	return 0;
175*a1157835SDaniel Fojt }
176*a1157835SDaniel Fojt 
177*a1157835SDaniel Fojt 
hmac_sha256(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)178*a1157835SDaniel Fojt int hmac_sha256(const u8 *key, size_t key_len, const u8 *data,
179*a1157835SDaniel Fojt 		size_t data_len, u8 *mac)
180*a1157835SDaniel Fojt {
181*a1157835SDaniel Fojt 	return hmac_sha256_vector(key, key_len, 1, &data, &data_len, mac);
182*a1157835SDaniel Fojt }
183*a1157835SDaniel Fojt 
184*a1157835SDaniel Fojt #endif /* CONFIG_SHA256 */
185*a1157835SDaniel Fojt 
186*a1157835SDaniel Fojt 
187*a1157835SDaniel Fojt #ifdef CONFIG_SHA384
188*a1157835SDaniel Fojt 
hmac_sha384_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)189*a1157835SDaniel Fojt int hmac_sha384_vector(const u8 *key, size_t key_len, size_t num_elem,
190*a1157835SDaniel Fojt 		       const u8 *addr[], const size_t *len, u8 *mac)
191*a1157835SDaniel Fojt {
192*a1157835SDaniel Fojt 	struct hmac_sha384_ctx ctx;
193*a1157835SDaniel Fojt 	size_t i;
194*a1157835SDaniel Fojt 
195*a1157835SDaniel Fojt 	if (TEST_FAIL())
196*a1157835SDaniel Fojt 		return -1;
197*a1157835SDaniel Fojt 
198*a1157835SDaniel Fojt 	hmac_sha384_set_key(&ctx, key_len, key);
199*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++)
200*a1157835SDaniel Fojt 		hmac_sha384_update(&ctx, len[i], addr[i]);
201*a1157835SDaniel Fojt 	hmac_sha384_digest(&ctx, SHA384_DIGEST_SIZE, mac);
202*a1157835SDaniel Fojt 	os_memset(&ctx, 0, sizeof(ctx));
203*a1157835SDaniel Fojt 	return 0;
204*a1157835SDaniel Fojt }
205*a1157835SDaniel Fojt 
206*a1157835SDaniel Fojt 
hmac_sha384(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)207*a1157835SDaniel Fojt int hmac_sha384(const u8 *key, size_t key_len, const u8 *data,
208*a1157835SDaniel Fojt 		size_t data_len, u8 *mac)
209*a1157835SDaniel Fojt {
210*a1157835SDaniel Fojt 	return hmac_sha384_vector(key, key_len, 1, &data, &data_len, mac);
211*a1157835SDaniel Fojt }
212*a1157835SDaniel Fojt 
213*a1157835SDaniel Fojt #endif /* CONFIG_SHA384 */
214*a1157835SDaniel Fojt 
215*a1157835SDaniel Fojt 
216*a1157835SDaniel Fojt #ifdef CONFIG_SHA512
217*a1157835SDaniel Fojt 
hmac_sha512_vector(const u8 * key,size_t key_len,size_t num_elem,const u8 * addr[],const size_t * len,u8 * mac)218*a1157835SDaniel Fojt int hmac_sha512_vector(const u8 *key, size_t key_len, size_t num_elem,
219*a1157835SDaniel Fojt 		       const u8 *addr[], const size_t *len, u8 *mac)
220*a1157835SDaniel Fojt {
221*a1157835SDaniel Fojt 	struct hmac_sha512_ctx ctx;
222*a1157835SDaniel Fojt 	size_t i;
223*a1157835SDaniel Fojt 
224*a1157835SDaniel Fojt 	if (TEST_FAIL())
225*a1157835SDaniel Fojt 		return -1;
226*a1157835SDaniel Fojt 
227*a1157835SDaniel Fojt 	hmac_sha512_set_key(&ctx, key_len, key);
228*a1157835SDaniel Fojt 	for (i = 0; i < num_elem; i++)
229*a1157835SDaniel Fojt 		hmac_sha512_update(&ctx, len[i], addr[i]);
230*a1157835SDaniel Fojt 	hmac_sha512_digest(&ctx, SHA512_DIGEST_SIZE, mac);
231*a1157835SDaniel Fojt 	os_memset(&ctx, 0, sizeof(ctx));
232*a1157835SDaniel Fojt 	return 0;
233*a1157835SDaniel Fojt }
234*a1157835SDaniel Fojt 
235*a1157835SDaniel Fojt 
hmac_sha512(const u8 * key,size_t key_len,const u8 * data,size_t data_len,u8 * mac)236*a1157835SDaniel Fojt int hmac_sha512(const u8 *key, size_t key_len, const u8 *data,
237*a1157835SDaniel Fojt 		size_t data_len, u8 *mac)
238*a1157835SDaniel Fojt {
239*a1157835SDaniel Fojt 	return hmac_sha512_vector(key, key_len, 1, &data, &data_len, mac);
240*a1157835SDaniel Fojt }
241*a1157835SDaniel Fojt 
242*a1157835SDaniel Fojt #endif /* CONFIG_SHA512 */
243*a1157835SDaniel Fojt 
244*a1157835SDaniel Fojt 
aes_encrypt_init(const u8 * key,size_t len)245*a1157835SDaniel Fojt void * aes_encrypt_init(const u8 *key, size_t len)
246*a1157835SDaniel Fojt {
247*a1157835SDaniel Fojt 	struct aes_ctx *ctx;
248*a1157835SDaniel Fojt 
249*a1157835SDaniel Fojt 	if (TEST_FAIL())
250*a1157835SDaniel Fojt 		return NULL;
251*a1157835SDaniel Fojt 	ctx = os_malloc(sizeof(*ctx));
252*a1157835SDaniel Fojt 	if (!ctx)
253*a1157835SDaniel Fojt 		return NULL;
254*a1157835SDaniel Fojt 
255*a1157835SDaniel Fojt 	nettle_aes_set_encrypt_key(ctx, len, key);
256*a1157835SDaniel Fojt 
257*a1157835SDaniel Fojt 	return ctx;
258*a1157835SDaniel Fojt }
259*a1157835SDaniel Fojt 
260*a1157835SDaniel Fojt 
aes_encrypt(void * ctx,const u8 * plain,u8 * crypt)261*a1157835SDaniel Fojt int aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
262*a1157835SDaniel Fojt {
263*a1157835SDaniel Fojt 	struct aes_ctx *actx = ctx;
264*a1157835SDaniel Fojt 	nettle_aes_encrypt(actx, AES_BLOCK_SIZE, crypt, plain);
265*a1157835SDaniel Fojt 	return 0;
266*a1157835SDaniel Fojt }
267*a1157835SDaniel Fojt 
268*a1157835SDaniel Fojt 
aes_encrypt_deinit(void * ctx)269*a1157835SDaniel Fojt void aes_encrypt_deinit(void *ctx)
270*a1157835SDaniel Fojt {
271*a1157835SDaniel Fojt 	struct aes_ctx *actx = ctx;
272*a1157835SDaniel Fojt 	bin_clear_free(actx, sizeof(*actx));
273*a1157835SDaniel Fojt }
274*a1157835SDaniel Fojt 
275*a1157835SDaniel Fojt 
aes_decrypt_init(const u8 * key,size_t len)276*a1157835SDaniel Fojt void * aes_decrypt_init(const u8 *key, size_t len)
277*a1157835SDaniel Fojt {
278*a1157835SDaniel Fojt 	struct aes_ctx *ctx;
279*a1157835SDaniel Fojt 
280*a1157835SDaniel Fojt 	if (TEST_FAIL())
281*a1157835SDaniel Fojt 		return NULL;
282*a1157835SDaniel Fojt 	ctx = os_malloc(sizeof(*ctx));
283*a1157835SDaniel Fojt 	if (!ctx)
284*a1157835SDaniel Fojt 		return NULL;
285*a1157835SDaniel Fojt 
286*a1157835SDaniel Fojt 	nettle_aes_set_decrypt_key(ctx, len, key);
287*a1157835SDaniel Fojt 
288*a1157835SDaniel Fojt 	return ctx;
289*a1157835SDaniel Fojt }
290*a1157835SDaniel Fojt 
291*a1157835SDaniel Fojt 
aes_decrypt(void * ctx,const u8 * crypt,u8 * plain)292*a1157835SDaniel Fojt int aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
293*a1157835SDaniel Fojt {
294*a1157835SDaniel Fojt 	struct aes_ctx *actx = ctx;
295*a1157835SDaniel Fojt 	nettle_aes_decrypt(actx, AES_BLOCK_SIZE, plain, crypt);
296*a1157835SDaniel Fojt 	return 0;
297*a1157835SDaniel Fojt }
298*a1157835SDaniel Fojt 
299*a1157835SDaniel Fojt 
aes_decrypt_deinit(void * ctx)300*a1157835SDaniel Fojt void aes_decrypt_deinit(void *ctx)
301*a1157835SDaniel Fojt {
302*a1157835SDaniel Fojt 	struct aes_ctx *actx = ctx;
303*a1157835SDaniel Fojt 	bin_clear_free(actx, sizeof(*actx));
304*a1157835SDaniel Fojt }
305*a1157835SDaniel Fojt 
306*a1157835SDaniel Fojt 
crypto_dh_init(u8 generator,const u8 * prime,size_t prime_len,u8 * privkey,u8 * pubkey)307*a1157835SDaniel Fojt int crypto_dh_init(u8 generator, const u8 *prime, size_t prime_len, u8 *privkey,
308*a1157835SDaniel Fojt 		   u8 *pubkey)
309*a1157835SDaniel Fojt {
310*a1157835SDaniel Fojt 	size_t pubkey_len, pad;
311*a1157835SDaniel Fojt 
312*a1157835SDaniel Fojt 	if (os_get_random(privkey, prime_len) < 0)
313*a1157835SDaniel Fojt 		return -1;
314*a1157835SDaniel Fojt 	if (os_memcmp(privkey, prime, prime_len) > 0) {
315*a1157835SDaniel Fojt 		/* Make sure private value is smaller than prime */
316*a1157835SDaniel Fojt 		privkey[0] = 0;
317*a1157835SDaniel Fojt 	}
318*a1157835SDaniel Fojt 
319*a1157835SDaniel Fojt 	pubkey_len = prime_len;
320*a1157835SDaniel Fojt 	if (crypto_mod_exp(&generator, 1, privkey, prime_len, prime, prime_len,
321*a1157835SDaniel Fojt 			   pubkey, &pubkey_len) < 0)
322*a1157835SDaniel Fojt 		return -1;
323*a1157835SDaniel Fojt 	if (pubkey_len < prime_len) {
324*a1157835SDaniel Fojt 		pad = prime_len - pubkey_len;
325*a1157835SDaniel Fojt 		os_memmove(pubkey + pad, pubkey, pubkey_len);
326*a1157835SDaniel Fojt 		os_memset(pubkey, 0, pad);
327*a1157835SDaniel Fojt 	}
328*a1157835SDaniel Fojt 
329*a1157835SDaniel Fojt 	return 0;
330*a1157835SDaniel Fojt }
331*a1157835SDaniel Fojt 
332*a1157835SDaniel Fojt 
crypto_dh_derive_secret(u8 generator,const u8 * prime,size_t prime_len,const u8 * order,size_t order_len,const u8 * privkey,size_t privkey_len,const u8 * pubkey,size_t pubkey_len,u8 * secret,size_t * len)333*a1157835SDaniel Fojt int crypto_dh_derive_secret(u8 generator, const u8 *prime, size_t prime_len,
334*a1157835SDaniel Fojt 			    const u8 *order, size_t order_len,
335*a1157835SDaniel Fojt 			    const u8 *privkey, size_t privkey_len,
336*a1157835SDaniel Fojt 			    const u8 *pubkey, size_t pubkey_len,
337*a1157835SDaniel Fojt 			    u8 *secret, size_t *len)
338*a1157835SDaniel Fojt {
339*a1157835SDaniel Fojt 	mpz_t pub;
340*a1157835SDaniel Fojt 	int res = -1;
341*a1157835SDaniel Fojt 
342*a1157835SDaniel Fojt 	if (pubkey_len > prime_len ||
343*a1157835SDaniel Fojt 	    (pubkey_len == prime_len &&
344*a1157835SDaniel Fojt 	     os_memcmp(pubkey, prime, prime_len) >= 0))
345*a1157835SDaniel Fojt 		return -1;
346*a1157835SDaniel Fojt 
347*a1157835SDaniel Fojt 	mpz_init(pub);
348*a1157835SDaniel Fojt 	mpz_import(pub, pubkey_len, 1, 1, 1, 0, pubkey);
349*a1157835SDaniel Fojt 	if (mpz_cmp_d(pub, 1) <= 0)
350*a1157835SDaniel Fojt 		goto fail;
351*a1157835SDaniel Fojt 
352*a1157835SDaniel Fojt 	if (order) {
353*a1157835SDaniel Fojt 		mpz_t p, q, tmp;
354*a1157835SDaniel Fojt 		int failed;
355*a1157835SDaniel Fojt 
356*a1157835SDaniel Fojt 		/* verify: pubkey^q == 1 mod p */
357*a1157835SDaniel Fojt 		mpz_inits(p, q, tmp, NULL);
358*a1157835SDaniel Fojt 		mpz_import(p, prime_len, 1, 1, 1, 0, prime);
359*a1157835SDaniel Fojt 		mpz_import(q, order_len, 1, 1, 1, 0, order);
360*a1157835SDaniel Fojt 		mpz_powm(tmp, pub, q, p);
361*a1157835SDaniel Fojt 		failed = mpz_cmp_d(tmp, 1) != 0;
362*a1157835SDaniel Fojt 		mpz_clears(p, q, tmp, NULL);
363*a1157835SDaniel Fojt 		if (failed)
364*a1157835SDaniel Fojt 			goto fail;
365*a1157835SDaniel Fojt 	}
366*a1157835SDaniel Fojt 
367*a1157835SDaniel Fojt 	res = crypto_mod_exp(pubkey, pubkey_len, privkey, privkey_len,
368*a1157835SDaniel Fojt 			     prime, prime_len, secret, len);
369*a1157835SDaniel Fojt fail:
370*a1157835SDaniel Fojt 	mpz_clear(pub);
371*a1157835SDaniel Fojt 	return res;
372*a1157835SDaniel Fojt }
373*a1157835SDaniel Fojt 
374*a1157835SDaniel Fojt 
crypto_mod_exp(const u8 * base,size_t base_len,const u8 * power,size_t power_len,const u8 * modulus,size_t modulus_len,u8 * result,size_t * result_len)375*a1157835SDaniel Fojt int crypto_mod_exp(const u8 *base, size_t base_len,
376*a1157835SDaniel Fojt 		   const u8 *power, size_t power_len,
377*a1157835SDaniel Fojt 		   const u8 *modulus, size_t modulus_len,
378*a1157835SDaniel Fojt 		   u8 *result, size_t *result_len)
379*a1157835SDaniel Fojt {
380*a1157835SDaniel Fojt 	mpz_t bn_base, bn_exp, bn_modulus, bn_result;
381*a1157835SDaniel Fojt 	int ret = -1;
382*a1157835SDaniel Fojt 	size_t len;
383*a1157835SDaniel Fojt 
384*a1157835SDaniel Fojt 	mpz_inits(bn_base, bn_exp, bn_modulus, bn_result, NULL);
385*a1157835SDaniel Fojt 	mpz_import(bn_base, base_len, 1, 1, 1, 0, base);
386*a1157835SDaniel Fojt 	mpz_import(bn_exp, power_len, 1, 1, 1, 0, power);
387*a1157835SDaniel Fojt 	mpz_import(bn_modulus, modulus_len, 1, 1, 1, 0, modulus);
388*a1157835SDaniel Fojt 
389*a1157835SDaniel Fojt 	mpz_powm(bn_result, bn_base, bn_exp, bn_modulus);
390*a1157835SDaniel Fojt 	len = mpz_sizeinbase(bn_result, 2);
391*a1157835SDaniel Fojt 	len = (len + 7) / 8;
392*a1157835SDaniel Fojt 	if (*result_len < len)
393*a1157835SDaniel Fojt 		goto error;
394*a1157835SDaniel Fojt 	mpz_export(result, result_len, 1, 1, 1, 0, bn_result);
395*a1157835SDaniel Fojt 	ret = 0;
396*a1157835SDaniel Fojt 
397*a1157835SDaniel Fojt error:
398*a1157835SDaniel Fojt 	mpz_clears(bn_base, bn_exp, bn_modulus, bn_result, NULL);
399*a1157835SDaniel Fojt 	return ret;
400*a1157835SDaniel Fojt }
401*a1157835SDaniel Fojt 
402*a1157835SDaniel Fojt 
403*a1157835SDaniel Fojt struct crypto_cipher {
404*a1157835SDaniel Fojt 	enum crypto_cipher_alg alg;
405*a1157835SDaniel Fojt 	union {
406*a1157835SDaniel Fojt 		struct arcfour_ctx arcfour_ctx;
407*a1157835SDaniel Fojt 	} u;
408*a1157835SDaniel Fojt };
409*a1157835SDaniel Fojt 
410*a1157835SDaniel Fojt 
crypto_cipher_init(enum crypto_cipher_alg alg,const u8 * iv,const u8 * key,size_t key_len)411*a1157835SDaniel Fojt struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
412*a1157835SDaniel Fojt 					  const u8 *iv, const u8 *key,
413*a1157835SDaniel Fojt 					  size_t key_len)
414*a1157835SDaniel Fojt {
415*a1157835SDaniel Fojt 	struct crypto_cipher *ctx;
416*a1157835SDaniel Fojt 
417*a1157835SDaniel Fojt 	ctx = os_zalloc(sizeof(*ctx));
418*a1157835SDaniel Fojt 	if (!ctx)
419*a1157835SDaniel Fojt 		return NULL;
420*a1157835SDaniel Fojt 
421*a1157835SDaniel Fojt 	ctx->alg = alg;
422*a1157835SDaniel Fojt 
423*a1157835SDaniel Fojt 	switch (alg) {
424*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_RC4:
425*a1157835SDaniel Fojt 		nettle_arcfour_set_key(&ctx->u.arcfour_ctx, key_len, key);
426*a1157835SDaniel Fojt 		break;
427*a1157835SDaniel Fojt 	default:
428*a1157835SDaniel Fojt 		os_free(ctx);
429*a1157835SDaniel Fojt 		return NULL;
430*a1157835SDaniel Fojt 	}
431*a1157835SDaniel Fojt 
432*a1157835SDaniel Fojt 	return ctx;
433*a1157835SDaniel Fojt }
434*a1157835SDaniel Fojt 
435*a1157835SDaniel Fojt 
crypto_cipher_encrypt(struct crypto_cipher * ctx,const u8 * plain,u8 * crypt,size_t len)436*a1157835SDaniel Fojt int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
437*a1157835SDaniel Fojt 			  u8 *crypt, size_t len)
438*a1157835SDaniel Fojt {
439*a1157835SDaniel Fojt 	switch (ctx->alg) {
440*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_RC4:
441*a1157835SDaniel Fojt 		nettle_arcfour_crypt(&ctx->u.arcfour_ctx, len, crypt, plain);
442*a1157835SDaniel Fojt 		break;
443*a1157835SDaniel Fojt 	default:
444*a1157835SDaniel Fojt 		return -1;
445*a1157835SDaniel Fojt 	}
446*a1157835SDaniel Fojt 
447*a1157835SDaniel Fojt 	return 0;
448*a1157835SDaniel Fojt }
449*a1157835SDaniel Fojt 
450*a1157835SDaniel Fojt 
crypto_cipher_decrypt(struct crypto_cipher * ctx,const u8 * crypt,u8 * plain,size_t len)451*a1157835SDaniel Fojt int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
452*a1157835SDaniel Fojt 			  u8 *plain, size_t len)
453*a1157835SDaniel Fojt {
454*a1157835SDaniel Fojt 	switch (ctx->alg) {
455*a1157835SDaniel Fojt 	case CRYPTO_CIPHER_ALG_RC4:
456*a1157835SDaniel Fojt 		nettle_arcfour_crypt(&ctx->u.arcfour_ctx, len, plain, crypt);
457*a1157835SDaniel Fojt 		break;
458*a1157835SDaniel Fojt 	default:
459*a1157835SDaniel Fojt 		return -1;
460*a1157835SDaniel Fojt 	}
461*a1157835SDaniel Fojt 
462*a1157835SDaniel Fojt 	return 0;
463*a1157835SDaniel Fojt }
464*a1157835SDaniel Fojt 
465*a1157835SDaniel Fojt 
crypto_cipher_deinit(struct crypto_cipher * ctx)466*a1157835SDaniel Fojt void crypto_cipher_deinit(struct crypto_cipher *ctx)
467*a1157835SDaniel Fojt {
468*a1157835SDaniel Fojt 	bin_clear_free(ctx, sizeof(*ctx));
469*a1157835SDaniel Fojt }
470