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 void eap_teap_put_tlv_hdr(struct wpabuf *buf, u16 type, u16 len)
22 struct teap_tlv_hdr hdr;
24 hdr.tlv_type = host_to_be16(type);
25 hdr.length = host_to_be16(len);
26 wpabuf_put_data(buf, &hdr, sizeof(hdr));
30 void eap_teap_put_tlv(struct wpabuf *buf, u16 type, const void *data, u16 len)
32 eap_teap_put_tlv_hdr(buf, type, len);
33 wpabuf_put_data(buf, data, len);
37 void eap_teap_put_tlv_buf(struct wpabuf *buf, u16 type,
38 const struct wpabuf *data)
40 eap_teap_put_tlv_hdr(buf, type, wpabuf_len(data));
41 wpabuf_put_buf(buf, data);
45 struct wpabuf * eap_teap_tlv_eap_payload(struct wpabuf *buf)
52 /* Encapsulate EAP packet in EAP-Payload TLV */
53 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add EAP-Payload TLV");
54 e = wpabuf_alloc(sizeof(struct teap_tlv_hdr) + wpabuf_len(buf));
57 "EAP-TEAP: Failed to allocate memory for TLV encapsulation");
61 eap_teap_put_tlv_buf(e, TEAP_TLV_MANDATORY | TEAP_TLV_EAP_PAYLOAD, buf);
64 /* TODO: followed by optional TLVs associated with the EAP packet */
70 static int eap_teap_tls_prf(const u8 *secret, size_t secret_len,
71 const char *label, const u8 *seed, size_t seed_len,
72 u8 *out, size_t outlen)
74 /* TODO: TLS-PRF for TLSv1.3 */
75 return tls_prf_sha256(secret, secret_len, label, seed, seed_len,
80 int eap_teap_derive_eap_msk(const u8 *simck, u8 *msk)
83 * RFC 7170, Section 5.4: EAP Master Session Key Generation
84 * MSK = TLS-PRF(S-IMCK[j], "Session Key Generating Function", 64)
87 if (eap_teap_tls_prf(simck, EAP_TEAP_SIMCK_LEN,
88 "Session Key Generating Function", (u8 *) "", 0,
89 msk, EAP_TEAP_KEY_LEN) < 0)
91 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Derived key (MSK)",
92 msk, EAP_TEAP_KEY_LEN);
97 int eap_teap_derive_eap_emsk(const u8 *simck, u8 *emsk)
100 * RFC 7170, Section 5.4: EAP Master Session Key Generation
101 * EMSK = TLS-PRF(S-IMCK[j],
102 * "Extended Session Key Generating Function", 64)
105 if (eap_teap_tls_prf(simck, EAP_TEAP_SIMCK_LEN,
106 "Extended Session Key Generating Function",
107 (u8 *) "", 0, emsk, EAP_EMSK_LEN) < 0)
109 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Derived key (EMSK)",
115 int eap_teap_derive_cmk_basic_pw_auth(const u8 *s_imck_msk, u8 *cmk)
117 u8 imsk[32], imck[EAP_TEAP_IMCK_LEN];
120 /* FIX: The Basic-Password-Auth (i.e., no inner EAP) case is
121 * not fully defined in RFC 7170, so this CMK derivation may
122 * need to be changed if a fixed definition is eventually
123 * published. For now, derive CMK[0] based on S-IMCK[0] and
124 * IMSK of 32 octets of zeros. */
125 os_memset(imsk, 0, 32);
126 res = eap_teap_tls_prf(s_imck_msk, EAP_TEAP_SIMCK_LEN,
127 "Inner Methods Compound Keys",
128 imsk, 32, imck, sizeof(imck));
131 os_memcpy(cmk, &imck[EAP_TEAP_SIMCK_LEN], EAP_TEAP_CMK_LEN);
132 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: CMK[no-inner-EAP]",
133 cmk, EAP_TEAP_CMK_LEN);
134 forced_memzero(imck, sizeof(imck));
139 int eap_teap_derive_imck(const u8 *prev_s_imck_msk, const u8 *prev_s_imck_emsk,
140 const u8 *msk, size_t msk_len,
141 const u8 *emsk, size_t emsk_len,
142 u8 *s_imck_msk, u8 *cmk_msk,
143 u8 *s_imck_emsk, u8 *cmk_emsk)
145 u8 imsk[64], imck[EAP_TEAP_IMCK_LEN];
149 * RFC 7170, Section 5.2:
150 * IMSK = First 32 octets of TLS-PRF(EMSK, "TEAPbindkey@ietf.org" |
152 * (if EMSK is not available, MSK is used instead; if neither is
153 * available, IMSK is 32 octets of zeros; MSK is truncated to 32 octets
154 * or padded to 32 octets, if needed)
155 * (64 is encoded as a 2-octet field in network byte order)
157 * S-IMCK[0] = session_key_seed
158 * IMCK[j] = TLS-PRF(S-IMCK[j-1], "Inner Methods Compound Keys",
160 * S-IMCK[j] = first 40 octets of IMCK[j]
161 * CMK[j] = last 20 octets of IMCK[j]
164 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: MSK[j]", msk, msk_len);
165 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: EMSK[j]", emsk, emsk_len);
167 if (emsk && emsk_len > 0) {
173 if (eap_teap_tls_prf(emsk, emsk_len, "TEAPbindkey@ietf.org",
174 context, sizeof(context), imsk, 64) < 0)
177 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: IMSK from EMSK",
180 res = eap_teap_tls_prf(prev_s_imck_emsk, EAP_TEAP_SIMCK_LEN,
181 "Inner Methods Compound Keys",
182 imsk, 32, imck, EAP_TEAP_IMCK_LEN);
183 forced_memzero(imsk, sizeof(imsk));
187 os_memcpy(s_imck_emsk, imck, EAP_TEAP_SIMCK_LEN);
188 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: EMSK S-IMCK[j]",
189 s_imck_emsk, EAP_TEAP_SIMCK_LEN);
190 os_memcpy(cmk_emsk, &imck[EAP_TEAP_SIMCK_LEN],
192 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: EMSK CMK[j]",
193 cmk_emsk, EAP_TEAP_CMK_LEN);
194 forced_memzero(imck, EAP_TEAP_IMCK_LEN);
197 if (msk && msk_len > 0) {
198 size_t copy_len = msk_len;
200 os_memset(imsk, 0, 32); /* zero pad, if needed */
203 os_memcpy(imsk, msk, copy_len);
204 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: IMSK from MSK", imsk, 32);
206 os_memset(imsk, 0, 32);
207 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: Zero IMSK", imsk, 32);
210 res = eap_teap_tls_prf(prev_s_imck_msk, EAP_TEAP_SIMCK_LEN,
211 "Inner Methods Compound Keys",
212 imsk, 32, imck, EAP_TEAP_IMCK_LEN);
213 forced_memzero(imsk, sizeof(imsk));
217 os_memcpy(s_imck_msk, imck, EAP_TEAP_SIMCK_LEN);
218 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: MSK S-IMCK[j]",
219 s_imck_msk, EAP_TEAP_SIMCK_LEN);
220 os_memcpy(cmk_msk, &imck[EAP_TEAP_SIMCK_LEN], EAP_TEAP_CMK_LEN);
221 wpa_hexdump_key(MSG_DEBUG, "EAP-TEAP: MSK CMK[j]",
222 cmk_msk, EAP_TEAP_CMK_LEN);
223 forced_memzero(imck, EAP_TEAP_IMCK_LEN);
229 static int tls_cipher_suite_match(const u16 *list, size_t count, u16 cs)
233 for (i = 0; i < count; i++) {
242 static int tls_cipher_suite_mac_sha1(u16 cs)
244 static const u16 sha1_cs[] = {
245 0x0005, 0x0007, 0x000a, 0x000d, 0x0010, 0x0013, 0x0016, 0x001b,
246 0x002f, 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036,
247 0x0037, 0x0038, 0x0039, 0x003a, 0x0041, 0x0042, 0x0043, 0x0044,
248 0x0045, 0x0046, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089,
249 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, 0x0090, 0x0091,
250 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099,
252 0xc002, 0xc003, 0xc004, 0xc005, 0xc007, 0xc008, 0xc009, 0xc009,
253 0xc00a, 0xc00c, 0xc00d, 0xc00e, 0xc00f, 0xc011, 0xc012, 0xc013,
254 0xc014, 0xc016, 0xc017, 0xc018, 0xc019, 0xc01a, 0xc01b, 0xc01c,
255 0xc014, 0xc01e, 0xc01f, 0xc020, 0xc021, 0xc022, 0xc033, 0xc034,
259 return tls_cipher_suite_match(sha1_cs, ARRAY_SIZE(sha1_cs), cs);
263 static int tls_cipher_suite_mac_sha256(u16 cs)
265 static const u16 sha256_cs[] = {
266 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0067, 0x0068, 0x0069,
267 0x006a, 0x006b, 0x006c, 0x006d, 0x009c, 0x009e, 0x00a0, 0x00a2,
268 0x00a4, 0x00a6, 0x00a8, 0x00aa, 0x00ac, 0x00ae, 0x00b2, 0x00b6,
269 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bd, 0x00be, 0x00be,
270 0x00bf, 0x00bf, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5,
271 0x1301, 0x1303, 0x1304, 0x1305,
272 0xc023, 0xc025, 0xc027, 0xc029, 0xc02b, 0xc02d, 0xc02f, 0xc031,
273 0xc037, 0xc03c, 0xc03e, 0xc040, 0xc040, 0xc042, 0xc044, 0xc046,
274 0xc048, 0xc04a, 0xc04c, 0xc04e, 0xc050, 0xc052, 0xc054, 0xc056,
275 0xc058, 0xc05a, 0xc05c, 0xc05e, 0xc060, 0xc062, 0xc064, 0xc066,
276 0xc068, 0xc06a, 0xc06c, 0xc06e, 0xc070, 0xc072, 0xc074, 0xc076,
277 0xc078, 0xc07a, 0xc07c, 0xc07e, 0xc080, 0xc082, 0xc084, 0xc086,
278 0xc088, 0xc08a, 0xc08c, 0xc08e, 0xc090, 0xc092, 0xc094, 0xc096,
279 0xc098, 0xc09a, 0xc0b0, 0xc0b2, 0xc0b4,
280 0xcca8, 0xcca9, 0xccaa, 0xccab, 0xccac, 0xccad, 0xccae,
281 0xd001, 0xd003, 0xd005
284 return tls_cipher_suite_match(sha256_cs, ARRAY_SIZE(sha256_cs), cs);
288 static int tls_cipher_suite_mac_sha384(u16 cs)
290 static const u16 sha384_cs[] = {
291 0x009d, 0x009f, 0x00a1, 0x00a3, 0x00a5, 0x00a7, 0x00a9, 0x00ab,
292 0x00ad, 0x00af, 0x00b3, 0x00b7, 0x1302,
293 0xc024, 0xc026, 0xc028, 0xc02a, 0xc02c, 0xc02e, 0xc030, 0xc032,
294 0xc038, 0xc03d, 0xc03f, 0xc041, 0xc043, 0xc045, 0xc047, 0xc049,
295 0xc04b, 0xc04d, 0xc04f, 0xc051, 0xc053, 0xc055, 0xc057, 0xc059,
296 0xc05b, 0xc05d, 0xc05f, 0xc061, 0xc063, 0xc065, 0xc067, 0xc069,
297 0xc06b, 0xc06d, 0xc06f, 0xc071, 0xc073, 0xc075, 0xc077, 0xc079,
298 0xc07b, 0xc07d, 0xc07f, 0xc081, 0xc083, 0xc085, 0xc087, 0xc089,
299 0xc08b, 0xc08d, 0xc08f, 0xc091, 0xc093, 0xc095, 0xc097, 0xc099,
300 0xc09b, 0xc0b1, 0xc0b3, 0xc0b5,
304 return tls_cipher_suite_match(sha384_cs, ARRAY_SIZE(sha384_cs), cs);
308 static int eap_teap_tls_mac(u16 tls_cs, const u8 *cmk, size_t cmk_len,
309 const u8 *buffer, size_t buffer_len,
310 u8 *mac, size_t mac_len)
315 os_memset(tmp, 0, sizeof(tmp));
316 os_memset(mac, 0, mac_len);
318 if (tls_cipher_suite_mac_sha1(tls_cs)) {
319 wpa_printf(MSG_DEBUG, "EAP-TEAP: MAC algorithm: HMAC-SHA1");
320 res = hmac_sha1(cmk, cmk_len, buffer, buffer_len, tmp);
321 } else if (tls_cipher_suite_mac_sha256(tls_cs)) {
322 wpa_printf(MSG_DEBUG, "EAP-TEAP: MAC algorithm: HMAC-SHA256");
323 res = hmac_sha256(cmk, cmk_len, buffer, buffer_len, tmp);
324 } else if (tls_cipher_suite_mac_sha384(tls_cs)) {
325 wpa_printf(MSG_DEBUG, "EAP-TEAP: MAC algorithm: HMAC-SHA384");
326 res = hmac_sha384(cmk, cmk_len, buffer, buffer_len, tmp);
329 "EAP-TEAP: Unsupported TLS cipher suite 0x%04x",
336 /* FIX: RFC 7170 does not describe how to handle truncation of the
337 * Compound MAC or if the fields are supposed to be of variable length
338 * based on the negotiated TLS cipher suite (they are defined as having
339 * fixed size of 20 octets in the TLV description) */
340 if (mac_len > sizeof(tmp))
341 mac_len = sizeof(tmp);
342 os_memcpy(mac, tmp, mac_len);
347 int eap_teap_compound_mac(u16 tls_cs, const struct teap_tlv_crypto_binding *cb,
348 const struct wpabuf *server_outer_tlvs,
349 const struct wpabuf *peer_outer_tlvs,
350 const u8 *cmk, u8 *compound_mac)
353 size_t bind_len, buffer_len;
354 struct teap_tlv_crypto_binding *tmp_cb;
357 /* RFC 7170, Section 5.3 */
358 bind_len = sizeof(struct teap_tlv_hdr) + be_to_host16(cb->length);
359 buffer_len = bind_len + 1;
360 if (server_outer_tlvs)
361 buffer_len += wpabuf_len(server_outer_tlvs);
363 buffer_len += wpabuf_len(peer_outer_tlvs);
364 buffer = os_malloc(buffer_len);
369 /* 1. The entire Crypto-Binding TLV attribute with both the EMSK and MSK
370 * Compound MAC fields zeroed out. */
371 os_memcpy(pos, cb, bind_len);
373 tmp_cb = (struct teap_tlv_crypto_binding *) buffer;
374 os_memset(tmp_cb->emsk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
375 os_memset(tmp_cb->msk_compound_mac, 0, EAP_TEAP_COMPOUND_MAC_LEN);
377 /* 2. The EAP Type sent by the other party in the first TEAP message. */
378 /* This is supposed to be the EAP Type sent by the other party in the
379 * first TEAP message, but since we cannot get here without having
380 * successfully negotiated use of TEAP, this can only be the fixed EAP
382 *pos++ = EAP_TYPE_TEAP;
384 /* 3. All the Outer TLVs from the first TEAP message sent by EAP server
386 if (server_outer_tlvs) {
387 os_memcpy(pos, wpabuf_head(server_outer_tlvs),
388 wpabuf_len(server_outer_tlvs));
389 pos += wpabuf_len(server_outer_tlvs);
392 /* 4. All the Outer TLVs from the first TEAP message sent by the peer to
394 if (peer_outer_tlvs) {
395 os_memcpy(pos, wpabuf_head(peer_outer_tlvs),
396 wpabuf_len(peer_outer_tlvs));
397 pos += wpabuf_len(peer_outer_tlvs);
400 buffer_len = pos - buffer;
402 wpa_hexdump_key(MSG_MSGDUMP,
403 "EAP-TEAP: CMK for Compound MAC calculation",
404 cmk, EAP_TEAP_CMK_LEN);
405 wpa_hexdump(MSG_MSGDUMP,
406 "EAP-TEAP: BUFFER for Compound MAC calculation",
408 res = eap_teap_tls_mac(tls_cs, cmk, EAP_TEAP_CMK_LEN,
410 compound_mac, EAP_TEAP_COMPOUND_MAC_LEN);
417 int eap_teap_parse_tlv(struct eap_teap_tlv_parse *tlv,
418 int tlv_type, u8 *pos, size_t len)
421 case TEAP_TLV_RESULT:
422 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Result TLV", pos, len);
425 "EAP-TEAP: More than one Result TLV in the message");
426 tlv->result = TEAP_STATUS_FAILURE;
430 wpa_printf(MSG_INFO, "EAP-TEAP: Too short Result TLV");
431 tlv->result = TEAP_STATUS_FAILURE;
434 tlv->result = WPA_GET_BE16(pos);
435 if (tlv->result != TEAP_STATUS_SUCCESS &&
436 tlv->result != TEAP_STATUS_FAILURE) {
437 wpa_printf(MSG_INFO, "EAP-TEAP: Unknown Result %d",
439 tlv->result = TEAP_STATUS_FAILURE;
441 wpa_printf(MSG_DEBUG, "EAP-TEAP: Result: %s",
442 tlv->result == TEAP_STATUS_SUCCESS ?
443 "Success" : "Failure");
446 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: NAK TLV", pos, len);
448 wpa_printf(MSG_INFO, "EAP-TEAP: Too short NAK TLV");
449 tlv->result = TEAP_STATUS_FAILURE;
455 case TEAP_TLV_REQUEST_ACTION:
456 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Request-Action TLV",
458 if (tlv->request_action) {
460 "EAP-TEAP: More than one Request-Action TLV in the message");
461 tlv->iresult = TEAP_STATUS_FAILURE;
466 "EAP-TEAP: Too short Request-Action TLV");
467 tlv->iresult = TEAP_STATUS_FAILURE;
470 tlv->request_action_status = pos[0];
471 tlv->request_action = pos[1];
472 wpa_printf(MSG_DEBUG,
473 "EAP-TEAP: Request-Action: Status=%u Action=%u",
474 tlv->request_action_status, tlv->request_action);
476 case TEAP_TLV_EAP_PAYLOAD:
477 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: EAP-Payload TLV",
479 if (tlv->eap_payload_tlv) {
481 "EAP-TEAP: More than one EAP-Payload TLV in the message");
482 tlv->iresult = TEAP_STATUS_FAILURE;
485 tlv->eap_payload_tlv = pos;
486 tlv->eap_payload_tlv_len = len;
488 case TEAP_TLV_INTERMEDIATE_RESULT:
489 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Intermediate-Result TLV",
493 "EAP-TEAP: Too short Intermediate-Result TLV");
494 tlv->iresult = TEAP_STATUS_FAILURE;
499 "EAP-TEAP: More than one Intermediate-Result TLV in the message");
500 tlv->iresult = TEAP_STATUS_FAILURE;
503 tlv->iresult = WPA_GET_BE16(pos);
504 if (tlv->iresult != TEAP_STATUS_SUCCESS &&
505 tlv->iresult != TEAP_STATUS_FAILURE) {
507 "EAP-TEAP: Unknown Intermediate Result %d",
509 tlv->iresult = TEAP_STATUS_FAILURE;
511 wpa_printf(MSG_DEBUG, "EAP-TEAP: Intermediate Result: %s",
512 tlv->iresult == TEAP_STATUS_SUCCESS ?
513 "Success" : "Failure");
516 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: PAC TLV", pos, len);
519 "EAP-TEAP: More than one PAC TLV in the message");
520 tlv->iresult = TEAP_STATUS_FAILURE;
526 case TEAP_TLV_CRYPTO_BINDING:
527 wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: Crypto-Binding TLV",
529 if (tlv->crypto_binding) {
531 "EAP-TEAP: More than one Crypto-Binding TLV in the message");
532 tlv->iresult = TEAP_STATUS_FAILURE;
535 tlv->crypto_binding_len = sizeof(struct teap_tlv_hdr) + len;
536 if (tlv->crypto_binding_len < sizeof(*tlv->crypto_binding)) {
538 "EAP-TEAP: Too short Crypto-Binding TLV");
539 tlv->iresult = TEAP_STATUS_FAILURE;
542 tlv->crypto_binding = (struct teap_tlv_crypto_binding *)
543 (pos - sizeof(struct teap_tlv_hdr));
545 case TEAP_TLV_BASIC_PASSWORD_AUTH_REQ:
546 wpa_hexdump_ascii(MSG_MSGDUMP,
547 "EAP-TEAP: Basic-Password-Auth-Req TLV",
549 if (tlv->basic_auth_req) {
551 "EAP-TEAP: More than one Basic-Password-Auth-Req TLV in the message");
552 tlv->iresult = TEAP_STATUS_FAILURE;
555 tlv->basic_auth_req = pos;
556 tlv->basic_auth_req_len = len;
558 case TEAP_TLV_BASIC_PASSWORD_AUTH_RESP:
559 wpa_hexdump_ascii(MSG_MSGDUMP,
560 "EAP-TEAP: Basic-Password-Auth-Resp TLV",
562 if (tlv->basic_auth_resp) {
564 "EAP-TEAP: More than one Basic-Password-Auth-Resp TLV in the message");
565 tlv->iresult = TEAP_STATUS_FAILURE;
568 tlv->basic_auth_resp = pos;
569 tlv->basic_auth_resp_len = len;
580 const char * eap_teap_tlv_type_str(enum teap_tlv_types type)
583 case TEAP_TLV_AUTHORITY_ID:
584 return "Authority-ID";
585 case TEAP_TLV_IDENTITY_TYPE:
586 return "Identity-Type";
587 case TEAP_TLV_RESULT:
593 case TEAP_TLV_CHANNEL_BINDING:
594 return "Channel-Binding";
595 case TEAP_TLV_VENDOR_SPECIFIC:
596 return "Vendor-Specific";
597 case TEAP_TLV_REQUEST_ACTION:
598 return "Request-Action";
599 case TEAP_TLV_EAP_PAYLOAD:
600 return "EAP-Payload";
601 case TEAP_TLV_INTERMEDIATE_RESULT:
602 return "Intermediate-Result";
605 case TEAP_TLV_CRYPTO_BINDING:
606 return "Crypto-Binding";
607 case TEAP_TLV_BASIC_PASSWORD_AUTH_REQ:
608 return "Basic-Password-Auth-Req";
609 case TEAP_TLV_BASIC_PASSWORD_AUTH_RESP:
610 return "Basic-Password-Auth-Resp";
613 case TEAP_TLV_PKCS10:
615 case TEAP_TLV_TRUSTED_SERVER_ROOT:
616 return "Trusted-Server-Root";
623 struct wpabuf * eap_teap_tlv_result(int status, int intermediate)
626 struct teap_tlv_result *result;
628 if (status != TEAP_STATUS_FAILURE && status != TEAP_STATUS_SUCCESS)
631 buf = wpabuf_alloc(sizeof(*result));
634 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add %sResult TLV(status=%s)",
635 intermediate ? "Intermediate-" : "",
636 status == TEAP_STATUS_SUCCESS ? "Success" : "Failure");
637 result = wpabuf_put(buf, sizeof(*result));
638 result->tlv_type = host_to_be16(TEAP_TLV_MANDATORY |
640 TEAP_TLV_INTERMEDIATE_RESULT :
642 result->length = host_to_be16(2);
643 result->status = host_to_be16(status);
648 struct wpabuf * eap_teap_tlv_error(enum teap_error_codes error)
652 buf = wpabuf_alloc(4 + 4);
655 wpa_printf(MSG_DEBUG, "EAP-TEAP: Add Error TLV(Error Code=%d)",
657 wpabuf_put_be16(buf, TEAP_TLV_MANDATORY | TEAP_TLV_ERROR);
658 wpabuf_put_be16(buf, 4);
659 wpabuf_put_be32(buf, error);
664 int eap_teap_allowed_anon_prov_phase2_method(u8 type)
666 /* RFC 7170, Section 3.8.3: MUST provide mutual authentication,
667 * provide key generation, and be resistant to dictionary attack.
668 * Section 3.8 also mentions requirement for using EMSK Compound MAC. */
669 return type == EAP_TYPE_PWD || type == EAP_TYPE_EKE;
673 int eap_teap_allowed_anon_prov_cipher_suite(u16 cs)
675 /* RFC 7170, Section 3.8.3: anonymous ciphersuites MAY be supported as
676 * long as the TLS pre-master secret is generated form contribution from
677 * both peers. Accept the recommended TLS_DH_anon_WITH_AES_128_CBC_SHA
678 * cipher suite and other ciphersuites that use DH in some form, have
679 * SHA-1 or stronger MAC function, and use reasonable strong cipher. */
680 static const u16 ok_cs[] = {
682 0x0034, 0x003a, 0x006c, 0x006d, 0x00a6, 0x00a7,
684 0x0033, 0x0039, 0x0067, 0x006b, 0x009e, 0x009f,
688 0xc003, 0xc00f, 0xc029, 0xc02a, 0xc031, 0xc032,
690 0xc004, 0xc005, 0xc025, 0xc026, 0xc02d, 0xc02e,
692 0xc013, 0xc014, 0xc027, 0xc028, 0xc02f, 0xc030,
694 0xc009, 0xc00a, 0xc023, 0xc024, 0xc02b, 0xc02c,
697 return tls_cipher_suite_match(ok_cs, ARRAY_SIZE(ok_cs), cs);