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