LCOV - code coverage report
Current view: top level - src/eap_common - eap_ikev2_common.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 29 48 60.4 %
Date: 2014-05-28 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * EAP-IKEv2 common routines
       3             :  * Copyright (c) 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             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "eap_defs.h"
      13             : #include "eap_common.h"
      14             : #include "ikev2_common.h"
      15             : #include "eap_ikev2_common.h"
      16             : 
      17             : 
      18          10 : int eap_ikev2_derive_keymat(int prf, struct ikev2_keys *keys,
      19             :                             const u8 *i_nonce, size_t i_nonce_len,
      20             :                             const u8 *r_nonce, size_t r_nonce_len,
      21             :                             u8 *keymat)
      22             : {
      23             :         u8 *nonces;
      24             :         size_t nlen;
      25             : 
      26             :         /* KEYMAT = prf+(SK_d, Ni | Nr) */
      27          10 :         if (keys->SK_d == NULL || i_nonce == NULL || r_nonce == NULL)
      28           0 :                 return -1;
      29             : 
      30          10 :         nlen = i_nonce_len + r_nonce_len;
      31          10 :         nonces = os_malloc(nlen);
      32          10 :         if (nonces == NULL)
      33           0 :                 return -1;
      34          10 :         os_memcpy(nonces, i_nonce, i_nonce_len);
      35          10 :         os_memcpy(nonces + i_nonce_len, r_nonce, r_nonce_len);
      36             : 
      37          10 :         if (ikev2_prf_plus(prf, keys->SK_d, keys->SK_d_len, nonces, nlen,
      38             :                            keymat, EAP_MSK_LEN + EAP_EMSK_LEN)) {
      39           0 :                 os_free(nonces);
      40           0 :                 return -1;
      41             :         }
      42          10 :         os_free(nonces);
      43             : 
      44          10 :         wpa_hexdump_key(MSG_DEBUG, "EAP-IKEV2: KEYMAT",
      45             :                         keymat, EAP_MSK_LEN + EAP_EMSK_LEN);
      46             : 
      47          10 :         return 0;
      48             : }
      49             : 
      50             : 
      51          20 : struct wpabuf * eap_ikev2_build_frag_ack(u8 id, u8 code)
      52             : {
      53             :         struct wpabuf *msg;
      54             : 
      55             : #ifdef CCNS_PL
      56             :         msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 1, code, id);
      57             :         if (msg == NULL) {
      58             :                 wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
      59             :                            "for fragment ack");
      60             :                 return NULL;
      61             :         }
      62             :         wpabuf_put_u8(msg, 0); /* Flags */
      63             : #else /* CCNS_PL */
      64          20 :         msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_IKEV2, 0, code, id);
      65          20 :         if (msg == NULL) {
      66           0 :                 wpa_printf(MSG_ERROR, "EAP-IKEV2: Failed to allocate memory "
      67             :                            "for fragment ack");
      68           0 :                 return NULL;
      69             :         }
      70             : #endif /* CCNS_PL */
      71             : 
      72          20 :         wpa_printf(MSG_DEBUG, "EAP-IKEV2: Send fragment ack");
      73             : 
      74          20 :         return msg;
      75             : }
      76             : 
      77             : 
      78          18 : int eap_ikev2_validate_icv(int integ_alg, struct ikev2_keys *keys,
      79             :                            int initiator, const struct wpabuf *msg,
      80             :                            const u8 *pos, const u8 *end)
      81             : {
      82             :         const struct ikev2_integ_alg *integ;
      83             :         size_t icv_len;
      84             :         u8 icv[IKEV2_MAX_HASH_LEN];
      85          18 :         const u8 *SK_a = initiator ? keys->SK_ai : keys->SK_ar;
      86             : 
      87          18 :         integ = ikev2_get_integ(integ_alg);
      88          18 :         if (integ == NULL) {
      89           0 :                 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Unknown INTEG "
      90             :                            "transform / cannot validate ICV");
      91           0 :                 return -1;
      92             :         }
      93          18 :         icv_len = integ->hash_len;
      94             : 
      95          18 :         if (end - pos < (int) icv_len) {
      96           0 :                 wpa_printf(MSG_DEBUG, "EAP-IKEV2: Not enough room in the "
      97             :                            "message for Integrity Checksum Data");
      98           0 :                 return -1;
      99             :         }
     100             : 
     101          18 :         if (SK_a == NULL) {
     102           0 :                 wpa_printf(MSG_DEBUG, "EAP-IKEV2: No SK_a for ICV validation");
     103           0 :                 return -1;
     104             :         }
     105             : 
     106          36 :         if (ikev2_integ_hash(integ_alg, SK_a, keys->SK_integ_len,
     107          18 :                              wpabuf_head(msg),
     108          18 :                              wpabuf_len(msg) - icv_len, icv) < 0) {
     109           0 :                 wpa_printf(MSG_INFO, "EAP-IKEV2: Could not calculate ICV");
     110           0 :                 return -1;
     111             :         }
     112             : 
     113          18 :         if (os_memcmp(icv, end - icv_len, icv_len) != 0) {
     114           0 :                 wpa_printf(MSG_INFO, "EAP-IKEV2: Invalid ICV");
     115           0 :                 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Calculated ICV",
     116             :                             icv, icv_len);
     117           0 :                 wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Received ICV",
     118           0 :                             end - icv_len, icv_len);
     119           0 :                 return -1;
     120             :         }
     121             : 
     122          18 :         wpa_printf(MSG_DEBUG, "EAP-IKEV2: Valid Integrity Checksum Data in "
     123             :                    "the received message");
     124             : 
     125          18 :         return icv_len;
     126             : }

Generated by: LCOV version 1.10