LCOV - code coverage report
Current view: top level - src/eap_peer - eap_psk.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 192 287 66.9 %
Date: 2014-05-28 Functions: 9 10 90.0 %

          Line data    Source code
       1             : /*
       2             :  * EAP peer method: EAP-PSK (RFC 4764)
       3             :  * Copyright (c) 2004-2008, 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             :  * Note: EAP-PSK is an EAP authentication method and as such, completely
       9             :  * different from WPA-PSK. This file is not needed for WPA-PSK functionality.
      10             :  */
      11             : 
      12             : #include "includes.h"
      13             : 
      14             : #include "common.h"
      15             : #include "crypto/aes_wrap.h"
      16             : #include "crypto/random.h"
      17             : #include "eap_common/eap_psk_common.h"
      18             : #include "eap_i.h"
      19             : 
      20             : 
      21             : struct eap_psk_data {
      22             :         enum { PSK_INIT, PSK_MAC_SENT, PSK_DONE } state;
      23             :         u8 rand_p[EAP_PSK_RAND_LEN];
      24             :         u8 rand_s[EAP_PSK_RAND_LEN];
      25             :         u8 ak[EAP_PSK_AK_LEN], kdk[EAP_PSK_KDK_LEN], tek[EAP_PSK_TEK_LEN];
      26             :         u8 *id_s, *id_p;
      27             :         size_t id_s_len, id_p_len;
      28             :         u8 msk[EAP_MSK_LEN];
      29             :         u8 emsk[EAP_EMSK_LEN];
      30             : };
      31             : 
      32             : 
      33          18 : static void * eap_psk_init(struct eap_sm *sm)
      34             : {
      35             :         struct eap_psk_data *data;
      36             :         const u8 *identity, *password;
      37             :         size_t identity_len, password_len;
      38             : 
      39          18 :         password = eap_get_config_password(sm, &password_len);
      40          18 :         if (!password || password_len != 16) {
      41           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: 16-octet pre-shared key not "
      42             :                            "configured");
      43           0 :                 return NULL;
      44             :         }
      45             : 
      46          18 :         data = os_zalloc(sizeof(*data));
      47          18 :         if (data == NULL)
      48           0 :                 return NULL;
      49          18 :         if (eap_psk_key_setup(password, data->ak, data->kdk)) {
      50           0 :                 os_free(data);
      51           0 :                 return NULL;
      52             :         }
      53          18 :         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: AK", data->ak, EAP_PSK_AK_LEN);
      54          18 :         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: KDK", data->kdk, EAP_PSK_KDK_LEN);
      55          18 :         data->state = PSK_INIT;
      56             : 
      57          18 :         identity = eap_get_config_identity(sm, &identity_len);
      58          18 :         if (identity) {
      59          18 :                 data->id_p = os_malloc(identity_len);
      60          18 :                 if (data->id_p)
      61          18 :                         os_memcpy(data->id_p, identity, identity_len);
      62          18 :                 data->id_p_len = identity_len;
      63             :         }
      64          18 :         if (data->id_p == NULL) {
      65           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: could not get own identity");
      66           0 :                 os_free(data);
      67           0 :                 return NULL;
      68             :         }
      69             : 
      70          18 :         return data;
      71             : }
      72             : 
      73             : 
      74          18 : static void eap_psk_deinit(struct eap_sm *sm, void *priv)
      75             : {
      76          18 :         struct eap_psk_data *data = priv;
      77          18 :         os_free(data->id_s);
      78          18 :         os_free(data->id_p);
      79          18 :         os_free(data);
      80          18 : }
      81             : 
      82             : 
      83          18 : static struct wpabuf * eap_psk_process_1(struct eap_psk_data *data,
      84             :                                          struct eap_method_ret *ret,
      85             :                                          const struct wpabuf *reqData)
      86             : {
      87             :         const struct eap_psk_hdr_1 *hdr1;
      88             :         struct eap_psk_hdr_2 *hdr2;
      89             :         struct wpabuf *resp;
      90             :         u8 *buf, *pos;
      91             :         size_t buflen, len;
      92             :         const u8 *cpos;
      93             : 
      94          18 :         wpa_printf(MSG_DEBUG, "EAP-PSK: in INIT state");
      95             : 
      96          18 :         cpos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
      97          18 :         hdr1 = (const struct eap_psk_hdr_1 *) cpos;
      98          18 :         if (cpos == NULL || len < sizeof(*hdr1)) {
      99           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: Invalid first message "
     100             :                            "length (%lu; expected %lu or more)",
     101             :                            (unsigned long) len,
     102             :                            (unsigned long) sizeof(*hdr1));
     103           0 :                 ret->ignore = TRUE;
     104           0 :                 return NULL;
     105             :         }
     106          18 :         wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr1->flags);
     107          18 :         if (EAP_PSK_FLAGS_GET_T(hdr1->flags) != 0) {
     108           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 0)",
     109           0 :                            EAP_PSK_FLAGS_GET_T(hdr1->flags));
     110           0 :                 ret->methodState = METHOD_DONE;
     111           0 :                 ret->decision = DECISION_FAIL;
     112           0 :                 return NULL;
     113             :         }
     114          18 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr1->rand_s,
     115             :                     EAP_PSK_RAND_LEN);
     116          18 :         os_memcpy(data->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
     117          18 :         os_free(data->id_s);
     118          18 :         data->id_s_len = len - sizeof(*hdr1);
     119          18 :         data->id_s = os_malloc(data->id_s_len);
     120          18 :         if (data->id_s == NULL) {
     121           0 :                 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to allocate memory for "
     122             :                            "ID_S (len=%lu)", (unsigned long) data->id_s_len);
     123           0 :                 ret->ignore = TRUE;
     124           0 :                 return NULL;
     125             :         }
     126          18 :         os_memcpy(data->id_s, (u8 *) (hdr1 + 1), data->id_s_len);
     127          36 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_S",
     128          18 :                           data->id_s, data->id_s_len);
     129             : 
     130          18 :         if (random_get_bytes(data->rand_p, EAP_PSK_RAND_LEN)) {
     131           0 :                 wpa_printf(MSG_ERROR, "EAP-PSK: Failed to get random data");
     132           0 :                 ret->ignore = TRUE;
     133           0 :                 return NULL;
     134             :         }
     135             : 
     136          36 :         resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK,
     137          18 :                              sizeof(*hdr2) + data->id_p_len, EAP_CODE_RESPONSE,
     138          18 :                              eap_get_id(reqData));
     139          18 :         if (resp == NULL)
     140           0 :                 return NULL;
     141          18 :         hdr2 = wpabuf_put(resp, sizeof(*hdr2));
     142          18 :         hdr2->flags = EAP_PSK_FLAGS_SET_T(1); /* T=1 */
     143          18 :         os_memcpy(hdr2->rand_s, hdr1->rand_s, EAP_PSK_RAND_LEN);
     144          18 :         os_memcpy(hdr2->rand_p, data->rand_p, EAP_PSK_RAND_LEN);
     145          18 :         wpabuf_put_data(resp, data->id_p, data->id_p_len);
     146             :         /* MAC_P = OMAC1-AES-128(AK, ID_P||ID_S||RAND_S||RAND_P) */
     147          18 :         buflen = data->id_p_len + data->id_s_len + 2 * EAP_PSK_RAND_LEN;
     148          18 :         buf = os_malloc(buflen);
     149          18 :         if (buf == NULL) {
     150           0 :                 wpabuf_free(resp);
     151           0 :                 return NULL;
     152             :         }
     153          18 :         os_memcpy(buf, data->id_p, data->id_p_len);
     154          18 :         pos = buf + data->id_p_len;
     155          18 :         os_memcpy(pos, data->id_s, data->id_s_len);
     156          18 :         pos += data->id_s_len;
     157          18 :         os_memcpy(pos, hdr1->rand_s, EAP_PSK_RAND_LEN);
     158          18 :         pos += EAP_PSK_RAND_LEN;
     159          18 :         os_memcpy(pos, data->rand_p, EAP_PSK_RAND_LEN);
     160          18 :         if (omac1_aes_128(data->ak, buf, buflen, hdr2->mac_p)) {
     161           0 :                 os_free(buf);
     162           0 :                 wpabuf_free(resp);
     163           0 :                 return NULL;
     164             :         }
     165          18 :         os_free(buf);
     166          18 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_P", hdr2->rand_p,
     167             :                     EAP_PSK_RAND_LEN);
     168          18 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_P", hdr2->mac_p, EAP_PSK_MAC_LEN);
     169          36 :         wpa_hexdump_ascii(MSG_DEBUG, "EAP-PSK: ID_P",
     170          18 :                           data->id_p, data->id_p_len);
     171             : 
     172          18 :         data->state = PSK_MAC_SENT;
     173             : 
     174          18 :         return resp;
     175             : }
     176             : 
     177             : 
     178          17 : static struct wpabuf * eap_psk_process_3(struct eap_psk_data *data,
     179             :                                          struct eap_method_ret *ret,
     180             :                                          const struct wpabuf *reqData)
     181             : {
     182             :         const struct eap_psk_hdr_3 *hdr3;
     183             :         struct eap_psk_hdr_4 *hdr4;
     184             :         struct wpabuf *resp;
     185             :         u8 *buf, *rpchannel, nonce[16], *decrypted;
     186             :         const u8 *pchannel, *tag, *msg;
     187             :         u8 mac[EAP_PSK_MAC_LEN];
     188             :         size_t buflen, left, data_len, len, plen;
     189          17 :         int failed = 0;
     190             :         const u8 *pos;
     191             : 
     192          17 :         wpa_printf(MSG_DEBUG, "EAP-PSK: in MAC_SENT state");
     193             : 
     194          17 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK,
     195             :                                reqData, &len);
     196          17 :         hdr3 = (const struct eap_psk_hdr_3 *) pos;
     197          17 :         if (pos == NULL || len < sizeof(*hdr3)) {
     198           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: Invalid third message "
     199             :                            "length (%lu; expected %lu or more)",
     200             :                            (unsigned long) len,
     201             :                            (unsigned long) sizeof(*hdr3));
     202           0 :                 ret->ignore = TRUE;
     203           0 :                 return NULL;
     204             :         }
     205          17 :         left = len - sizeof(*hdr3);
     206          17 :         pchannel = (const u8 *) (hdr3 + 1);
     207          17 :         wpa_printf(MSG_DEBUG, "EAP-PSK: Flags=0x%x", hdr3->flags);
     208          17 :         if (EAP_PSK_FLAGS_GET_T(hdr3->flags) != 2) {
     209           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: Unexpected T=%d (expected 2)",
     210           0 :                            EAP_PSK_FLAGS_GET_T(hdr3->flags));
     211           0 :                 ret->methodState = METHOD_DONE;
     212           0 :                 ret->decision = DECISION_FAIL;
     213           0 :                 return NULL;
     214             :         }
     215          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: RAND_S", hdr3->rand_s,
     216             :                     EAP_PSK_RAND_LEN);
     217          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: MAC_S", hdr3->mac_s, EAP_PSK_MAC_LEN);
     218          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: PCHANNEL", pchannel, left);
     219             : 
     220          17 :         if (left < 4 + 16 + 1) {
     221           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: Too short PCHANNEL data in "
     222             :                            "third message (len=%lu, expected 21)",
     223             :                            (unsigned long) left);
     224           0 :                 ret->ignore = TRUE;
     225           0 :                 return NULL;
     226             :         }
     227             : 
     228             :         /* MAC_S = OMAC1-AES-128(AK, ID_S||RAND_P) */
     229          17 :         buflen = data->id_s_len + EAP_PSK_RAND_LEN;
     230          17 :         buf = os_malloc(buflen);
     231          17 :         if (buf == NULL)
     232           0 :                 return NULL;
     233          17 :         os_memcpy(buf, data->id_s, data->id_s_len);
     234          17 :         os_memcpy(buf + data->id_s_len, data->rand_p, EAP_PSK_RAND_LEN);
     235          17 :         if (omac1_aes_128(data->ak, buf, buflen, mac)) {
     236           0 :                 os_free(buf);
     237           0 :                 return NULL;
     238             :         }
     239          17 :         os_free(buf);
     240          17 :         if (os_memcmp(mac, hdr3->mac_s, EAP_PSK_MAC_LEN) != 0) {
     241           0 :                 wpa_printf(MSG_WARNING, "EAP-PSK: Invalid MAC_S in third "
     242             :                            "message");
     243           0 :                 ret->methodState = METHOD_DONE;
     244           0 :                 ret->decision = DECISION_FAIL;
     245           0 :                 return NULL;
     246             :         }
     247          17 :         wpa_printf(MSG_DEBUG, "EAP-PSK: MAC_S verified successfully");
     248             : 
     249          17 :         if (eap_psk_derive_keys(data->kdk, data->rand_p, data->tek,
     250          17 :                                 data->msk, data->emsk)) {
     251           0 :                 ret->methodState = METHOD_DONE;
     252           0 :                 ret->decision = DECISION_FAIL;
     253           0 :                 return NULL;
     254             :         }
     255          17 :         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: TEK", data->tek, EAP_PSK_TEK_LEN);
     256          17 :         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: MSK", data->msk, EAP_MSK_LEN);
     257          17 :         wpa_hexdump_key(MSG_DEBUG, "EAP-PSK: EMSK", data->emsk, EAP_EMSK_LEN);
     258             : 
     259          17 :         os_memset(nonce, 0, 12);
     260          17 :         os_memcpy(nonce + 12, pchannel, 4);
     261          17 :         pchannel += 4;
     262          17 :         left -= 4;
     263             : 
     264          17 :         tag = pchannel;
     265          17 :         pchannel += 16;
     266          17 :         left -= 16;
     267             : 
     268          17 :         msg = pchannel;
     269             : 
     270          17 :         wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - nonce",
     271             :                     nonce, sizeof(nonce));
     272          17 :         wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - hdr",
     273             :                     wpabuf_head(reqData), 5);
     274          17 :         wpa_hexdump(MSG_MSGDUMP, "EAP-PSK: PCHANNEL - cipher msg", msg, left);
     275             : 
     276          17 :         decrypted = os_malloc(left);
     277          17 :         if (decrypted == NULL) {
     278           0 :                 ret->methodState = METHOD_DONE;
     279           0 :                 ret->decision = DECISION_FAIL;
     280           0 :                 return NULL;
     281             :         }
     282          17 :         os_memcpy(decrypted, msg, left);
     283             : 
     284          17 :         if (aes_128_eax_decrypt(data->tek, nonce, sizeof(nonce),
     285          17 :                                 wpabuf_head(reqData),
     286             :                                 sizeof(struct eap_hdr) + 1 +
     287             :                                 sizeof(*hdr3) - EAP_PSK_MAC_LEN, decrypted,
     288             :                                 left, tag)) {
     289           0 :                 wpa_printf(MSG_WARNING, "EAP-PSK: PCHANNEL decryption failed");
     290           0 :                 os_free(decrypted);
     291           0 :                 return NULL;
     292             :         }
     293          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: Decrypted PCHANNEL message",
     294             :                     decrypted, left);
     295             : 
     296             :         /* Verify R flag */
     297          17 :         switch (decrypted[0] >> 6) {
     298             :         case EAP_PSK_R_FLAG_CONT:
     299           0 :                 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - CONT - unsupported");
     300           0 :                 failed = 1;
     301           0 :                 break;
     302             :         case EAP_PSK_R_FLAG_DONE_SUCCESS:
     303          17 :                 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_SUCCESS");
     304          17 :                 break;
     305             :         case EAP_PSK_R_FLAG_DONE_FAILURE:
     306           0 :                 wpa_printf(MSG_DEBUG, "EAP-PSK: R flag - DONE_FAILURE");
     307           0 :                 wpa_printf(MSG_INFO, "EAP-PSK: Authentication server rejected "
     308             :                            "authentication");
     309           0 :                 failed = 1;
     310           0 :                 break;
     311             :         }
     312             : 
     313          17 :         data_len = 1;
     314          17 :         if ((decrypted[0] & EAP_PSK_E_FLAG) && left > 1)
     315           0 :                 data_len++;
     316          17 :         plen = sizeof(*hdr4) + 4 + 16 + data_len;
     317          17 :         resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_PSK, plen,
     318          17 :                              EAP_CODE_RESPONSE, eap_get_id(reqData));
     319          17 :         if (resp == NULL) {
     320           0 :                 os_free(decrypted);
     321           0 :                 return NULL;
     322             :         }
     323          17 :         hdr4 = wpabuf_put(resp, sizeof(*hdr4));
     324          17 :         hdr4->flags = EAP_PSK_FLAGS_SET_T(3); /* T=3 */
     325          17 :         os_memcpy(hdr4->rand_s, hdr3->rand_s, EAP_PSK_RAND_LEN);
     326          17 :         rpchannel = wpabuf_put(resp, 4 + 16 + data_len);
     327             : 
     328             :         /* nonce++ */
     329          17 :         inc_byte_array(nonce, sizeof(nonce));
     330          17 :         os_memcpy(rpchannel, nonce + 12, 4);
     331             : 
     332          17 :         if (decrypted[0] & EAP_PSK_E_FLAG) {
     333           0 :                 wpa_printf(MSG_DEBUG, "EAP-PSK: Unsupported E (Ext) flag");
     334           0 :                 failed = 1;
     335           0 :                 rpchannel[4 + 16] = (EAP_PSK_R_FLAG_DONE_FAILURE << 6) |
     336             :                         EAP_PSK_E_FLAG;
     337           0 :                 if (left > 1) {
     338             :                         /* Add empty EXT_Payload with same EXT_Type */
     339           0 :                         rpchannel[4 + 16 + 1] = decrypted[1];
     340             :                 }
     341          17 :         } else if (failed)
     342           0 :                 rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_FAILURE << 6;
     343             :         else
     344          17 :                 rpchannel[4 + 16] = EAP_PSK_R_FLAG_DONE_SUCCESS << 6;
     345             : 
     346          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (plaintext)",
     347             :                     rpchannel + 4 + 16, data_len);
     348          34 :         if (aes_128_eax_encrypt(data->tek, nonce, sizeof(nonce),
     349          17 :                                 wpabuf_head(resp),
     350             :                                 sizeof(struct eap_hdr) + 1 + sizeof(*hdr4),
     351             :                                 rpchannel + 4 + 16, data_len, rpchannel + 4)) {
     352           0 :                 os_free(decrypted);
     353           0 :                 wpabuf_free(resp);
     354           0 :                 return NULL;
     355             :         }
     356          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: reply message (PCHANNEL)",
     357             :                     rpchannel, 4 + 16 + data_len);
     358             : 
     359          17 :         wpa_printf(MSG_DEBUG, "EAP-PSK: Completed %ssuccessfully",
     360             :                    failed ? "un" : "");
     361          17 :         data->state = PSK_DONE;
     362          17 :         ret->methodState = METHOD_DONE;
     363          17 :         ret->decision = failed ? DECISION_FAIL : DECISION_UNCOND_SUCC;
     364             : 
     365          17 :         os_free(decrypted);
     366             : 
     367          17 :         return resp;
     368             : }
     369             : 
     370             : 
     371          35 : static struct wpabuf * eap_psk_process(struct eap_sm *sm, void *priv,
     372             :                                        struct eap_method_ret *ret,
     373             :                                        const struct wpabuf *reqData)
     374             : {
     375          35 :         struct eap_psk_data *data = priv;
     376             :         const u8 *pos;
     377          35 :         struct wpabuf *resp = NULL;
     378             :         size_t len;
     379             : 
     380          35 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_PSK, reqData, &len);
     381          35 :         if (pos == NULL) {
     382           0 :                 ret->ignore = TRUE;
     383           0 :                 return NULL;
     384             :         }
     385             : 
     386          35 :         ret->ignore = FALSE;
     387          35 :         ret->methodState = METHOD_MAY_CONT;
     388          35 :         ret->decision = DECISION_FAIL;
     389          35 :         ret->allowNotifications = TRUE;
     390             : 
     391          35 :         switch (data->state) {
     392             :         case PSK_INIT:
     393          18 :                 resp = eap_psk_process_1(data, ret, reqData);
     394          18 :                 break;
     395             :         case PSK_MAC_SENT:
     396          17 :                 resp = eap_psk_process_3(data, ret, reqData);
     397          17 :                 break;
     398             :         case PSK_DONE:
     399           0 :                 wpa_printf(MSG_DEBUG, "EAP-PSK: in DONE state - ignore "
     400             :                            "unexpected message");
     401           0 :                 ret->ignore = TRUE;
     402           0 :                 return NULL;
     403             :         }
     404             : 
     405          35 :         if (ret->methodState == METHOD_DONE) {
     406          17 :                 ret->allowNotifications = FALSE;
     407             :         }
     408             : 
     409          35 :         return resp;
     410             : }
     411             : 
     412             : 
     413          35 : static Boolean eap_psk_isKeyAvailable(struct eap_sm *sm, void *priv)
     414             : {
     415          35 :         struct eap_psk_data *data = priv;
     416          35 :         return data->state == PSK_DONE;
     417             : }
     418             : 
     419             : 
     420          17 : static u8 * eap_psk_getKey(struct eap_sm *sm, void *priv, size_t *len)
     421             : {
     422          17 :         struct eap_psk_data *data = priv;
     423             :         u8 *key;
     424             : 
     425          17 :         if (data->state != PSK_DONE)
     426           0 :                 return NULL;
     427             : 
     428          17 :         key = os_malloc(EAP_MSK_LEN);
     429          17 :         if (key == NULL)
     430           0 :                 return NULL;
     431             : 
     432          17 :         *len = EAP_MSK_LEN;
     433          17 :         os_memcpy(key, data->msk, EAP_MSK_LEN);
     434             : 
     435          17 :         return key;
     436             : }
     437             : 
     438             : 
     439          17 : static u8 * eap_psk_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
     440             : {
     441          17 :         struct eap_psk_data *data = priv;
     442             :         u8 *id;
     443             : 
     444          17 :         if (data->state != PSK_DONE)
     445           0 :                 return NULL;
     446             : 
     447          17 :         *len = 1 + 2 * EAP_PSK_RAND_LEN;
     448          17 :         id = os_malloc(*len);
     449          17 :         if (id == NULL)
     450           0 :                 return NULL;
     451             : 
     452          17 :         id[0] = EAP_TYPE_PSK;
     453          17 :         os_memcpy(id + 1, data->rand_p, EAP_PSK_RAND_LEN);
     454          17 :         os_memcpy(id + 1 + EAP_PSK_RAND_LEN, data->rand_s, EAP_PSK_RAND_LEN);
     455          17 :         wpa_hexdump(MSG_DEBUG, "EAP-PSK: Derived Session-Id", id, *len);
     456             : 
     457          17 :         return id;
     458             : }
     459             : 
     460             : 
     461           0 : static u8 * eap_psk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
     462             : {
     463           0 :         struct eap_psk_data *data = priv;
     464             :         u8 *key;
     465             : 
     466           0 :         if (data->state != PSK_DONE)
     467           0 :                 return NULL;
     468             : 
     469           0 :         key = os_malloc(EAP_EMSK_LEN);
     470           0 :         if (key == NULL)
     471           0 :                 return NULL;
     472             : 
     473           0 :         *len = EAP_EMSK_LEN;
     474           0 :         os_memcpy(key, data->emsk, EAP_EMSK_LEN);
     475             : 
     476           0 :         return key;
     477             : }
     478             : 
     479             : 
     480           4 : int eap_peer_psk_register(void)
     481             : {
     482             :         struct eap_method *eap;
     483             :         int ret;
     484             : 
     485           4 :         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
     486             :                                     EAP_VENDOR_IETF, EAP_TYPE_PSK, "PSK");
     487           4 :         if (eap == NULL)
     488           0 :                 return -1;
     489             : 
     490           4 :         eap->init = eap_psk_init;
     491           4 :         eap->deinit = eap_psk_deinit;
     492           4 :         eap->process = eap_psk_process;
     493           4 :         eap->isKeyAvailable = eap_psk_isKeyAvailable;
     494           4 :         eap->getKey = eap_psk_getKey;
     495           4 :         eap->getSessionId = eap_psk_get_session_id;
     496           4 :         eap->get_emsk = eap_psk_get_emsk;
     497             : 
     498           4 :         ret = eap_peer_method_register(eap);
     499           4 :         if (ret)
     500           0 :                 eap_peer_method_free(eap);
     501           4 :         return ret;
     502             : }

Generated by: LCOV version 1.10