eap_gpsk_common.c revision 8d520ff1dc2da35cdca849e982051b86468016d8
18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP server/peer: EAP-GPSK shared routines 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/aes_wrap.h" 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha256.h" 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_defs.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_gpsk_common.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_gpsk_supported_ciphersuite - Check whether ciphersuite is supported 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: CSuite/Vendor 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @specifier: CSuite/Specifier 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 1 if ciphersuite is support, or 0 if not 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_gpsk_supported_ciphersuite(int vendor, int specifier) 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor == EAP_GPSK_VENDOR_IETF && 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt specifier == EAP_GPSK_CIPHER_AES) 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor == EAP_GPSK_VENDOR_IETF && 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt specifier == EAP_GPSK_CIPHER_SHA256) 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_gpsk_gkdf_cmac(const u8 *psk /* Y */, 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data /* Z */, size_t data_len, 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len /* X */) 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *opos; 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, n, hashlen, left, clen; 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ibuf[2], hash[16]; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[2]; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t vlen[2]; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hashlen = sizeof(hash); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* M_i = MAC_Y (i || Z); (MAC = AES-CMAC-128) */ 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = ibuf; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlen[0] = sizeof(ibuf); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[1] = data; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlen[1] = data_len; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opos = buf; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n = (len + hashlen - 1) / hashlen; 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i <= n; i++) { 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(ibuf, i); 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (omac1_aes_128_vector(psk, 2, addr, vlen, hash)) 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clen = left > hashlen ? hashlen : left; 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(opos, hash, clen); 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opos += clen; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= clen; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_gpsk_gkdf_sha256(const u8 *psk /* Y */, 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data /* Z */, size_t data_len, 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len /* X */) 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *opos; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i, n, hashlen, left, clen; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 ibuf[2], hash[SHA256_MAC_LEN]; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *addr[2]; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t vlen[2]; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hashlen = SHA256_MAC_LEN; 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* M_i = MAC_Y (i || Z); (MAC = HMAC-SHA256) */ 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[0] = ibuf; 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlen[0] = sizeof(ibuf); 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt addr[1] = data; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vlen[1] = data_len; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opos = buf; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = len; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt n = (len + hashlen - 1) / hashlen; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 1; i <= n; i++) { 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(ibuf, i); 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_sha256_vector(psk, 32, 2, addr, vlen, hash); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt clen = left > hashlen ? hashlen : left; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(opos, hash, clen); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt opos += clen; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= clen; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_gpsk_derive_keys_helper(u32 csuite_specifier, 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *kdf_out, size_t kdf_out_len, 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *psk, size_t psk_len, 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seed, size_t seed_len, 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msk, u8 *emsk, 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *sk, size_t sk_len, 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pk, size_t pk_len) 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 mk[32], *pos, *data; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t data_len, mk_len; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*gkdf)(const u8 *_psk, const u8 *_data, size_t _data_len, 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *buf, size_t len); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gkdf = NULL; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (csuite_specifier) { 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_AES: 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gkdf = eap_gpsk_gkdf_cmac; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mk_len = 16; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_SHA256: 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt gkdf = eap_gpsk_gkdf_sha256; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt mk_len = SHA256_MAC_LEN; 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (psk_len < mk_len) 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data_len = 2 + psk_len + 6 + seed_len; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_malloc(data_len); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = data; 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, psk_len); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, psk, psk_len); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += psk_len; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE32(pos, EAP_GPSK_VENDOR_IETF); /* CSuite/Vendor = IETF */ 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_PUT_BE16(pos, csuite_specifier); /* CSuite/Specifier */ 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, seed, seed_len); /* inputString */ 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: Data to MK derivation", 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data, data_len); 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gkdf(psk, data, data_len, mk, mk_len) < 0) { 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MK", mk, mk_len); 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (gkdf(mk, seed, seed_len, kdf_out, kdf_out_len) < 0) 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = kdf_out; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: MSK", pos, EAP_MSK_LEN); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(msk, pos, EAP_MSK_LEN); 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += EAP_MSK_LEN; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: EMSK", pos, EAP_EMSK_LEN); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(emsk, pos, EAP_EMSK_LEN); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += EAP_EMSK_LEN; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: SK", pos, sk_len); 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(sk, pos, sk_len); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += sk_len; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pk) { 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PK", pos, pk_len); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pk, pos, pk_len); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_gpsk_derive_keys_aes(const u8 *psk, size_t psk_len, 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seed, size_t seed_len, 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len, 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pk, size_t *pk_len) 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_GPSK_SK_LEN_AES 16 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_GPSK_PK_LEN_AES 16 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 kdf_out[EAP_MSK_LEN + EAP_EMSK_LEN + EAP_GPSK_SK_LEN_AES + 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_GPSK_PK_LEN_AES]; 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (= seed) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * KS = 16, PL = psk_len, CSuite_Sel = 0x00000000 0x0001 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MK = GKDF-16 (PSK[0..15], PL || PSK || CSuite_Sel || inputString) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MSK = GKDF-160 (MK, inputString)[0..63] 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EMSK = GKDF-160 (MK, inputString)[64..127] 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SK = GKDF-160 (MK, inputString)[128..143] 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PK = GKDF-160 (MK, inputString)[144..159] 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * zero = 0x00 || 0x00 || ... || 0x00 (16 times) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type || 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * CSuite_Sel || inputString) 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *sk_len = EAP_GPSK_SK_LEN_AES; 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pk_len = EAP_GPSK_PK_LEN_AES; 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_gpsk_derive_keys_helper(EAP_GPSK_CIPHER_AES, 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kdf_out, sizeof(kdf_out), 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt psk, psk_len, seed, seed_len, 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msk, emsk, sk, *sk_len, 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pk, *pk_len); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_gpsk_derive_keys_sha256(const u8 *psk, size_t psk_len, 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *seed, size_t seed_len, 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msk, u8 *emsk, 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *sk, size_t *sk_len) 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_GPSK_SK_LEN_SHA256 SHA256_MAC_LEN 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define EAP_GPSK_PK_LEN_SHA256 SHA256_MAC_LEN 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 kdf_out[EAP_MSK_LEN + EAP_EMSK_LEN + EAP_GPSK_SK_LEN_SHA256 + 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_GPSK_PK_LEN_SHA256]; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * inputString = RAND_Peer || ID_Peer || RAND_Server || ID_Server 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * (= seed) 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * KS = 32, PL = psk_len, CSuite_Sel = 0x00000000 0x0002 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MK = GKDF-32 (PSK[0..31], PL || PSK || CSuite_Sel || inputString) 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * MSK = GKDF-160 (MK, inputString)[0..63] 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EMSK = GKDF-160 (MK, inputString)[64..127] 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * SK = GKDF-160 (MK, inputString)[128..159] 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * zero = 0x00 || 0x00 || ... || 0x00 (32 times) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Method-ID = GKDF-16 (zero, "Method ID" || EAP_Method_Type || 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * CSuite_Sel || inputString) 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *sk_len = EAP_GPSK_SK_LEN_SHA256; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_gpsk_derive_keys_helper(EAP_GPSK_CIPHER_SHA256, 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt kdf_out, sizeof(kdf_out), 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt psk, psk_len, seed, seed_len, 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msk, emsk, sk, *sk_len, 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, 0); 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_gpsk_derive_keys - Derive EAP-GPSK keys 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @psk: Pre-shared key 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @psk_len: Length of psk in bytes 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: CSuite/Vendor 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @specifier: CSuite/Specifier 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rand_peer: 32-byte RAND_Peer 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @rand_server: 32-byte RAND_Server 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id_peer: ID_Peer 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id_peer_len: Length of ID_Peer 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id_server: ID_Server 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id_server_len: Length of ID_Server 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @msk: Buffer for 64-byte MSK 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @emsk: Buffer for 64-byte EMSK 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sk: Buffer for SK (at least EAP_GPSK_MAX_SK_LEN bytes) 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sk_len: Buffer for returning length of SK 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pk: Buffer for PK (at least EAP_GPSK_MAX_PK_LEN bytes) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @pk_len: Buffer for returning length of PK 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_gpsk_derive_keys(const u8 *psk, size_t psk_len, int vendor, 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int specifier, 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *rand_peer, const u8 *rand_server, 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *id_peer, size_t id_peer_len, 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *id_server, size_t id_server_len, 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *msk, u8 *emsk, u8 *sk, size_t *sk_len, 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pk, size_t *pk_len) 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *seed, *pos; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t seed_len; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Deriving keys (%d:%d)", 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt vendor, specifier); 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor != EAP_GPSK_VENDOR_IETF) 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-GPSK: PSK", psk, psk_len); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Seed = RAND_Peer || ID_Peer || RAND_Server || ID_Server */ 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt seed_len = 2 * EAP_GPSK_RAND_LEN + id_server_len + id_peer_len; 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt seed = os_malloc(seed_len); 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (seed == NULL) { 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to allocate memory " 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "for key derivation"); 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = seed; 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, rand_peer, EAP_GPSK_RAND_LEN); 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += EAP_GPSK_RAND_LEN; 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, id_peer, id_peer_len); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += id_peer_len; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, rand_server, EAP_GPSK_RAND_LEN); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += EAP_GPSK_RAND_LEN; 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(pos, id_server, id_server_len); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += id_server_len; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Seed", seed, seed_len); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (specifier) { 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_AES: 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_gpsk_derive_keys_aes(psk, psk_len, seed, seed_len, 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msk, emsk, sk, sk_len, 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pk, pk_len); 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_SHA256: 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_gpsk_derive_keys_sha256(psk, psk_len, seed, seed_len, 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msk, emsk, sk, sk_len); 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown cipher %d:%d used in " 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key derivation", vendor, specifier); 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(seed); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_gpsk_mic_len - Get the length of the MIC 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: CSuite/Vendor 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @specifier: CSuite/Specifier 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: MIC length in bytes 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtsize_t eap_gpsk_mic_len(int vendor, int specifier) 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor != EAP_GPSK_VENDOR_IETF) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (specifier) { 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_AES: 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 16; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_SHA256: 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 32; 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_gpsk_compute_mic_aes(const u8 *sk, size_t sk_len, 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *data, size_t len, u8 *mic) 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sk_len != 16) { 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Invalid SK length %lu for " 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "AES-CMAC MIC", (unsigned long) sk_len); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return omac1_aes_128(sk, data, len, mic); 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_gpsk_compute_mic - Compute EAP-GPSK MIC for an EAP packet 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sk: Session key SK from eap_gpsk_derive_keys() 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sk_len: SK length in bytes from eap_gpsk_derive_keys() 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @vendor: CSuite/Vendor 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @specifier: CSuite/Specifier 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Input data to MIC 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Input data length in bytes 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @mic: Buffer for the computed MIC, eap_gpsk_mic_len(cipher) bytes 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_gpsk_compute_mic(const u8 *sk, size_t sk_len, int vendor, 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int specifier, const u8 *data, size_t len, u8 *mic) 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor != EAP_GPSK_VENDOR_IETF) 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (specifier) { 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_AES: 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_gpsk_compute_mic_aes(sk, sk_len, data, len, mic); 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef EAP_GPSK_SHA256 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case EAP_GPSK_CIPHER_SHA256: 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt hmac_sha256(sk, sk_len, data, len, mic); 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = 0; 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* EAP_GPSK_SHA256 */ 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown cipher %d:%d used in " 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "MIC computation", vendor, specifier); 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 424