1189251Ssam/* 2189251Ssam * IKEv2 definitions 3189251Ssam * Copyright (c) 2007, Jouni Malinen <j@w1.fi> 4189251Ssam * 5252726Srpaulo * This software may be distributed under the terms of the BSD license. 6252726Srpaulo * See README for more details. 7189251Ssam */ 8189251Ssam 9189251Ssam#ifndef IKEV2_COMMON_H 10189251Ssam#define IKEV2_COMMON_H 11189251Ssam 12189251Ssam/* 13189251Ssam * Nonce length must be at least 16 octets. It must also be at least half the 14189251Ssam * key size of the negotiated PRF. 15189251Ssam */ 16189251Ssam#define IKEV2_NONCE_MIN_LEN 16 17189251Ssam#define IKEV2_NONCE_MAX_LEN 256 18189251Ssam 19189251Ssam/* IKE Header - RFC 4306, Sect. 3.1 */ 20189251Ssam#ifdef _MSC_VER 21189251Ssam#pragma pack(push, 1) 22189251Ssam#endif /* _MSC_VER */ 23189251Ssam 24189251Ssam#define IKEV2_SPI_LEN 8 25189251Ssam 26189251Ssamstruct ikev2_hdr { 27189251Ssam u8 i_spi[IKEV2_SPI_LEN]; /* IKE_SA Initiator's SPI */ 28189251Ssam u8 r_spi[IKEV2_SPI_LEN]; /* IKE_SA Responder's SPI */ 29189251Ssam u8 next_payload; 30189251Ssam u8 version; /* MjVer | MnVer */ 31189251Ssam u8 exchange_type; 32189251Ssam u8 flags; 33189251Ssam u8 message_id[4]; 34189251Ssam u8 length[4]; /* total length of HDR + payloads */ 35189251Ssam} STRUCT_PACKED; 36189251Ssam 37189251Ssamstruct ikev2_payload_hdr { 38189251Ssam u8 next_payload; 39189251Ssam u8 flags; 40189251Ssam u8 payload_length[2]; /* this payload, including the payload header */ 41189251Ssam} STRUCT_PACKED; 42189251Ssam 43189251Ssamstruct ikev2_proposal { 44189251Ssam u8 type; /* 0 (last) or 2 (more) */ 45189251Ssam u8 reserved; 46189251Ssam u8 proposal_length[2]; /* including all transform and attributes */ 47189251Ssam u8 proposal_num; 48189251Ssam u8 protocol_id; /* IKEV2_PROTOCOL_* */ 49189251Ssam u8 spi_size; 50189251Ssam u8 num_transforms; 51189251Ssam /* SPI of spi_size octets */ 52189251Ssam /* Transforms */ 53189251Ssam} STRUCT_PACKED; 54189251Ssam 55189251Ssamstruct ikev2_transform { 56189251Ssam u8 type; /* 0 (last) or 3 (more) */ 57189251Ssam u8 reserved; 58189251Ssam u8 transform_length[2]; /* including Header and Attributes */ 59189251Ssam u8 transform_type; 60189251Ssam u8 reserved2; 61189251Ssam u8 transform_id[2]; 62189251Ssam /* Transform Attributes */ 63189251Ssam} STRUCT_PACKED; 64189251Ssam 65189251Ssam#ifdef _MSC_VER 66189251Ssam#pragma pack(pop) 67189251Ssam#endif /* _MSC_VER */ 68189251Ssam 69189251Ssam 70189251Ssam/* Current IKEv2 version from RFC 4306 */ 71189251Ssam#define IKEV2_MjVer 2 72189251Ssam#define IKEV2_MnVer 0 73189251Ssam#ifdef CCNS_PL 74189251Ssam#define IKEV2_VERSION ((IKEV2_MjVer) | ((IKEV2_MnVer) << 4)) 75189251Ssam#else /* CCNS_PL */ 76189251Ssam#define IKEV2_VERSION (((IKEV2_MjVer) << 4) | (IKEV2_MnVer)) 77189251Ssam#endif /* CCNS_PL */ 78189251Ssam 79189251Ssam/* IKEv2 Exchange Types */ 80189251Ssamenum { 81189251Ssam /* 0-33 RESERVED */ 82189251Ssam IKE_SA_INIT = 34, 83189251Ssam IKE_SA_AUTH = 35, 84189251Ssam CREATE_CHILD_SA = 36, 85189251Ssam INFORMATION = 37 86189251Ssam /* 38-239 RESERVED TO IANA */ 87189251Ssam /* 240-255 Reserved for private use */ 88189251Ssam}; 89189251Ssam 90189251Ssam/* IKEv2 Flags */ 91189251Ssam#define IKEV2_HDR_INITIATOR 0x08 92189251Ssam#define IKEV2_HDR_VERSION 0x10 93189251Ssam#define IKEV2_HDR_RESPONSE 0x20 94189251Ssam 95189251Ssam/* Payload Header Flags */ 96189251Ssam#define IKEV2_PAYLOAD_FLAGS_CRITICAL 0x01 97189251Ssam 98189251Ssam 99189251Ssam/* EAP-IKEv2 Payload Types (in Next Payload Type field) 100189251Ssam * http://www.iana.org/assignments/eap-ikev2-payloads */ 101189251Ssamenum { 102189251Ssam IKEV2_PAYLOAD_NO_NEXT_PAYLOAD = 0, 103189251Ssam IKEV2_PAYLOAD_SA = 33, 104189251Ssam IKEV2_PAYLOAD_KEY_EXCHANGE = 34, 105189251Ssam IKEV2_PAYLOAD_IDi = 35, 106189251Ssam IKEV2_PAYLOAD_IDr = 36, 107189251Ssam IKEV2_PAYLOAD_CERTIFICATE = 37, 108189251Ssam IKEV2_PAYLOAD_CERT_REQ = 38, 109189251Ssam IKEV2_PAYLOAD_AUTHENTICATION = 39, 110189251Ssam IKEV2_PAYLOAD_NONCE = 40, 111189251Ssam IKEV2_PAYLOAD_NOTIFICATION = 41, 112189251Ssam IKEV2_PAYLOAD_VENDOD_ID = 43, 113189251Ssam IKEV2_PAYLOAD_ENCRYPTED = 46, 114189251Ssam IKEV2_PAYLOAD_NEXT_FAST_ID = 121 115189251Ssam}; 116189251Ssam 117189251Ssam 118189251Ssam/* IKEv2 Proposal - Protocol ID */ 119189251Ssamenum { 120189251Ssam IKEV2_PROTOCOL_RESERVED = 0, 121189251Ssam IKEV2_PROTOCOL_IKE = 1, /* IKE is the only one allowed for EAP-IKEv2 */ 122189251Ssam IKEV2_PROTOCOL_AH = 2, 123189251Ssam IKEV2_PROTOCOL_ESP = 3 124189251Ssam}; 125189251Ssam 126189251Ssam 127189251Ssam/* IKEv2 Transform Types */ 128189251Ssamenum { 129189251Ssam IKEV2_TRANSFORM_ENCR = 1, 130189251Ssam IKEV2_TRANSFORM_PRF = 2, 131189251Ssam IKEV2_TRANSFORM_INTEG = 3, 132189251Ssam IKEV2_TRANSFORM_DH = 4, 133189251Ssam IKEV2_TRANSFORM_ESN = 5 134189251Ssam}; 135189251Ssam 136252726Srpaulo/* IKEv2 Transform Type 1 (Encryption Algorithm) */ 137189251Ssamenum { 138189251Ssam ENCR_DES_IV64 = 1, 139189251Ssam ENCR_DES = 2, 140189251Ssam ENCR_3DES = 3, 141189251Ssam ENCR_RC5 = 4, 142189251Ssam ENCR_IDEA = 5, 143189251Ssam ENCR_CAST = 6, 144189251Ssam ENCR_BLOWFISH = 7, 145189251Ssam ENCR_3IDEA = 8, 146189251Ssam ENCR_DES_IV32 = 9, 147189251Ssam ENCR_NULL = 11, 148189251Ssam ENCR_AES_CBC = 12, 149189251Ssam ENCR_AES_CTR = 13 150189251Ssam}; 151189251Ssam 152189251Ssam/* IKEv2 Transform Type 2 (Pseudo-random Function) */ 153189251Ssamenum { 154189251Ssam PRF_HMAC_MD5 = 1, 155189251Ssam PRF_HMAC_SHA1 = 2, 156189251Ssam PRF_HMAC_TIGER = 3, 157189251Ssam PRF_AES128_XCBC = 4 158189251Ssam}; 159189251Ssam 160189251Ssam/* IKEv2 Transform Type 3 (Integrity Algorithm) */ 161189251Ssamenum { 162189251Ssam AUTH_HMAC_MD5_96 = 1, 163189251Ssam AUTH_HMAC_SHA1_96 = 2, 164189251Ssam AUTH_DES_MAC = 3, 165189251Ssam AUTH_KPDK_MD5 = 4, 166189251Ssam AUTH_AES_XCBC_96 = 5 167189251Ssam}; 168189251Ssam 169189251Ssam/* IKEv2 Transform Type 4 (Diffie-Hellman Group) */ 170189251Ssamenum { 171189251Ssam DH_GROUP1_768BIT_MODP = 1, /* RFC 4306 */ 172189251Ssam DH_GROUP2_1024BIT_MODP = 2, /* RFC 4306 */ 173189251Ssam DH_GROUP5_1536BIT_MODP = 5, /* RFC 3526 */ 174189251Ssam DH_GROUP5_2048BIT_MODP = 14, /* RFC 3526 */ 175189251Ssam DH_GROUP5_3072BIT_MODP = 15, /* RFC 3526 */ 176189251Ssam DH_GROUP5_4096BIT_MODP = 16, /* RFC 3526 */ 177189251Ssam DH_GROUP5_6144BIT_MODP = 17, /* RFC 3526 */ 178189251Ssam DH_GROUP5_8192BIT_MODP = 18 /* RFC 3526 */ 179189251Ssam}; 180189251Ssam 181189251Ssam 182189251Ssam/* Identification Data Types (RFC 4306, Sect. 3.5) */ 183189251Ssamenum { 184189251Ssam ID_IPV4_ADDR = 1, 185189251Ssam ID_FQDN = 2, 186189251Ssam ID_RFC822_ADDR = 3, 187189251Ssam ID_IPV6_ADDR = 5, 188189251Ssam ID_DER_ASN1_DN = 9, 189189251Ssam ID_DER_ASN1_GN= 10, 190189251Ssam ID_KEY_ID = 11 191189251Ssam}; 192189251Ssam 193189251Ssam 194189251Ssam/* Certificate Encoding (RFC 4306, Sect. 3.6) */ 195189251Ssamenum { 196189251Ssam CERT_ENCODING_PKCS7_X509 = 1, 197189251Ssam CERT_ENCODING_PGP_CERT = 2, 198189251Ssam CERT_ENCODING_DNS_SIGNED_KEY = 3, 199189251Ssam /* X.509 Certificate - Signature: DER encoded X.509 certificate whose 200189251Ssam * public key is used to validate the sender's AUTH payload */ 201189251Ssam CERT_ENCODING_X509_CERT_SIGN = 4, 202189251Ssam CERT_ENCODING_KERBEROS_TOKEN = 6, 203189251Ssam /* DER encoded X.509 certificate revocation list */ 204189251Ssam CERT_ENCODING_CRL = 7, 205189251Ssam CERT_ENCODING_ARL = 8, 206189251Ssam CERT_ENCODING_SPKI_CERT = 9, 207189251Ssam CERT_ENCODING_X509_CERT_ATTR = 10, 208189251Ssam /* PKCS #1 encoded RSA key */ 209189251Ssam CERT_ENCODING_RAW_RSA_KEY = 11, 210189251Ssam CERT_ENCODING_HASH_AND_URL_X509_CERT = 12, 211189251Ssam CERT_ENCODING_HASH_AND_URL_X509_BUNDLE = 13 212189251Ssam}; 213189251Ssam 214189251Ssam 215189251Ssam/* Authentication Method (RFC 4306, Sect. 3.8) */ 216189251Ssamenum { 217189251Ssam AUTH_RSA_SIGN = 1, 218189251Ssam AUTH_SHARED_KEY_MIC = 2, 219189251Ssam AUTH_DSS_SIGN = 3 220189251Ssam}; 221189251Ssam 222189251Ssam 223189251Ssam/* Notify Message Types (RFC 4306, Sect. 3.10.1) */ 224189251Ssamenum { 225189251Ssam UNSUPPORTED_CRITICAL_PAYLOAD = 1, 226189251Ssam INVALID_IKE_SPI = 4, 227189251Ssam INVALID_MAJOR_VERSION = 5, 228189251Ssam INVALID_SYNTAX = 7, 229189251Ssam INVALID_MESSAGE_ID = 9, 230189251Ssam INVALID_SPI = 11, 231189251Ssam NO_PROPOSAL_CHOSEN = 14, 232189251Ssam INVALID_KE_PAYLOAD = 17, 233189251Ssam AUTHENTICATION_FAILED = 24, 234189251Ssam SINGLE_PAIR_REQUIRED = 34, 235189251Ssam NO_ADDITIONAL_SAS = 35, 236189251Ssam INTERNAL_ADDRESS_FAILURE = 36, 237189251Ssam FAILED_CP_REQUIRED = 37, 238189251Ssam TS_UNACCEPTABLE = 38, 239189251Ssam INVALID_SELECTORS = 39 240189251Ssam}; 241189251Ssam 242189251Ssam 243189251Ssamstruct ikev2_keys { 244189251Ssam u8 *SK_d, *SK_ai, *SK_ar, *SK_ei, *SK_er, *SK_pi, *SK_pr; 245189251Ssam size_t SK_d_len, SK_integ_len, SK_encr_len, SK_prf_len; 246189251Ssam}; 247189251Ssam 248189251Ssam 249189251Ssamint ikev2_keys_set(struct ikev2_keys *keys); 250189251Ssamvoid ikev2_free_keys(struct ikev2_keys *keys); 251189251Ssam 252189251Ssam 253189251Ssam/* Maximum hash length for supported hash algorithms */ 254189251Ssam#define IKEV2_MAX_HASH_LEN 20 255189251Ssam 256189251Ssamstruct ikev2_integ_alg { 257189251Ssam int id; 258189251Ssam size_t key_len; 259189251Ssam size_t hash_len; 260189251Ssam}; 261189251Ssam 262189251Ssamstruct ikev2_prf_alg { 263189251Ssam int id; 264189251Ssam size_t key_len; 265189251Ssam size_t hash_len; 266189251Ssam}; 267189251Ssam 268189251Ssamstruct ikev2_encr_alg { 269189251Ssam int id; 270189251Ssam size_t key_len; 271189251Ssam size_t block_size; 272189251Ssam}; 273189251Ssam 274189251Ssamconst struct ikev2_integ_alg * ikev2_get_integ(int id); 275189251Ssamint ikev2_integ_hash(int alg, const u8 *key, size_t key_len, const u8 *data, 276189251Ssam size_t data_len, u8 *hash); 277189251Ssamconst struct ikev2_prf_alg * ikev2_get_prf(int id); 278189251Ssamint ikev2_prf_hash(int alg, const u8 *key, size_t key_len, 279189251Ssam size_t num_elem, const u8 *addr[], const size_t *len, 280189251Ssam u8 *hash); 281189251Ssamint ikev2_prf_plus(int alg, const u8 *key, size_t key_len, 282189251Ssam const u8 *data, size_t data_len, 283189251Ssam u8 *out, size_t out_len); 284189251Ssamconst struct ikev2_encr_alg * ikev2_get_encr(int id); 285189251Ssamint ikev2_encr_encrypt(int alg, const u8 *key, size_t key_len, const u8 *iv, 286189251Ssam const u8 *plain, u8 *crypt, size_t len); 287189251Ssamint ikev2_encr_decrypt(int alg, const u8 *key, size_t key_len, const u8 *iv, 288189251Ssam const u8 *crypt, u8 *plain, size_t len); 289189251Ssam 290189251Ssamint ikev2_derive_auth_data(int prf_alg, const struct wpabuf *sign_msg, 291189251Ssam const u8 *ID, size_t ID_len, u8 ID_type, 292189251Ssam struct ikev2_keys *keys, int initiator, 293189251Ssam const u8 *shared_secret, size_t shared_secret_len, 294189251Ssam const u8 *nonce, size_t nonce_len, 295189251Ssam const u8 *key_pad, size_t key_pad_len, 296189251Ssam u8 *auth_data); 297189251Ssam 298189251Ssam 299189251Ssamstruct ikev2_payloads { 300189251Ssam const u8 *sa; 301189251Ssam size_t sa_len; 302189251Ssam const u8 *ke; 303189251Ssam size_t ke_len; 304189251Ssam const u8 *idi; 305189251Ssam size_t idi_len; 306189251Ssam const u8 *idr; 307189251Ssam size_t idr_len; 308189251Ssam const u8 *cert; 309189251Ssam size_t cert_len; 310189251Ssam const u8 *auth; 311189251Ssam size_t auth_len; 312189251Ssam const u8 *nonce; 313189251Ssam size_t nonce_len; 314189251Ssam const u8 *encrypted; 315189251Ssam size_t encrypted_len; 316189251Ssam u8 encr_next_payload; 317189251Ssam const u8 *notification; 318189251Ssam size_t notification_len; 319189251Ssam}; 320189251Ssam 321189251Ssamint ikev2_parse_payloads(struct ikev2_payloads *payloads, 322189251Ssam u8 next_payload, const u8 *pos, const u8 *end); 323189251Ssam 324189251Ssamu8 * ikev2_decrypt_payload(int encr_id, int integ_id, struct ikev2_keys *keys, 325189251Ssam int initiator, const struct ikev2_hdr *hdr, 326189251Ssam const u8 *encrypted, size_t encrypted_len, 327189251Ssam size_t *res_len); 328189251Ssamvoid ikev2_update_hdr(struct wpabuf *msg); 329189251Ssamint ikev2_build_encrypted(int encr_id, int integ_id, struct ikev2_keys *keys, 330189251Ssam int initiator, struct wpabuf *msg, 331189251Ssam struct wpabuf *plain, u8 next_payload); 332189251Ssamint ikev2_derive_sk_keys(const struct ikev2_prf_alg *prf, 333189251Ssam const struct ikev2_integ_alg *integ, 334189251Ssam const struct ikev2_encr_alg *encr, 335189251Ssam const u8 *skeyseed, const u8 *data, size_t data_len, 336189251Ssam struct ikev2_keys *keys); 337189251Ssam 338189251Ssam#endif /* IKEV2_COMMON_H */ 339