buf, end - buf);
pos = buf;
- while (pos + 1 < end) {
- if (pos + 2 + pos[1] > end)
+ while (end - pos > 1) {
+ u8 id, elen;
+
+ id = *pos++;
+ elen = *pos++;
+ if (elen > end - pos)
break;
- switch (*pos) {
+ switch (id) {
case PAC_OPAQUE_TYPE_PAD:
goto done;
case PAC_OPAQUE_TYPE_KEY:
- if (pos[1] != EAP_FAST_PAC_KEY_LEN) {
- wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
- "PAC-Key length %d", pos[1]);
+ if (elen != EAP_FAST_PAC_KEY_LEN) {
+ wpa_printf(MSG_DEBUG,
+ "EAP-FAST: Invalid PAC-Key length %d",
+ elen);
os_free(buf);
return -1;
}
- pac_key = pos + 2;
+ pac_key = pos;
wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from "
"decrypted PAC-Opaque",
pac_key, EAP_FAST_PAC_KEY_LEN);
break;
case PAC_OPAQUE_TYPE_LIFETIME:
- if (pos[1] != 4) {
+ if (elen != 4) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid "
"PAC-Key lifetime length %d",
- pos[1]);
+ elen);
os_free(buf);
return -1;
}
- lifetime = WPA_GET_BE32(pos + 2);
+ lifetime = WPA_GET_BE32(pos);
break;
case PAC_OPAQUE_TYPE_IDENTITY:
- identity = pos + 2;
- identity_len = pos[1];
+ identity = pos;
+ identity_len = elen;
break;
}
- pos += 2 + pos[1];
+ pos += elen;
}
done:
* Extra key material after TLS key_block: session_key_seed[40]
*/
- sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion",
+ sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn,
EAP_FAST_SKS_LEN);
if (sks == NULL) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive "
os_free(data->key_block_p);
data->key_block_p = (struct eap_fast_key_block_provisioning *)
eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn,
- "key expansion",
sizeof(*data->key_block_p));
if (data->key_block_p == NULL) {
wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block");
static void * eap_fast_init(struct eap_sm *sm)
{
struct eap_fast_data *data;
- u8 ciphers[5] = {
+ u8 ciphers[7] = {
TLS_CIPHER_ANON_DH_AES128_SHA,
TLS_CIPHER_AES128_SHA,
TLS_CIPHER_RSA_DHE_AES128_SHA,
TLS_CIPHER_RC4_SHA,
+ TLS_CIPHER_RSA_DHE_AES256_SHA,
+ TLS_CIPHER_AES256_SHA,
TLS_CIPHER_NONE
};
pos = wpabuf_mhead(data);
end = pos + wpabuf_len(data);
- while (pos + 4 < end) {
+ while (end - pos > 4) {
mandatory = pos[0] & 0x80;
tlv_type = WPA_GET_BE16(pos) & 0x3fff;
pos += 2;
if (eapKeyData == NULL)
return NULL;
- eap_fast_derive_eap_msk(data->simck, eapKeyData);
+ if (eap_fast_derive_eap_msk(data->simck, eapKeyData) < 0) {
+ os_free(eapKeyData);
+ return NULL;
+ }
*len = EAP_FAST_KEY_LEN;
return eapKeyData;
if (eapKeyData == NULL)
return NULL;
- eap_fast_derive_eap_emsk(data->simck, eapKeyData);
+ if (eap_fast_derive_eap_emsk(data->simck, eapKeyData) < 0) {
+ os_free(eapKeyData);
+ return NULL;
+ }
*len = EAP_EMSK_LEN;
return eapKeyData;
int eap_server_fast_register(void)
{
struct eap_method *eap;
- int ret;
eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST");
eap->isSuccess = eap_fast_isSuccess;
eap->getSessionId = eap_fast_get_session_id;
- ret = eap_server_method_register(eap);
- if (ret)
- eap_server_method_free(eap);
- return ret;
+ return eap_server_method_register(eap);
}