eap_server_gpsk.c
Go to the documentation of this file.
00001 /*
00002  * hostapd / EAP-GPSK (RFC 5433) server
00003  * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 
00017 #include "common.h"
00018 #include "eap_server/eap_i.h"
00019 #include "eap_common/eap_gpsk_common.h"
00020 
00021 
00022 struct eap_gpsk_data {
00023         enum { GPSK_1, GPSK_3, SUCCESS, FAILURE } state;
00024         u8 rand_server[EAP_GPSK_RAND_LEN];
00025         u8 rand_peer[EAP_GPSK_RAND_LEN];
00026         u8 msk[EAP_MSK_LEN];
00027         u8 emsk[EAP_EMSK_LEN];
00028         u8 sk[EAP_GPSK_MAX_SK_LEN];
00029         size_t sk_len;
00030         u8 pk[EAP_GPSK_MAX_PK_LEN];
00031         size_t pk_len;
00032         u8 *id_peer;
00033         size_t id_peer_len;
00034         u8 *id_server;
00035         size_t id_server_len;
00036 #define MAX_NUM_CSUITES 2
00037         struct eap_gpsk_csuite csuite_list[MAX_NUM_CSUITES];
00038         size_t csuite_count;
00039         int vendor; /* CSuite/Vendor */
00040         int specifier; /* CSuite/Specifier */
00041 };
00042 
00043 
00044 static const char * eap_gpsk_state_txt(int state)
00045 {
00046         switch (state) {
00047         case GPSK_1:
00048                 return "GPSK-1";
00049         case GPSK_3:
00050                 return "GPSK-3";
00051         case SUCCESS:
00052                 return "SUCCESS";
00053         case FAILURE:
00054                 return "FAILURE";
00055         default:
00056                 return "?";
00057         }
00058 }
00059 
00060 
00061 static void eap_gpsk_state(struct eap_gpsk_data *data, int state)
00062 {
00063         wpa_printf(MSG_DEBUG, "EAP-GPSK: %s -> %s",
00064                    eap_gpsk_state_txt(data->state),
00065                    eap_gpsk_state_txt(state));
00066         data->state = state;
00067 }
00068 
00069 
00070 static void * eap_gpsk_init(struct eap_sm *sm)
00071 {
00072         struct eap_gpsk_data *data;
00073 
00074         data = os_zalloc(sizeof(*data));
00075         if (data == NULL)
00076                 return NULL;
00077         data->state = GPSK_1;
00078 
00079         /* TODO: add support for configuring ID_Server */
00080         data->id_server = (u8 *) os_strdup("hostapd");
00081         if (data->id_server)
00082                 data->id_server_len = os_strlen((char *) data->id_server);
00083 
00084         data->csuite_count = 0;
00085         if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
00086                                            EAP_GPSK_CIPHER_AES)) {
00087                 WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
00088                              EAP_GPSK_VENDOR_IETF);
00089                 WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
00090                              EAP_GPSK_CIPHER_AES);
00091                 data->csuite_count++;
00092         }
00093         if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
00094                                            EAP_GPSK_CIPHER_SHA256)) {
00095                 WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
00096                              EAP_GPSK_VENDOR_IETF);
00097                 WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
00098                              EAP_GPSK_CIPHER_SHA256);
00099                 data->csuite_count++;
00100         }
00101 
00102         return data;
00103 }
00104 
00105 
00106 static void eap_gpsk_reset(struct eap_sm *sm, void *priv)
00107 {
00108         struct eap_gpsk_data *data = priv;
00109         os_free(data->id_server);
00110         os_free(data->id_peer);
00111         os_free(data);
00112 }
00113 
00114 
00115 static struct wpabuf * eap_gpsk_build_gpsk_1(struct eap_sm *sm,
00116                                              struct eap_gpsk_data *data, u8 id)
00117 {
00118         size_t len;
00119         struct wpabuf *req;
00120 
00121         wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-1");
00122 
00123         if (os_get_random(data->rand_server, EAP_GPSK_RAND_LEN)) {
00124                 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to get random data");
00125                 eap_gpsk_state(data, FAILURE);
00126                 return NULL;
00127         }
00128         wpa_hexdump(MSG_MSGDUMP, "EAP-GPSK: RAND_Server",
00129                     data->rand_server, EAP_GPSK_RAND_LEN);
00130 
00131         len = 1 + 2 + data->id_server_len + EAP_GPSK_RAND_LEN + 2 +
00132                 data->csuite_count * sizeof(struct eap_gpsk_csuite);
00133         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
00134                             EAP_CODE_REQUEST, id);
00135         if (req == NULL) {
00136                 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
00137                            "for request/GPSK-1");
00138                 eap_gpsk_state(data, FAILURE);
00139                 return NULL;
00140         }
00141 
00142         wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_1);
00143         wpabuf_put_be16(req, data->id_server_len);
00144         wpabuf_put_data(req, data->id_server, data->id_server_len);
00145         wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
00146         wpabuf_put_be16(req,
00147                         data->csuite_count * sizeof(struct eap_gpsk_csuite));
00148         wpabuf_put_data(req, data->csuite_list,
00149                         data->csuite_count * sizeof(struct eap_gpsk_csuite));
00150 
00151         return req;
00152 }
00153 
00154 
00155 static struct wpabuf * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
00156                                              struct eap_gpsk_data *data, u8 id)
00157 {
00158         u8 *pos, *start;
00159         size_t len, miclen;
00160         struct eap_gpsk_csuite *csuite;
00161         struct wpabuf *req;
00162 
00163         wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-3");
00164 
00165         miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
00166         len = 1 + 2 * EAP_GPSK_RAND_LEN + 2 + data->id_server_len +
00167                 sizeof(struct eap_gpsk_csuite) + 2 + miclen;
00168         req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
00169                             EAP_CODE_REQUEST, id);
00170         if (req == NULL) {
00171                 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
00172                            "for request/GPSK-3");
00173                 eap_gpsk_state(data, FAILURE);
00174                 return NULL;
00175         }
00176 
00177         wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_3);
00178         start = wpabuf_put(req, 0);
00179 
00180         wpabuf_put_data(req, data->rand_peer, EAP_GPSK_RAND_LEN);
00181         wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
00182         wpabuf_put_be16(req, data->id_server_len);
00183         wpabuf_put_data(req, data->id_server, data->id_server_len);
00184         csuite = wpabuf_put(req, sizeof(*csuite));
00185         WPA_PUT_BE32(csuite->vendor, data->vendor);
00186         WPA_PUT_BE16(csuite->specifier, data->specifier);
00187 
00188         /* no PD_Payload_2 */
00189         wpabuf_put_be16(req, 0);
00190 
00191         pos = wpabuf_put(req, miclen);
00192         if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
00193                                  data->specifier, start, pos - start, pos) < 0)
00194         {
00195                 os_free(req);
00196                 eap_gpsk_state(data, FAILURE);
00197                 return NULL;
00198         }
00199 
00200         return req;
00201 }
00202 
00203 
00204 static struct wpabuf * eap_gpsk_buildReq(struct eap_sm *sm, void *priv, u8 id)
00205 {
00206         struct eap_gpsk_data *data = priv;
00207 
00208         switch (data->state) {
00209         case GPSK_1:
00210                 return eap_gpsk_build_gpsk_1(sm, data, id);
00211         case GPSK_3:
00212                 return eap_gpsk_build_gpsk_3(sm, data, id);
00213         default:
00214                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown state %d in buildReq",
00215                            data->state);
00216                 break;
00217         }
00218         return NULL;
00219 }
00220 
00221 
00222 static Boolean eap_gpsk_check(struct eap_sm *sm, void *priv,
00223                               struct wpabuf *respData)
00224 {
00225         struct eap_gpsk_data *data = priv;
00226         const u8 *pos;
00227         size_t len;
00228 
00229         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
00230         if (pos == NULL || len < 1) {
00231                 wpa_printf(MSG_INFO, "EAP-GPSK: Invalid frame");
00232                 return TRUE;
00233         }
00234 
00235         wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode=%d", *pos);
00236 
00237         if (data->state == GPSK_1 && *pos == EAP_GPSK_OPCODE_GPSK_2)
00238                 return FALSE;
00239 
00240         if (data->state == GPSK_3 && *pos == EAP_GPSK_OPCODE_GPSK_4)
00241                 return FALSE;
00242 
00243         wpa_printf(MSG_INFO, "EAP-GPSK: Unexpected opcode=%d in state=%d",
00244                    *pos, data->state);
00245 
00246         return TRUE;
00247 }
00248 
00249 
00250 static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
00251                                     struct eap_gpsk_data *data,
00252                                     const u8 *payload, size_t payloadlen)
00253 {
00254         const u8 *pos, *end;
00255         u16 alen;
00256         const struct eap_gpsk_csuite *csuite;
00257         size_t i, miclen;
00258         u8 mic[EAP_GPSK_MAX_MIC_LEN];
00259 
00260         if (data->state != GPSK_1)
00261                 return;
00262 
00263         wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Response/GPSK-2");
00264 
00265         pos = payload;
00266         end = payload + payloadlen;
00267 
00268         if (end - pos < 2) {
00269                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00270                            "ID_Peer length");
00271                 eap_gpsk_state(data, FAILURE);
00272                 return;
00273         }
00274         alen = WPA_GET_BE16(pos);
00275         pos += 2;
00276         if (end - pos < alen) {
00277                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00278                            "ID_Peer");
00279                 eap_gpsk_state(data, FAILURE);
00280                 return;
00281         }
00282         os_free(data->id_peer);
00283         data->id_peer = os_malloc(alen);
00284         if (data->id_peer == NULL) {
00285                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Not enough memory to store "
00286                            "%d-octet ID_Peer", alen);
00287                 return;
00288         }
00289         os_memcpy(data->id_peer, pos, alen);
00290         data->id_peer_len = alen;
00291         wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
00292                           data->id_peer, data->id_peer_len);
00293         pos += alen;
00294 
00295         if (end - pos < 2) {
00296                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00297                            "ID_Server length");
00298                 eap_gpsk_state(data, FAILURE);
00299                 return;
00300         }
00301         alen = WPA_GET_BE16(pos);
00302         pos += 2;
00303         if (end - pos < alen) {
00304                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00305                            "ID_Server");
00306                 eap_gpsk_state(data, FAILURE);
00307                 return;
00308         }
00309         if (alen != data->id_server_len ||
00310             os_memcmp(pos, data->id_server, alen) != 0) {
00311                 wpa_printf(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1 and "
00312                            "GPSK-2 did not match");
00313                 eap_gpsk_state(data, FAILURE);
00314                 return;
00315         }
00316         pos += alen;
00317 
00318         if (end - pos < EAP_GPSK_RAND_LEN) {
00319                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00320                            "RAND_Peer");
00321                 eap_gpsk_state(data, FAILURE);
00322                 return;
00323         }
00324         os_memcpy(data->rand_peer, pos, EAP_GPSK_RAND_LEN);
00325         wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
00326                     data->rand_peer, EAP_GPSK_RAND_LEN);
00327         pos += EAP_GPSK_RAND_LEN;
00328 
00329         if (end - pos < EAP_GPSK_RAND_LEN) {
00330                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00331                            "RAND_Server");
00332                 eap_gpsk_state(data, FAILURE);
00333                 return;
00334         }
00335         if (os_memcmp(data->rand_server, pos, EAP_GPSK_RAND_LEN) != 0) {
00336                 wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1 and "
00337                            "GPSK-2 did not match");
00338                 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1",
00339                             data->rand_server, EAP_GPSK_RAND_LEN);
00340                 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-2",
00341                             pos, EAP_GPSK_RAND_LEN);
00342                 eap_gpsk_state(data, FAILURE);
00343                 return;
00344         }
00345         pos += EAP_GPSK_RAND_LEN;
00346 
00347         if (end - pos < 2) {
00348                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00349                            "CSuite_List length");
00350                 eap_gpsk_state(data, FAILURE);
00351                 return;
00352         }
00353         alen = WPA_GET_BE16(pos);
00354         pos += 2;
00355         if (end - pos < alen) {
00356                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00357                            "CSuite_List");
00358                 eap_gpsk_state(data, FAILURE);
00359                 return;
00360         }
00361         if (alen != data->csuite_count * sizeof(struct eap_gpsk_csuite) ||
00362             os_memcmp(pos, data->csuite_list, alen) != 0) {
00363                 wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List in GPSK-1 and "
00364                            "GPSK-2 did not match");
00365                 eap_gpsk_state(data, FAILURE);
00366                 return;
00367         }
00368         pos += alen;
00369 
00370         if (end - pos < (int) sizeof(*csuite)) {
00371                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00372                            "CSuite_Sel");
00373                 eap_gpsk_state(data, FAILURE);
00374                 return;
00375         }
00376         csuite = (const struct eap_gpsk_csuite *) pos;
00377         for (i = 0; i < data->csuite_count; i++) {
00378                 if (os_memcmp(csuite, &data->csuite_list[i], sizeof(*csuite))
00379                     == 0)
00380                         break;
00381         }
00382         if (i == data->csuite_count) {
00383                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Peer selected unsupported "
00384                            "ciphersuite %d:%d",
00385                            WPA_GET_BE32(csuite->vendor),
00386                            WPA_GET_BE16(csuite->specifier));
00387                 eap_gpsk_state(data, FAILURE);
00388                 return;
00389         }
00390         data->vendor = WPA_GET_BE32(csuite->vendor);
00391         data->specifier = WPA_GET_BE16(csuite->specifier);
00392         wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel %d:%d",
00393                    data->vendor, data->specifier);
00394         pos += sizeof(*csuite); 
00395 
00396         if (end - pos < 2) {
00397                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00398                            "PD_Payload_1 length");
00399                 eap_gpsk_state(data, FAILURE);
00400                 return;
00401         }
00402         alen = WPA_GET_BE16(pos);
00403         pos += 2;
00404         if (end - pos < alen) {
00405                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00406                            "PD_Payload_1");
00407                 eap_gpsk_state(data, FAILURE);
00408                 return;
00409         }
00410         wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_1", pos, alen);
00411         pos += alen;
00412 
00413         if (sm->user == NULL || sm->user->password == NULL) {
00414                 wpa_printf(MSG_INFO, "EAP-GPSK: No PSK/password configured "
00415                            "for the user");
00416                 eap_gpsk_state(data, FAILURE);
00417                 return;
00418         }
00419 
00420         if (eap_gpsk_derive_keys(sm->user->password, sm->user->password_len,
00421                                  data->vendor, data->specifier,
00422                                  data->rand_peer, data->rand_server,
00423                                  data->id_peer, data->id_peer_len,
00424                                  data->id_server, data->id_server_len,
00425                                  data->msk, data->emsk,
00426                                  data->sk, &data->sk_len,
00427                                  data->pk, &data->pk_len) < 0) {
00428                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive keys");
00429                 eap_gpsk_state(data, FAILURE);
00430                 return;
00431         }
00432 
00433         miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
00434         if (end - pos < (int) miclen) {
00435                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
00436                            "(left=%lu miclen=%lu)",
00437                            (unsigned long) (end - pos),
00438                            (unsigned long) miclen);
00439                 eap_gpsk_state(data, FAILURE);
00440                 return;
00441         }
00442         if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
00443                                  data->specifier, payload, pos - payload, mic)
00444             < 0) {
00445                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
00446                 eap_gpsk_state(data, FAILURE);
00447                 return;
00448         }
00449         if (os_memcmp(mic, pos, miclen) != 0) {
00450                 wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-2");
00451                 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
00452                 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
00453                 eap_gpsk_state(data, FAILURE);
00454                 return;
00455         }
00456         pos += miclen;
00457 
00458         if (pos != end) {
00459                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
00460                            "data in the end of GPSK-2",
00461                            (unsigned long) (end - pos));
00462         }
00463 
00464         eap_gpsk_state(data, GPSK_3);
00465 }
00466 
00467 
00468 static void eap_gpsk_process_gpsk_4(struct eap_sm *sm,
00469                                     struct eap_gpsk_data *data,
00470                                     const u8 *payload, size_t payloadlen)
00471 {
00472         const u8 *pos, *end;
00473         u16 alen;
00474         size_t miclen;
00475         u8 mic[EAP_GPSK_MAX_MIC_LEN];
00476 
00477         if (data->state != GPSK_3)
00478                 return;
00479 
00480         wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Response/GPSK-4");
00481 
00482         pos = payload;
00483         end = payload + payloadlen;
00484 
00485         if (end - pos < 2) {
00486                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00487                            "PD_Payload_1 length");
00488                 eap_gpsk_state(data, FAILURE);
00489                 return;
00490         }
00491         alen = WPA_GET_BE16(pos);
00492         pos += 2;
00493         if (end - pos < alen) {
00494                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
00495                            "PD_Payload_1");
00496                 eap_gpsk_state(data, FAILURE);
00497                 return;
00498         }
00499         wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_1", pos, alen);
00500         pos += alen;
00501 
00502         miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
00503         if (end - pos < (int) miclen) {
00504                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
00505                            "(left=%lu miclen=%lu)",
00506                            (unsigned long) (end - pos),
00507                            (unsigned long) miclen);
00508                 eap_gpsk_state(data, FAILURE);
00509                 return;
00510         }
00511         if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
00512                                  data->specifier, payload, pos - payload, mic)
00513             < 0) {
00514                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
00515                 eap_gpsk_state(data, FAILURE);
00516                 return;
00517         }
00518         if (os_memcmp(mic, pos, miclen) != 0) {
00519                 wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-4");
00520                 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
00521                 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
00522                 eap_gpsk_state(data, FAILURE);
00523                 return;
00524         }
00525         pos += miclen;
00526 
00527         if (pos != end) {
00528                 wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
00529                            "data in the end of GPSK-4",
00530                            (unsigned long) (end - pos));
00531         }
00532 
00533         eap_gpsk_state(data, SUCCESS);
00534 }
00535 
00536 
00537 static void eap_gpsk_process(struct eap_sm *sm, void *priv,
00538                              struct wpabuf *respData)
00539 {
00540         struct eap_gpsk_data *data = priv;
00541         const u8 *pos;
00542         size_t len;
00543 
00544         pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
00545         if (pos == NULL || len < 1)
00546                 return;
00547 
00548         switch (*pos) {
00549         case EAP_GPSK_OPCODE_GPSK_2:
00550                 eap_gpsk_process_gpsk_2(sm, data, pos + 1, len - 1);
00551                 break;
00552         case EAP_GPSK_OPCODE_GPSK_4:
00553                 eap_gpsk_process_gpsk_4(sm, data, pos + 1, len - 1);
00554                 break;
00555         }
00556 }
00557 
00558 
00559 static Boolean eap_gpsk_isDone(struct eap_sm *sm, void *priv)
00560 {
00561         struct eap_gpsk_data *data = priv;
00562         return data->state == SUCCESS || data->state == FAILURE;
00563 }
00564 
00565 
00566 static u8 * eap_gpsk_getKey(struct eap_sm *sm, void *priv, size_t *len)
00567 {
00568         struct eap_gpsk_data *data = priv;
00569         u8 *key;
00570 
00571         if (data->state != SUCCESS)
00572                 return NULL;
00573 
00574         key = os_malloc(EAP_MSK_LEN);
00575         if (key == NULL)
00576                 return NULL;
00577         os_memcpy(key, data->msk, EAP_MSK_LEN);
00578         *len = EAP_MSK_LEN;
00579 
00580         return key;
00581 }
00582 
00583 
00584 static u8 * eap_gpsk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
00585 {
00586         struct eap_gpsk_data *data = priv;
00587         u8 *key;
00588 
00589         if (data->state != SUCCESS)
00590                 return NULL;
00591 
00592         key = os_malloc(EAP_EMSK_LEN);
00593         if (key == NULL)
00594                 return NULL;
00595         os_memcpy(key, data->emsk, EAP_EMSK_LEN);
00596         *len = EAP_EMSK_LEN;
00597 
00598         return key;
00599 }
00600 
00601 
00602 static Boolean eap_gpsk_isSuccess(struct eap_sm *sm, void *priv)
00603 {
00604         struct eap_gpsk_data *data = priv;
00605         return data->state == SUCCESS;
00606 }
00607 
00608 
00609 int eap_server_gpsk_register(void)
00610 {
00611         struct eap_method *eap;
00612         int ret;
00613 
00614         eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
00615                                       EAP_VENDOR_IETF, EAP_TYPE_GPSK, "GPSK");
00616         if (eap == NULL)
00617                 return -1;
00618 
00619         eap->init = eap_gpsk_init;
00620         eap->reset = eap_gpsk_reset;
00621         eap->buildReq = eap_gpsk_buildReq;
00622         eap->check = eap_gpsk_check;
00623         eap->process = eap_gpsk_process;
00624         eap->isDone = eap_gpsk_isDone;
00625         eap->getKey = eap_gpsk_getKey;
00626         eap->isSuccess = eap_gpsk_isSuccess;
00627         eap->get_emsk = eap_gpsk_get_emsk;
00628 
00629         ret = eap_server_method_register(eap);
00630         if (ret)
00631                 eap_server_method_free(eap);
00632         return ret;
00633 }


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