Removed strayed code fragment
[strongswan.git] / src / charon / sa / authenticators / eap / sim_manager.h
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 /**
17 * @defgroup sim_manager sim_manager
18 * @{ @ingroup eap
19 */
20
21 #ifndef SIM_MANAGER_H_
22 #define SIM_MANAGER_H_
23
24 #include <crypto/hashers/hasher.h>
25 #include <utils/identification.h>
26 #include <utils/enumerator.h>
27 #include <sa/authenticators/eap/eap_method.h>
28
29 typedef struct sim_manager_t sim_manager_t;
30 typedef struct sim_card_t sim_card_t;
31 typedef struct sim_provider_t sim_provider_t;
32 typedef struct sim_hooks_t sim_hooks_t;
33
34 /** implemented in libsimaka, but we need it for the message hook */
35 typedef struct simaka_message_t simaka_message_t;
36
37 #define SIM_RAND_LEN 16
38 #define SIM_SRES_LEN 4
39 #define SIM_KC_LEN 8
40
41 #define AKA_RAND_LEN 16
42 #define AKA_RES_MAX 16
43 #define AKA_CK_LEN 16
44 #define AKA_IK_LEN 16
45 #define AKA_AUTN_LEN 16
46 #define AKA_AUTS_LEN 14
47
48 /**
49 * Interface for a (U)SIM card (used as EAP client).
50 *
51 * The SIM card completes triplets/quintuplets requested in a challenge
52 * received from the server.
53 * An implementation supporting only one of SIM/AKA authentication may
54 * implement the other methods with return_false()/return NOT_SUPPORTED/NULL.
55 */
56 struct sim_card_t {
57
58 /**
59 * Calculate SRES/KC from a RAND for SIM authentication.
60 *
61 * @param id permanent identity to get a triplet for
62 * @param rand RAND input buffer, fixed size 16 bytes
63 * @param sres SRES output buffer, fixed size 4 byte
64 * @param kc KC output buffer, fixed size 8 bytes
65 * @return TRUE if SRES/KC calculated, FALSE on error/wrong identity
66 */
67 bool (*get_triplet)(sim_card_t *this, identification_t *id,
68 char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
69 char kc[SIM_KC_LEN]);
70
71 /**
72 * Calculate CK/IK/RES from RAND/AUTN for AKA authentication.
73 *
74 * If the received sequence number (in autn) is out of sync, INVALID_STATE
75 * is returned.
76 * The RES value is the only one with variable length. Pass a buffer
77 * of at least AKA_RES_MAX, the actual number of bytes is written to the
78 * res_len value. While the standard would allow any bit length between
79 * 32 and 128 bits, we support only full bytes for now.
80 *
81 * @param id permanent identity to request quintuplet for
82 * @param rand random value rand
83 * @param autn authentication token autn
84 * @param ck buffer receiving encryption key ck
85 * @param ik buffer receiving integrity key ik
86 * @param res buffer receiving authentication result res
87 * @param res_len nubmer of bytes written to res buffer
88 * @return SUCCESS, FAILED, or INVALID_STATE if out of sync
89 */
90 status_t (*get_quintuplet)(sim_card_t *this, identification_t *id,
91 char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN],
92 char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
93 char res[AKA_RES_MAX], int *res_len);
94
95 /**
96 * Calculate AUTS from RAND for AKA resynchronization.
97 *
98 * @param id permanent identity to request quintuplet for
99 * @param rand random value rand
100 * @param auts resynchronization parameter auts
101 * @return TRUE if parameter generated successfully
102 */
103 bool (*resync)(sim_card_t *this, identification_t *id,
104 char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
105
106 /**
107 * Set the pseudonym to use for next authentication.
108 *
109 * @param id permanent identity of the peer
110 * @param pseudonym pseudonym identity received from the server
111 */
112 void (*set_pseudonym)(sim_card_t *this, identification_t *id,
113 identification_t *pseudonym);
114
115 /**
116 * Get the pseudonym previously stored via set_pseudonym().
117 *
118 * @param id permanent identity of the peer
119 * @return associated pseudonym identity, NULL if none stored
120 */
121 identification_t* (*get_pseudonym)(sim_card_t *this, identification_t *id);
122
123 /**
124 * Store parameters to use for the next fast reauthentication.
125 *
126 * @param id permanent identity of the peer
127 * @param next next fast reauthentication identity to use
128 * @param mk master key MK to store for reauthentication
129 * @param counter counter value to store, host order
130 */
131 void (*set_reauth)(sim_card_t *this, identification_t *id,
132 identification_t *next, char mk[HASH_SIZE_SHA1],
133 u_int16_t counter);
134
135 /**
136 * Retrieve parameters for fast reauthentication stored via set_reauth().
137 *
138 * @param id permanent identity of the peer
139 * @param mk buffer receiving master key MK
140 * @param counter pointer receiving counter value, in host order
141 * @return fast reauthentication identity, NULL if not found
142 */
143 identification_t* (*get_reauth)(sim_card_t *this, identification_t *id,
144 char mk[HASH_SIZE_SHA1], u_int16_t *counter);
145 };
146
147 /**
148 * Interface for a triplet/quintuplet provider (used as EAP server).
149 *
150 * A SIM provider hands out triplets for SIM authentication and quintuplets
151 * for AKA authentication. Multiple SIM provider instances can serve as
152 * authentication backend to authenticate clients using SIM/AKA.
153 * An implementation supporting only one of SIM/AKA authentication may
154 * implement the other methods with return_false().
155 */
156 struct sim_provider_t {
157
158 /**
159 * Create a challenge for SIM authentication.
160 *
161 * @param id permanent identity of peer to gen triplet for
162 * @param rand RAND output buffer, fixed size 16 bytes
163 * @param sres SRES output buffer, fixed size 4 byte
164 * @param kc KC output buffer, fixed size 8 bytes
165 * @return TRUE if triplet received, FALSE otherwise
166 */
167 bool (*get_triplet)(sim_provider_t *this, identification_t *id,
168 char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
169 char kc[SIM_KC_LEN]);
170
171 /**
172 * Create a challenge for AKA authentication.
173 *
174 * The XRES value is the only one with variable length. Pass a buffer
175 * of at least AKA_RES_MAX, the actual number of bytes is written to the
176 * xres_len value. While the standard would allow any bit length between
177 * 32 and 128 bits, we support only full bytes for now.
178 *
179 * @param id permanent identity of peer to create challenge for
180 * @param rand buffer receiving random value rand
181 * @param xres buffer receiving expected authentication result xres
182 * @param xres_len nubmer of bytes written to xres buffer
183 * @param ck buffer receiving encryption key ck
184 * @param ik buffer receiving integrity key ik
185 * @param autn authentication token autn
186 * @return TRUE if quintuplet generated successfully
187 */
188 bool (*get_quintuplet)(sim_provider_t *this, identification_t *id,
189 char rand[AKA_RAND_LEN],
190 char xres[AKA_RES_MAX], int *xres_len,
191 char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
192 char autn[AKA_AUTN_LEN]);
193
194 /**
195 * Process AKA resynchroniusation request of a peer.
196 *
197 * @param id permanent identity of peer requesting resynchronisation
198 * @param rand random value rand
199 * @param auts synchronization parameter auts
200 * @return TRUE if resynchronized successfully
201 */
202 bool (*resync)(sim_provider_t *this, identification_t *id,
203 char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
204
205 /**
206 * Check if peer uses a pseudonym, get permanent identity.
207 *
208 * @param id pseudonym identity candidate
209 * @return permanent identity, NULL if id not a pseudonym
210 */
211 identification_t* (*is_pseudonym)(sim_provider_t *this,
212 identification_t *id);
213
214 /**
215 * Generate a pseudonym identitiy for a given peer identity.
216 *
217 * @param id permanent identity to generate a pseudonym for
218 * @return generated pseudonym, NULL to not use a pseudonym identity
219 */
220 identification_t* (*gen_pseudonym)(sim_provider_t *this,
221 identification_t *id);
222
223 /**
224 * Check if peer uses reauthentication, retrieve reauth parameters.
225 *
226 * @param id reauthentication identity (candidate)
227 * @param mk buffer receiving master key MK
228 * @param counter pointer receiving current counter value, host order
229 * @return permanent identity, NULL if id not a reauth identity
230 */
231 identification_t* (*is_reauth)(sim_provider_t *this, identification_t *id,
232 char mk[HASH_SIZE_SHA1], u_int16_t *counter);
233
234 /**
235 * Generate a fast reauthentication identity, associated to a master key.
236 *
237 * @param id permanent peer identity
238 * @param mk master key to store along with generated identity
239 * @return fast reauthentication identity, NULL to not use reauth
240 */
241 identification_t* (*gen_reauth)(sim_provider_t *this, identification_t *id,
242 char mk[HASH_SIZE_SHA1]);
243 };
244
245 /**
246 * Additional hooks invoked during EAP-SIM/AKA message processing.
247 */
248 struct sim_hooks_t {
249
250 /**
251 * SIM/AKA message parsing.
252 *
253 * As a SIM/AKA optionally contains encrypted attributes, the hook
254 * might get invoked twice, once before and once after decryption.
255 *
256 * @param message SIM/AKA message
257 * @param inbound TRUE for incoming messages, FALSE for outgoing
258 * @param decrypted TRUE if AT_ENCR_DATA has been decrypted
259 */
260 void (*message)(sim_hooks_t *this, simaka_message_t *message,
261 bool inbound, bool decrypted);
262
263 /**
264 * SIM/AKA encryption/authentication key hooks.
265 *
266 * @param k_encr derived SIM/AKA encryption key k_encr
267 * @param k_auth derived SIM/AKA authentication key k_auth
268 */
269 void (*keys)(sim_hooks_t *this, chunk_t k_encr, chunk_t k_auth);
270 };
271
272 /**
273 * The SIM manager handles multiple (U)SIM cards/providers and hooks.
274 */
275 struct sim_manager_t {
276
277 /**
278 * Register a SIM card (client) at the manager.
279 *
280 * @param card sim card to register
281 */
282 void (*add_card)(sim_manager_t *this, sim_card_t *card);
283
284 /**
285 * Unregister a previously registered card from the manager.
286 *
287 * @param card sim card to unregister
288 */
289 void (*remove_card)(sim_manager_t *this, sim_card_t *card);
290
291 /**
292 * Calculate SIM triplets on one of the registered SIM cards.
293 *
294 * @param id permanent identity to get a triplet for
295 * @param rand RAND input buffer, fixed size 16 bytes
296 * @param sres SRES output buffer, fixed size 4 byte
297 * @param kc KC output buffer, fixed size 8 bytes
298 * @return TRUE if calculated, FALSE if no matching card found
299 */
300 bool (*card_get_triplet)(sim_manager_t *this, identification_t *id,
301 char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
302 char kc[SIM_KC_LEN]);
303
304 /**
305 * Calculate AKA quitpulets on one of the registered SIM cards.
306 *
307 * @param id permanent identity to request quintuplet for
308 * @param rand random value rand
309 * @param autn authentication token autn
310 * @param ck buffer receiving encryption key ck
311 * @param ik buffer receiving integrity key ik
312 * @param res buffer receiving authentication result res
313 * @param res_len nubmer of bytes written to res buffer
314 * @return SUCCESS, FAILED, or INVALID_STATE if out of sync
315 */
316 status_t (*card_get_quintuplet)(sim_manager_t *this, identification_t *id,
317 char rand[AKA_RAND_LEN], char autn[AKA_AUTN_LEN],
318 char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
319 char res[AKA_RES_MAX], int *res_len);
320
321 /**
322 * Calculate resynchronization data on one of the registered SIM cards.
323 *
324 * @param id permanent identity to request quintuplet for
325 * @param rand random value rand
326 * @param auts resynchronization parameter auts
327 * @return TRUE if calculated, FALSE if no matcing card found
328 */
329 bool (*card_resync)(sim_manager_t *this, identification_t *id,
330 char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
331
332 /**
333 * Store a received pseudonym on one of the registered SIM cards.
334 *
335 * @param id permanent identity of the peer
336 * @param pseudonym pseudonym identity received from the server
337 */
338 void (*card_set_pseudonym)(sim_manager_t *this, identification_t *id,
339 identification_t *pseudonym);
340
341 /**
342 * Get a stored pseudonym from one of the registerd SIM cards.
343 *
344 * @param id permanent identity of the peer
345 * @return associated pseudonym identity, NULL if none found
346 */
347 identification_t* (*card_get_pseudonym)(sim_manager_t *this,
348 identification_t *id);
349
350 /**
351 * Store fast reauthentication parameters on one of the registered cards.
352 *
353 * @param id permanent identity of the peer
354 * @param next next fast reauthentication identity to use
355 * @param mk master key MK to store for reauthentication
356 * @param counter counter value to store, host order
357 */
358 void (*card_set_reauth)(sim_manager_t *this, identification_t *id,
359 identification_t *next, char mk[HASH_SIZE_SHA1],
360 u_int16_t counter);
361
362 /**
363 * Retrieve fast reauthentication parameters from one of the registerd cards.
364 *
365 * @param id permanent identity of the peer
366 * @param mk buffer receiving master key MK
367 * @param counter pointer receiving counter value, in host order
368 * @return fast reauthentication identity, NULL if none found
369 */
370 identification_t* (*card_get_reauth)(sim_manager_t *this,
371 identification_t *id, char mk[HASH_SIZE_SHA1],
372 u_int16_t *counter);
373
374 /**
375 * Register a triplet provider (server) at the manager.
376 *
377 * @param card sim card to register
378 */
379 void (*add_provider)(sim_manager_t *this, sim_provider_t *provider);
380
381 /**
382 * Unregister a previously registered provider from the manager.
383 *
384 * @param card sim card to unregister
385 */
386 void (*remove_provider)(sim_manager_t *this, sim_provider_t *provider);
387
388 /**
389 * Get a SIM triplet from one of the registered providers.
390 *
391 * @param id permanent identity of peer to gen triplet for
392 * @param rand RAND output buffer, fixed size 16 bytes
393 * @param sres SRES output buffer, fixed size 4 byte
394 * @param kc KC output buffer, fixed size 8 bytes
395 * @return TRUE if triplet received, FALSE if no match found
396 */
397 bool (*provider_get_triplet)(sim_manager_t *this, identification_t *id,
398 char rand[SIM_RAND_LEN], char sres[SIM_SRES_LEN],
399 char kc[SIM_KC_LEN]);
400
401 /**
402 * Get a AKA quintuplet from one of the registered providers.
403 *
404 * @param id permanent identity of peer to create challenge for
405 * @param rand buffer receiving random value rand
406 * @param xres buffer receiving expected authentication result xres
407 * @param ck buffer receiving encryption key ck
408 * @param ik buffer receiving integrity key ik
409 * @param autn authentication token autn
410 * @return TRUE if quintuplet received, FALSE if no match found
411 */
412 bool (*provider_get_quintuplet)(sim_manager_t *this, identification_t *id,
413 char rand[AKA_RAND_LEN],
414 char xres[AKA_RES_MAX], int *xres_len,
415 char ck[AKA_CK_LEN], char ik[AKA_IK_LEN],
416 char autn[AKA_AUTN_LEN]);
417
418 /**
419 * Pass AKA resynchronization data to one of the registered providers.
420 *
421 * @param id permanent identity of peer requesting resynchronisation
422 * @param rand random value rand
423 * @param auts synchronization parameter auts
424 * @return TRUE if resynchronized, FALSE if not handled
425 */
426 bool (*provider_resync)(sim_manager_t *this, identification_t *id,
427 char rand[AKA_RAND_LEN], char auts[AKA_AUTS_LEN]);
428
429 /**
430 * Check if a peer uses a pseudonym using one of the registered providers.
431 *
432 * @param id pseudonym identity candidate
433 * @return permanent identity, NULL if id not a pseudonym
434 */
435 identification_t* (*provider_is_pseudonym)(sim_manager_t *this,
436 identification_t *id);
437
438 /**
439 * Generate a new pseudonym using one of the registered providers.
440 *
441 * @param id permanent identity to generate a pseudonym for
442 * @return generated pseudonym, NULL to not use a pseudonym identity
443 */
444 identification_t* (*provider_gen_pseudonym)(sim_manager_t *this,
445 identification_t *id);
446
447 /**
448 * Check if a peer uses a reauth id using one of the registered providers.
449 *
450 * @param id reauthentication identity (candidate)
451 * @param mk buffer receiving master key MK
452 * @param counter pointer receiving current counter value, host order
453 * @return permanent identity, NULL if not a known reauth identity
454 */
455 identification_t* (*provider_is_reauth)(sim_manager_t *this,
456 identification_t *id, char mk[HASH_SIZE_SHA1],
457 u_int16_t *counter);
458
459 /**
460 * Generate a fast reauth id using one of the registered providers.
461 *
462 * @param id permanent peer identity
463 * @param mk master key to store along with generated identity
464 * @return fast reauthentication identity, NULL to not use reauth
465 */
466 identification_t* (*provider_gen_reauth)(sim_manager_t *this,
467 identification_t *id, char mk[HASH_SIZE_SHA1]);
468
469 /**
470 * Register a set of hooks to the manager.
471 *
472 * @param hooks hook interface implementation to register
473 */
474 void (*add_hooks)(sim_manager_t *this, sim_hooks_t *hooks);
475
476 /**
477 * Unregister a set of hooks from the manager.
478 *
479 * @param hooks hook interface implementation to unregister
480 */
481 void (*remove_hooks)(sim_manager_t *this, sim_hooks_t *hooks);
482
483 /**
484 * Invoke SIM/AKA message hook.
485 *
486 * @param message SIM message
487 * @param inbound TRUE for incoming messages, FALSE for outgoing
488 * @param decrypted TRUE if AT_ENCR_DATA has been decrypted
489 */
490 void (*message_hook)(sim_manager_t *this, simaka_message_t *message,
491 bool inbound, bool decrypted);
492
493 /**
494 * Invoke SIM/AKA key hook.
495 *
496 * @param k_encr SIM/AKA encryption key k_encr
497 * @param k_auth SIM/AKA authentication key k_auth
498 */
499 void (*key_hook)(sim_manager_t *this, chunk_t k_encr, chunk_t k_auth);
500
501 /**
502 * Destroy a manager instance.
503 */
504 void (*destroy)(sim_manager_t *this);
505 };
506
507 /**
508 * Create an SIM manager to handle multiple (U)SIM cards/providers.
509 *
510 * @return sim_t object
511 */
512 sim_manager_t *sim_manager_create();
513
514 #endif /** SIM_MANAGER_H_ @}*/