16d49e1aeSJan Lentfer /*
26d49e1aeSJan Lentfer  * EAP peer/server: EAP-SIM/AKA/AKA' shared routines
36d49e1aeSJan Lentfer  * Copyright (c) 2004-2008, Jouni Malinen <j@w1.fi>
46d49e1aeSJan Lentfer  *
53ff40c12SJohn Marino  * This software may be distributed under the terms of the BSD license.
63ff40c12SJohn Marino  * See README for more details.
76d49e1aeSJan Lentfer  */
86d49e1aeSJan Lentfer 
96d49e1aeSJan Lentfer #ifndef EAP_SIM_COMMON_H
106d49e1aeSJan Lentfer #define EAP_SIM_COMMON_H
116d49e1aeSJan Lentfer 
126d49e1aeSJan Lentfer #define EAP_SIM_NONCE_S_LEN 16
136d49e1aeSJan Lentfer #define EAP_SIM_NONCE_MT_LEN 16
146d49e1aeSJan Lentfer #define EAP_SIM_MAC_LEN 16
156d49e1aeSJan Lentfer #define EAP_SIM_MK_LEN 20
166d49e1aeSJan Lentfer #define EAP_SIM_K_AUT_LEN 16
176d49e1aeSJan Lentfer #define EAP_SIM_K_ENCR_LEN 16
186d49e1aeSJan Lentfer #define EAP_SIM_KEYING_DATA_LEN 64
196d49e1aeSJan Lentfer #define EAP_SIM_IV_LEN 16
206d49e1aeSJan Lentfer #define EAP_SIM_KC_LEN 8
216d49e1aeSJan Lentfer #define EAP_SIM_SRES_LEN 4
226d49e1aeSJan Lentfer 
236d49e1aeSJan Lentfer #define GSM_RAND_LEN 16
246d49e1aeSJan Lentfer 
256d49e1aeSJan Lentfer #define EAP_SIM_VERSION 1
266d49e1aeSJan Lentfer 
276d49e1aeSJan Lentfer /* EAP-SIM Subtypes */
286d49e1aeSJan Lentfer #define EAP_SIM_SUBTYPE_START 10
296d49e1aeSJan Lentfer #define EAP_SIM_SUBTYPE_CHALLENGE 11
306d49e1aeSJan Lentfer #define EAP_SIM_SUBTYPE_NOTIFICATION 12
316d49e1aeSJan Lentfer #define EAP_SIM_SUBTYPE_REAUTHENTICATION 13
326d49e1aeSJan Lentfer #define EAP_SIM_SUBTYPE_CLIENT_ERROR 14
336d49e1aeSJan Lentfer 
346d49e1aeSJan Lentfer /* AT_CLIENT_ERROR_CODE error codes */
356d49e1aeSJan Lentfer #define EAP_SIM_UNABLE_TO_PROCESS_PACKET 0
366d49e1aeSJan Lentfer #define EAP_SIM_UNSUPPORTED_VERSION 1
376d49e1aeSJan Lentfer #define EAP_SIM_INSUFFICIENT_NUM_OF_CHAL 2
386d49e1aeSJan Lentfer #define EAP_SIM_RAND_NOT_FRESH 3
396d49e1aeSJan Lentfer 
406d49e1aeSJan Lentfer #define EAP_SIM_MAX_FAST_REAUTHS 1000
416d49e1aeSJan Lentfer 
426d49e1aeSJan Lentfer #define EAP_SIM_MAX_CHAL 3
436d49e1aeSJan Lentfer 
446d49e1aeSJan Lentfer 
456d49e1aeSJan Lentfer /* EAP-AKA Subtypes */
466d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_CHALLENGE 1
476d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_AUTHENTICATION_REJECT 2
486d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_SYNCHRONIZATION_FAILURE 4
496d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_IDENTITY 5
506d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_NOTIFICATION 12
516d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_REAUTHENTICATION 13
526d49e1aeSJan Lentfer #define EAP_AKA_SUBTYPE_CLIENT_ERROR 14
536d49e1aeSJan Lentfer 
546d49e1aeSJan Lentfer /* AT_CLIENT_ERROR_CODE error codes */
556d49e1aeSJan Lentfer #define EAP_AKA_UNABLE_TO_PROCESS_PACKET 0
566d49e1aeSJan Lentfer 
576d49e1aeSJan Lentfer #define EAP_AKA_RAND_LEN 16
586d49e1aeSJan Lentfer #define EAP_AKA_AUTN_LEN 16
596d49e1aeSJan Lentfer #define EAP_AKA_AUTS_LEN 14
606d49e1aeSJan Lentfer #define EAP_AKA_RES_MAX_LEN 16
616d49e1aeSJan Lentfer #define EAP_AKA_IK_LEN 16
626d49e1aeSJan Lentfer #define EAP_AKA_CK_LEN 16
636d49e1aeSJan Lentfer #define EAP_AKA_MAX_FAST_REAUTHS 1000
646d49e1aeSJan Lentfer #define EAP_AKA_MIN_RES_LEN 4
656d49e1aeSJan Lentfer #define EAP_AKA_MAX_RES_LEN 16
666d49e1aeSJan Lentfer #define EAP_AKA_CHECKCODE_LEN 20
676d49e1aeSJan Lentfer 
686d49e1aeSJan Lentfer #define EAP_AKA_PRIME_K_AUT_LEN 32
696d49e1aeSJan Lentfer #define EAP_AKA_PRIME_CHECKCODE_LEN 32
706d49e1aeSJan Lentfer #define EAP_AKA_PRIME_K_RE_LEN 32
716d49e1aeSJan Lentfer 
726d49e1aeSJan Lentfer struct wpabuf;
736d49e1aeSJan Lentfer 
746d49e1aeSJan Lentfer void eap_sim_derive_mk(const u8 *identity, size_t identity_len,
756d49e1aeSJan Lentfer 		       const u8 *nonce_mt, u16 selected_version,
766d49e1aeSJan Lentfer 		       const u8 *ver_list, size_t ver_list_len,
776d49e1aeSJan Lentfer 		       int num_chal, const u8 *kc, u8 *mk);
786d49e1aeSJan Lentfer void eap_aka_derive_mk(const u8 *identity, size_t identity_len,
796d49e1aeSJan Lentfer 		       const u8 *ik, const u8 *ck, u8 *mk);
806d49e1aeSJan Lentfer int eap_sim_derive_keys(const u8 *mk, u8 *k_encr, u8 *k_aut, u8 *msk,
816d49e1aeSJan Lentfer 			u8 *emsk);
826d49e1aeSJan Lentfer int eap_sim_derive_keys_reauth(u16 _counter,
836d49e1aeSJan Lentfer 			       const u8 *identity, size_t identity_len,
846d49e1aeSJan Lentfer 			       const u8 *nonce_s, const u8 *mk, u8 *msk,
856d49e1aeSJan Lentfer 			       u8 *emsk);
866d49e1aeSJan Lentfer int eap_sim_verify_mac(const u8 *k_aut, const struct wpabuf *req,
876d49e1aeSJan Lentfer 		       const u8 *mac, const u8 *extra, size_t extra_len);
886d49e1aeSJan Lentfer void eap_sim_add_mac(const u8 *k_aut, const u8 *msg, size_t msg_len, u8 *mac,
896d49e1aeSJan Lentfer 		     const u8 *extra, size_t extra_len);
906d49e1aeSJan Lentfer 
913ff40c12SJohn Marino #if defined(EAP_AKA_PRIME) || defined(EAP_SERVER_AKA_PRIME)
926d49e1aeSJan Lentfer void eap_aka_prime_derive_keys(const u8 *identity, size_t identity_len,
936d49e1aeSJan Lentfer 			       const u8 *ik, const u8 *ck, u8 *k_encr,
946d49e1aeSJan Lentfer 			       u8 *k_aut, u8 *k_re, u8 *msk, u8 *emsk);
956d49e1aeSJan Lentfer int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
966d49e1aeSJan Lentfer 				     const u8 *identity, size_t identity_len,
976d49e1aeSJan Lentfer 				     const u8 *nonce_s, u8 *msk, u8 *emsk);
986d49e1aeSJan Lentfer int eap_sim_verify_mac_sha256(const u8 *k_aut, const struct wpabuf *req,
996d49e1aeSJan Lentfer 			      const u8 *mac, const u8 *extra,
1006d49e1aeSJan Lentfer 			      size_t extra_len);
1016d49e1aeSJan Lentfer void eap_sim_add_mac_sha256(const u8 *k_aut, const u8 *msg, size_t msg_len,
1026d49e1aeSJan Lentfer 			    u8 *mac, const u8 *extra, size_t extra_len);
1036d49e1aeSJan Lentfer 
1046d49e1aeSJan Lentfer void eap_aka_prime_derive_ck_ik_prime(u8 *ck, u8 *ik, const u8 *sqn_ak,
1056d49e1aeSJan Lentfer 				      const u8 *network_name,
1066d49e1aeSJan Lentfer 				      size_t network_name_len);
1073ff40c12SJohn Marino #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)1086d49e1aeSJan Lentfer static inline void eap_aka_prime_derive_keys(const u8 *identity,
1096d49e1aeSJan Lentfer 					     size_t identity_len,
1106d49e1aeSJan Lentfer 					     const u8 *ik, const u8 *ck,
1116d49e1aeSJan Lentfer 					     u8 *k_encr, u8 *k_aut, u8 *k_re,
1126d49e1aeSJan Lentfer 					     u8 *msk, u8 *emsk)
1136d49e1aeSJan Lentfer {
1146d49e1aeSJan Lentfer }
1156d49e1aeSJan Lentfer 
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)1166d49e1aeSJan Lentfer static inline int eap_aka_prime_derive_keys_reauth(const u8 *k_re, u16 counter,
1176d49e1aeSJan Lentfer 						   const u8 *identity,
1186d49e1aeSJan Lentfer 						   size_t identity_len,
1196d49e1aeSJan Lentfer 						   const u8 *nonce_s, u8 *msk,
1206d49e1aeSJan Lentfer 						   u8 *emsk)
1216d49e1aeSJan Lentfer {
1226d49e1aeSJan Lentfer 	return -1;
1236d49e1aeSJan Lentfer }
1246d49e1aeSJan Lentfer 
eap_sim_verify_mac_sha256(const u8 * k_aut,const struct wpabuf * req,const u8 * mac,const u8 * extra,size_t extra_len)1256d49e1aeSJan Lentfer static inline int eap_sim_verify_mac_sha256(const u8 *k_aut,
1266d49e1aeSJan Lentfer 					    const struct wpabuf *req,
1276d49e1aeSJan Lentfer 					    const u8 *mac, const u8 *extra,
1286d49e1aeSJan Lentfer 					    size_t extra_len)
1296d49e1aeSJan Lentfer {
1306d49e1aeSJan Lentfer 	return -1;
1316d49e1aeSJan Lentfer }
1323ff40c12SJohn Marino #endif /* EAP_AKA_PRIME || EAP_SERVER_AKA_PRIME */
1336d49e1aeSJan Lentfer 
1346d49e1aeSJan Lentfer 
1356d49e1aeSJan Lentfer /* EAP-SIM/AKA Attributes (0..127 non-skippable) */
1366d49e1aeSJan Lentfer #define EAP_SIM_AT_RAND 1
1376d49e1aeSJan Lentfer #define EAP_SIM_AT_AUTN 2 /* only AKA */
1386d49e1aeSJan Lentfer #define EAP_SIM_AT_RES 3 /* only AKA, only peer->server */
1396d49e1aeSJan Lentfer #define EAP_SIM_AT_AUTS 4 /* only AKA, only peer->server */
1406d49e1aeSJan Lentfer #define EAP_SIM_AT_PADDING 6 /* only encrypted */
1416d49e1aeSJan Lentfer #define EAP_SIM_AT_NONCE_MT 7 /* only SIM, only send */
1426d49e1aeSJan Lentfer #define EAP_SIM_AT_PERMANENT_ID_REQ 10
1436d49e1aeSJan Lentfer #define EAP_SIM_AT_MAC 11
1446d49e1aeSJan Lentfer #define EAP_SIM_AT_NOTIFICATION 12
1456d49e1aeSJan Lentfer #define EAP_SIM_AT_ANY_ID_REQ 13
1466d49e1aeSJan Lentfer #define EAP_SIM_AT_IDENTITY 14 /* only send */
1476d49e1aeSJan Lentfer #define EAP_SIM_AT_VERSION_LIST 15 /* only SIM */
1486d49e1aeSJan Lentfer #define EAP_SIM_AT_SELECTED_VERSION 16 /* only SIM */
1496d49e1aeSJan Lentfer #define EAP_SIM_AT_FULLAUTH_ID_REQ 17
1506d49e1aeSJan Lentfer #define EAP_SIM_AT_COUNTER 19 /* only encrypted */
1516d49e1aeSJan Lentfer #define EAP_SIM_AT_COUNTER_TOO_SMALL 20 /* only encrypted */
1526d49e1aeSJan Lentfer #define EAP_SIM_AT_NONCE_S 21 /* only encrypted */
1536d49e1aeSJan Lentfer #define EAP_SIM_AT_CLIENT_ERROR_CODE 22 /* only send */
1546d49e1aeSJan Lentfer #define EAP_SIM_AT_KDF_INPUT 23 /* only AKA' */
1556d49e1aeSJan Lentfer #define EAP_SIM_AT_KDF 24 /* only AKA' */
1566d49e1aeSJan Lentfer #define EAP_SIM_AT_IV 129
1576d49e1aeSJan Lentfer #define EAP_SIM_AT_ENCR_DATA 130
1586d49e1aeSJan Lentfer #define EAP_SIM_AT_NEXT_PSEUDONYM 132 /* only encrypted */
1596d49e1aeSJan Lentfer #define EAP_SIM_AT_NEXT_REAUTH_ID 133 /* only encrypted */
1606d49e1aeSJan Lentfer #define EAP_SIM_AT_CHECKCODE 134 /* only AKA */
1616d49e1aeSJan Lentfer #define EAP_SIM_AT_RESULT_IND 135
1626d49e1aeSJan Lentfer #define EAP_SIM_AT_BIDDING 136
1636d49e1aeSJan Lentfer 
1646d49e1aeSJan Lentfer /* AT_NOTIFICATION notification code values */
1656d49e1aeSJan Lentfer #define EAP_SIM_GENERAL_FAILURE_AFTER_AUTH 0
1666d49e1aeSJan Lentfer #define EAP_SIM_TEMPORARILY_DENIED 1026
1676d49e1aeSJan Lentfer #define EAP_SIM_NOT_SUBSCRIBED 1031
1686d49e1aeSJan Lentfer #define EAP_SIM_GENERAL_FAILURE_BEFORE_AUTH 16384
1696d49e1aeSJan Lentfer #define EAP_SIM_SUCCESS 32768
1706d49e1aeSJan Lentfer 
1716d49e1aeSJan Lentfer /* EAP-AKA' AT_KDF Key Derivation Function values */
1726d49e1aeSJan Lentfer #define EAP_AKA_PRIME_KDF 1
1736d49e1aeSJan Lentfer 
1746d49e1aeSJan Lentfer /* AT_BIDDING flags */
1756d49e1aeSJan Lentfer #define EAP_AKA_BIDDING_FLAG_D 0x8000
1766d49e1aeSJan Lentfer 
1776d49e1aeSJan Lentfer 
1786d49e1aeSJan Lentfer enum eap_sim_id_req {
1796d49e1aeSJan Lentfer 	NO_ID_REQ, ANY_ID, FULLAUTH_ID, PERMANENT_ID
1806d49e1aeSJan Lentfer };
1816d49e1aeSJan Lentfer 
1826d49e1aeSJan Lentfer 
1836d49e1aeSJan Lentfer struct eap_sim_attrs {
1846d49e1aeSJan Lentfer 	const u8 *rand, *autn, *mac, *iv, *encr_data, *version_list, *nonce_s;
1856d49e1aeSJan Lentfer 	const u8 *next_pseudonym, *next_reauth_id;
1866d49e1aeSJan Lentfer 	const u8 *nonce_mt, *identity, *res, *auts;
1876d49e1aeSJan Lentfer 	const u8 *checkcode;
1886d49e1aeSJan Lentfer 	const u8 *kdf_input;
1896d49e1aeSJan Lentfer 	const u8 *bidding;
1906d49e1aeSJan Lentfer 	size_t num_chal, version_list_len, encr_data_len;
1916d49e1aeSJan Lentfer 	size_t next_pseudonym_len, next_reauth_id_len, identity_len, res_len;
1926d49e1aeSJan Lentfer 	size_t res_len_bits;
1936d49e1aeSJan Lentfer 	size_t checkcode_len;
1946d49e1aeSJan Lentfer 	size_t kdf_input_len;
1956d49e1aeSJan Lentfer 	enum eap_sim_id_req id_req;
1966d49e1aeSJan Lentfer 	int notification, counter, selected_version, client_error_code;
1976d49e1aeSJan Lentfer 	int counter_too_small;
1986d49e1aeSJan Lentfer 	int result_ind;
1996d49e1aeSJan Lentfer #define EAP_AKA_PRIME_KDF_MAX 10
2006d49e1aeSJan Lentfer 	u16 kdf[EAP_AKA_PRIME_KDF_MAX];
2016d49e1aeSJan Lentfer 	size_t kdf_count;
2026d49e1aeSJan Lentfer };
2036d49e1aeSJan Lentfer 
2046d49e1aeSJan Lentfer int eap_sim_parse_attr(const u8 *start, const u8 *end,
2056d49e1aeSJan Lentfer 		       struct eap_sim_attrs *attr, int aka, int encr);
2066d49e1aeSJan Lentfer u8 * eap_sim_parse_encr(const u8 *k_encr, const u8 *encr_data,
2076d49e1aeSJan Lentfer 			size_t encr_data_len, const u8 *iv,
2086d49e1aeSJan Lentfer 			struct eap_sim_attrs *attr, int aka);
2096d49e1aeSJan Lentfer 
2106d49e1aeSJan Lentfer 
2116d49e1aeSJan Lentfer struct eap_sim_msg;
2126d49e1aeSJan Lentfer 
2136d49e1aeSJan Lentfer struct eap_sim_msg * eap_sim_msg_init(int code, int id, int type, int subtype);
214*a1157835SDaniel Fojt struct wpabuf * eap_sim_msg_finish(struct eap_sim_msg *msg, int type,
215*a1157835SDaniel Fojt 				   const u8 *k_aut,
2166d49e1aeSJan Lentfer 				   const u8 *extra, size_t extra_len);
2176d49e1aeSJan Lentfer void eap_sim_msg_free(struct eap_sim_msg *msg);
2186d49e1aeSJan Lentfer u8 * eap_sim_msg_add_full(struct eap_sim_msg *msg, u8 attr,
2196d49e1aeSJan Lentfer 			  const u8 *data, size_t len);
2206d49e1aeSJan Lentfer u8 * eap_sim_msg_add(struct eap_sim_msg *msg, u8 attr,
2216d49e1aeSJan Lentfer 		     u16 value, const u8 *data, size_t len);
2226d49e1aeSJan Lentfer u8 * eap_sim_msg_add_mac(struct eap_sim_msg *msg, u8 attr);
2236d49e1aeSJan Lentfer int eap_sim_msg_add_encr_start(struct eap_sim_msg *msg, u8 attr_iv,
2246d49e1aeSJan Lentfer 			       u8 attr_encr);
2256d49e1aeSJan Lentfer int eap_sim_msg_add_encr_end(struct eap_sim_msg *msg, u8 *k_encr,
2266d49e1aeSJan Lentfer 			     int attr_pad);
2276d49e1aeSJan Lentfer 
2286d49e1aeSJan Lentfer void eap_sim_report_notification(void *msg_ctx, int notification, int aka);
229*a1157835SDaniel Fojt int eap_sim_anonymous_username(const u8 *id, size_t id_len);
2306d49e1aeSJan Lentfer 
2316d49e1aeSJan Lentfer #endif /* EAP_SIM_COMMON_H */
232