1275970Scy/*
2275970Scy * IKEv2 definitions
3275970Scy * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
4275970Scy *
5275970Scy * This software may be distributed under the terms of the BSD license.
6275970Scy * See README for more details.
7275970Scy */
8275970Scy
9275970Scy#ifndef IKEV2_COMMON_H
10275970Scy#define IKEV2_COMMON_H
11275970Scy
12275970Scy/*
13275970Scy * Nonce length must be at least 16 octets. It must also be at least half the
14275970Scy * key size of the negotiated PRF.
15275970Scy */
16275970Scy#define IKEV2_NONCE_MIN_LEN 16
17275970Scy#define IKEV2_NONCE_MAX_LEN 256
18275970Scy
19275970Scy/* IKE Header - RFC 4306, Sect. 3.1 */
20275970Scy#ifdef _MSC_VER
21275970Scy#pragma pack(push, 1)
22275970Scy#endif /* _MSC_VER */
23275970Scy
24275970Scy#define IKEV2_SPI_LEN 8
25275970Scy
26275970Scystruct ikev2_hdr {
27275970Scy	u8 i_spi[IKEV2_SPI_LEN]; /* IKE_SA Initiator's SPI */
28275970Scy	u8 r_spi[IKEV2_SPI_LEN]; /* IKE_SA Responder's SPI */
29275970Scy	u8 next_payload;
30275970Scy	u8 version; /* MjVer | MnVer */
31275970Scy	u8 exchange_type;
32275970Scy	u8 flags;
33275970Scy	u8 message_id[4];
34275970Scy	u8 length[4]; /* total length of HDR + payloads */
35275970Scy} STRUCT_PACKED;
36275970Scy
37275970Scystruct ikev2_payload_hdr {
38275970Scy	u8 next_payload;
39275970Scy	u8 flags;
40275970Scy	u8 payload_length[2]; /* this payload, including the payload header */
41275970Scy} STRUCT_PACKED;
42275970Scy
43275970Scystruct ikev2_proposal {
44275970Scy	u8 type; /* 0 (last) or 2 (more) */
45275970Scy	u8 reserved;
46275970Scy	u8 proposal_length[2]; /* including all transform and attributes */
47275970Scy	u8 proposal_num;
48275970Scy	u8 protocol_id; /* IKEV2_PROTOCOL_* */
49275970Scy	u8 spi_size;
50275970Scy	u8 num_transforms;
51275970Scy	/* SPI of spi_size octets */
52275970Scy	/* Transforms */
53275970Scy} STRUCT_PACKED;
54275970Scy
55275970Scystruct ikev2_transform {
56275970Scy	u8 type; /* 0 (last) or 3 (more) */
57275970Scy	u8 reserved;
58275970Scy	u8 transform_length[2]; /* including Header and Attributes */
59275970Scy	u8 transform_type;
60275970Scy	u8 reserved2;
61275970Scy	u8 transform_id[2];
62275970Scy	/* Transform Attributes */
63275970Scy} STRUCT_PACKED;
64275970Scy
65275970Scy#ifdef _MSC_VER
66275970Scy#pragma pack(pop)
67275970Scy#endif /* _MSC_VER */
68275970Scy
69275970Scy
70275970Scy/* Current IKEv2 version from RFC 4306 */
71275970Scy#define IKEV2_MjVer 2
72275970Scy#define IKEV2_MnVer 0
73275970Scy#ifdef CCNS_PL
74275970Scy#define IKEV2_VERSION ((IKEV2_MjVer) | ((IKEV2_MnVer) << 4))
75275970Scy#else /* CCNS_PL */
76275970Scy#define IKEV2_VERSION (((IKEV2_MjVer) << 4) | (IKEV2_MnVer))
77275970Scy#endif /* CCNS_PL */
78275970Scy
79275970Scy/* IKEv2 Exchange Types */
80275970Scyenum {
81275970Scy	/* 0-33 RESERVED */
82275970Scy	IKE_SA_INIT = 34,
83275970Scy	IKE_SA_AUTH = 35,
84275970Scy	CREATE_CHILD_SA = 36,
85275970Scy	INFORMATION = 37
86275970Scy	/* 38-239 RESERVED TO IANA */
87275970Scy	/* 240-255 Reserved for private use */
88275970Scy};
89275970Scy
90275970Scy/* IKEv2 Flags */
91275970Scy#define IKEV2_HDR_INITIATOR	0x08
92275970Scy#define IKEV2_HDR_VERSION	0x10
93275970Scy#define IKEV2_HDR_RESPONSE	0x20
94275970Scy
95275970Scy/* Payload Header Flags */
96275970Scy#define IKEV2_PAYLOAD_FLAGS_CRITICAL 0x01
97275970Scy
98275970Scy
99275970Scy/* EAP-IKEv2 Payload Types (in Next Payload Type field)
100275970Scy * http://www.iana.org/assignments/eap-ikev2-payloads */
101275970Scyenum {
102275970Scy	IKEV2_PAYLOAD_NO_NEXT_PAYLOAD = 0,
103275970Scy	IKEV2_PAYLOAD_SA = 33,
104275970Scy	IKEV2_PAYLOAD_KEY_EXCHANGE = 34,
105275970Scy	IKEV2_PAYLOAD_IDi = 35,
106275970Scy	IKEV2_PAYLOAD_IDr = 36,
107275970Scy	IKEV2_PAYLOAD_CERTIFICATE = 37,
108275970Scy	IKEV2_PAYLOAD_CERT_REQ = 38,
109275970Scy	IKEV2_PAYLOAD_AUTHENTICATION = 39,
110275970Scy	IKEV2_PAYLOAD_NONCE = 40,
111275970Scy	IKEV2_PAYLOAD_NOTIFICATION = 41,
112275970Scy	IKEV2_PAYLOAD_VENDOD_ID = 43,
113275970Scy	IKEV2_PAYLOAD_ENCRYPTED = 46,
114275970Scy	IKEV2_PAYLOAD_NEXT_FAST_ID = 121
115275970Scy};
116275970Scy
117275970Scy
118275970Scy/* IKEv2 Proposal - Protocol ID */
119275970Scyenum {
120275970Scy	IKEV2_PROTOCOL_RESERVED = 0,
121275970Scy	IKEV2_PROTOCOL_IKE = 1, /* IKE is the only one allowed for EAP-IKEv2 */
122275970Scy	IKEV2_PROTOCOL_AH = 2,
123275970Scy	IKEV2_PROTOCOL_ESP = 3
124275970Scy};
125275970Scy
126275970Scy
127275970Scy/* IKEv2 Transform Types */
128275970Scyenum {
129275970Scy	IKEV2_TRANSFORM_ENCR = 1,
130275970Scy	IKEV2_TRANSFORM_PRF = 2,
131275970Scy	IKEV2_TRANSFORM_INTEG = 3,
132275970Scy	IKEV2_TRANSFORM_DH = 4,
133275970Scy	IKEV2_TRANSFORM_ESN = 5
134275970Scy};
135275970Scy
136275970Scy/* IKEv2 Transform Type 1 (Encryption Algorithm) */
137275970Scyenum {
138275970Scy	ENCR_DES_IV64 = 1,
139275970Scy	ENCR_DES = 2,
140275970Scy	ENCR_3DES = 3,
141275970Scy	ENCR_RC5 = 4,
142275970Scy	ENCR_IDEA = 5,
143275970Scy	ENCR_CAST = 6,
144275970Scy	ENCR_BLOWFISH = 7,
145275970Scy	ENCR_3IDEA = 8,
146275970Scy	ENCR_DES_IV32 = 9,
147275970Scy	ENCR_NULL = 11,
148275970Scy	ENCR_AES_CBC = 12,
149275970Scy	ENCR_AES_CTR = 13
150275970Scy};
151275970Scy
152275970Scy/* IKEv2 Transform Type 2 (Pseudo-random Function) */
153275970Scyenum {
154275970Scy	PRF_HMAC_MD5 = 1,
155275970Scy	PRF_HMAC_SHA1 = 2,
156275970Scy	PRF_HMAC_TIGER = 3,
157275970Scy	PRF_AES128_XCBC = 4
158275970Scy};
159275970Scy
160275970Scy/* IKEv2 Transform Type 3 (Integrity Algorithm) */
161275970Scyenum {
162275970Scy	AUTH_HMAC_MD5_96 = 1,
163275970Scy	AUTH_HMAC_SHA1_96 = 2,
164275970Scy	AUTH_DES_MAC = 3,
165275970Scy	AUTH_KPDK_MD5 = 4,
166275970Scy	AUTH_AES_XCBC_96 = 5
167275970Scy};
168275970Scy
169275970Scy/* IKEv2 Transform Type 4 (Diffie-Hellman Group) */
170275970Scyenum {
171275970Scy	DH_GROUP1_768BIT_MODP = 1, /* RFC 4306 */
172275970Scy	DH_GROUP2_1024BIT_MODP = 2, /* RFC 4306 */
173275970Scy	DH_GROUP5_1536BIT_MODP = 5, /* RFC 3526 */
174275970Scy	DH_GROUP5_2048BIT_MODP = 14, /* RFC 3526 */
175275970Scy	DH_GROUP5_3072BIT_MODP = 15, /* RFC 3526 */
176275970Scy	DH_GROUP5_4096BIT_MODP = 16, /* RFC 3526 */
177275970Scy	DH_GROUP5_6144BIT_MODP = 17, /* RFC 3526 */
178275970Scy	DH_GROUP5_8192BIT_MODP = 18 /* RFC 3526 */
179275970Scy};
180275970Scy
181275970Scy
182275970Scy/* Identification Data Types (RFC 4306, Sect. 3.5) */
183275970Scyenum {
184275970Scy	ID_IPV4_ADDR = 1,
185275970Scy	ID_FQDN = 2,
186275970Scy	ID_RFC822_ADDR = 3,
187275970Scy	ID_IPV6_ADDR = 5,
188275970Scy	ID_DER_ASN1_DN = 9,
189275970Scy	ID_DER_ASN1_GN= 10,
190275970Scy	ID_KEY_ID = 11
191275970Scy};
192275970Scy
193275970Scy
194275970Scy/* Certificate Encoding (RFC 4306, Sect. 3.6) */
195275970Scyenum {
196275970Scy	CERT_ENCODING_PKCS7_X509 = 1,
197275970Scy	CERT_ENCODING_PGP_CERT = 2,
198275970Scy	CERT_ENCODING_DNS_SIGNED_KEY = 3,
199275970Scy	/* X.509 Certificate - Signature: DER encoded X.509 certificate whose
200275970Scy	 * public key is used to validate the sender's AUTH payload */
201275970Scy	CERT_ENCODING_X509_CERT_SIGN = 4,
202275970Scy	CERT_ENCODING_KERBEROS_TOKEN = 6,
203275970Scy	/* DER encoded X.509 certificate revocation list */
204275970Scy	CERT_ENCODING_CRL = 7,
205275970Scy	CERT_ENCODING_ARL = 8,
206275970Scy	CERT_ENCODING_SPKI_CERT = 9,
207275970Scy	CERT_ENCODING_X509_CERT_ATTR = 10,
208275970Scy	/* PKCS #1 encoded RSA key */
209275970Scy	CERT_ENCODING_RAW_RSA_KEY = 11,
210275970Scy	CERT_ENCODING_HASH_AND_URL_X509_CERT = 12,
211275970Scy	CERT_ENCODING_HASH_AND_URL_X509_BUNDLE = 13
212275970Scy};
213275970Scy
214275970Scy
215275970Scy/* Authentication Method (RFC 4306, Sect. 3.8) */
216275970Scyenum {
217275970Scy	AUTH_RSA_SIGN = 1,
218275970Scy	AUTH_SHARED_KEY_MIC = 2,
219275970Scy	AUTH_DSS_SIGN = 3
220275970Scy};
221275970Scy
222275970Scy
223275970Scy/* Notify Message Types (RFC 4306, Sect. 3.10.1) */
224275970Scyenum {
225275970Scy	UNSUPPORTED_CRITICAL_PAYLOAD = 1,
226275970Scy	INVALID_IKE_SPI = 4,
227275970Scy	INVALID_MAJOR_VERSION = 5,
228275970Scy	INVALID_SYNTAX = 7,
229275970Scy	INVALID_MESSAGE_ID = 9,
230275970Scy	INVALID_SPI = 11,
231275970Scy	NO_PROPOSAL_CHOSEN = 14,
232275970Scy	INVALID_KE_PAYLOAD = 17,
233275970Scy	AUTHENTICATION_FAILED = 24,
234275970Scy	SINGLE_PAIR_REQUIRED = 34,
235275970Scy	NO_ADDITIONAL_SAS = 35,
236275970Scy	INTERNAL_ADDRESS_FAILURE = 36,
237275970Scy	FAILED_CP_REQUIRED = 37,
238275970Scy	TS_UNACCEPTABLE = 38,
239275970Scy	INVALID_SELECTORS = 39
240275970Scy};
241275970Scy
242275970Scy
243275970Scystruct ikev2_keys {
244275970Scy	u8 *SK_d, *SK_ai, *SK_ar, *SK_ei, *SK_er, *SK_pi, *SK_pr;
245275970Scy	size_t SK_d_len, SK_integ_len, SK_encr_len, SK_prf_len;
246275970Scy};
247275970Scy
248275970Scy
249275970Scyint ikev2_keys_set(struct ikev2_keys *keys);
250275970Scyvoid ikev2_free_keys(struct ikev2_keys *keys);
251275970Scy
252275970Scy
253275970Scy/* Maximum hash length for supported hash algorithms */
254275970Scy#define IKEV2_MAX_HASH_LEN 20
255275970Scy
256275970Scystruct ikev2_integ_alg {
257275970Scy	int id;
258275970Scy	size_t key_len;
259275970Scy	size_t hash_len;
260275970Scy};
261275970Scy
262275970Scystruct ikev2_prf_alg {
263275970Scy	int id;
264275970Scy	size_t key_len;
265275970Scy	size_t hash_len;
266275970Scy};
267275970Scy
268275970Scystruct ikev2_encr_alg {
269275970Scy	int id;
270275970Scy	size_t key_len;
271275970Scy	size_t block_size;
272275970Scy};
273275970Scy
274275970Scyconst struct ikev2_integ_alg * ikev2_get_integ(int id);
275275970Scyint ikev2_integ_hash(int alg, const u8 *key, size_t key_len, const u8 *data,
276275970Scy		     size_t data_len, u8 *hash);
277275970Scyconst struct ikev2_prf_alg * ikev2_get_prf(int id);
278275970Scyint ikev2_prf_hash(int alg, const u8 *key, size_t key_len,
279275970Scy		   size_t num_elem, const u8 *addr[], const size_t *len,
280275970Scy		   u8 *hash);
281275970Scyint ikev2_prf_plus(int alg, const u8 *key, size_t key_len,
282275970Scy		   const u8 *data, size_t data_len,
283275970Scy		   u8 *out, size_t out_len);
284275970Scyconst struct ikev2_encr_alg * ikev2_get_encr(int id);
285275970Scyint ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
286275970Scy		       const u8 *plain, u8 *crypt, size_t len);
287275970Scyint ikev2_encr_decrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
288275970Scy		       const u8 *crypt, u8 *plain, size_t len);
289275970Scy
290275970Scyint ikev2_derive_auth_data(int prf_alg, const struct wpabuf *sign_msg,
291275970Scy			   const u8 *ID, size_t ID_len, u8 ID_type,
292275970Scy			   struct ikev2_keys *keys, int initiator,
293275970Scy			   const u8 *shared_secret, size_t shared_secret_len,
294275970Scy			   const u8 *nonce, size_t nonce_len,
295275970Scy			   const u8 *key_pad, size_t key_pad_len,
296275970Scy			   u8 *auth_data);
297275970Scy
298275970Scy
299275970Scystruct ikev2_payloads {
300275970Scy	const u8 *sa;
301275970Scy	size_t sa_len;
302275970Scy	const u8 *ke;
303275970Scy	size_t ke_len;
304275970Scy	const u8 *idi;
305275970Scy	size_t idi_len;
306275970Scy	const u8 *idr;
307275970Scy	size_t idr_len;
308275970Scy	const u8 *cert;
309275970Scy	size_t cert_len;
310275970Scy	const u8 *auth;
311275970Scy	size_t auth_len;
312275970Scy	const u8 *nonce;
313275970Scy	size_t nonce_len;
314275970Scy	const u8 *encrypted;
315275970Scy	size_t encrypted_len;
316275970Scy	u8 encr_next_payload;
317275970Scy	const u8 *notification;
318275970Scy	size_t notification_len;
319275970Scy};
320275970Scy
321275970Scyint ikev2_parse_payloads(struct ikev2_payloads *payloads,
322275970Scy			 u8 next_payload, const u8 *pos, const u8 *end);
323275970Scy
324275970Scyu8 * ikev2_decrypt_payload(int encr_id, int integ_id, struct ikev2_keys *keys,
325275970Scy			   int initiator, const struct ikev2_hdr *hdr,
326275970Scy			   const u8 *encrypted, size_t encrypted_len,
327275970Scy			   size_t *res_len);
328275970Scyvoid ikev2_update_hdr(struct wpabuf *msg);
329275970Scyint ikev2_build_encrypted(int encr_id, int integ_id, struct ikev2_keys *keys,
330275970Scy			  int initiator, struct wpabuf *msg,
331275970Scy			  struct wpabuf *plain, u8 next_payload);
332275970Scyint ikev2_derive_sk_keys(const struct ikev2_prf_alg *prf,
333275970Scy			 const struct ikev2_integ_alg *integ,
334275970Scy			 const struct ikev2_encr_alg *encr,
335275970Scy			 const u8 *skeyseed, const u8 *data, size_t data_len,
336275970Scy			 struct ikev2_keys *keys);
337275970Scy
338275970Scy#endif /* IKEV2_COMMON_H */
339275970Scy