Deleted Added
full compact
eap_gpsk_common.c (252726) eap_gpsk_common.c (281806)
1/*
2 * EAP server/peer: EAP-GPSK shared routines
3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8

--- 270 unchanged lines hidden (view full) ---

279 int specifier,
280 const u8 *rand_peer, const u8 *rand_server,
281 const u8 *id_peer, size_t id_peer_len,
282 const u8 *id_server, size_t id_server_len,
283 u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len,
284 u8 *pk, size_t *pk_len)
285{
286 u8 *seed, *pos;
1/*
2 * EAP server/peer: EAP-GPSK shared routines
3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8

--- 270 unchanged lines hidden (view full) ---

279 int specifier,
280 const u8 *rand_peer, const u8 *rand_server,
281 const u8 *id_peer, size_t id_peer_len,
282 const u8 *id_server, size_t id_server_len,
283 u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len,
284 u8 *pk, size_t *pk_len)
285{
286 u8 *seed, *pos;
287 size_t seed_len;
288 int ret;
289
290 wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving keys (%d:%d)",
291 vendor, specifier);
292
293 if (vendor != EAP_GPSK_VENDOR_IETF)
294 return -1;
295
296 wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len);
297
298 /* Seed = RAND_Peer || ID_Peer || RAND_Server || ID_Server */
287 int ret;
288
289 wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving keys (%d:%d)",
290 vendor, specifier);
291
292 if (vendor != EAP_GPSK_VENDOR_IETF)
293 return -1;
294
295 wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len);
296
297 /* Seed = RAND_Peer || ID_Peer || RAND_Server || ID_Server */
299 seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len;
300 seed = os_malloc(seed_len);
298 seed = os_malloc(2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len);
301 if (seed == NULL) {
302 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory "
303 "for key derivation");
304 return -1;
305 }
306
307 pos = seed;
308 os_memcpy(pos, rand_peer, EAP_GPSK_RAND_LEN);
309 pos += EAP_GPSK_RAND_LEN;
310 os_memcpy(pos, id_peer, id_peer_len);
311 pos += id_peer_len;
312 os_memcpy(pos, rand_server, EAP_GPSK_RAND_LEN);
313 pos += EAP_GPSK_RAND_LEN;
314 os_memcpy(pos, id_server, id_server_len);
315 pos += id_server_len;
299 if (seed == NULL) {
300 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory "
301 "for key derivation");
302 return -1;
303 }
304
305 pos = seed;
306 os_memcpy(pos, rand_peer, EAP_GPSK_RAND_LEN);
307 pos += EAP_GPSK_RAND_LEN;
308 os_memcpy(pos, id_peer, id_peer_len);
309 pos += id_peer_len;
310 os_memcpy(pos, rand_server, EAP_GPSK_RAND_LEN);
311 pos += EAP_GPSK_RAND_LEN;
312 os_memcpy(pos, id_server, id_server_len);
313 pos += id_server_len;
316 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, seed_len);
314 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, pos - seed);
317
318 switch (specifier) {
319 case EAP_GPSK_CIPHER_AES:
315
316 switch (specifier) {
317 case EAP_GPSK_CIPHER_AES:
320 ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, seed_len,
318 ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, pos - seed,
321 msk, emsk, sk, sk_len,
322 pk, pk_len);
323 break;
324#ifdef EAP_GPSK_SHA256
325 case EAP_GPSK_CIPHER_SHA256:
319 msk, emsk, sk, sk_len,
320 pk, pk_len);
321 break;
322#ifdef EAP_GPSK_SHA256
323 case EAP_GPSK_CIPHER_SHA256:
326 ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed, seed_len,
324 ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed,
325 pos - seed,
327 msk, emsk, sk, sk_len);
328 break;
329#endif /* EAP_GPSK_SHA256 */
330 default:
331 wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown cipher %d:%d used in "
332 "key derivation", vendor, specifier);
333 ret = -1;
334 break;
335 }
336
337 os_free(seed);
338
339 return ret;
340}
341
342
326 msk, emsk, sk, sk_len);
327 break;
328#endif /* EAP_GPSK_SHA256 */
329 default:
330 wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown cipher %d:%d used in "
331 "key derivation", vendor, specifier);
332 ret = -1;
333 break;
334 }
335
336 os_free(seed);
337
338 return ret;
339}
340
341
342static int eap_gpsk_derive_mid_helper(u32 csuite_specifier,
343 u8 *kdf_out, size_t kdf_out_len,
344 const u8 *psk, const u8 *seed,
345 size_t seed_len, u8 method_type)
346{
347 u8 *pos, *data;
348 size_t data_len;
349 int (*gkdf)(const u8 *_psk, const u8 *_data, size_t _data_len,
350 u8 *buf, size_t len);
351
352 gkdf = NULL;
353 switch (csuite_specifier) {
354 case EAP_GPSK_CIPHER_AES:
355 gkdf = eap_gpsk_gkdf_cmac;
356 break;
357#ifdef EAP_GPSK_SHA256
358 case EAP_GPSK_CIPHER_SHA256:
359 gkdf = eap_gpsk_gkdf_sha256;
360 break;
361#endif /* EAP_GPSK_SHA256 */
362 default:
363 wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown cipher %d used in "
364 "Session-Id derivation", csuite_specifier);
365 return -1;
366 }
367
368#define SID_LABEL "Method ID"
369 /* "Method ID" || EAP_Method_Type || CSuite_Sel || inputString */
370 data_len = strlen(SID_LABEL) + 1 + 6 + seed_len;
371 data = os_malloc(data_len);
372 if (data == NULL)
373 return -1;
374 pos = data;
375 os_memcpy(pos, SID_LABEL, strlen(SID_LABEL));
376 pos += strlen(SID_LABEL);
377#undef SID_LABEL
378 os_memcpy(pos, &method_type, 1);
379 pos += 1;
380 WPA_PUT_BE32(pos, EAP_GPSK_VENDOR_IETF); /* CSuite/Vendor = IETF */
381 pos += 4;
382 WPA_PUT_BE16(pos, csuite_specifier); /* CSuite/Specifier */
383 pos += 2;
384 os_memcpy(pos, seed, seed_len); /* inputString */
385 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Data to Method ID derivation",
386 data, data_len);
387
388 if (gkdf(psk, data, data_len, kdf_out, kdf_out_len) < 0) {
389 os_free(data);
390 return -1;
391 }
392 os_free(data);
393 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Method ID", kdf_out, kdf_out_len);
394
395 return 0;
396}
397
398
343/**
399/**
400 * eap_gpsk_session_id - Derive EAP-GPSK Session ID
401 * @psk: Pre-shared key
402 * @psk_len: Length of psk in bytes
403 * @vendor: CSuite/Vendor
404 * @specifier: CSuite/Specifier
405 * @rand_peer: 32-byte RAND_Peer
406 * @rand_server: 32-byte RAND_Server
407 * @id_peer: ID_Peer
408 * @id_peer_len: Length of ID_Peer
409 * @id_server: ID_Server
410 * @id_server_len: Length of ID_Server
411 * @method_type: EAP Authentication Method Type
412 * @sid: Buffer for 17-byte Session ID
413 * @sid_len: Buffer for returning length of Session ID
414 * Returns: 0 on success, -1 on failure
415 */
416int eap_gpsk_derive_session_id(const u8 *psk, size_t psk_len, int vendor,
417 int specifier,
418 const u8 *rand_peer, const u8 *rand_server,
419 const u8 *id_peer, size_t id_peer_len,
420 const u8 *id_server, size_t id_server_len,
421 u8 method_type, u8 *sid, size_t *sid_len)
422{
423 u8 *seed, *pos;
424 u8 kdf_out[16];
425 int ret;
426
427 wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving Session ID(%d:%d)",
428 vendor, specifier);
429
430 if (vendor != EAP_GPSK_VENDOR_IETF)
431 return -1;
432
433 wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len);
434
435 /*
436 * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server
437 * (= seed)
438 * KS = 16, CSuite_Sel = 0x00000000 0x0001
439 * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type ||
440 * CSuite_Sel || inputString)
441 */
442 seed = os_malloc(2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len);
443 if (seed == NULL) {
444 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory "
445 "for Session-Id derivation");
446 return -1;
447 }
448
449 pos = seed;
450 os_memcpy(pos, rand_peer, EAP_GPSK_RAND_LEN);
451 pos += EAP_GPSK_RAND_LEN;
452 os_memcpy(pos, id_peer, id_peer_len);
453 pos += id_peer_len;
454 os_memcpy(pos, rand_server, EAP_GPSK_RAND_LEN);
455 pos += EAP_GPSK_RAND_LEN;
456 os_memcpy(pos, id_server, id_server_len);
457 pos += id_server_len;
458 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, pos - seed);
459
460 ret = eap_gpsk_derive_mid_helper(specifier,
461 kdf_out, sizeof(kdf_out),
462 psk, seed, pos - seed,
463 method_type);
464
465 sid[0] = method_type;
466 os_memcpy(sid + 1, kdf_out, sizeof(kdf_out));
467 *sid_len = 1 + sizeof(kdf_out);
468
469 os_free(seed);
470
471 return ret;
472}
473
474
475/**
344 * eap_gpsk_mic_len - Get the length of the MIC
345 * @vendor: CSuite/Vendor
346 * @specifier: CSuite/Specifier
347 * Returns: MIC length in bytes
348 */
349size_t eap_gpsk_mic_len(int vendor, int specifier)
350{
351 if (vendor != EAP_GPSK_VENDOR_IETF)

--- 66 unchanged lines hidden ---
476 * eap_gpsk_mic_len - Get the length of the MIC
477 * @vendor: CSuite/Vendor
478 * @specifier: CSuite/Specifier
479 * Returns: MIC length in bytes
480 */
481size_t eap_gpsk_mic_len(int vendor, int specifier)
482{
483 if (vendor != EAP_GPSK_VENDOR_IETF)

--- 66 unchanged lines hidden ---