139beb93cSSam Leffler /*
239beb93cSSam Leffler * EAP peer/server: EAP-SIM/AKA/AKA' shared routines
339beb93cSSam Leffler * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
439beb93cSSam Leffler *
5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license.
6f05cddf9SRui Paulo * See README for more details.
739beb93cSSam Leffler */
839beb93cSSam Leffler
939beb93cSSam Leffler #ifndef EAP_SIM_COMMON_H
1039beb93cSSam Leffler #define EAP_SIM_COMMON_H
1139beb93cSSam Leffler
1239beb93cSSam Leffler #define EAP_SIM_NONCE_S_LEN 16
1339beb93cSSam Leffler #define EAP_SIM_NONCE_MT_LEN 16
1439beb93cSSam Leffler #define EAP_SIM_MAC_LEN 16
1539beb93cSSam Leffler #define EAP_SIM_MK_LEN 20
1639beb93cSSam Leffler #define EAP_SIM_K_AUT_LEN 16
1739beb93cSSam Leffler #define EAP_SIM_K_ENCR_LEN 16
1839beb93cSSam Leffler #define EAP_SIM_KEYING_DATA_LEN 64
1939beb93cSSam Leffler #define EAP_SIM_IV_LEN 16
2039beb93cSSam Leffler #define EAP_SIM_KC_LEN 8
2139beb93cSSam Leffler #define EAP_SIM_SRES_LEN 4
2239beb93cSSam Leffler
2339beb93cSSam Leffler #define GSM_RAND_LEN 16
2439beb93cSSam Leffler
2539beb93cSSam Leffler #define EAP_SIM_VERSION 1
2639beb93cSSam Leffler
2739beb93cSSam Leffler /* EAP-SIM Subtypes */
2839beb93cSSam Leffler #define EAP_SIM_SUBTYPE_START 10
2939beb93cSSam Leffler #define EAP_SIM_SUBTYPE_CHALLENGE 11
3039beb93cSSam Leffler #define EAP_SIM_SUBTYPE_NOTIFICATION 12
3139beb93cSSam Leffler #define EAP_SIM_SUBTYPE_REAUTHENTICATION 13
3239beb93cSSam Leffler #define EAP_SIM_SUBTYPE_CLIENT_ERROR 14
3339beb93cSSam Leffler
3439beb93cSSam Leffler /* AT_CLIENT_ERROR_CODE error codes */
3539beb93cSSam Leffler #define EAP_SIM_UNABLE_TO_PROCESS_PACKET 0
3639beb93cSSam Leffler #define EAP_SIM_UNSUPPORTED_VERSION 1
3739beb93cSSam Leffler #define EAP_SIM_INSUFFICIENT_NUM_OF_CHAL 2
3839beb93cSSam Leffler #define EAP_SIM_RAND_NOT_FRESH 3
3939beb93cSSam Leffler
4039beb93cSSam Leffler #define EAP_SIM_MAX_FAST_REAUTHS 1000
4139beb93cSSam Leffler
4239beb93cSSam Leffler #define EAP_SIM_MAX_CHAL 3
4339beb93cSSam Leffler
4439beb93cSSam Leffler
4539beb93cSSam Leffler /* EAP-AKA Subtypes */
4639beb93cSSam Leffler #define EAP_AKA_SUBTYPE_CHALLENGE 1
4739beb93cSSam Leffler #define EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT 2
4839beb93cSSam Leffler #define EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE 4
4939beb93cSSam Leffler #define EAP_AKA_SUBTYPE_IDENTITY 5
5039beb93cSSam Leffler #define EAP_AKA_SUBTYPE_NOTIFICATION 12
5139beb93cSSam Leffler #define EAP_AKA_SUBTYPE_REAUTHENTICATION 13
5239beb93cSSam Leffler #define EAP_AKA_SUBTYPE_CLIENT_ERROR 14
5339beb93cSSam Leffler
5439beb93cSSam Leffler /* AT_CLIENT_ERROR_CODE error codes */
5539beb93cSSam Leffler #define EAP_AKA_UNABLE_TO_PROCESS_PACKET 0
5639beb93cSSam Leffler
5739beb93cSSam Leffler #define EAP_AKA_RAND_LEN 16
5839beb93cSSam Leffler #define EAP_AKA_AUTN_LEN 16
5939beb93cSSam Leffler #define EAP_AKA_AUTS_LEN 14
6039beb93cSSam Leffler #define EAP_AKA_RES_MAX_LEN 16
6139beb93cSSam Leffler #define EAP_AKA_IK_LEN 16
6239beb93cSSam Leffler #define EAP_AKA_CK_LEN 16
6339beb93cSSam Leffler #define EAP_AKA_MAX_FAST_REAUTHS 1000
6439beb93cSSam Leffler #define EAP_AKA_MIN_RES_LEN 4
6539beb93cSSam Leffler #define EAP_AKA_MAX_RES_LEN 16
6639beb93cSSam Leffler #define EAP_AKA_CHECKCODE_LEN 20
6739beb93cSSam Leffler
6839beb93cSSam Leffler #define EAP_AKA_PRIME_K_AUT_LEN 32
6939beb93cSSam Leffler #define EAP_AKA_PRIME_CHECKCODE_LEN 32
7039beb93cSSam Leffler #define EAP_AKA_PRIME_K_RE_LEN 32
7139beb93cSSam Leffler
7239beb93cSSam Leffler struct wpabuf;
7339beb93cSSam Leffler
7439beb93cSSam Leffler void eap_sim_derive_mk(const u8 *identity, size_t identity_len,
7539beb93cSSam Leffler const u8 *nonce_mt, u16 selected_version,
7639beb93cSSam Leffler const u8 *ver_list, size_t ver_list_len,
7739beb93cSSam Leffler int num_chal, const u8 *kc, u8 *mk);
7839beb93cSSam Leffler void eap_aka_derive_mk(const u8 *identity, size_t identity_len,
7939beb93cSSam Leffler const u8 *ik, const u8 *ck, u8 *mk);
8039beb93cSSam Leffler int eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk,
8139beb93cSSam Leffler u8 *emsk);
8239beb93cSSam Leffler int eap_sim_derive_keys_reauth(u16 _counter,
8339beb93cSSam Leffler const u8 *identity, size_t identity_len,
8439beb93cSSam Leffler const u8 *nonce_s, const u8 *mk, u8 *msk,
8539beb93cSSam Leffler u8 *emsk);
8639beb93cSSam Leffler int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req,
8739beb93cSSam Leffler const u8 *mac, const u8 *extra, size_t extra_len);
8839beb93cSSam Leffler void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
8939beb93cSSam Leffler const u8 *extra, size_t extra_len);
9039beb93cSSam Leffler
91e28a4053SRui Paulo #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME)
9239beb93cSSam Leffler void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
9339beb93cSSam Leffler const u8 *ik, const u8 *ck, u8 *k_encr,
9439beb93cSSam Leffler u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk);
9539beb93cSSam Leffler int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
9639beb93cSSam Leffler const u8 *identity, size_t identity_len,
9739beb93cSSam Leffler const u8 *nonce_s, u8 *msk, u8 *emsk);
9839beb93cSSam Leffler int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
9939beb93cSSam Leffler const u8 *mac, const u8 *extra,
10039beb93cSSam Leffler size_t extra_len);
10139beb93cSSam Leffler void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len,
10239beb93cSSam Leffler u8 *mac, const u8 *extra, size_t extra_len);
10339beb93cSSam Leffler
10439beb93cSSam Leffler void eap_aka_prime_derive_ck_ik_prime(u8 *ck, u8 *ik, const u8 *sqn_ak,
10539beb93cSSam Leffler const u8 *network_name,
10639beb93cSSam Leffler size_t network_name_len);
107e28a4053SRui Paulo #else /* EAP_AKA_PRIME || EAP_SERVER_AKA_PRIME */
eap_aka_prime_derive_keys(const u8 * identity,size_t identity_len,const u8 * ik,const u8 * ck,u8 * k_encr,u8 * k_aut,u8 * k_re,u8 * msk,u8 * emsk)10839beb93cSSam Leffler static inline void eap_aka_prime_derive_keys(const u8 *identity,
10939beb93cSSam Leffler size_t identity_len,
11039beb93cSSam Leffler const u8 *ik, const u8 *ck,
11139beb93cSSam Leffler u8 *k_encr, u8 *k_aut, u8 *k_re,
11239beb93cSSam Leffler u8 *msk, u8 *emsk)
11339beb93cSSam Leffler {
11439beb93cSSam Leffler }
11539beb93cSSam Leffler
eap_aka_prime_derive_keys_reauth(const u8 * k_re,u16 counter,const u8 * identity,size_t identity_len,const u8 * nonce_s,u8 * msk,u8 * emsk)11639beb93cSSam Leffler static inline int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
11739beb93cSSam Leffler const u8 *identity,
11839beb93cSSam Leffler size_t identity_len,
11939beb93cSSam Leffler const u8 *nonce_s, u8 *msk,
12039beb93cSSam Leffler u8 *emsk)
12139beb93cSSam Leffler {
12239beb93cSSam Leffler return -1;
12339beb93cSSam Leffler }
12439beb93cSSam Leffler
eap_sim_verify_mac_sha256(const u8 * k_aut,const struct wpabuf * req,const u8 * mac,const u8 * extra,size_t extra_len)12539beb93cSSam Leffler static inline int eap_sim_verify_mac_sha256(const u8 *k_aut,
12639beb93cSSam Leffler const struct wpabuf *req,
12739beb93cSSam Leffler const u8 *mac, const u8 *extra,
12839beb93cSSam Leffler size_t extra_len)
12939beb93cSSam Leffler {
13039beb93cSSam Leffler return -1;
13139beb93cSSam Leffler }
132e28a4053SRui Paulo #endif /* EAP_AKA_PRIME || EAP_SERVER_AKA_PRIME */
13339beb93cSSam Leffler
13439beb93cSSam Leffler
13539beb93cSSam Leffler /* EAP-SIM/AKA Attributes (0..127 non-skippable) */
13639beb93cSSam Leffler #define EAP_SIM_AT_RAND 1
13739beb93cSSam Leffler #define EAP_SIM_AT_AUTN 2 /* only AKA */
13839beb93cSSam Leffler #define EAP_SIM_AT_RES 3 /* only AKA, only peer->server */
13939beb93cSSam Leffler #define EAP_SIM_AT_AUTS 4 /* only AKA, only peer->server */
14039beb93cSSam Leffler #define EAP_SIM_AT_PADDING 6 /* only encrypted */
14139beb93cSSam Leffler #define EAP_SIM_AT_NONCE_MT 7 /* only SIM, only send */
14239beb93cSSam Leffler #define EAP_SIM_AT_PERMANENT_ID_REQ 10
14339beb93cSSam Leffler #define EAP_SIM_AT_MAC 11
14439beb93cSSam Leffler #define EAP_SIM_AT_NOTIFICATION 12
14539beb93cSSam Leffler #define EAP_SIM_AT_ANY_ID_REQ 13
14639beb93cSSam Leffler #define EAP_SIM_AT_IDENTITY 14 /* only send */
14739beb93cSSam Leffler #define EAP_SIM_AT_VERSION_LIST 15 /* only SIM */
14839beb93cSSam Leffler #define EAP_SIM_AT_SELECTED_VERSION 16 /* only SIM */
14939beb93cSSam Leffler #define EAP_SIM_AT_FULLAUTH_ID_REQ 17
15039beb93cSSam Leffler #define EAP_SIM_AT_COUNTER 19 /* only encrypted */
15139beb93cSSam Leffler #define EAP_SIM_AT_COUNTER_TOO_SMALL 20 /* only encrypted */
15239beb93cSSam Leffler #define EAP_SIM_AT_NONCE_S 21 /* only encrypted */
15339beb93cSSam Leffler #define EAP_SIM_AT_CLIENT_ERROR_CODE 22 /* only send */
15439beb93cSSam Leffler #define EAP_SIM_AT_KDF_INPUT 23 /* only AKA' */
15539beb93cSSam Leffler #define EAP_SIM_AT_KDF 24 /* only AKA' */
15639beb93cSSam Leffler #define EAP_SIM_AT_IV 129
15739beb93cSSam Leffler #define EAP_SIM_AT_ENCR_DATA 130
15839beb93cSSam Leffler #define EAP_SIM_AT_NEXT_PSEUDONYM 132 /* only encrypted */
15939beb93cSSam Leffler #define EAP_SIM_AT_NEXT_REAUTH_ID 133 /* only encrypted */
16039beb93cSSam Leffler #define EAP_SIM_AT_CHECKCODE 134 /* only AKA */
16139beb93cSSam Leffler #define EAP_SIM_AT_RESULT_IND 135
16239beb93cSSam Leffler #define EAP_SIM_AT_BIDDING 136
16339beb93cSSam Leffler
16439beb93cSSam Leffler /* AT_NOTIFICATION notification code values */
16539beb93cSSam Leffler #define EAP_SIM_GENERAL_FAILURE_AFTER_AUTH 0
16639beb93cSSam Leffler #define EAP_SIM_TEMPORARILY_DENIED 1026
16739beb93cSSam Leffler #define EAP_SIM_NOT_SUBSCRIBED 1031
16839beb93cSSam Leffler #define EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH 16384
16939beb93cSSam Leffler #define EAP_SIM_SUCCESS 32768
17039beb93cSSam Leffler
17139beb93cSSam Leffler /* EAP-AKA' AT_KDF Key Derivation Function values */
17239beb93cSSam Leffler #define EAP_AKA_PRIME_KDF 1
17339beb93cSSam Leffler
17439beb93cSSam Leffler /* AT_BIDDING flags */
17539beb93cSSam Leffler #define EAP_AKA_BIDDING_FLAG_D 0x8000
17639beb93cSSam Leffler
17739beb93cSSam Leffler
17839beb93cSSam Leffler enum eap_sim_id_req {
17939beb93cSSam Leffler NO_ID_REQ, ANY_ID, FULLAUTH_ID, PERMANENT_ID
18039beb93cSSam Leffler };
18139beb93cSSam Leffler
18239beb93cSSam Leffler
18339beb93cSSam Leffler struct eap_sim_attrs {
18439beb93cSSam Leffler const u8 *rand, *autn, *mac, *iv, *encr_data, *version_list, *nonce_s;
18539beb93cSSam Leffler const u8 *next_pseudonym, *next_reauth_id;
18639beb93cSSam Leffler const u8 *nonce_mt, *identity, *res, *auts;
18739beb93cSSam Leffler const u8 *checkcode;
18839beb93cSSam Leffler const u8 *kdf_input;
18939beb93cSSam Leffler const u8 *bidding;
19039beb93cSSam Leffler size_t num_chal, version_list_len, encr_data_len;
19139beb93cSSam Leffler size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
19239beb93cSSam Leffler size_t res_len_bits;
19339beb93cSSam Leffler size_t checkcode_len;
19439beb93cSSam Leffler size_t kdf_input_len;
19539beb93cSSam Leffler enum eap_sim_id_req id_req;
19639beb93cSSam Leffler int notification, counter, selected_version, client_error_code;
19739beb93cSSam Leffler int counter_too_small;
19839beb93cSSam Leffler int result_ind;
19939beb93cSSam Leffler #define EAP_AKA_PRIME_KDF_MAX 10
20039beb93cSSam Leffler u16 kdf[EAP_AKA_PRIME_KDF_MAX];
20139beb93cSSam Leffler size_t kdf_count;
20239beb93cSSam Leffler };
20339beb93cSSam Leffler
20439beb93cSSam Leffler int eap_sim_parse_attr(const u8 *start, const u8 *end,
20539beb93cSSam Leffler struct eap_sim_attrs *attr, int aka, int encr);
20639beb93cSSam Leffler u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data,
20739beb93cSSam Leffler size_t encr_data_len, const u8 *iv,
20839beb93cSSam Leffler struct eap_sim_attrs *attr, int aka);
20939beb93cSSam Leffler
21039beb93cSSam Leffler
21139beb93cSSam Leffler struct eap_sim_msg;
21239beb93cSSam Leffler
21339beb93cSSam Leffler struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype);
2145b9c547cSRui Paulo struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, int type,
2155b9c547cSRui Paulo const u8 *k_aut,
21639beb93cSSam Leffler const u8 *extra, size_t extra_len);
21739beb93cSSam Leffler void eap_sim_msg_free(struct eap_sim_msg *msg);
21839beb93cSSam Leffler u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr,
21939beb93cSSam Leffler const u8 *data, size_t len);
22039beb93cSSam Leffler u8 * eap_sim_msg_add(struct eap_sim_msg *msg, u8 attr,
22139beb93cSSam Leffler u16 value, const u8 *data, size_t len);
22239beb93cSSam Leffler u8 * eap_sim_msg_add_mac(struct eap_sim_msg *msg, u8 attr);
22339beb93cSSam Leffler int eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv,
22439beb93cSSam Leffler u8 attr_encr);
22539beb93cSSam Leffler int eap_sim_msg_add_encr_end(struct eap_sim_msg *msg, u8 *k_encr,
22639beb93cSSam Leffler int attr_pad);
22739beb93cSSam Leffler
22839beb93cSSam Leffler void eap_sim_report_notification(void *msg_ctx, int notification, int aka);
229*206b73d0SCy Schubert int eap_sim_anonymous_username(const u8 *id, size_t id_len);
23039beb93cSSam Leffler
23139beb93cSSam Leffler #endif /* EAP_SIM_COMMON_H */
232