/** * eap_peer_tls_encrypt - Encrypt phase 2 TLS message * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * @data: Data for TLS processing * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) * @peap_version: Version number for EAP-PEAP/TTLS * @id: EAP identifier for the response * @in_data: Plaintext phase 2 data to encrypt or %NULL to continue fragments * @out_data: Buffer for returning a pointer to the encrypted response message * Returns: 0 on success, -1 on failure */ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, EapType eap_type, int peap_version, u8 id, const struct wpabuf *in_data, struct wpabuf **out_data) { int res; size_t len; if (in_data) { eap_peer_tls_reset_output(data); len = wpabuf_len(in_data) + 300; data->tls_out = os_malloc(len); if (data->tls_out == NULL) return -1; res = tls_connection_encrypt(sm->ssl_ctx, data->conn, wpabuf_head(in_data), wpabuf_len(in_data), data->tls_out, len); if (res < 0) { wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 " "data (in_len=%lu)", (unsigned long) wpabuf_len(in_data)); eap_peer_tls_reset_output(data); return -1; } data->tls_out_len = res; } return eap_tls_process_output(data, eap_type, peap_version, id, 0, out_data); }
static u8 * eap_peap_encrypt(struct eap_sm *sm, struct eap_peap_data *data, int id, u8 *plain, size_t plain_len, size_t *out_len) { int res; u8 *pos; struct eap_hdr *req; /* TODO: add support for fragmentation, if needed. This will need to * add TLS Message Length field, if the frame is fragmented. */ req = malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit); if (req == NULL) return NULL; req->code = EAP_CODE_REQUEST; req->identifier = id; pos = (u8 *) (req + 1); *pos++ = EAP_TYPE_PEAP; *pos++ = data->peap_version; res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn, plain, plain_len, pos, data->ssl.tls_out_limit); if (res < 0) { wpa_printf(MSG_INFO, "EAP-PEAP: Failed to encrypt Phase 2 " "data"); free(req); return NULL; } *out_len = sizeof(struct eap_hdr) + 2 + res; req->length = host_to_be16(*out_len); return (u8 *) req; }
static int eap_peapv2_start_phase2(struct eap_sm *sm, struct eap_peap_data *data) { struct wpabuf *buf, *buf2; int res; wpa_printf(MSG_DEBUG, "EAP-PEAPv2: Phase1 done, include first Phase2 " "payload in the same message"); eap_peap_state(data, PHASE1_ID2); if (eap_peap_phase2_init(sm, data, EAP_TYPE_IDENTITY)) return -1; /* TODO: which Id to use here? */ buf = data->phase2_method->buildReq(sm, data->phase2_priv, 6); if (buf == NULL) return -1; buf2 = eap_peapv2_tlv_eap_payload(buf); if (buf2 == NULL) return -1; wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAPv2: Identity Request", buf2); buf = wpabuf_alloc(data->ssl.tls_out_limit); if (buf == NULL) { wpabuf_free(buf2); return -1; } res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn, wpabuf_head(buf2), wpabuf_len(buf2), wpabuf_put(buf, 0), data->ssl.tls_out_limit); wpabuf_free(buf2); if (res < 0) { wpa_printf(MSG_INFO, "EAP-PEAPv2: Failed to encrypt Phase 2 " "data"); wpabuf_free(buf); return -1; } wpabuf_put(buf, res); wpa_hexdump_buf(MSG_DEBUG, "EAP-PEAPv2: Encrypted Identity Request", buf); /* Append TLS data into the pending buffer after the Server Finished */ if (wpabuf_resize(&data->ssl.out_buf, wpabuf_len(buf)) < 0) { wpabuf_free(buf); return -1; } wpabuf_put_buf(data->ssl.out_buf, buf); wpabuf_free(buf); return 0; }
struct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, const struct wpabuf *plain) { struct wpabuf *buf; buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, plain); if (buf == NULL) { wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); return NULL; } return buf; }
/** * eap_peer_tls_encrypt - Encrypt phase 2 TLS message * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() * @data: Data for TLS processing * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) * @peap_version: Version number for EAP-PEAP/TTLS * @id: EAP identifier for the response * @in_data: Plaintext phase 2 data to encrypt or %NULL to continue fragments * @out_data: Buffer for returning a pointer to the encrypted response message * Returns: 0 on success, -1 on failure */ int eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, EapType eap_type, int peap_version, u8 id, const struct wpabuf *in_data, struct wpabuf **out_data) { if (in_data) { eap_peer_tls_reset_output(data); data->tls_out = tls_connection_encrypt(data->ssl_ctx, data->conn, in_data); if (data->tls_out == NULL) { wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 " "data (in_len=%lu)", (unsigned long) wpabuf_len(in_data)); eap_peer_tls_reset_output(data); return -1; } } return eap_tls_process_output(data, eap_type, peap_version, id, 0, out_data); }
static int eap_ttls_encrypt(struct eap_sm *sm, struct eap_ttls_data *data, int id, const u8 *plain, size_t plain_len, u8 **out_data, size_t *out_len) { int res; u8 *pos; struct eap_hdr *resp; /* TODO: add support for fragmentation, if needed. This will need to * add TLS Message Length field, if the frame is fragmented. */ resp = os_malloc(sizeof(struct eap_hdr) + 2 + data->ssl.tls_out_limit); if (resp == NULL) return -1; resp->code = EAP_CODE_RESPONSE; resp->identifier = id; pos = (u8 *) (resp + 1); *pos++ = EAP_TYPE_TTLS; *pos++ = data->ttls_version; res = tls_connection_encrypt(sm->ssl_ctx, data->ssl.conn, plain, plain_len, pos, data->ssl.tls_out_limit); if (res < 0) { wpa_printf(MSG_INFO, "EAP-TTLS: Failed to encrypt Phase 2 " "data"); os_free(resp); return -1; } *out_len = sizeof(struct eap_hdr) + 2 + res; resp->length = host_to_be16(*out_len); *out_data = (u8 *) resp; return 0; }