eap_gpsk.c

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

Generated on Sat Nov 21 23:16:51 2009 for hostapd by  doxygen 1.6.1