18dbcf02cSchristos /*
28dbcf02cSchristos  * IKEv2 definitions
38dbcf02cSchristos  * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos  *
5*62a52023Schristos  * This software may be distributed under the terms of the BSD license.
6*62a52023Schristos  * See README for more details.
78dbcf02cSchristos  */
88dbcf02cSchristos 
98dbcf02cSchristos #ifndef IKEV2_COMMON_H
108dbcf02cSchristos #define IKEV2_COMMON_H
118dbcf02cSchristos 
128dbcf02cSchristos /*
138dbcf02cSchristos  * Nonce length must be at least 16 octets. It must also be at least half the
148dbcf02cSchristos  * key size of the negotiated PRF.
158dbcf02cSchristos  */
168dbcf02cSchristos #define IKEV2_NONCE_MIN_LEN 16
178dbcf02cSchristos #define IKEV2_NONCE_MAX_LEN 256
188dbcf02cSchristos 
198dbcf02cSchristos /* IKE Header - RFC 4306, Sect. 3.1 */
208dbcf02cSchristos #ifdef _MSC_VER
218dbcf02cSchristos #pragma pack(push, 1)
228dbcf02cSchristos #endif /* _MSC_VER */
238dbcf02cSchristos 
248dbcf02cSchristos #define IKEV2_SPI_LEN 8
258dbcf02cSchristos 
268dbcf02cSchristos struct ikev2_hdr {
278dbcf02cSchristos 	u8 i_spi[IKEV2_SPI_LEN]; /* IKE_SA Initiator's SPI */
288dbcf02cSchristos 	u8 r_spi[IKEV2_SPI_LEN]; /* IKE_SA Responder's SPI */
298dbcf02cSchristos 	u8 next_payload;
308dbcf02cSchristos 	u8 version; /* MjVer | MnVer */
318dbcf02cSchristos 	u8 exchange_type;
328dbcf02cSchristos 	u8 flags;
338dbcf02cSchristos 	u8 message_id[4];
348dbcf02cSchristos 	u8 length[4]; /* total length of HDR + payloads */
358dbcf02cSchristos } STRUCT_PACKED;
368dbcf02cSchristos 
378dbcf02cSchristos struct ikev2_payload_hdr {
388dbcf02cSchristos 	u8 next_payload;
398dbcf02cSchristos 	u8 flags;
408dbcf02cSchristos 	u8 payload_length[2]; /* this payload, including the payload header */
418dbcf02cSchristos } STRUCT_PACKED;
428dbcf02cSchristos 
438dbcf02cSchristos struct ikev2_proposal {
448dbcf02cSchristos 	u8 type; /* 0 (last) or 2 (more) */
458dbcf02cSchristos 	u8 reserved;
468dbcf02cSchristos 	u8 proposal_length[2]; /* including all transform and attributes */
478dbcf02cSchristos 	u8 proposal_num;
488dbcf02cSchristos 	u8 protocol_id; /* IKEV2_PROTOCOL_* */
498dbcf02cSchristos 	u8 spi_size;
508dbcf02cSchristos 	u8 num_transforms;
518dbcf02cSchristos 	/* SPI of spi_size octets */
528dbcf02cSchristos 	/* Transforms */
538dbcf02cSchristos } STRUCT_PACKED;
548dbcf02cSchristos 
558dbcf02cSchristos struct ikev2_transform {
568dbcf02cSchristos 	u8 type; /* 0 (last) or 3 (more) */
578dbcf02cSchristos 	u8 reserved;
588dbcf02cSchristos 	u8 transform_length[2]; /* including Header and Attributes */
598dbcf02cSchristos 	u8 transform_type;
608dbcf02cSchristos 	u8 reserved2;
618dbcf02cSchristos 	u8 transform_id[2];
628dbcf02cSchristos 	/* Transform Attributes */
638dbcf02cSchristos } STRUCT_PACKED;
648dbcf02cSchristos 
658dbcf02cSchristos #ifdef _MSC_VER
668dbcf02cSchristos #pragma pack(pop)
678dbcf02cSchristos #endif /* _MSC_VER */
688dbcf02cSchristos 
698dbcf02cSchristos 
708dbcf02cSchristos /* Current IKEv2 version from RFC 4306 */
718dbcf02cSchristos #define IKEV2_MjVer 2
728dbcf02cSchristos #define IKEV2_MnVer 0
738dbcf02cSchristos #define IKEV2_VERSION (((IKEV2_MjVer) << 4) | (IKEV2_MnVer))
748dbcf02cSchristos 
758dbcf02cSchristos /* IKEv2 Exchange Types */
768dbcf02cSchristos enum {
778dbcf02cSchristos 	/* 0-33 RESERVED */
788dbcf02cSchristos 	IKE_SA_INIT = 34,
798dbcf02cSchristos 	IKE_SA_AUTH = 35,
808dbcf02cSchristos 	CREATE_CHILD_SA = 36,
818dbcf02cSchristos 	INFORMATION = 37
828dbcf02cSchristos 	/* 38-239 RESERVED TO IANA */
838dbcf02cSchristos 	/* 240-255 Reserved for private use */
848dbcf02cSchristos };
858dbcf02cSchristos 
868dbcf02cSchristos /* IKEv2 Flags */
878dbcf02cSchristos #define IKEV2_HDR_INITIATOR	0x08
888dbcf02cSchristos #define IKEV2_HDR_VERSION	0x10
898dbcf02cSchristos #define IKEV2_HDR_RESPONSE	0x20
908dbcf02cSchristos 
918dbcf02cSchristos /* Payload Header Flags */
928dbcf02cSchristos #define IKEV2_PAYLOAD_FLAGS_CRITICAL 0x01
938dbcf02cSchristos 
948dbcf02cSchristos 
958dbcf02cSchristos /* EAP-IKEv2 Payload Types (in Next Payload Type field)
968dbcf02cSchristos  * http://www.iana.org/assignments/eap-ikev2-payloads */
978dbcf02cSchristos enum {
988dbcf02cSchristos 	IKEV2_PAYLOAD_NO_NEXT_PAYLOAD = 0,
998dbcf02cSchristos 	IKEV2_PAYLOAD_SA = 33,
1008dbcf02cSchristos 	IKEV2_PAYLOAD_KEY_EXCHANGE = 34,
1018dbcf02cSchristos 	IKEV2_PAYLOAD_IDi = 35,
1028dbcf02cSchristos 	IKEV2_PAYLOAD_IDr = 36,
1038dbcf02cSchristos 	IKEV2_PAYLOAD_CERTIFICATE = 37,
1048dbcf02cSchristos 	IKEV2_PAYLOAD_CERT_REQ = 38,
1058dbcf02cSchristos 	IKEV2_PAYLOAD_AUTHENTICATION = 39,
1068dbcf02cSchristos 	IKEV2_PAYLOAD_NONCE = 40,
1078dbcf02cSchristos 	IKEV2_PAYLOAD_NOTIFICATION = 41,
1088dbcf02cSchristos 	IKEV2_PAYLOAD_VENDOD_ID = 43,
1098dbcf02cSchristos 	IKEV2_PAYLOAD_ENCRYPTED = 46,
1108dbcf02cSchristos 	IKEV2_PAYLOAD_NEXT_FAST_ID = 121
1118dbcf02cSchristos };
1128dbcf02cSchristos 
1138dbcf02cSchristos 
1148dbcf02cSchristos /* IKEv2 Proposal - Protocol ID */
1158dbcf02cSchristos enum {
1168dbcf02cSchristos 	IKEV2_PROTOCOL_RESERVED = 0,
1178dbcf02cSchristos 	IKEV2_PROTOCOL_IKE = 1, /* IKE is the only one allowed for EAP-IKEv2 */
1188dbcf02cSchristos 	IKEV2_PROTOCOL_AH = 2,
1198dbcf02cSchristos 	IKEV2_PROTOCOL_ESP = 3
1208dbcf02cSchristos };
1218dbcf02cSchristos 
1228dbcf02cSchristos 
1238dbcf02cSchristos /* IKEv2 Transform Types */
1248dbcf02cSchristos enum {
1258dbcf02cSchristos 	IKEV2_TRANSFORM_ENCR = 1,
1268dbcf02cSchristos 	IKEV2_TRANSFORM_PRF = 2,
1278dbcf02cSchristos 	IKEV2_TRANSFORM_INTEG = 3,
1288dbcf02cSchristos 	IKEV2_TRANSFORM_DH = 4,
1298dbcf02cSchristos 	IKEV2_TRANSFORM_ESN = 5
1308dbcf02cSchristos };
1318dbcf02cSchristos 
13242669be3Schristos /* IKEv2 Transform Type 1 (Encryption Algorithm) */
1338dbcf02cSchristos enum {
1348dbcf02cSchristos 	ENCR_DES_IV64 = 1,
1358dbcf02cSchristos 	ENCR_DES = 2,
1368dbcf02cSchristos 	ENCR_3DES = 3,
1378dbcf02cSchristos 	ENCR_RC5 = 4,
1388dbcf02cSchristos 	ENCR_IDEA = 5,
1398dbcf02cSchristos 	ENCR_CAST = 6,
1408dbcf02cSchristos 	ENCR_BLOWFISH = 7,
1418dbcf02cSchristos 	ENCR_3IDEA = 8,
1428dbcf02cSchristos 	ENCR_DES_IV32 = 9,
1438dbcf02cSchristos 	ENCR_NULL = 11,
1448dbcf02cSchristos 	ENCR_AES_CBC = 12,
1458dbcf02cSchristos 	ENCR_AES_CTR = 13
1468dbcf02cSchristos };
1478dbcf02cSchristos 
1488dbcf02cSchristos /* IKEv2 Transform Type 2 (Pseudo-random Function) */
1498dbcf02cSchristos enum {
1508dbcf02cSchristos 	PRF_HMAC_MD5 = 1,
1518dbcf02cSchristos 	PRF_HMAC_SHA1 = 2,
1528dbcf02cSchristos 	PRF_HMAC_TIGER = 3,
1538dbcf02cSchristos 	PRF_AES128_XCBC = 4
1548dbcf02cSchristos };
1558dbcf02cSchristos 
1568dbcf02cSchristos /* IKEv2 Transform Type 3 (Integrity Algorithm) */
1578dbcf02cSchristos enum {
1588dbcf02cSchristos 	AUTH_HMAC_MD5_96 = 1,
1598dbcf02cSchristos 	AUTH_HMAC_SHA1_96 = 2,
1608dbcf02cSchristos 	AUTH_DES_MAC = 3,
1618dbcf02cSchristos 	AUTH_KPDK_MD5 = 4,
1628dbcf02cSchristos 	AUTH_AES_XCBC_96 = 5
1638dbcf02cSchristos };
1648dbcf02cSchristos 
1658dbcf02cSchristos /* IKEv2 Transform Type 4 (Diffie-Hellman Group) */
1668dbcf02cSchristos enum {
1678dbcf02cSchristos 	DH_GROUP1_768BIT_MODP = 1, /* RFC 4306 */
1688dbcf02cSchristos 	DH_GROUP2_1024BIT_MODP = 2, /* RFC 4306 */
1698dbcf02cSchristos 	DH_GROUP5_1536BIT_MODP = 5, /* RFC 3526 */
1708dbcf02cSchristos 	DH_GROUP5_2048BIT_MODP = 14, /* RFC 3526 */
1718dbcf02cSchristos 	DH_GROUP5_3072BIT_MODP = 15, /* RFC 3526 */
1728dbcf02cSchristos 	DH_GROUP5_4096BIT_MODP = 16, /* RFC 3526 */
1738dbcf02cSchristos 	DH_GROUP5_6144BIT_MODP = 17, /* RFC 3526 */
1748dbcf02cSchristos 	DH_GROUP5_8192BIT_MODP = 18 /* RFC 3526 */
1758dbcf02cSchristos };
1768dbcf02cSchristos 
1778dbcf02cSchristos 
1788dbcf02cSchristos /* Identification Data Types (RFC 4306, Sect. 3.5) */
1798dbcf02cSchristos enum {
1808dbcf02cSchristos 	ID_IPV4_ADDR = 1,
1818dbcf02cSchristos 	ID_FQDN = 2,
1828dbcf02cSchristos 	ID_RFC822_ADDR = 3,
1838dbcf02cSchristos 	ID_IPV6_ADDR = 5,
1848dbcf02cSchristos 	ID_DER_ASN1_DN = 9,
1858dbcf02cSchristos 	ID_DER_ASN1_GN= 10,
1868dbcf02cSchristos 	ID_KEY_ID = 11
1878dbcf02cSchristos };
1888dbcf02cSchristos 
1898dbcf02cSchristos 
1908dbcf02cSchristos /* Certificate Encoding (RFC 4306, Sect. 3.6) */
1918dbcf02cSchristos enum {
1928dbcf02cSchristos 	CERT_ENCODING_PKCS7_X509 = 1,
1938dbcf02cSchristos 	CERT_ENCODING_PGP_CERT = 2,
1948dbcf02cSchristos 	CERT_ENCODING_DNS_SIGNED_KEY = 3,
1958dbcf02cSchristos 	/* X.509 Certificate - Signature: DER encoded X.509 certificate whose
1968dbcf02cSchristos 	 * public key is used to validate the sender's AUTH payload */
1978dbcf02cSchristos 	CERT_ENCODING_X509_CERT_SIGN = 4,
1988dbcf02cSchristos 	CERT_ENCODING_KERBEROS_TOKEN = 6,
1998dbcf02cSchristos 	/* DER encoded X.509 certificate revocation list */
2008dbcf02cSchristos 	CERT_ENCODING_CRL = 7,
2018dbcf02cSchristos 	CERT_ENCODING_ARL = 8,
2028dbcf02cSchristos 	CERT_ENCODING_SPKI_CERT = 9,
2038dbcf02cSchristos 	CERT_ENCODING_X509_CERT_ATTR = 10,
2048dbcf02cSchristos 	/* PKCS #1 encoded RSA key */
2058dbcf02cSchristos 	CERT_ENCODING_RAW_RSA_KEY = 11,
2068dbcf02cSchristos 	CERT_ENCODING_HASH_AND_URL_X509_CERT = 12,
2078dbcf02cSchristos 	CERT_ENCODING_HASH_AND_URL_X509_BUNDLE = 13
2088dbcf02cSchristos };
2098dbcf02cSchristos 
2108dbcf02cSchristos 
2118dbcf02cSchristos /* Authentication Method (RFC 4306, Sect. 3.8) */
2128dbcf02cSchristos enum {
2138dbcf02cSchristos 	AUTH_RSA_SIGN = 1,
2148dbcf02cSchristos 	AUTH_SHARED_KEY_MIC = 2,
2158dbcf02cSchristos 	AUTH_DSS_SIGN = 3
2168dbcf02cSchristos };
2178dbcf02cSchristos 
2188dbcf02cSchristos 
2198dbcf02cSchristos /* Notify Message Types (RFC 4306, Sect. 3.10.1) */
2208dbcf02cSchristos enum {
2218dbcf02cSchristos 	UNSUPPORTED_CRITICAL_PAYLOAD = 1,
2228dbcf02cSchristos 	INVALID_IKE_SPI = 4,
2238dbcf02cSchristos 	INVALID_MAJOR_VERSION = 5,
2248dbcf02cSchristos 	INVALID_SYNTAX = 7,
2258dbcf02cSchristos 	INVALID_MESSAGE_ID = 9,
2268dbcf02cSchristos 	INVALID_SPI = 11,
2278dbcf02cSchristos 	NO_PROPOSAL_CHOSEN = 14,
2288dbcf02cSchristos 	INVALID_KE_PAYLOAD = 17,
2298dbcf02cSchristos 	AUTHENTICATION_FAILED = 24,
2308dbcf02cSchristos 	SINGLE_PAIR_REQUIRED = 34,
2318dbcf02cSchristos 	NO_ADDITIONAL_SAS = 35,
2328dbcf02cSchristos 	INTERNAL_ADDRESS_FAILURE = 36,
2338dbcf02cSchristos 	FAILED_CP_REQUIRED = 37,
2348dbcf02cSchristos 	TS_UNACCEPTABLE = 38,
2358dbcf02cSchristos 	INVALID_SELECTORS = 39
2368dbcf02cSchristos };
2378dbcf02cSchristos 
2388dbcf02cSchristos 
2398dbcf02cSchristos struct ikev2_keys {
2408dbcf02cSchristos 	u8 *SK_d, *SK_ai, *SK_ar, *SK_ei, *SK_er, *SK_pi, *SK_pr;
2418dbcf02cSchristos 	size_t SK_d_len, SK_integ_len, SK_encr_len, SK_prf_len;
2428dbcf02cSchristos };
2438dbcf02cSchristos 
2448dbcf02cSchristos 
2458dbcf02cSchristos int ikev2_keys_set(struct ikev2_keys *keys);
2468dbcf02cSchristos void ikev2_free_keys(struct ikev2_keys *keys);
2478dbcf02cSchristos 
2488dbcf02cSchristos 
2498dbcf02cSchristos /* Maximum hash length for supported hash algorithms */
2508dbcf02cSchristos #define IKEV2_MAX_HASH_LEN 20
2518dbcf02cSchristos 
2528dbcf02cSchristos struct ikev2_integ_alg {
2538dbcf02cSchristos 	int id;
2548dbcf02cSchristos 	size_t key_len;
2558dbcf02cSchristos 	size_t hash_len;
2568dbcf02cSchristos };
2578dbcf02cSchristos 
2588dbcf02cSchristos struct ikev2_prf_alg {
2598dbcf02cSchristos 	int id;
2608dbcf02cSchristos 	size_t key_len;
2618dbcf02cSchristos 	size_t hash_len;
2628dbcf02cSchristos };
2638dbcf02cSchristos 
2648dbcf02cSchristos struct ikev2_encr_alg {
2658dbcf02cSchristos 	int id;
2668dbcf02cSchristos 	size_t key_len;
2678dbcf02cSchristos 	size_t block_size;
2688dbcf02cSchristos };
2698dbcf02cSchristos 
2708dbcf02cSchristos const struct ikev2_integ_alg * ikev2_get_integ(int id);
2718dbcf02cSchristos int ikev2_integ_hash(int alg, const u8 *key, size_t key_len, const u8 *data,
2728dbcf02cSchristos 		     size_t data_len, u8 *hash);
2738dbcf02cSchristos const struct ikev2_prf_alg * ikev2_get_prf(int id);
2748dbcf02cSchristos int ikev2_prf_hash(int alg, const u8 *key, size_t key_len,
2758dbcf02cSchristos 		   size_t num_elem, const u8 *addr[], const size_t *len,
2768dbcf02cSchristos 		   u8 *hash);
2778dbcf02cSchristos int ikev2_prf_plus(int alg, const u8 *key, size_t key_len,
2788dbcf02cSchristos 		   const u8 *data, size_t data_len,
2798dbcf02cSchristos 		   u8 *out, size_t out_len);
2808dbcf02cSchristos const struct ikev2_encr_alg * ikev2_get_encr(int id);
2818dbcf02cSchristos int ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
2828dbcf02cSchristos 		       const u8 *plain, u8 *crypt, size_t len);
2838dbcf02cSchristos int ikev2_encr_decrypt(int alg, const u8 *key, size_t key_len, const u8 *iv,
2848dbcf02cSchristos 		       const u8 *crypt, u8 *plain, size_t len);
2858dbcf02cSchristos 
2868dbcf02cSchristos int ikev2_derive_auth_data(int prf_alg, const struct wpabuf *sign_msg,
2878dbcf02cSchristos 			   const u8 *ID, size_t ID_len, u8 ID_type,
2888dbcf02cSchristos 			   struct ikev2_keys *keys, int initiator,
2898dbcf02cSchristos 			   const u8 *shared_secret, size_t shared_secret_len,
2908dbcf02cSchristos 			   const u8 *nonce, size_t nonce_len,
2918dbcf02cSchristos 			   const u8 *key_pad, size_t key_pad_len,
2928dbcf02cSchristos 			   u8 *auth_data);
2938dbcf02cSchristos 
2948dbcf02cSchristos 
2958dbcf02cSchristos struct ikev2_payloads {
2968dbcf02cSchristos 	const u8 *sa;
2978dbcf02cSchristos 	size_t sa_len;
2988dbcf02cSchristos 	const u8 *ke;
2998dbcf02cSchristos 	size_t ke_len;
3008dbcf02cSchristos 	const u8 *idi;
3018dbcf02cSchristos 	size_t idi_len;
3028dbcf02cSchristos 	const u8 *idr;
3038dbcf02cSchristos 	size_t idr_len;
3048dbcf02cSchristos 	const u8 *cert;
3058dbcf02cSchristos 	size_t cert_len;
3068dbcf02cSchristos 	const u8 *auth;
3078dbcf02cSchristos 	size_t auth_len;
3088dbcf02cSchristos 	const u8 *nonce;
3098dbcf02cSchristos 	size_t nonce_len;
3108dbcf02cSchristos 	const u8 *encrypted;
3118dbcf02cSchristos 	size_t encrypted_len;
3128dbcf02cSchristos 	u8 encr_next_payload;
3138dbcf02cSchristos 	const u8 *notification;
3148dbcf02cSchristos 	size_t notification_len;
3158dbcf02cSchristos };
3168dbcf02cSchristos 
3178dbcf02cSchristos int ikev2_parse_payloads(struct ikev2_payloads *payloads,
3188dbcf02cSchristos 			 u8 next_payload, const u8 *pos, const u8 *end);
3198dbcf02cSchristos 
3208dbcf02cSchristos u8 * ikev2_decrypt_payload(int encr_id, int integ_id, struct ikev2_keys *keys,
3218dbcf02cSchristos 			   int initiator, const struct ikev2_hdr *hdr,
3228dbcf02cSchristos 			   const u8 *encrypted, size_t encrypted_len,
3238dbcf02cSchristos 			   size_t *res_len);
3248dbcf02cSchristos void ikev2_update_hdr(struct wpabuf *msg);
3258dbcf02cSchristos int ikev2_build_encrypted(int encr_id, int integ_id, struct ikev2_keys *keys,
3268dbcf02cSchristos 			  int initiator, struct wpabuf *msg,
3278dbcf02cSchristos 			  struct wpabuf *plain, u8 next_payload);
3288dbcf02cSchristos int ikev2_derive_sk_keys(const struct ikev2_prf_alg *prf,
3298dbcf02cSchristos 			 const struct ikev2_integ_alg *integ,
3308dbcf02cSchristos 			 const struct ikev2_encr_alg *encr,
3318dbcf02cSchristos 			 const u8 *skeyseed, const u8 *data, size_t data_len,
3328dbcf02cSchristos 			 struct ikev2_keys *keys);
3338dbcf02cSchristos 
3348dbcf02cSchristos #endif /* IKEV2_COMMON_H */
335