eap_ikev2_common.c
Go to the documentation of this file.
00001 /*
00002  * EAP-IKEv2 common routines
00003  * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "eap_defs.h"
00019 #include "eap_common.h"
00020 #include "ikev2_common.h"
00021 #include "eap_ikev2_common.h"
00022 
00023 
00024 int eap_ikev2_derive_keymat(int prf, struct ikev2_keys *keys,
00025                             const u8 *i_nonce, size_t i_nonce_len,
00026                             const u8 *r_nonce, size_t r_nonce_len,
00027                             u8 *keymat)
00028 {
00029         u8 *nonces;
00030         size_t nlen;
00031 
00032         /* KEYMAT = prf+(SK_d, Ni | Nr) */
00033         if (keys->SK_d == NULL || i_nonce == NULL || r_nonce == NULL)
00034                 return -1;
00035 
00036         nlen = i_nonce_len + r_nonce_len;
00037         nonces = os_malloc(nlen);
00038         if (nonces == NULL)
00039                 return -1;
00040         os_memcpy(nonces, i_nonce, i_nonce_len);
00041         os_memcpy(nonces + i_nonce_len, r_nonce, r_nonce_len);
00042 
00043         if (ikev2_prf_plus(prf, keys->SK_d, keys->SK_d_len, nonces, nlen,
00044                            keymat, EAP_MSK_LEN + EAP_EMSK_LEN)) {
00045                 os_free(nonces);
00046                 return -1;
00047         }
00048         os_free(nonces);
00049 
00050         wpa_hexdump_key(MSG_DEBUG, "EAP-IKEV2: KEYMAT",
00051                         keymat, EAP_MSK_LEN + EAP_EMSK_LEN);
00052 
00053         return 0;
00054 }
00055 
00056 
00057 struct wpabuf * eap_ikev2_build_frag_ack(u8 id, u8 code)
00058 {
00059         struct wpabuf *msg;
00060 
00061 #ifdef CCNS_PL
00062         msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 1, code, id);
00063         if (msg == NULL) {
00064                 wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
00065                            "for fragment ack");
00066                 return NULL;
00067         }
00068         wpabuf_put_u8(msg, 0); /* Flags */
00069 #else /* CCNS_PL */
00070         msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 0, code, id);
00071         if (msg == NULL) {
00072                 wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
00073                            "for fragment ack");
00074                 return NULL;
00075         }
00076 #endif /* CCNS_PL */
00077 
00078         wpa_printf(MSG_DEBUG, "EAP-IKEV2: Send fragment ack");
00079 
00080         return msg;
00081 }
00082 
00083 
00084 int eap_ikev2_validate_icv(int integ_alg, struct ikev2_keys *keys,
00085                            int initiator, const struct wpabuf *msg,
00086                            const u8 *pos, const u8 *end)
00087 {
00088         const struct ikev2_integ_alg *integ;
00089         size_t icv_len;
00090         u8 icv[IKEV2_MAX_HASH_LEN];
00091         const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar;
00092 
00093         integ = ikev2_get_integ(integ_alg);
00094         if (integ == NULL) {
00095                 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
00096                            "transform / cannot validate ICV");
00097                 return -1;
00098         }
00099         icv_len = integ->hash_len;
00100 
00101         if (end - pos < (int) icv_len) {
00102                 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Not enough room in the "
00103                            "message for Integrity Checksum Data");
00104                 return -1;
00105         }
00106 
00107         if (SK_a == NULL) {
00108                 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No SK_a for ICV validation");
00109                 return -1;
00110         }
00111 
00112         if (ikev2_integ_hash(integ_alg, SK_a, keys->SK_integ_len,
00113                              wpabuf_head(msg),
00114                              wpabuf_len(msg) - icv_len, icv) < 0) {
00115                 wpa_printf(MSG_INFO, "EAP-IKEV2: Could not calculate ICV");
00116                 return -1;
00117         }
00118 
00119         if (os_memcmp(icv, end - icv_len, icv_len) != 0) {
00120                 wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid ICV");
00121                 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Calculated ICV",
00122                             icv, icv_len);
00123                 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Received ICV",
00124                             end - icv_len, icv_len);
00125                 return -1;
00126         }
00127 
00128         wpa_printf(MSG_DEBUG, "EAP-IKEV2: Valid Integrity Checksum Data in "
00129                    "the received message");
00130 
00131         return icv_len;
00132 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34