LCOV - code coverage report
Current view: top level - src/eap_peer - eap_sake.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1401264779 Lines: 180 267 67.4 %
Date: 2014-05-28 Functions: 12 14 85.7 %

          Line data    Source code
       1             : /*
       2             :  * EAP peer method: EAP-SAKE (RFC 4763)
       3             :  * Copyright (c) 2006-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             : 
       9             : #include "includes.h"
      10             : 
      11             : #include "common.h"
      12             : #include "crypto/random.h"
      13             : #include "eap_peer/eap_i.h"
      14             : #include "eap_common/eap_sake_common.h"
      15             : 
      16             : struct eap_sake_data {
      17             :         enum { IDENTITY, CHALLENGE, CONFIRM, SUCCESS, FAILURE } state;
      18             :         u8 root_secret_a[EAP_SAKE_ROOT_SECRET_LEN];
      19             :         u8 root_secret_b[EAP_SAKE_ROOT_SECRET_LEN];
      20             :         u8 rand_s[EAP_SAKE_RAND_LEN];
      21             :         u8 rand_p[EAP_SAKE_RAND_LEN];
      22             :         struct {
      23             :                 u8 auth[EAP_SAKE_TEK_AUTH_LEN];
      24             :                 u8 cipher[EAP_SAKE_TEK_CIPHER_LEN];
      25             :         } tek;
      26             :         u8 msk[EAP_MSK_LEN];
      27             :         u8 emsk[EAP_EMSK_LEN];
      28             :         u8 session_id;
      29             :         int session_id_set;
      30             :         u8 *peerid;
      31             :         size_t peerid_len;
      32             :         u8 *serverid;
      33             :         size_t serverid_len;
      34             : };
      35             : 
      36             : 
      37          16 : static const char * eap_sake_state_txt(int state)
      38             : {
      39          16 :         switch (state) {
      40             :         case IDENTITY:
      41           3 :                 return "IDENTITY";
      42             :         case CHALLENGE:
      43           6 :                 return "CHALLENGE";
      44             :         case CONFIRM:
      45           5 :                 return "CONFIRM";
      46             :         case SUCCESS:
      47           2 :                 return "SUCCESS";
      48             :         case FAILURE:
      49           0 :                 return "FAILURE";
      50             :         default:
      51           0 :                 return "?";
      52             :         }
      53             : }
      54             : 
      55             : 
      56           8 : static void eap_sake_state(struct eap_sake_data *data, int state)
      57             : {
      58          16 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: %s -> %s",
      59           8 :                    eap_sake_state_txt(data->state),
      60             :                    eap_sake_state_txt(state));
      61           8 :         data->state = state;
      62           8 : }
      63             : 
      64             : 
      65             : static void eap_sake_deinit(struct eap_sm *sm, void *priv);
      66             : 
      67             : 
      68           3 : static void * eap_sake_init(struct eap_sm *sm)
      69             : {
      70             :         struct eap_sake_data *data;
      71             :         const u8 *identity, *password;
      72             :         size_t identity_len, password_len;
      73             : 
      74           3 :         password = eap_get_config_password(sm, &password_len);
      75           3 :         if (!password || password_len != 2 * EAP_SAKE_ROOT_SECRET_LEN) {
      76           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: No key of correct length "
      77             :                            "configured");
      78           0 :                 return NULL;
      79             :         }
      80             : 
      81           3 :         data = os_zalloc(sizeof(*data));
      82           3 :         if (data == NULL)
      83           0 :                 return NULL;
      84           3 :         data->state = IDENTITY;
      85             : 
      86           3 :         identity = eap_get_config_identity(sm, &identity_len);
      87           3 :         if (identity) {
      88           3 :                 data->peerid = os_malloc(identity_len);
      89           3 :                 if (data->peerid == NULL) {
      90           0 :                         eap_sake_deinit(sm, data);
      91           0 :                         return NULL;
      92             :                 }
      93           3 :                 os_memcpy(data->peerid, identity, identity_len);
      94           3 :                 data->peerid_len = identity_len;
      95             :         }
      96             : 
      97           3 :         os_memcpy(data->root_secret_a, password, EAP_SAKE_ROOT_SECRET_LEN);
      98           3 :         os_memcpy(data->root_secret_b,
      99             :                   password + EAP_SAKE_ROOT_SECRET_LEN,
     100             :                   EAP_SAKE_ROOT_SECRET_LEN);
     101             : 
     102           3 :         return data;
     103             : }
     104             : 
     105             : 
     106           3 : static void eap_sake_deinit(struct eap_sm *sm, void *priv)
     107             : {
     108           3 :         struct eap_sake_data *data = priv;
     109           3 :         os_free(data->serverid);
     110           3 :         os_free(data->peerid);
     111           3 :         os_free(data);
     112           3 : }
     113             : 
     114             : 
     115           5 : static struct wpabuf * eap_sake_build_msg(struct eap_sake_data *data,
     116             :                                           int id, size_t length, u8 subtype)
     117             : {
     118             :         struct eap_sake_hdr *sake;
     119             :         struct wpabuf *msg;
     120             :         size_t plen;
     121             : 
     122           5 :         plen = length + sizeof(struct eap_sake_hdr);
     123             : 
     124           5 :         msg = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_SAKE, plen,
     125             :                             EAP_CODE_RESPONSE, id);
     126           5 :         if (msg == NULL) {
     127           0 :                 wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to allocate memory "
     128             :                            "request");
     129           0 :                 return NULL;
     130             :         }
     131             : 
     132           5 :         sake = wpabuf_put(msg, sizeof(*sake));
     133           5 :         sake->version = EAP_SAKE_VERSION;
     134           5 :         sake->session_id = data->session_id;
     135           5 :         sake->subtype = subtype;
     136             : 
     137           5 :         return msg;
     138             : }
     139             : 
     140             : 
     141           0 : static struct wpabuf * eap_sake_process_identity(struct eap_sm *sm,
     142             :                                                  struct eap_sake_data *data,
     143             :                                                  struct eap_method_ret *ret,
     144             :                                                  const struct wpabuf *reqData,
     145             :                                                  const u8 *payload,
     146             :                                                  size_t payload_len)
     147             : {
     148             :         struct eap_sake_parse_attr attr;
     149             :         struct wpabuf *resp;
     150             : 
     151           0 :         if (data->state != IDENTITY) {
     152           0 :                 ret->ignore = TRUE;
     153           0 :                 return NULL;
     154             :         }
     155             : 
     156           0 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Identity");
     157             : 
     158           0 :         if (eap_sake_parse_attributes(payload, payload_len, &attr))
     159           0 :                 return NULL;
     160             : 
     161           0 :         if (!attr.perm_id_req && !attr.any_id_req) {
     162           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: No AT_PERM_ID_REQ or "
     163             :                            "AT_ANY_ID_REQ in Request/Identity");
     164           0 :                 return NULL;
     165             :         }
     166             : 
     167           0 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Identity");
     168             : 
     169           0 :         resp = eap_sake_build_msg(data, eap_get_id(reqData),
     170           0 :                                   2 + data->peerid_len,
     171             :                                   EAP_SAKE_SUBTYPE_IDENTITY);
     172           0 :         if (resp == NULL)
     173           0 :                 return NULL;
     174             : 
     175           0 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID");
     176           0 :         eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID,
     177           0 :                           data->peerid, data->peerid_len);
     178             : 
     179           0 :         eap_sake_state(data, CHALLENGE);
     180             : 
     181           0 :         return resp;
     182             : }
     183             : 
     184             : 
     185           3 : static struct wpabuf * eap_sake_process_challenge(struct eap_sm *sm,
     186             :                                                   struct eap_sake_data *data,
     187             :                                                   struct eap_method_ret *ret,
     188             :                                                   const struct wpabuf *reqData,
     189             :                                                   const u8 *payload,
     190             :                                                   size_t payload_len)
     191             : {
     192             :         struct eap_sake_parse_attr attr;
     193             :         struct wpabuf *resp;
     194             :         u8 *rpos;
     195             :         size_t rlen;
     196             : 
     197           3 :         if (data->state != IDENTITY && data->state != CHALLENGE) {
     198           0 :                 wpa_printf(MSG_DEBUG, "EAP-SAKE: Request/Challenge received "
     199           0 :                            "in unexpected state (%d)", data->state);
     200           0 :                 ret->ignore = TRUE;
     201           0 :                 return NULL;
     202             :         }
     203           3 :         if (data->state == IDENTITY)
     204           3 :                 eap_sake_state(data, CHALLENGE);
     205             : 
     206           3 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Challenge");
     207             : 
     208           3 :         if (eap_sake_parse_attributes(payload, payload_len, &attr))
     209           0 :                 return NULL;
     210             : 
     211           3 :         if (!attr.rand_s) {
     212           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: Request/Challenge did not "
     213             :                            "include AT_RAND_S");
     214           0 :                 return NULL;
     215             :         }
     216             : 
     217           3 :         os_memcpy(data->rand_s, attr.rand_s, EAP_SAKE_RAND_LEN);
     218           3 :         wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_S (server rand)",
     219           3 :                     data->rand_s, EAP_SAKE_RAND_LEN);
     220             : 
     221           3 :         if (random_get_bytes(data->rand_p, EAP_SAKE_RAND_LEN)) {
     222           0 :                 wpa_printf(MSG_ERROR, "EAP-SAKE: Failed to get random data");
     223           0 :                 return NULL;
     224             :         }
     225           3 :         wpa_hexdump(MSG_MSGDUMP, "EAP-SAKE: RAND_P (peer rand)",
     226           3 :                     data->rand_p, EAP_SAKE_RAND_LEN);
     227             : 
     228           3 :         os_free(data->serverid);
     229           3 :         data->serverid = NULL;
     230           3 :         data->serverid_len = 0;
     231           3 :         if (attr.serverid) {
     232           6 :                 wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-SAKE: SERVERID",
     233           3 :                                   attr.serverid, attr.serverid_len);
     234           3 :                 data->serverid = os_malloc(attr.serverid_len);
     235           3 :                 if (data->serverid == NULL)
     236           0 :                         return NULL;
     237           3 :                 os_memcpy(data->serverid, attr.serverid, attr.serverid_len);
     238           3 :                 data->serverid_len = attr.serverid_len;
     239             :         }
     240             : 
     241           3 :         eap_sake_derive_keys(data->root_secret_a, data->root_secret_b,
     242           3 :                              data->rand_s, data->rand_p,
     243           3 :                              (u8 *) &data->tek, data->msk, data->emsk);
     244             : 
     245           3 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Challenge");
     246             : 
     247           3 :         rlen = 2 + EAP_SAKE_RAND_LEN + 2 + EAP_SAKE_MIC_LEN;
     248           3 :         if (data->peerid)
     249           3 :                 rlen += 2 + data->peerid_len;
     250           3 :         resp = eap_sake_build_msg(data, eap_get_id(reqData), rlen,
     251             :                                   EAP_SAKE_SUBTYPE_CHALLENGE);
     252           3 :         if (resp == NULL)
     253           0 :                 return NULL;
     254             : 
     255           3 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_RAND_P");
     256           3 :         eap_sake_add_attr(resp, EAP_SAKE_AT_RAND_P,
     257           3 :                           data->rand_p, EAP_SAKE_RAND_LEN);
     258             : 
     259           3 :         if (data->peerid) {
     260           3 :                 wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_PEERID");
     261           6 :                 eap_sake_add_attr(resp, EAP_SAKE_AT_PEERID,
     262           3 :                                   data->peerid, data->peerid_len);
     263             :         }
     264             : 
     265           3 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P");
     266           3 :         wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P);
     267           3 :         wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN);
     268           3 :         rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN);
     269          12 :         if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
     270           3 :                                  data->serverid, data->serverid_len,
     271           3 :                                  data->peerid, data->peerid_len, 1,
     272           3 :                                  wpabuf_head(resp), wpabuf_len(resp), rpos,
     273             :                                  rpos)) {
     274           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC");
     275           0 :                 wpabuf_free(resp);
     276           0 :                 return NULL;
     277             :         }
     278             : 
     279           3 :         eap_sake_state(data, CONFIRM);
     280             : 
     281           3 :         return resp;
     282             : }
     283             : 
     284             : 
     285           2 : static struct wpabuf * eap_sake_process_confirm(struct eap_sm *sm,
     286             :                                                 struct eap_sake_data *data,
     287             :                                                 struct eap_method_ret *ret,
     288             :                                                 const struct wpabuf *reqData,
     289             :                                                 const u8 *payload,
     290             :                                                 size_t payload_len)
     291             : {
     292             :         struct eap_sake_parse_attr attr;
     293             :         u8 mic_s[EAP_SAKE_MIC_LEN];
     294             :         struct wpabuf *resp;
     295             :         u8 *rpos;
     296             : 
     297           2 :         if (data->state != CONFIRM) {
     298           0 :                 ret->ignore = TRUE;
     299           0 :                 return NULL;
     300             :         }
     301             : 
     302           2 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Received Request/Confirm");
     303             : 
     304           2 :         if (eap_sake_parse_attributes(payload, payload_len, &attr))
     305           0 :                 return NULL;
     306             : 
     307           2 :         if (!attr.mic_s) {
     308           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: Request/Confirm did not "
     309             :                            "include AT_MIC_S");
     310           0 :                 return NULL;
     311             :         }
     312             : 
     313           8 :         eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
     314           2 :                              data->serverid, data->serverid_len,
     315           2 :                              data->peerid, data->peerid_len, 0,
     316           2 :                              wpabuf_head(reqData), wpabuf_len(reqData),
     317             :                              attr.mic_s, mic_s);
     318           2 :         if (os_memcmp(attr.mic_s, mic_s, EAP_SAKE_MIC_LEN) != 0) {
     319           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: Incorrect AT_MIC_S");
     320           0 :                 eap_sake_state(data, FAILURE);
     321           0 :                 ret->methodState = METHOD_DONE;
     322           0 :                 ret->decision = DECISION_FAIL;
     323           0 :                 ret->allowNotifications = FALSE;
     324           0 :                 wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending "
     325             :                            "Response/Auth-Reject");
     326           0 :                 return eap_sake_build_msg(data, eap_get_id(reqData), 0,
     327             :                                           EAP_SAKE_SUBTYPE_AUTH_REJECT);
     328             :         }
     329             : 
     330           2 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Sending Response/Confirm");
     331             : 
     332           2 :         resp = eap_sake_build_msg(data, eap_get_id(reqData),
     333             :                                   2 + EAP_SAKE_MIC_LEN,
     334             :                                   EAP_SAKE_SUBTYPE_CONFIRM);
     335           2 :         if (resp == NULL)
     336           0 :                 return NULL;
     337             : 
     338           2 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: * AT_MIC_P");
     339           2 :         wpabuf_put_u8(resp, EAP_SAKE_AT_MIC_P);
     340           2 :         wpabuf_put_u8(resp, 2 + EAP_SAKE_MIC_LEN);
     341           2 :         rpos = wpabuf_put(resp, EAP_SAKE_MIC_LEN);
     342           8 :         if (eap_sake_compute_mic(data->tek.auth, data->rand_s, data->rand_p,
     343           2 :                                  data->serverid, data->serverid_len,
     344           2 :                                  data->peerid, data->peerid_len, 1,
     345           2 :                                  wpabuf_head(resp), wpabuf_len(resp), rpos,
     346             :                                  rpos)) {
     347           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: Failed to compute MIC");
     348           0 :                 wpabuf_free(resp);
     349           0 :                 return NULL;
     350             :         }
     351             : 
     352           2 :         eap_sake_state(data, SUCCESS);
     353           2 :         ret->methodState = METHOD_DONE;
     354           2 :         ret->decision = DECISION_UNCOND_SUCC;
     355           2 :         ret->allowNotifications = FALSE;
     356             : 
     357           2 :         return resp;
     358             : }
     359             : 
     360             : 
     361           5 : static struct wpabuf * eap_sake_process(struct eap_sm *sm, void *priv,
     362             :                                         struct eap_method_ret *ret,
     363             :                                         const struct wpabuf *reqData)
     364             : {
     365           5 :         struct eap_sake_data *data = priv;
     366             :         const struct eap_sake_hdr *req;
     367             :         struct wpabuf *resp;
     368             :         const u8 *pos, *end;
     369             :         size_t len;
     370             :         u8 subtype, session_id;
     371             : 
     372           5 :         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_SAKE, reqData, &len);
     373           5 :         if (pos == NULL || len < sizeof(struct eap_sake_hdr)) {
     374           0 :                 ret->ignore = TRUE;
     375           0 :                 return NULL;
     376             :         }
     377             : 
     378           5 :         req = (const struct eap_sake_hdr *) pos;
     379           5 :         end = pos + len;
     380           5 :         subtype = req->subtype;
     381           5 :         session_id = req->session_id;
     382           5 :         pos = (const u8 *) (req + 1);
     383             : 
     384           5 :         wpa_printf(MSG_DEBUG, "EAP-SAKE: Received frame: subtype %d "
     385             :                    "session_id %d", subtype, session_id);
     386           5 :         wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Received attributes",
     387           5 :                     pos, end - pos);
     388             : 
     389           5 :         if (data->session_id_set && data->session_id != session_id) {
     390           0 :                 wpa_printf(MSG_INFO, "EAP-SAKE: Session ID mismatch (%d,%d)",
     391           0 :                            session_id, data->session_id);
     392           0 :                 ret->ignore = TRUE;
     393           0 :                 return NULL;
     394             :         }
     395           5 :         data->session_id = session_id;
     396           5 :         data->session_id_set = 1;
     397             : 
     398           5 :         ret->ignore = FALSE;
     399           5 :         ret->methodState = METHOD_MAY_CONT;
     400           5 :         ret->decision = DECISION_FAIL;
     401           5 :         ret->allowNotifications = TRUE;
     402             : 
     403           5 :         switch (subtype) {
     404             :         case EAP_SAKE_SUBTYPE_IDENTITY:
     405           0 :                 resp = eap_sake_process_identity(sm, data, ret, reqData,
     406           0 :                                                  pos, end - pos);
     407           0 :                 break;
     408             :         case EAP_SAKE_SUBTYPE_CHALLENGE:
     409           3 :                 resp = eap_sake_process_challenge(sm, data, ret, reqData,
     410           3 :                                                   pos, end - pos);
     411           3 :                 break;
     412             :         case EAP_SAKE_SUBTYPE_CONFIRM:
     413           2 :                 resp = eap_sake_process_confirm(sm, data, ret, reqData,
     414           2 :                                                 pos, end - pos);
     415           2 :                 break;
     416             :         default:
     417           0 :                 wpa_printf(MSG_DEBUG, "EAP-SAKE: Ignoring message with "
     418             :                            "unknown subtype %d", subtype);
     419           0 :                 ret->ignore = TRUE;
     420           0 :                 return NULL;
     421             :         }
     422             : 
     423           5 :         if (ret->methodState == METHOD_DONE)
     424           2 :                 ret->allowNotifications = FALSE;
     425             : 
     426           5 :         return resp;
     427             : }
     428             : 
     429             : 
     430           5 : static Boolean eap_sake_isKeyAvailable(struct eap_sm *sm, void *priv)
     431             : {
     432           5 :         struct eap_sake_data *data = priv;
     433           5 :         return data->state == SUCCESS;
     434             : }
     435             : 
     436             : 
     437           2 : static u8 * eap_sake_getKey(struct eap_sm *sm, void *priv, size_t *len)
     438             : {
     439           2 :         struct eap_sake_data *data = priv;
     440             :         u8 *key;
     441             : 
     442           2 :         if (data->state != SUCCESS)
     443           0 :                 return NULL;
     444             : 
     445           2 :         key = os_malloc(EAP_MSK_LEN);
     446           2 :         if (key == NULL)
     447           0 :                 return NULL;
     448           2 :         os_memcpy(key, data->msk, EAP_MSK_LEN);
     449           2 :         *len = EAP_MSK_LEN;
     450             : 
     451           2 :         return key;
     452             : }
     453             : 
     454             : 
     455           2 : static u8 * eap_sake_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
     456             : {
     457           2 :         struct eap_sake_data *data = priv;
     458             :         u8 *id;
     459             : 
     460           2 :         if (data->state != SUCCESS)
     461           0 :                 return NULL;
     462             : 
     463           2 :         *len = 1 + 2 * EAP_SAKE_RAND_LEN;
     464           2 :         id = os_malloc(*len);
     465           2 :         if (id == NULL)
     466           0 :                 return NULL;
     467             : 
     468           2 :         id[0] = EAP_TYPE_SAKE;
     469           2 :         os_memcpy(id + 1, data->rand_s, EAP_SAKE_RAND_LEN);
     470           2 :         os_memcpy(id + 1 + EAP_SAKE_RAND_LEN, data->rand_s, EAP_SAKE_RAND_LEN);
     471           2 :         wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Derived Session-Id", id, *len);
     472             : 
     473           2 :         return id;
     474             : }
     475             : 
     476             : 
     477           0 : static u8 * eap_sake_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
     478             : {
     479           0 :         struct eap_sake_data *data = priv;
     480             :         u8 *key;
     481             : 
     482           0 :         if (data->state != SUCCESS)
     483           0 :                 return NULL;
     484             : 
     485           0 :         key = os_malloc(EAP_EMSK_LEN);
     486           0 :         if (key == NULL)
     487           0 :                 return NULL;
     488           0 :         os_memcpy(key, data->emsk, EAP_EMSK_LEN);
     489           0 :         *len = EAP_EMSK_LEN;
     490             : 
     491           0 :         return key;
     492             : }
     493             : 
     494             : 
     495           4 : int eap_peer_sake_register(void)
     496             : {
     497             :         struct eap_method *eap;
     498             :         int ret;
     499             : 
     500           4 :         eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION,
     501             :                                     EAP_VENDOR_IETF, EAP_TYPE_SAKE, "SAKE");
     502           4 :         if (eap == NULL)
     503           0 :                 return -1;
     504             : 
     505           4 :         eap->init = eap_sake_init;
     506           4 :         eap->deinit = eap_sake_deinit;
     507           4 :         eap->process = eap_sake_process;
     508           4 :         eap->isKeyAvailable = eap_sake_isKeyAvailable;
     509           4 :         eap->getKey = eap_sake_getKey;
     510           4 :         eap->getSessionId = eap_sake_get_session_id;
     511           4 :         eap->get_emsk = eap_sake_get_emsk;
     512             : 
     513           4 :         ret = eap_peer_method_register(eap);
     514           4 :         if (ret)
     515           0 :                 eap_peer_method_free(eap);
     516           4 :         return ret;
     517             : }

Generated by: LCOV version 1.10