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