1 /*
2 * hostapd / EAP-GPSK (RFC 5433) server
3 * Copyright (c) 2006-2007, 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_server/eap_i.h"
14 #include "eap_common/eap_gpsk_common.h"
15
16
17 struct eap_gpsk_data {
18 enum { GPSK_1, GPSK_3, SUCCESS, FAILURE } state;
19 u8 rand_server[EAP_GPSK_RAND_LEN];
20 u8 rand_peer[EAP_GPSK_RAND_LEN];
21 u8 msk[EAP_MSK_LEN];
22 u8 emsk[EAP_EMSK_LEN];
23 u8 sk[EAP_GPSK_MAX_SK_LEN];
24 size_t sk_len;
25 u8 pk[EAP_GPSK_MAX_PK_LEN];
26 size_t pk_len;
27 u8 *id_peer;
28 size_t id_peer_len;
29 #define MAX_NUM_CSUITES 2
30 struct eap_gpsk_csuite csuite_list[MAX_NUM_CSUITES];
31 size_t csuite_count;
32 int vendor; /* CSuite/Vendor */
33 int specifier; /* CSuite/Specifier */
34 };
35
36
eap_gpsk_state_txt(int state)37 static const char * eap_gpsk_state_txt(int state)
38 {
39 switch (state) {
40 case GPSK_1:
41 return "GPSK-1";
42 case GPSK_3:
43 return "GPSK-3";
44 case SUCCESS:
45 return "SUCCESS";
46 case FAILURE:
47 return "FAILURE";
48 default:
49 return "?";
50 }
51 }
52
53
eap_gpsk_state(struct eap_gpsk_data * data,int state)54 static void eap_gpsk_state(struct eap_gpsk_data *data, int state)
55 {
56 wpa_printf(MSG_DEBUG, "EAP-GPSK: %s -> %s",
57 eap_gpsk_state_txt(data->state),
58 eap_gpsk_state_txt(state));
59 data->state = state;
60 }
61
62
eap_gpsk_init(struct eap_sm * sm)63 static void * eap_gpsk_init(struct eap_sm *sm)
64 {
65 struct eap_gpsk_data *data;
66
67 data = os_zalloc(sizeof(*data));
68 if (data == NULL)
69 return NULL;
70 data->state = GPSK_1;
71
72 data->csuite_count = 0;
73 if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
74 EAP_GPSK_CIPHER_AES)) {
75 WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
76 EAP_GPSK_VENDOR_IETF);
77 WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
78 EAP_GPSK_CIPHER_AES);
79 data->csuite_count++;
80 }
81 if (eap_gpsk_supported_ciphersuite(EAP_GPSK_VENDOR_IETF,
82 EAP_GPSK_CIPHER_SHA256)) {
83 WPA_PUT_BE32(data->csuite_list[data->csuite_count].vendor,
84 EAP_GPSK_VENDOR_IETF);
85 WPA_PUT_BE16(data->csuite_list[data->csuite_count].specifier,
86 EAP_GPSK_CIPHER_SHA256);
87 data->csuite_count++;
88 }
89
90 return data;
91 }
92
93
eap_gpsk_reset(struct eap_sm * sm,void * priv)94 static void eap_gpsk_reset(struct eap_sm *sm, void *priv)
95 {
96 struct eap_gpsk_data *data = priv;
97 os_free(data->id_peer);
98 bin_clear_free(data, sizeof(*data));
99 }
100
101
eap_gpsk_build_gpsk_1(struct eap_sm * sm,struct eap_gpsk_data * data,u8 id)102 static struct wpabuf * eap_gpsk_build_gpsk_1(struct eap_sm *sm,
103 struct eap_gpsk_data *data, u8 id)
104 {
105 size_t len;
106 struct wpabuf *req;
107
108 wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-1");
109
110 if (random_get_bytes(data->rand_server, EAP_GPSK_RAND_LEN)) {
111 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to get random data");
112 eap_gpsk_state(data, FAILURE);
113 return NULL;
114 }
115 wpa_hexdump(MSG_MSGDUMP, "EAP-GPSK: RAND_Server",
116 data->rand_server, EAP_GPSK_RAND_LEN);
117
118 len = 1 + 2 + sm->server_id_len + EAP_GPSK_RAND_LEN + 2 +
119 data->csuite_count * sizeof(struct eap_gpsk_csuite);
120 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
121 EAP_CODE_REQUEST, id);
122 if (req == NULL) {
123 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
124 "for request/GPSK-1");
125 eap_gpsk_state(data, FAILURE);
126 return NULL;
127 }
128
129 wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_1);
130 wpabuf_put_be16(req, sm->server_id_len);
131 wpabuf_put_data(req, sm->server_id, sm->server_id_len);
132 wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
133 wpabuf_put_be16(req,
134 data->csuite_count * sizeof(struct eap_gpsk_csuite));
135 wpabuf_put_data(req, data->csuite_list,
136 data->csuite_count * sizeof(struct eap_gpsk_csuite));
137
138 return req;
139 }
140
141
eap_gpsk_build_gpsk_3(struct eap_sm * sm,struct eap_gpsk_data * data,u8 id)142 static struct wpabuf * eap_gpsk_build_gpsk_3(struct eap_sm *sm,
143 struct eap_gpsk_data *data, u8 id)
144 {
145 u8 *pos, *start;
146 size_t len, miclen;
147 struct eap_gpsk_csuite *csuite;
148 struct wpabuf *req;
149
150 wpa_printf(MSG_DEBUG, "EAP-GPSK: Request/GPSK-3");
151
152 miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
153 len = 1 + 2 * EAP_GPSK_RAND_LEN + 2 + sm->server_id_len +
154 sizeof(struct eap_gpsk_csuite) + 2 + miclen;
155 req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_GPSK, len,
156 EAP_CODE_REQUEST, id);
157 if (req == NULL) {
158 wpa_printf(MSG_ERROR, "EAP-GPSK: Failed to allocate memory "
159 "for request/GPSK-3");
160 eap_gpsk_state(data, FAILURE);
161 return NULL;
162 }
163
164 wpabuf_put_u8(req, EAP_GPSK_OPCODE_GPSK_3);
165 start = wpabuf_put(req, 0);
166
167 wpabuf_put_data(req, data->rand_peer, EAP_GPSK_RAND_LEN);
168 wpabuf_put_data(req, data->rand_server, EAP_GPSK_RAND_LEN);
169 wpabuf_put_be16(req, sm->server_id_len);
170 wpabuf_put_data(req, sm->server_id, sm->server_id_len);
171 csuite = wpabuf_put(req, sizeof(*csuite));
172 WPA_PUT_BE32(csuite->vendor, data->vendor);
173 WPA_PUT_BE16(csuite->specifier, data->specifier);
174
175 /* no PD_Payload_2 */
176 wpabuf_put_be16(req, 0);
177
178 pos = wpabuf_put(req, miclen);
179 if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
180 data->specifier, start, pos - start, pos) < 0)
181 {
182 os_free(req);
183 eap_gpsk_state(data, FAILURE);
184 return NULL;
185 }
186
187 return req;
188 }
189
190
eap_gpsk_buildReq(struct eap_sm * sm,void * priv,u8 id)191 static struct wpabuf * eap_gpsk_buildReq(struct eap_sm *sm, void *priv, u8 id)
192 {
193 struct eap_gpsk_data *data = priv;
194
195 switch (data->state) {
196 case GPSK_1:
197 return eap_gpsk_build_gpsk_1(sm, data, id);
198 case GPSK_3:
199 return eap_gpsk_build_gpsk_3(sm, data, id);
200 default:
201 wpa_printf(MSG_DEBUG, "EAP-GPSK: Unknown state %d in buildReq",
202 data->state);
203 break;
204 }
205 return NULL;
206 }
207
208
eap_gpsk_check(struct eap_sm * sm,void * priv,struct wpabuf * respData)209 static Boolean eap_gpsk_check(struct eap_sm *sm, void *priv,
210 struct wpabuf *respData)
211 {
212 struct eap_gpsk_data *data = priv;
213 const u8 *pos;
214 size_t len;
215
216 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
217 if (pos == NULL || len < 1) {
218 wpa_printf(MSG_INFO, "EAP-GPSK: Invalid frame");
219 return TRUE;
220 }
221
222 wpa_printf(MSG_DEBUG, "EAP-GPSK: Received frame: opcode=%d", *pos);
223
224 if (data->state == GPSK_1 && *pos == EAP_GPSK_OPCODE_GPSK_2)
225 return FALSE;
226
227 if (data->state == GPSK_3 && *pos == EAP_GPSK_OPCODE_GPSK_4)
228 return FALSE;
229
230 wpa_printf(MSG_INFO, "EAP-GPSK: Unexpected opcode=%d in state=%d",
231 *pos, data->state);
232
233 return TRUE;
234 }
235
236
eap_gpsk_process_gpsk_2(struct eap_sm * sm,struct eap_gpsk_data * data,const u8 * payload,size_t payloadlen)237 static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
238 struct eap_gpsk_data *data,
239 const u8 *payload, size_t payloadlen)
240 {
241 const u8 *pos, *end;
242 u16 alen;
243 const struct eap_gpsk_csuite *csuite;
244 size_t i, miclen;
245 u8 mic[EAP_GPSK_MAX_MIC_LEN];
246
247 if (data->state != GPSK_1)
248 return;
249
250 wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Response/GPSK-2");
251
252 pos = payload;
253 end = payload + payloadlen;
254
255 if (end - pos < 2) {
256 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
257 "ID_Peer length");
258 eap_gpsk_state(data, FAILURE);
259 return;
260 }
261 alen = WPA_GET_BE16(pos);
262 pos += 2;
263 if (end - pos < alen) {
264 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
265 "ID_Peer");
266 eap_gpsk_state(data, FAILURE);
267 return;
268 }
269 os_free(data->id_peer);
270 data->id_peer = os_malloc(alen);
271 if (data->id_peer == NULL) {
272 wpa_printf(MSG_DEBUG, "EAP-GPSK: Not enough memory to store "
273 "%d-octet ID_Peer", alen);
274 return;
275 }
276 os_memcpy(data->id_peer, pos, alen);
277 data->id_peer_len = alen;
278 wpa_hexdump_ascii(MSG_DEBUG, "EAP-GPSK: ID_Peer",
279 data->id_peer, data->id_peer_len);
280 pos += alen;
281
282 if (end - pos < 2) {
283 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
284 "ID_Server length");
285 eap_gpsk_state(data, FAILURE);
286 return;
287 }
288 alen = WPA_GET_BE16(pos);
289 pos += 2;
290 if (end - pos < alen) {
291 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
292 "ID_Server");
293 eap_gpsk_state(data, FAILURE);
294 return;
295 }
296 if (alen != sm->server_id_len ||
297 os_memcmp(pos, sm->server_id, alen) != 0) {
298 wpa_printf(MSG_DEBUG, "EAP-GPSK: ID_Server in GPSK-1 and "
299 "GPSK-2 did not match");
300 eap_gpsk_state(data, FAILURE);
301 return;
302 }
303 pos += alen;
304
305 if (end - pos < EAP_GPSK_RAND_LEN) {
306 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
307 "RAND_Peer");
308 eap_gpsk_state(data, FAILURE);
309 return;
310 }
311 os_memcpy(data->rand_peer, pos, EAP_GPSK_RAND_LEN);
312 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Peer",
313 data->rand_peer, EAP_GPSK_RAND_LEN);
314 pos += EAP_GPSK_RAND_LEN;
315
316 if (end - pos < EAP_GPSK_RAND_LEN) {
317 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
318 "RAND_Server");
319 eap_gpsk_state(data, FAILURE);
320 return;
321 }
322 if (os_memcmp(data->rand_server, pos, EAP_GPSK_RAND_LEN) != 0) {
323 wpa_printf(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1 and "
324 "GPSK-2 did not match");
325 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-1",
326 data->rand_server, EAP_GPSK_RAND_LEN);
327 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: RAND_Server in GPSK-2",
328 pos, EAP_GPSK_RAND_LEN);
329 eap_gpsk_state(data, FAILURE);
330 return;
331 }
332 pos += EAP_GPSK_RAND_LEN;
333
334 if (end - pos < 2) {
335 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
336 "CSuite_List length");
337 eap_gpsk_state(data, FAILURE);
338 return;
339 }
340 alen = WPA_GET_BE16(pos);
341 pos += 2;
342 if (end - pos < alen) {
343 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
344 "CSuite_List");
345 eap_gpsk_state(data, FAILURE);
346 return;
347 }
348 if (alen != data->csuite_count * sizeof(struct eap_gpsk_csuite) ||
349 os_memcmp(pos, data->csuite_list, alen) != 0) {
350 wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_List in GPSK-1 and "
351 "GPSK-2 did not match");
352 eap_gpsk_state(data, FAILURE);
353 return;
354 }
355 pos += alen;
356
357 if (end - pos < (int) sizeof(*csuite)) {
358 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
359 "CSuite_Sel");
360 eap_gpsk_state(data, FAILURE);
361 return;
362 }
363 csuite = (const struct eap_gpsk_csuite *) pos;
364 for (i = 0; i < data->csuite_count; i++) {
365 if (os_memcmp(csuite, &data->csuite_list[i], sizeof(*csuite))
366 == 0)
367 break;
368 }
369 if (i == data->csuite_count) {
370 wpa_printf(MSG_DEBUG, "EAP-GPSK: Peer selected unsupported "
371 "ciphersuite %d:%d",
372 WPA_GET_BE32(csuite->vendor),
373 WPA_GET_BE16(csuite->specifier));
374 eap_gpsk_state(data, FAILURE);
375 return;
376 }
377 data->vendor = WPA_GET_BE32(csuite->vendor);
378 data->specifier = WPA_GET_BE16(csuite->specifier);
379 wpa_printf(MSG_DEBUG, "EAP-GPSK: CSuite_Sel %d:%d",
380 data->vendor, data->specifier);
381 pos += sizeof(*csuite);
382
383 if (end - pos < 2) {
384 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
385 "PD_Payload_1 length");
386 eap_gpsk_state(data, FAILURE);
387 return;
388 }
389 alen = WPA_GET_BE16(pos);
390 pos += 2;
391 if (end - pos < alen) {
392 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
393 "PD_Payload_1");
394 eap_gpsk_state(data, FAILURE);
395 return;
396 }
397 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_1", pos, alen);
398 pos += alen;
399
400 if (sm->user == NULL || sm->user->password == NULL) {
401 wpa_printf(MSG_INFO, "EAP-GPSK: No PSK/password configured "
402 "for the user");
403 eap_gpsk_state(data, FAILURE);
404 return;
405 }
406
407 if (eap_gpsk_derive_keys(sm->user->password, sm->user->password_len,
408 data->vendor, data->specifier,
409 data->rand_peer, data->rand_server,
410 data->id_peer, data->id_peer_len,
411 sm->server_id, sm->server_id_len,
412 data->msk, data->emsk,
413 data->sk, &data->sk_len,
414 data->pk, &data->pk_len) < 0) {
415 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive keys");
416 eap_gpsk_state(data, FAILURE);
417 return;
418 }
419
420 miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
421 if (end - pos < (int) miclen) {
422 wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
423 "(left=%lu miclen=%lu)",
424 (unsigned long) (end - pos),
425 (unsigned long) miclen);
426 eap_gpsk_state(data, FAILURE);
427 return;
428 }
429 if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
430 data->specifier, payload, pos - payload, mic)
431 < 0) {
432 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
433 eap_gpsk_state(data, FAILURE);
434 return;
435 }
436 if (os_memcmp_const(mic, pos, miclen) != 0) {
437 wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-2");
438 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
439 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
440 eap_gpsk_state(data, FAILURE);
441 return;
442 }
443 pos += miclen;
444
445 if (pos != end) {
446 wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
447 "data in the end of GPSK-2",
448 (unsigned long) (end - pos));
449 }
450
451 eap_gpsk_state(data, GPSK_3);
452 }
453
454
eap_gpsk_process_gpsk_4(struct eap_sm * sm,struct eap_gpsk_data * data,const u8 * payload,size_t payloadlen)455 static void eap_gpsk_process_gpsk_4(struct eap_sm *sm,
456 struct eap_gpsk_data *data,
457 const u8 *payload, size_t payloadlen)
458 {
459 const u8 *pos, *end;
460 u16 alen;
461 size_t miclen;
462 u8 mic[EAP_GPSK_MAX_MIC_LEN];
463
464 if (data->state != GPSK_3)
465 return;
466
467 wpa_printf(MSG_DEBUG, "EAP-GPSK: Received Response/GPSK-4");
468
469 pos = payload;
470 end = payload + payloadlen;
471
472 if (end - pos < 2) {
473 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
474 "PD_Payload_1 length");
475 eap_gpsk_state(data, FAILURE);
476 return;
477 }
478 alen = WPA_GET_BE16(pos);
479 pos += 2;
480 if (end - pos < alen) {
481 wpa_printf(MSG_DEBUG, "EAP-GPSK: Too short message for "
482 "PD_Payload_1");
483 eap_gpsk_state(data, FAILURE);
484 return;
485 }
486 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: PD_Payload_1", pos, alen);
487 pos += alen;
488
489 miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
490 if (end - pos < (int) miclen) {
491 wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
492 "(left=%lu miclen=%lu)",
493 (unsigned long) (end - pos),
494 (unsigned long) miclen);
495 eap_gpsk_state(data, FAILURE);
496 return;
497 }
498 if (eap_gpsk_compute_mic(data->sk, data->sk_len, data->vendor,
499 data->specifier, payload, pos - payload, mic)
500 < 0) {
501 wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to compute MIC");
502 eap_gpsk_state(data, FAILURE);
503 return;
504 }
505 if (os_memcmp_const(mic, pos, miclen) != 0) {
506 wpa_printf(MSG_INFO, "EAP-GPSK: Incorrect MIC in GPSK-4");
507 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Received MIC", pos, miclen);
508 wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Computed MIC", mic, miclen);
509 eap_gpsk_state(data, FAILURE);
510 return;
511 }
512 pos += miclen;
513
514 if (pos != end) {
515 wpa_printf(MSG_DEBUG, "EAP-GPSK: Ignored %lu bytes of extra "
516 "data in the end of GPSK-4",
517 (unsigned long) (end - pos));
518 }
519
520 eap_gpsk_state(data, SUCCESS);
521 }
522
523
eap_gpsk_process(struct eap_sm * sm,void * priv,struct wpabuf * respData)524 static void eap_gpsk_process(struct eap_sm *sm, void *priv,
525 struct wpabuf *respData)
526 {
527 struct eap_gpsk_data *data = priv;
528 const u8 *pos;
529 size_t len;
530
531 pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_GPSK, respData, &len);
532 if (pos == NULL || len < 1)
533 return;
534
535 switch (*pos) {
536 case EAP_GPSK_OPCODE_GPSK_2:
537 eap_gpsk_process_gpsk_2(sm, data, pos + 1, len - 1);
538 break;
539 case EAP_GPSK_OPCODE_GPSK_4:
540 eap_gpsk_process_gpsk_4(sm, data, pos + 1, len - 1);
541 break;
542 }
543 }
544
545
eap_gpsk_isDone(struct eap_sm * sm,void * priv)546 static Boolean eap_gpsk_isDone(struct eap_sm *sm, void *priv)
547 {
548 struct eap_gpsk_data *data = priv;
549 return data->state == SUCCESS || data->state == FAILURE;
550 }
551
552
eap_gpsk_getKey(struct eap_sm * sm,void * priv,size_t * len)553 static u8 * eap_gpsk_getKey(struct eap_sm *sm, void *priv, size_t *len)
554 {
555 struct eap_gpsk_data *data = priv;
556 u8 *key;
557
558 if (data->state != SUCCESS)
559 return NULL;
560
561 key = os_malloc(EAP_MSK_LEN);
562 if (key == NULL)
563 return NULL;
564 os_memcpy(key, data->msk, EAP_MSK_LEN);
565 *len = EAP_MSK_LEN;
566
567 return key;
568 }
569
570
eap_gpsk_get_emsk(struct eap_sm * sm,void * priv,size_t * len)571 static u8 * eap_gpsk_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
572 {
573 struct eap_gpsk_data *data = priv;
574 u8 *key;
575
576 if (data->state != SUCCESS)
577 return NULL;
578
579 key = os_malloc(EAP_EMSK_LEN);
580 if (key == NULL)
581 return NULL;
582 os_memcpy(key, data->emsk, EAP_EMSK_LEN);
583 *len = EAP_EMSK_LEN;
584
585 return key;
586 }
587
588
eap_gpsk_isSuccess(struct eap_sm * sm,void * priv)589 static Boolean eap_gpsk_isSuccess(struct eap_sm *sm, void *priv)
590 {
591 struct eap_gpsk_data *data = priv;
592 return data->state == SUCCESS;
593 }
594
595
eap_server_gpsk_register(void)596 int eap_server_gpsk_register(void)
597 {
598 struct eap_method *eap;
599 int ret;
600
601 eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
602 EAP_VENDOR_IETF, EAP_TYPE_GPSK, "GPSK");
603 if (eap == NULL)
604 return -1;
605
606 eap->init = eap_gpsk_init;
607 eap->reset = eap_gpsk_reset;
608 eap->buildReq = eap_gpsk_buildReq;
609 eap->check = eap_gpsk_check;
610 eap->process = eap_gpsk_process;
611 eap->isDone = eap_gpsk_isDone;
612 eap->getKey = eap_gpsk_getKey;
613 eap->isSuccess = eap_gpsk_isSuccess;
614 eap->get_emsk = eap_gpsk_get_emsk;
615
616 ret = eap_server_method_register(eap);
617 if (ret)
618 eap_server_method_free(eap);
619 return ret;
620 }
621