2 * EAP-TEAP common helper functions (RFC 7170)
3 * Copyright (c) 2008-2019, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "crypto/sha1.h"
13 #include "crypto/sha256.h"
14 #include "crypto/sha384.h"
15 #include "crypto/tls.h"
17 #include "eap_teap_common.h"
20 static int tls_cipher_suite_mac_sha384(u16 cs
);
23 void eap_teap_put_tlv_hdr(struct wpabuf
*buf
, u16 type
, u16 len
)
25 struct teap_tlv_hdr hdr
;
27 hdr
.tlv_type
= host_to_be16(type
);
28 hdr
.length
= host_to_be16(len
);
29 wpabuf_put_data(buf
, &hdr
, sizeof(hdr
));
33 void eap_teap_put_tlv(struct wpabuf
*buf
, u16 type
, const void *data
, u16 len
)
35 eap_teap_put_tlv_hdr(buf
, type
, len
);
36 wpabuf_put_data(buf
, data
, len
);
40 void eap_teap_put_tlv_buf(struct wpabuf
*buf
, u16 type
,
41 const struct wpabuf
*data
)
43 eap_teap_put_tlv_hdr(buf
, type
, wpabuf_len(data
));
44 wpabuf_put_buf(buf
, data
);
48 struct wpabuf
* eap_teap_tlv_eap_payload(struct wpabuf
*buf
)
55 /* Encapsulate EAP packet in EAP-Payload TLV */
56 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Add EAP-Payload TLV");
57 e
= wpabuf_alloc(sizeof(struct teap_tlv_hdr
) + wpabuf_len(buf
));
60 "EAP-TEAP: Failed to allocate memory for TLV encapsulation");
64 eap_teap_put_tlv_buf(e
, TEAP_TLV_MANDATORY
| TEAP_TLV_EAP_PAYLOAD
, buf
);
67 /* TODO: followed by optional TLVs associated with the EAP packet */
73 static int eap_teap_tls_prf(u16 tls_cs
, const u8
*secret
, size_t secret_len
,
74 const char *label
, const u8
*seed
, size_t seed_len
,
75 u8
*out
, size_t outlen
)
77 /* TODO: TLS-PRF for TLSv1.3 */
78 if (tls_cipher_suite_mac_sha384(tls_cs
))
79 return tls_prf_sha384(secret
, secret_len
, label
, seed
, seed_len
,
81 return tls_prf_sha256(secret
, secret_len
, label
, seed
, seed_len
,
86 int eap_teap_derive_eap_msk(u16 tls_cs
, const u8
*simck
, u8
*msk
)
89 * RFC 7170, Section 5.4: EAP Master Session Key Generation
90 * MSK = TLS-PRF(S-IMCK[j], "Session Key Generating Function", 64)
93 if (eap_teap_tls_prf(tls_cs
, simck
, EAP_TEAP_SIMCK_LEN
,
94 "Session Key Generating Function", (u8
*) "", 0,
95 msk
, EAP_TEAP_KEY_LEN
) < 0)
97 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: Derived key (MSK)",
98 msk
, EAP_TEAP_KEY_LEN
);
103 int eap_teap_derive_eap_emsk(u16 tls_cs
, const u8
*simck
, u8
*emsk
)
106 * RFC 7170, Section 5.4: EAP Master Session Key Generation
107 * EMSK = TLS-PRF(S-IMCK[j],
108 * "Extended Session Key Generating Function", 64)
111 if (eap_teap_tls_prf(tls_cs
, simck
, EAP_TEAP_SIMCK_LEN
,
112 "Extended Session Key Generating Function",
113 (u8
*) "", 0, emsk
, EAP_EMSK_LEN
) < 0)
115 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: Derived key (EMSK)",
121 int eap_teap_derive_cmk_basic_pw_auth(u16 tls_cs
, const u8
*s_imck_msk
, u8
*cmk
)
123 u8 imsk
[32], imck
[EAP_TEAP_IMCK_LEN
];
126 /* FIX: The Basic-Password-Auth (i.e., no inner EAP) case is
127 * not fully defined in RFC 7170, so this CMK derivation may
128 * need to be changed if a fixed definition is eventually
129 * published. For now, derive CMK[0] based on S-IMCK[0] and
130 * IMSK of 32 octets of zeros. */
131 os_memset(imsk
, 0, 32);
132 res
= eap_teap_tls_prf(tls_cs
, s_imck_msk
, EAP_TEAP_SIMCK_LEN
,
133 "Inner Methods Compound Keys",
134 imsk
, 32, imck
, sizeof(imck
));
137 os_memcpy(cmk
, &imck
[EAP_TEAP_SIMCK_LEN
], EAP_TEAP_CMK_LEN
);
138 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: CMK[no-inner-EAP]",
139 cmk
, EAP_TEAP_CMK_LEN
);
140 forced_memzero(imck
, sizeof(imck
));
145 int eap_teap_derive_imck(u16 tls_cs
,
146 const u8
*prev_s_imck_msk
, const u8
*prev_s_imck_emsk
,
147 const u8
*msk
, size_t msk_len
,
148 const u8
*emsk
, size_t emsk_len
,
149 u8
*s_imck_msk
, u8
*cmk_msk
,
150 u8
*s_imck_emsk
, u8
*cmk_emsk
)
152 u8 imsk
[64], imck
[EAP_TEAP_IMCK_LEN
];
156 * RFC 7170, Section 5.2:
157 * IMSK = First 32 octets of TLS-PRF(EMSK, "TEAPbindkey@ietf.org" |
159 * (if EMSK is not available, MSK is used instead; if neither is
160 * available, IMSK is 32 octets of zeros; MSK is truncated to 32 octets
161 * or padded to 32 octets, if needed)
162 * (64 is encoded as a 2-octet field in network byte order)
164 * S-IMCK[0] = session_key_seed
165 * IMCK[j] = TLS-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
167 * S-IMCK[j] = first 40 octets of IMCK[j]
168 * CMK[j] = last 20 octets of IMCK[j]
171 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: MSK[j]", msk
, msk_len
);
172 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: EMSK[j]", emsk
, emsk_len
);
174 if (emsk
&& emsk_len
> 0) {
180 if (eap_teap_tls_prf(tls_cs
, emsk
, emsk_len
,
181 "TEAPbindkey@ietf.org",
182 context
, sizeof(context
), imsk
, 64) < 0)
185 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: IMSK from EMSK",
188 res
= eap_teap_tls_prf(tls_cs
,
189 prev_s_imck_emsk
, EAP_TEAP_SIMCK_LEN
,
190 "Inner Methods Compound Keys",
191 imsk
, 32, imck
, EAP_TEAP_IMCK_LEN
);
192 forced_memzero(imsk
, sizeof(imsk
));
196 os_memcpy(s_imck_emsk
, imck
, EAP_TEAP_SIMCK_LEN
);
197 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: EMSK S-IMCK[j]",
198 s_imck_emsk
, EAP_TEAP_SIMCK_LEN
);
199 os_memcpy(cmk_emsk
, &imck
[EAP_TEAP_SIMCK_LEN
],
201 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: EMSK CMK[j]",
202 cmk_emsk
, EAP_TEAP_CMK_LEN
);
203 forced_memzero(imck
, EAP_TEAP_IMCK_LEN
);
206 if (msk
&& msk_len
> 0) {
207 size_t copy_len
= msk_len
;
209 os_memset(imsk
, 0, 32); /* zero pad, if needed */
212 os_memcpy(imsk
, msk
, copy_len
);
213 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: IMSK from MSK", imsk
, 32);
215 os_memset(imsk
, 0, 32);
216 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: Zero IMSK", imsk
, 32);
219 res
= eap_teap_tls_prf(tls_cs
, prev_s_imck_msk
, EAP_TEAP_SIMCK_LEN
,
220 "Inner Methods Compound Keys",
221 imsk
, 32, imck
, EAP_TEAP_IMCK_LEN
);
222 forced_memzero(imsk
, sizeof(imsk
));
226 os_memcpy(s_imck_msk
, imck
, EAP_TEAP_SIMCK_LEN
);
227 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: MSK S-IMCK[j]",
228 s_imck_msk
, EAP_TEAP_SIMCK_LEN
);
229 os_memcpy(cmk_msk
, &imck
[EAP_TEAP_SIMCK_LEN
], EAP_TEAP_CMK_LEN
);
230 wpa_hexdump_key(MSG_DEBUG
, "EAP-TEAP: MSK CMK[j]",
231 cmk_msk
, EAP_TEAP_CMK_LEN
);
232 forced_memzero(imck
, EAP_TEAP_IMCK_LEN
);
238 static int tls_cipher_suite_match(const u16
*list
, size_t count
, u16 cs
)
242 for (i
= 0; i
< count
; i
++) {
251 static int tls_cipher_suite_mac_sha1(u16 cs
)
253 static const u16 sha1_cs
[] = {
254 0x0005, 0x0007, 0x000a, 0x000d, 0x0010, 0x0013, 0x0016, 0x001b,
255 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036,
256 0x0037, 0x0038, 0x0039, 0x003a, 0x0041, 0x0042, 0x0043, 0x0044,
257 0x0045, 0x0046, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089,
258 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091,
259 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099,
261 0xc002, 0xc003, 0xc004, 0xc005, 0xc007, 0xc008, 0xc009, 0xc009,
262 0xc00a, 0xc00c, 0xc00d, 0xc00e, 0xc00f, 0xc011, 0xc012, 0xc013,
263 0xc014, 0xc016, 0xc017, 0xc018, 0xc019, 0xc01a, 0xc01b, 0xc01c,
264 0xc014, 0xc01e, 0xc01f, 0xc020, 0xc021, 0xc022, 0xc033, 0xc034,
268 return tls_cipher_suite_match(sha1_cs
, ARRAY_SIZE(sha1_cs
), cs
);
272 static int tls_cipher_suite_mac_sha256(u16 cs
)
274 static const u16 sha256_cs
[] = {
275 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0067, 0x0068, 0x0069,
276 0x006a, 0x006b, 0x006c, 0x006d, 0x009c, 0x009e, 0x00a0, 0x00a2,
277 0x00a4, 0x00a6, 0x00a8, 0x00aa, 0x00ac, 0x00ae, 0x00b2, 0x00b6,
278 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bd, 0x00be, 0x00be,
279 0x00bf, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
280 0x1301, 0x1303, 0x1304, 0x1305,
281 0xc023, 0xc025, 0xc027, 0xc029, 0xc02b, 0xc02d, 0xc02f, 0xc031,
282 0xc037, 0xc03c, 0xc03e, 0xc040, 0xc040, 0xc042, 0xc044, 0xc046,
283 0xc048, 0xc04a, 0xc04c, 0xc04e, 0xc050, 0xc052, 0xc054, 0xc056,
284 0xc058, 0xc05a, 0xc05c, 0xc05e, 0xc060, 0xc062, 0xc064, 0xc066,
285 0xc068, 0xc06a, 0xc06c, 0xc06e, 0xc070, 0xc072, 0xc074, 0xc076,
286 0xc078, 0xc07a, 0xc07c, 0xc07e, 0xc080, 0xc082, 0xc084, 0xc086,
287 0xc088, 0xc08a, 0xc08c, 0xc08e, 0xc090, 0xc092, 0xc094, 0xc096,
288 0xc098, 0xc09a, 0xc0b0, 0xc0b2, 0xc0b4,
289 0xcca8, 0xcca9, 0xccaa, 0xccab, 0xccac, 0xccad, 0xccae,
290 0xd001, 0xd003, 0xd005
293 return tls_cipher_suite_match(sha256_cs
, ARRAY_SIZE(sha256_cs
), cs
);
297 static int tls_cipher_suite_mac_sha384(u16 cs
)
299 static const u16 sha384_cs
[] = {
300 0x009d, 0x009f, 0x00a1, 0x00a3, 0x00a5, 0x00a7, 0x00a9, 0x00ab,
301 0x00ad, 0x00af, 0x00b3, 0x00b7, 0x1302,
302 0xc024, 0xc026, 0xc028, 0xc02a, 0xc02c, 0xc02e, 0xc030, 0xc032,
303 0xc038, 0xc03d, 0xc03f, 0xc041, 0xc043, 0xc045, 0xc047, 0xc049,
304 0xc04b, 0xc04d, 0xc04f, 0xc051, 0xc053, 0xc055, 0xc057, 0xc059,
305 0xc05b, 0xc05d, 0xc05f, 0xc061, 0xc063, 0xc065, 0xc067, 0xc069,
306 0xc06b, 0xc06d, 0xc06f, 0xc071, 0xc073, 0xc075, 0xc077, 0xc079,
307 0xc07b, 0xc07d, 0xc07f, 0xc081, 0xc083, 0xc085, 0xc087, 0xc089,
308 0xc08b, 0xc08d, 0xc08f, 0xc091, 0xc093, 0xc095, 0xc097, 0xc099,
309 0xc09b, 0xc0b1, 0xc0b3, 0xc0b5,
313 return tls_cipher_suite_match(sha384_cs
, ARRAY_SIZE(sha384_cs
), cs
);
317 static int eap_teap_tls_mac(u16 tls_cs
, const u8
*cmk
, size_t cmk_len
,
318 const u8
*buffer
, size_t buffer_len
,
319 u8
*mac
, size_t mac_len
)
324 os_memset(tmp
, 0, sizeof(tmp
));
325 os_memset(mac
, 0, mac_len
);
327 if (tls_cipher_suite_mac_sha1(tls_cs
)) {
328 wpa_printf(MSG_DEBUG
, "EAP-TEAP: MAC algorithm: HMAC-SHA1");
329 res
= hmac_sha1(cmk
, cmk_len
, buffer
, buffer_len
, tmp
);
330 } else if (tls_cipher_suite_mac_sha256(tls_cs
)) {
331 wpa_printf(MSG_DEBUG
, "EAP-TEAP: MAC algorithm: HMAC-SHA256");
332 res
= hmac_sha256(cmk
, cmk_len
, buffer
, buffer_len
, tmp
);
333 } else if (tls_cipher_suite_mac_sha384(tls_cs
)) {
334 wpa_printf(MSG_DEBUG
, "EAP-TEAP: MAC algorithm: HMAC-SHA384");
335 res
= hmac_sha384(cmk
, cmk_len
, buffer
, buffer_len
, tmp
);
338 "EAP-TEAP: Unsupported TLS cipher suite 0x%04x",
345 /* FIX: RFC 7170 does not describe how to handle truncation of the
346 * Compound MAC or if the fields are supposed to be of variable length
347 * based on the negotiated TLS cipher suite (they are defined as having
348 * fixed size of 20 octets in the TLV description) */
349 if (mac_len
> sizeof(tmp
))
350 mac_len
= sizeof(tmp
);
351 os_memcpy(mac
, tmp
, mac_len
);
356 int eap_teap_compound_mac(u16 tls_cs
, const struct teap_tlv_crypto_binding
*cb
,
357 const struct wpabuf
*server_outer_tlvs
,
358 const struct wpabuf
*peer_outer_tlvs
,
359 const u8
*cmk
, u8
*compound_mac
)
362 size_t bind_len
, buffer_len
;
363 struct teap_tlv_crypto_binding
*tmp_cb
;
366 /* RFC 7170, Section 5.3 */
367 bind_len
= sizeof(struct teap_tlv_hdr
) + be_to_host16(cb
->length
);
368 buffer_len
= bind_len
+ 1;
369 if (server_outer_tlvs
)
370 buffer_len
+= wpabuf_len(server_outer_tlvs
);
372 buffer_len
+= wpabuf_len(peer_outer_tlvs
);
373 buffer
= os_malloc(buffer_len
);
378 /* 1. The entire Crypto-Binding TLV attribute with both the EMSK and MSK
379 * Compound MAC fields zeroed out. */
380 os_memcpy(pos
, cb
, bind_len
);
382 tmp_cb
= (struct teap_tlv_crypto_binding
*) buffer
;
383 os_memset(tmp_cb
->emsk_compound_mac
, 0, EAP_TEAP_COMPOUND_MAC_LEN
);
384 os_memset(tmp_cb
->msk_compound_mac
, 0, EAP_TEAP_COMPOUND_MAC_LEN
);
386 /* 2. The EAP Type sent by the other party in the first TEAP message. */
387 /* This is supposed to be the EAP Type sent by the other party in the
388 * first TEAP message, but since we cannot get here without having
389 * successfully negotiated use of TEAP, this can only be the fixed EAP
391 *pos
++ = EAP_TYPE_TEAP
;
393 /* 3. All the Outer TLVs from the first TEAP message sent by EAP server
395 if (server_outer_tlvs
) {
396 os_memcpy(pos
, wpabuf_head(server_outer_tlvs
),
397 wpabuf_len(server_outer_tlvs
));
398 pos
+= wpabuf_len(server_outer_tlvs
);
401 /* 4. All the Outer TLVs from the first TEAP message sent by the peer to
403 if (peer_outer_tlvs
) {
404 os_memcpy(pos
, wpabuf_head(peer_outer_tlvs
),
405 wpabuf_len(peer_outer_tlvs
));
406 pos
+= wpabuf_len(peer_outer_tlvs
);
409 buffer_len
= pos
- buffer
;
411 wpa_hexdump_key(MSG_MSGDUMP
,
412 "EAP-TEAP: CMK for Compound MAC calculation",
413 cmk
, EAP_TEAP_CMK_LEN
);
414 wpa_hexdump(MSG_MSGDUMP
,
415 "EAP-TEAP: BUFFER for Compound MAC calculation",
417 res
= eap_teap_tls_mac(tls_cs
, cmk
, EAP_TEAP_CMK_LEN
,
419 compound_mac
, EAP_TEAP_COMPOUND_MAC_LEN
);
426 int eap_teap_parse_tlv(struct eap_teap_tlv_parse
*tlv
,
427 int tlv_type
, u8
*pos
, size_t len
)
430 case TEAP_TLV_RESULT
:
431 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: Result TLV", pos
, len
);
434 "EAP-TEAP: More than one Result TLV in the message");
435 tlv
->result
= TEAP_STATUS_FAILURE
;
439 wpa_printf(MSG_INFO
, "EAP-TEAP: Too short Result TLV");
440 tlv
->result
= TEAP_STATUS_FAILURE
;
443 tlv
->result
= WPA_GET_BE16(pos
);
444 if (tlv
->result
!= TEAP_STATUS_SUCCESS
&&
445 tlv
->result
!= TEAP_STATUS_FAILURE
) {
446 wpa_printf(MSG_INFO
, "EAP-TEAP: Unknown Result %d",
448 tlv
->result
= TEAP_STATUS_FAILURE
;
450 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Result: %s",
451 tlv
->result
== TEAP_STATUS_SUCCESS
?
452 "Success" : "Failure");
455 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: NAK TLV", pos
, len
);
457 wpa_printf(MSG_INFO
, "EAP-TEAP: Too short NAK TLV");
458 tlv
->result
= TEAP_STATUS_FAILURE
;
466 wpa_printf(MSG_INFO
, "EAP-TEAP: Too short Error TLV");
467 tlv
->result
= TEAP_STATUS_FAILURE
;
470 tlv
->error_code
= WPA_GET_BE32(pos
);
471 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Error: %u", tlv
->error_code
);
473 case TEAP_TLV_REQUEST_ACTION
:
474 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: Request-Action TLV",
476 if (tlv
->request_action
) {
478 "EAP-TEAP: More than one Request-Action TLV in the message");
479 tlv
->iresult
= TEAP_STATUS_FAILURE
;
484 "EAP-TEAP: Too short Request-Action TLV");
485 tlv
->iresult
= TEAP_STATUS_FAILURE
;
488 tlv
->request_action_status
= pos
[0];
489 tlv
->request_action
= pos
[1];
490 wpa_printf(MSG_DEBUG
,
491 "EAP-TEAP: Request-Action: Status=%u Action=%u",
492 tlv
->request_action_status
, tlv
->request_action
);
494 case TEAP_TLV_EAP_PAYLOAD
:
495 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: EAP-Payload TLV",
497 if (tlv
->eap_payload_tlv
) {
499 "EAP-TEAP: More than one EAP-Payload TLV in the message");
500 tlv
->iresult
= TEAP_STATUS_FAILURE
;
503 tlv
->eap_payload_tlv
= pos
;
504 tlv
->eap_payload_tlv_len
= len
;
506 case TEAP_TLV_INTERMEDIATE_RESULT
:
507 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: Intermediate-Result TLV",
511 "EAP-TEAP: Too short Intermediate-Result TLV");
512 tlv
->iresult
= TEAP_STATUS_FAILURE
;
517 "EAP-TEAP: More than one Intermediate-Result TLV in the message");
518 tlv
->iresult
= TEAP_STATUS_FAILURE
;
521 tlv
->iresult
= WPA_GET_BE16(pos
);
522 if (tlv
->iresult
!= TEAP_STATUS_SUCCESS
&&
523 tlv
->iresult
!= TEAP_STATUS_FAILURE
) {
525 "EAP-TEAP: Unknown Intermediate Result %d",
527 tlv
->iresult
= TEAP_STATUS_FAILURE
;
529 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Intermediate Result: %s",
530 tlv
->iresult
== TEAP_STATUS_SUCCESS
?
531 "Success" : "Failure");
534 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: PAC TLV", pos
, len
);
537 "EAP-TEAP: More than one PAC TLV in the message");
538 tlv
->iresult
= TEAP_STATUS_FAILURE
;
544 case TEAP_TLV_CRYPTO_BINDING
:
545 wpa_hexdump(MSG_MSGDUMP
, "EAP-TEAP: Crypto-Binding TLV",
547 if (tlv
->crypto_binding
) {
549 "EAP-TEAP: More than one Crypto-Binding TLV in the message");
550 tlv
->iresult
= TEAP_STATUS_FAILURE
;
553 tlv
->crypto_binding_len
= sizeof(struct teap_tlv_hdr
) + len
;
554 if (tlv
->crypto_binding_len
< sizeof(*tlv
->crypto_binding
)) {
556 "EAP-TEAP: Too short Crypto-Binding TLV");
557 tlv
->iresult
= TEAP_STATUS_FAILURE
;
560 tlv
->crypto_binding
= (struct teap_tlv_crypto_binding
*)
561 (pos
- sizeof(struct teap_tlv_hdr
));
563 case TEAP_TLV_BASIC_PASSWORD_AUTH_REQ
:
564 wpa_hexdump_ascii(MSG_MSGDUMP
,
565 "EAP-TEAP: Basic-Password-Auth-Req TLV",
567 if (tlv
->basic_auth_req
) {
569 "EAP-TEAP: More than one Basic-Password-Auth-Req TLV in the message");
570 tlv
->iresult
= TEAP_STATUS_FAILURE
;
573 tlv
->basic_auth_req
= pos
;
574 tlv
->basic_auth_req_len
= len
;
576 case TEAP_TLV_BASIC_PASSWORD_AUTH_RESP
:
577 wpa_hexdump_ascii(MSG_MSGDUMP
,
578 "EAP-TEAP: Basic-Password-Auth-Resp TLV",
580 if (tlv
->basic_auth_resp
) {
582 "EAP-TEAP: More than one Basic-Password-Auth-Resp TLV in the message");
583 tlv
->iresult
= TEAP_STATUS_FAILURE
;
586 tlv
->basic_auth_resp
= pos
;
587 tlv
->basic_auth_resp_len
= len
;
598 const char * eap_teap_tlv_type_str(enum teap_tlv_types type
)
601 case TEAP_TLV_AUTHORITY_ID
:
602 return "Authority-ID";
603 case TEAP_TLV_IDENTITY_TYPE
:
604 return "Identity-Type";
605 case TEAP_TLV_RESULT
:
611 case TEAP_TLV_CHANNEL_BINDING
:
612 return "Channel-Binding";
613 case TEAP_TLV_VENDOR_SPECIFIC
:
614 return "Vendor-Specific";
615 case TEAP_TLV_REQUEST_ACTION
:
616 return "Request-Action";
617 case TEAP_TLV_EAP_PAYLOAD
:
618 return "EAP-Payload";
619 case TEAP_TLV_INTERMEDIATE_RESULT
:
620 return "Intermediate-Result";
623 case TEAP_TLV_CRYPTO_BINDING
:
624 return "Crypto-Binding";
625 case TEAP_TLV_BASIC_PASSWORD_AUTH_REQ
:
626 return "Basic-Password-Auth-Req";
627 case TEAP_TLV_BASIC_PASSWORD_AUTH_RESP
:
628 return "Basic-Password-Auth-Resp";
631 case TEAP_TLV_PKCS10
:
633 case TEAP_TLV_TRUSTED_SERVER_ROOT
:
634 return "Trusted-Server-Root";
641 struct wpabuf
* eap_teap_tlv_result(int status
, int intermediate
)
644 struct teap_tlv_result
*result
;
646 if (status
!= TEAP_STATUS_FAILURE
&& status
!= TEAP_STATUS_SUCCESS
)
649 buf
= wpabuf_alloc(sizeof(*result
));
652 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Add %sResult TLV(status=%s)",
653 intermediate
? "Intermediate-" : "",
654 status
== TEAP_STATUS_SUCCESS
? "Success" : "Failure");
655 result
= wpabuf_put(buf
, sizeof(*result
));
656 result
->tlv_type
= host_to_be16(TEAP_TLV_MANDATORY
|
658 TEAP_TLV_INTERMEDIATE_RESULT
:
660 result
->length
= host_to_be16(2);
661 result
->status
= host_to_be16(status
);
666 struct wpabuf
* eap_teap_tlv_error(enum teap_error_codes error
)
670 buf
= wpabuf_alloc(4 + 4);
673 wpa_printf(MSG_DEBUG
, "EAP-TEAP: Add Error TLV(Error Code=%d)",
675 wpabuf_put_be16(buf
, TEAP_TLV_MANDATORY
| TEAP_TLV_ERROR
);
676 wpabuf_put_be16(buf
, 4);
677 wpabuf_put_be32(buf
, error
);
682 int eap_teap_allowed_anon_prov_phase2_method(u8 type
)
684 /* RFC 7170, Section 3.8.3: MUST provide mutual authentication,
685 * provide key generation, and be resistant to dictionary attack.
686 * Section 3.8 also mentions requirement for using EMSK Compound MAC. */
687 return type
== EAP_TYPE_PWD
|| type
== EAP_TYPE_EKE
;
691 int eap_teap_allowed_anon_prov_cipher_suite(u16 cs
)
693 /* RFC 7170, Section 3.8.3: anonymous ciphersuites MAY be supported as
694 * long as the TLS pre-master secret is generated form contribution from
695 * both peers. Accept the recommended TLS_DH_anon_WITH_AES_128_CBC_SHA
696 * cipher suite and other ciphersuites that use DH in some form, have
697 * SHA-1 or stronger MAC function, and use reasonable strong cipher. */
698 static const u16 ok_cs
[] = {
700 0x0034, 0x003a, 0x006c, 0x006d, 0x00a6, 0x00a7,
702 0x0033, 0x0039, 0x0067, 0x006b, 0x009e, 0x009f,
706 0xc003, 0xc00f, 0xc029, 0xc02a, 0xc031, 0xc032,
708 0xc004, 0xc005, 0xc025, 0xc026, 0xc02d, 0xc02e,
710 0xc013, 0xc014, 0xc027, 0xc028, 0xc02f, 0xc030,
712 0xc009, 0xc00a, 0xc023, 0xc024, 0xc02b, 0xc02c,
715 return tls_cipher_suite_match(ok_cs
, ARRAY_SIZE(ok_cs
), cs
);