summaryrefslogtreecommitdiffstats
path: root/src/include/ipxe/eap.h
blob: a44f01e0a2bef9f0583bc5203787ec3e87ef6606 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#ifndef _IPXE_EAP_H
#define _IPXE_EAP_H

/** @file
 *
 * Extensible Authentication Protocol
 *
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

#include <stdint.h>
#include <ipxe/netdevice.h>
#include <ipxe/timer.h>
#include <ipxe/tables.h>

/** EAP header */
struct eap_header {
	/** Code */
	uint8_t code;
	/** Identifier */
	uint8_t id;
	/** Length */
	uint16_t len;
} __attribute__ (( packed ));

/** EAP request */
#define EAP_CODE_REQUEST 1

/** EAP response */
#define EAP_CODE_RESPONSE 2

/** EAP request/response message */
struct eap_message {
	/** Header */
	struct eap_header hdr;
	/** Type */
	uint8_t type;
	/** Type data */
	uint8_t data[0];
} __attribute__ (( packed ));

/** EAP "no available types" marker */
#define EAP_TYPE_NONE 0

/** EAP identity */
#define EAP_TYPE_IDENTITY 1

/** EAP NAK */
#define EAP_TYPE_NAK 3

/** EAP MD5 challenge request/response */
#define EAP_TYPE_MD5 4

/** EAP MD5 challenge request/response type data */
struct eap_md5 {
	/** Value length */
	uint8_t len;
	/** Value */
	uint8_t value[0];
} __attribute__ (( packed ));

/** EAP MS-CHAPv2 request/response */
#define EAP_TYPE_MSCHAPV2 26

/** EAP MS-CHAPv2 request/response type data */
struct eap_mschapv2 {
	/** Code
	 *
	 * This is in the same namespace as the EAP header's code
	 * field, but is used to extend the handshake by allowing for
	 * "success request" and "success response" packets.
	 */
	uint8_t code;
	/** Identifier
	 *
	 * This field serves no purposes: it always has the same value
	 * as the EAP header's identifier field (located 5 bytes
	 * earlier in the same packet).
	 */
	uint8_t id;
	/** Length
	 *
	 * This field serves no purpose: it always has the same value
	 * as the EAP header's length field (located 5 bytes earlier
	 * in the same packet), minus the 5 byte length of the EAP
	 * header.
	 */
	uint16_t len;
} __attribute__ (( packed ));

/** EAP success */
#define EAP_CODE_SUCCESS 3

/** EAP failure */
#define EAP_CODE_FAILURE 4

/** EAP packet */
union eap_packet {
	/** Header */
	struct eap_header hdr;
	/** Request/response message */
	struct eap_message msg;
};

/** EAP link block timeout
 *
 * We mark the link as blocked upon receiving a Request-Identity, on
 * the basis that this most likely indicates that the switch will not
 * yet be forwarding packets.
 *
 * There is no way to tell how frequently the Request-Identity packet
 * will be retransmitted by the switch.  The default value for Cisco
 * switches seems to be 30 seconds, so treat the link as blocked for
 * 45 seconds.
 */
#define EAP_BLOCK_TIMEOUT ( 45 * TICKS_PER_SEC )

/** EAP protocol wait timeout
 *
 * In the EAP model, the supplicant is a pure responder.  The model
 * also defines no acknowledgement response for the final Success or
 * Failure "requests".  This leaves open the possibility that the
 * final Success or Failure packet is lost, with the supplicant having
 * no way to determine the final authentication status.
 *
 * Sideband mechanisms such as EAPoL-Start may be used to restart the
 * entire EAP process, as a (crude) workaround for this protocol flaw.
 * When expecting to receive a further EAP request (e.g. an
 * authentication challenge), we may wait for some length of time
 * before triggering this restart.  Choose a duration that is shorter
 * than the link block timeout, so that there is no period during
 * which we erroneously leave the link marked as not blocked.
 */
#define EAP_WAIT_TIMEOUT ( EAP_BLOCK_TIMEOUT * 7 / 8 )

/** An EAP supplicant */
struct eap_supplicant {
	/** Network device */
	struct net_device *netdev;
	/** Flags */
	uint16_t flags;
	/** ID for current request/response */
	uint8_t id;
	/** Type for current request/response */
	uint8_t type;
	/**
	 * Transmit EAP response
	 *
	 * @v supplicant	EAP supplicant
	 * @v data		Response data
	 * @v len		Length of response data
	 * @ret rc		Return status code
	 */
	int ( * tx ) ( struct eap_supplicant *supplicant,
		       const void *data, size_t len );
};

/** EAP authentication is in progress
 *
 * This indicates that we have received an EAP Request-Identity, but
 * have not yet received a final EAP Success or EAP Failure.
 */
#define EAP_FL_ONGOING 0x0001

/** EAP supplicant is passive
 *
 * This indicates that the supplicant should not transmit any futher
 * unsolicited packets (e.g. EAPoL-Start for a supplicant running over
 * EAPoL).  This could be because authentication has already
 * completed, or because we are relying upon MAC Authentication Bypass
 * (MAB) which may have a very long timeout.
 */
#define EAP_FL_PASSIVE 0x0002

/** An EAP method */
struct eap_method {
	/** Type */
	uint8_t type;
	/**
	 * Handle EAP request
	 *
	 * @v supplicant	EAP supplicant
	 * @v req		Request type data
	 * @v req_len		Length of request type data
	 * @ret rc		Return status code
	 */
	int ( * rx ) ( struct eap_supplicant *supplicant,
		       const void *req, size_t req_len );
};

/** EAP method table */
#define EAP_METHODS __table ( struct eap_method, "eap_methods" )

/** Declare an EAP method */
#define __eap_method __table_entry ( EAP_METHODS, 01 )

extern int eap_tx_response ( struct eap_supplicant *supplicant,
			     const void *rsp, size_t rsp_len );
extern int eap_rx ( struct eap_supplicant *supplicant,
		    const void *data, size_t len );

#endif /* _IPXE_EAP_H */