Moving charon to libcharon.
[strongswan.git] / src / libcharon / plugins / eap_aka_3gpp2 / eap_aka_3gpp2_functions.c
1 /*
2 * Copyright (C) 2008-2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "eap_aka_3gpp2_functions.h"
17
18 #include <gmp.h>
19 #include <limits.h>
20
21 #include <daemon.h>
22
23 typedef struct private_eap_aka_3gpp2_functions_t private_eap_aka_3gpp2_functions_t;
24
25 /**
26 * Private data of an eap_aka_3gpp2_functions_t object.
27 */
28 struct private_eap_aka_3gpp2_functions_t {
29
30 /**
31 * Public eap_aka_3gpp2_functions_t interface.
32 */
33 eap_aka_3gpp2_functions_t public;
34
35 /**
36 * Used keyed SHA1 function, as PRF
37 */
38 prf_t *prf;
39 };
40
41 #define AKA_PAYLOAD_LEN 64
42
43 #define F1 0x42
44 #define F1STAR 0x43
45 #define F2 0x44
46 #define F3 0x45
47 #define F4 0x46
48 #define F5 0x47
49 #define F5STAR 0x48
50
51 /** Family key, as proposed in S.S0055 */
52 static chunk_t fmk = chunk_from_chars(0x41, 0x48, 0x41, 0x47);
53
54 /**
55 * Binary represnation of the polynom T^160 + T^5 + T^3 + T^2 + 1
56 */
57 static u_int8_t g[] = {
58 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x2d
61 };
62
63 /**
64 * Predefined random bits from the RAND Corporation book
65 */
66 static u_int8_t a[] = {
67 0x9d, 0xe9, 0xc9, 0xc8, 0xef, 0xd5, 0x78, 0x11,
68 0x48, 0x23, 0x14, 0x01, 0x90, 0x1f, 0x2d, 0x49,
69 0x3f, 0x4c, 0x63, 0x65
70 };
71
72 /**
73 * Predefined random bits from the RAND Corporation book
74 */
75 static u_int8_t b[] = {
76 0x75, 0xef, 0xd1, 0x5c, 0x4b, 0x8f, 0x8f, 0x51,
77 0x4e, 0xf3, 0xbc, 0xc3, 0x79, 0x4a, 0x76, 0x5e,
78 0x7e, 0xec, 0x45, 0xe0
79 };
80
81 /**
82 * Multiplicate two mpz_t with bits interpreted as polynoms.
83 */
84 static void mpz_mul_poly(mpz_t r, mpz_t a, mpz_t b)
85 {
86 mpz_t bm, rm;
87 int current = 0, shifted = 0, shift;
88
89 mpz_init_set(bm, b);
90 mpz_init_set_ui(rm, 0);
91 /* scan through a, for each found bit: */
92 while ((current = mpz_scan1(a, current)) != ULONG_MAX)
93 {
94 /* XOR shifted b into r */
95 shift = current - shifted;
96 mpz_mul_2exp(bm, bm, shift);
97 shifted += shift;
98 mpz_xor(rm, rm, bm);
99 current++;
100 }
101
102 mpz_swap(r, rm);
103 mpz_clear(rm);
104 mpz_clear(bm);
105 }
106
107 /**
108 * Calculate the sum of a + b interpreted as polynoms.
109 */
110 static void mpz_add_poly(mpz_t res, mpz_t a, mpz_t b)
111 {
112 /* addition of polynominals is just the XOR */
113 mpz_xor(res, a, b);
114 }
115
116 /**
117 * Calculate the remainder of a/b interpreted as polynoms.
118 */
119 static void mpz_mod_poly(mpz_t r, mpz_t a, mpz_t b)
120 {
121 /* Example:
122 * a = 10001010
123 * b = 00000101
124 */
125 int a_bit, b_bit, diff;
126 mpz_t bm, am;
127
128 mpz_init_set(am, a);
129 mpz_init(bm);
130
131 a_bit = mpz_sizeinbase(a, 2);
132 b_bit = mpz_sizeinbase(b, 2);
133
134 /* don't do anything if b > a */
135 if (a_bit >= b_bit)
136 {
137 /* shift b left to align up most signaficant "1" to a:
138 * a = 10001010
139 * b = 10100000
140 */
141 mpz_mul_2exp(bm, b, a_bit - b_bit);
142 do
143 {
144 /* XOR b into a, this kills the most significant "1":
145 * a = 00101010
146 */
147 mpz_xor(am, am, bm);
148 /* find the next most significant "1" in a, and align up b:
149 * a = 00101010
150 * b = 00101000
151 */
152 diff = a_bit - mpz_sizeinbase(am, 2);
153 mpz_div_2exp(bm, bm, diff);
154 a_bit -= diff;
155 }
156 while (b_bit <= mpz_sizeinbase(bm, 2));
157 /* While b is not shifted to its original value */
158 }
159 /* after another iteration:
160 * a = 00000010
161 * which is the polynomial modulo
162 */
163
164 mpz_swap(r, am);
165 mpz_clear(am);
166 mpz_clear(bm);
167 }
168
169 /**
170 * Step 3 of the various fx() functions:
171 * XOR the key into the SHA1 IV
172 */
173 static void step3(prf_t *prf, u_char k[AKA_K_LEN],
174 u_char payload[AKA_PAYLOAD_LEN], u_int8_t h[HASH_SIZE_SHA1])
175 {
176 /* use the keyed hasher to build the hash */
177 prf->set_key(prf, chunk_create(k, AKA_K_LEN));
178 prf->get_bytes(prf, chunk_create(payload, AKA_PAYLOAD_LEN), h);
179 }
180
181 /**
182 * Step 4 of the various fx() functions:
183 * Polynomial whiten calculations
184 */
185 static void step4(u_char x[HASH_SIZE_SHA1])
186 {
187 mpz_t xm, am, bm, gm;
188
189 mpz_init(xm);
190 mpz_init(am);
191 mpz_init(bm);
192 mpz_init(gm);
193
194 mpz_import(xm, HASH_SIZE_SHA1, 1, 1, 1, 0, x);
195 mpz_import(am, sizeof(a), 1, 1, 1, 0, a);
196 mpz_import(bm, sizeof(b), 1, 1, 1, 0, b);
197 mpz_import(gm, sizeof(g), 1, 1, 1, 0, g);
198
199 mpz_mul_poly(xm, am, xm);
200 mpz_add_poly(xm, bm, xm);
201 mpz_mod_poly(xm, xm, gm);
202
203 mpz_export(x, NULL, 1, HASH_SIZE_SHA1, 1, 0, xm);
204
205 mpz_clear(xm);
206 mpz_clear(am);
207 mpz_clear(bm);
208 mpz_clear(gm);
209 }
210
211 /**
212 * Calculation function for f2(), f3(), f4()
213 */
214 static void fx(prf_t *prf, u_char f, u_char k[AKA_K_LEN],
215 u_char rand[AKA_RAND_LEN], u_char out[AKA_MAC_LEN])
216 {
217 u_char payload[AKA_PAYLOAD_LEN];
218 u_char h[HASH_SIZE_SHA1];
219 u_char i;
220
221 for (i = 0; i < 2; i++)
222 {
223 memset(payload, 0x5c, AKA_PAYLOAD_LEN);
224 payload[11] ^= f;
225 memxor(payload + 12, fmk.ptr, fmk.len);
226 memxor(payload + 24, rand, AKA_RAND_LEN);
227
228 payload[3] ^= i;
229 payload[19] ^= i;
230 payload[35] ^= i;
231 payload[51] ^= i;
232
233 step3(prf, k, payload, h);
234 step4(h);
235 memcpy(out + i * 8, h, 8);
236 }
237 }
238
239 /**
240 * Calculation function of f1() and f1star()
241 */
242 static void f1x(prf_t *prf, u_int8_t f, u_char k[AKA_K_LEN],
243 u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
244 u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN])
245 {
246 /* generate MAC = f1(FMK, SQN, RAND, AMF)
247 * K is loaded into hashers IV; FMK, RAND, SQN, AMF are XORed in a 512-bit
248 * payload which gets hashed
249 */
250 u_char payload[AKA_PAYLOAD_LEN];
251 u_char h[HASH_SIZE_SHA1];
252
253 memset(payload, 0x5c, AKA_PAYLOAD_LEN);
254 payload[11] ^= f;
255 memxor(payload + 12, fmk.ptr, fmk.len);
256 memxor(payload + 16, rand, AKA_RAND_LEN);
257 memxor(payload + 34, sqn, AKA_SQN_LEN);
258 memxor(payload + 42, amf, AKA_AMF_LEN);
259
260 step3(prf, k, payload, h);
261 step4(h);
262 memcpy(mac, h, AKA_MAC_LEN);
263 }
264
265 /**
266 * Calculation function of f5() and f5star()
267 */
268 static void f5x(prf_t *prf, u_char f, u_char k[AKA_K_LEN],
269 u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN])
270 {
271 u_char payload[AKA_PAYLOAD_LEN];
272 u_char h[HASH_SIZE_SHA1];
273
274 memset(payload, 0x5c, AKA_PAYLOAD_LEN);
275 payload[11] ^= f;
276 memxor(payload + 12, fmk.ptr, fmk.len);
277 memxor(payload + 16, rand, AKA_RAND_LEN);
278
279 step3(prf, k, payload, h);
280 step4(h);
281 memcpy(ak, h, AKA_AK_LEN);
282 }
283
284 /**
285 * Calculate MAC from RAND, SQN, AMF using K
286 */
287 static void f1(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
288 u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
289 u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN])
290 {
291 f1x(this->prf, F1, k, rand, sqn, amf, mac);
292 DBG3(DBG_IKE, "MAC %b", mac, AKA_MAC_LEN);
293 }
294
295 /**
296 * Calculate MACS from RAND, SQN, AMF using K
297 */
298 static void f1star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
299 u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN],
300 u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN])
301 {
302 f1x(this->prf, F1STAR, k, rand, sqn, amf, macs);
303 DBG3(DBG_IKE, "MACS %b", macs, AKA_MAC_LEN);
304 }
305
306 /**
307 * Calculate RES from RAND using K
308 */
309 static void f2(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
310 u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX])
311 {
312 fx(this->prf, F2, k, rand, res);
313 DBG3(DBG_IKE, "RES %b", res, AKA_RES_MAX);
314 }
315
316 /**
317 * Calculate CK from RAND using K
318 */
319 static void f3(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
320 u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN])
321 {
322 fx(this->prf, F3, k, rand, ck);
323 DBG3(DBG_IKE, "CK %b", ck, AKA_CK_LEN);
324 }
325
326 /**
327 * Calculate IK from RAND using K
328 */
329 static void f4(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
330 u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN])
331 {
332 fx(this->prf, F4, k, rand, ik);
333 DBG3(DBG_IKE, "IK %b", ik, AKA_IK_LEN);
334 }
335
336 /**
337 * Calculate AK from a RAND using K
338 */
339 static void f5(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
340 u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN])
341 {
342 f5x(this->prf, F5, k, rand, ak);
343 DBG3(DBG_IKE, "AK %b", ak, AKA_AK_LEN);
344 }
345
346 /**
347 * Calculate AKS from a RAND using K
348 */
349 static void f5star(private_eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN],
350 u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN])
351 {
352 f5x(this->prf, F5STAR, k, rand, aks);
353 DBG3(DBG_IKE, "AKS %b", aks, AKA_AK_LEN);
354 }
355
356
357 /**
358 * Implementation of eap_aka_3gpp2_functions_t.destroy.
359 */
360 static void destroy(private_eap_aka_3gpp2_functions_t *this)
361 {
362 this->prf->destroy(this->prf);
363 free(this);
364 }
365
366 /**
367 * See header
368 */
369 eap_aka_3gpp2_functions_t *eap_aka_3gpp2_functions_create()
370 {
371 private_eap_aka_3gpp2_functions_t *this;
372
373 this = malloc_thing(private_eap_aka_3gpp2_functions_t);
374
375 this->public.f1 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char mac[AKA_MAC_LEN]))f1;
376 this->public.f1star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char sqn[AKA_SQN_LEN], u_char amf[AKA_AMF_LEN], u_char macs[AKA_MAC_LEN]))f1star;
377 this->public.f2 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char res[AKA_RES_MAX]))f2;
378 this->public.f3 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ck[AKA_CK_LEN]))f3;
379 this->public.f4 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ik[AKA_IK_LEN]))f4;
380 this->public.f5 = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char ak[AKA_AK_LEN]))f5;
381 this->public.f5star = (void(*)(eap_aka_3gpp2_functions_t *this, u_char k[AKA_K_LEN], u_char rand[AKA_RAND_LEN], u_char aks[AKA_AK_LEN]))f5star;
382 this->public.destroy = (void(*)(eap_aka_3gpp2_functions_t*))destroy;
383
384 this->prf = lib->crypto->create_prf(lib->crypto, PRF_KEYED_SHA1);
385 if (!this->prf)
386 {
387 DBG1(DBG_CFG, "%N not supported, unable to use 3GPP2 algorithm",
388 pseudo_random_function_names, PRF_KEYED_SHA1);
389 free(this);
390 return NULL;
391 }
392 return &this->public;
393 }
394