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 1443382998 Lines: 241 267 90.3 %
Date: 2015-09-27 Functions: 14 14 100.0 %

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

Generated by: LCOV version 1.10