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