aboutsummaryrefslogtreecommitdiffstats
path: root/src/eap_server
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-07-19 12:16:46 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-07-19 16:03:19 -0700
commit04949598a23f501be6eec21697465fd46a28840a (patch)
tree6eb315b8d139b0690cb644dc914c53bacb42df42 /src/eap_server
parentce1e0634ed741293de60d5ba3476b26ccbd58ce2 (diff)
downloadexternal_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.zip
external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.tar.gz
external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.tar.bz2
wpa_supplicant: Update to 07-Jul-2012 TOT
commit a5ed45586c63ffd8f9d2b44e27c251d7bacbeaf4 Author: Jouni Malinen <j@w1.fi> Date: Sat Jul 7 13:01:45 2012 +0300 WPS SSDP: Fix socket leaks on error paths Change-Id: I0864aac7fc88fa2a60f5cca7d524b94363410c85 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/eap_server')
-rw-r--r--src/eap_server/eap_server_aka.c45
-rw-r--r--src/eap_server/eap_server_pwd.c65
-rw-r--r--src/eap_server/eap_server_sim.c31
-rw-r--r--src/eap_server/eap_sim_db.c75
-rw-r--r--src/eap_server/eap_sim_db.h17
5 files changed, 155 insertions, 78 deletions
diff --git a/src/eap_server/eap_server_aka.c b/src/eap_server/eap_server_aka.c
index 135c02b..9cd5509 100644
--- a/src/eap_server/eap_server_aka.c
+++ b/src/eap_server/eap_server_aka.c
@@ -1,6 +1,6 @@
/*
- * hostapd / EAP-AKA (RFC 4187) and EAP-AKA' (draft-arkko-eap-aka-kdf)
- * Copyright (c) 2005-2008, Jouni Malinen <j@w1.fi>
+ * hostapd / EAP-AKA (RFC 4187) and EAP-AKA' (RFC 5448)
+ * Copyright (c) 2005-2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -266,8 +266,18 @@ static struct wpabuf * eap_aka_build_identity(struct eap_sm *sm,
EAP_AKA_SUBTYPE_IDENTITY);
if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity,
sm->identity_len)) {
- wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
- eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
+ if (sm->identity_len > 0 &&
+ (sm->identity[0] == EAP_AKA_REAUTH_ID_PREFIX ||
+ sm->identity[0] == EAP_AKA_PRIME_REAUTH_ID_PREFIX)) {
+ /* Reauth id may have expired - try fullauth */
+ wpa_printf(MSG_DEBUG, " AT_FULLAUTH_ID_REQ");
+ eap_sim_msg_add(msg, EAP_SIM_AT_FULLAUTH_ID_REQ, 0,
+ NULL, 0);
+ } else {
+ wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
+ eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0,
+ NULL, 0);
+ }
} else {
/*
* RFC 4187, Chap. 4.1.4 recommends that identity from EAP is
@@ -292,12 +302,23 @@ static int eap_aka_build_encr(struct eap_sm *sm, struct eap_aka_data *data,
const u8 *nonce_s)
{
os_free(data->next_pseudonym);
- data->next_pseudonym =
- eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 1);
+ if (nonce_s == NULL) {
+ data->next_pseudonym =
+ eap_sim_db_get_next_pseudonym(
+ sm->eap_sim_db_priv,
+ data->eap_method == EAP_TYPE_AKA_PRIME ?
+ EAP_SIM_DB_AKA_PRIME : EAP_SIM_DB_AKA);
+ } else {
+ /* Do not update pseudonym during re-authentication */
+ data->next_pseudonym = NULL;
+ }
os_free(data->next_reauth_id);
if (data->counter <= EAP_AKA_MAX_FAST_REAUTHS) {
data->next_reauth_id =
- eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 1);
+ eap_sim_db_get_next_reauth_id(
+ sm->eap_sim_db_priv,
+ data->eap_method == EAP_TYPE_AKA_PRIME ?
+ EAP_SIM_DB_AKA_PRIME : EAP_SIM_DB_AKA);
} else {
wpa_printf(MSG_DEBUG, "EAP-AKA: Max fast re-authentication "
"count exceeded - force full authentication");
@@ -615,7 +636,8 @@ static void eap_aka_determine_identity(struct eap_sm *sm,
identity = data->reauth->identity;
identity_len = data->reauth->identity_len;
} else if (sm->identity && sm->identity_len > 0 &&
- sm->identity[0] == EAP_AKA_PERMANENT_PREFIX) {
+ (sm->identity[0] == EAP_AKA_PERMANENT_PREFIX ||
+ sm->identity[0] == EAP_AKA_PRIME_PERMANENT_PREFIX)) {
identity = sm->identity;
identity_len = sm->identity_len;
} else {
@@ -731,7 +753,7 @@ static void eap_aka_determine_identity(struct eap_sm *sm,
sm->identity, identity_len);
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
- eap_aka_prime_derive_keys(identity, identity_len, data->ik,
+ eap_aka_prime_derive_keys(sm->identity, identity_len, data->ik,
data->ck, data->k_encr, data->k_aut,
data->k_re, data->msk, data->emsk);
} else {
@@ -1017,11 +1039,6 @@ static void eap_aka_process_reauth(struct eap_sm *sm,
identity_len = id2_len;
}
- if (data->next_pseudonym) {
- eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
- identity_len, data->next_pseudonym);
- data->next_pseudonym = NULL;
- }
if (data->next_reauth_id) {
if (data->eap_method == EAP_TYPE_AKA_PRIME) {
#ifdef EAP_SERVER_AKA_PRIME
diff --git a/src/eap_server/eap_server_pwd.c b/src/eap_server/eap_server_pwd.c
index 6c47dee..b61061b 100644
--- a/src/eap_server/eap_server_pwd.c
+++ b/src/eap_server/eap_server_pwd.c
@@ -9,6 +9,7 @@
#include "includes.h"
#include "common.h"
+#include "crypto/sha256.h"
#include "eap_server/eap_i.h"
#include "eap_common/eap_pwd_common.h"
@@ -40,7 +41,7 @@ struct eap_pwd_data {
EC_POINT *my_element;
EC_POINT *peer_element;
- u8 my_confirm[SHA256_DIGEST_LENGTH];
+ u8 my_confirm[SHA256_MAC_LEN];
u8 msk[EAP_MSK_LEN];
u8 emsk[EAP_EMSK_LEN];
@@ -288,8 +289,8 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
struct eap_pwd_data *data, u8 id)
{
BIGNUM *x = NULL, *y = NULL;
- HMAC_CTX ctx;
- u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+ struct crypto_hash *hash;
+ u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
u16 grp;
int offset;
@@ -313,7 +314,9 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
* commit is H(k | server_element | server_scalar | peer_element |
* peer_scalar | ciphersuite)
*/
- H_Init(&ctx);
+ hash = eap_pwd_h_init();
+ if (hash == NULL)
+ goto fin;
/*
* Zero the memory each time because this is mod prime math and some
@@ -324,7 +327,7 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
BN_bn2bin(data->k, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* server element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -338,18 +341,18 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
BN_bn2bin(x, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
BN_bn2bin(y, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* server scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->order) -
BN_num_bytes(data->my_scalar);
BN_bn2bin(data->my_scalar, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* peer element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -363,18 +366,18 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
BN_bn2bin(x, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
BN_bn2bin(y, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* peer scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->order) -
BN_num_bytes(data->peer_scalar);
BN_bn2bin(data->peer_scalar, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* ciphersuite */
grp = htons(data->group_num);
@@ -386,17 +389,17 @@ static void eap_pwd_build_confirm_req(struct eap_sm *sm,
ptr += sizeof(u8);
*ptr = EAP_PWD_DEFAULT_PRF;
ptr += sizeof(u8);
- H_Update(&ctx, cruft, ptr-cruft);
+ eap_pwd_h_update(hash, cruft, ptr - cruft);
/* all done with the random function */
- H_Final(&ctx, conf);
- os_memcpy(data->my_confirm, conf, SHA256_DIGEST_LENGTH);
+ eap_pwd_h_final(hash, conf);
+ os_memcpy(data->my_confirm, conf, SHA256_MAC_LEN);
- data->outbuf = wpabuf_alloc(SHA256_DIGEST_LENGTH);
+ data->outbuf = wpabuf_alloc(SHA256_MAC_LEN);
if (data->outbuf == NULL)
goto fin;
- wpabuf_put_data(data->outbuf, conf, SHA256_DIGEST_LENGTH);
+ wpabuf_put_data(data->outbuf, conf, SHA256_MAC_LEN);
fin:
os_free(cruft);
@@ -404,8 +407,6 @@ fin:
BN_free(y);
if (data->outbuf == NULL)
eap_pwd_state(data, FAILURE);
-
- return;
}
@@ -735,10 +736,10 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
const u8 *payload, size_t payload_len)
{
BIGNUM *x = NULL, *y = NULL;
- HMAC_CTX ctx;
+ struct crypto_hash *hash;
u32 cs;
u16 grp;
- u8 conf[SHA256_DIGEST_LENGTH], *cruft = NULL, *ptr;
+ u8 conf[SHA256_MAC_LEN], *cruft = NULL, *ptr;
int offset;
/* build up the ciphersuite: group | random_function | prf */
@@ -761,13 +762,15 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
* commit is H(k | peer_element | peer_scalar | server_element |
* server_scalar | ciphersuite)
*/
- H_Init(&ctx);
+ hash = eap_pwd_h_init();
+ if (hash == NULL)
+ goto fin;
/* k */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(data->k);
BN_bn2bin(data->k, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* peer element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -780,18 +783,18 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
BN_bn2bin(x, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
BN_bn2bin(y, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* peer scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->order) -
BN_num_bytes(data->peer_scalar);
BN_bn2bin(data->peer_scalar, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* server element: x, y */
if (!EC_POINT_get_affine_coordinates_GFp(data->grp->group,
@@ -805,28 +808,28 @@ eap_pwd_process_confirm_resp(struct eap_sm *sm, struct eap_pwd_data *data,
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(x);
BN_bn2bin(x, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->prime) - BN_num_bytes(y);
BN_bn2bin(y, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->prime));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->prime));
/* server scalar */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
offset = BN_num_bytes(data->grp->order) -
BN_num_bytes(data->my_scalar);
BN_bn2bin(data->my_scalar, cruft + offset);
- H_Update(&ctx, cruft, BN_num_bytes(data->grp->order));
+ eap_pwd_h_update(hash, cruft, BN_num_bytes(data->grp->order));
/* ciphersuite */
os_memset(cruft, 0, BN_num_bytes(data->grp->prime));
- H_Update(&ctx, (u8 *)&cs, sizeof(u32));
+ eap_pwd_h_update(hash, (u8 *) &cs, sizeof(u32));
/* all done */
- H_Final(&ctx, conf);
+ eap_pwd_h_final(hash, conf);
ptr = (u8 *) payload;
- if (os_memcmp(conf, ptr, SHA256_DIGEST_LENGTH)) {
+ if (os_memcmp(conf, ptr, SHA256_MAC_LEN)) {
wpa_printf(MSG_INFO, "EAP-PWD (server): confirm did not "
"verify");
goto fin;
diff --git a/src/eap_server/eap_server_sim.c b/src/eap_server/eap_server_sim.c
index f49f70e..6658d9c 100644
--- a/src/eap_server/eap_server_sim.c
+++ b/src/eap_server/eap_server_sim.c
@@ -107,8 +107,17 @@ static struct wpabuf * eap_sim_build_start(struct eap_sm *sm,
EAP_SIM_SUBTYPE_START);
if (eap_sim_db_identity_known(sm->eap_sim_db_priv, sm->identity,
sm->identity_len)) {
- wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
- eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0, NULL, 0);
+ if (sm->identity_len > 0 &&
+ sm->identity[0] == EAP_SIM_REAUTH_ID_PREFIX) {
+ /* Reauth id may have expired - try fullauth */
+ wpa_printf(MSG_DEBUG, " AT_FULLAUTH_ID_REQ");
+ eap_sim_msg_add(msg, EAP_SIM_AT_FULLAUTH_ID_REQ, 0,
+ NULL, 0);
+ } else {
+ wpa_printf(MSG_DEBUG, " AT_PERMANENT_ID_REQ");
+ eap_sim_msg_add(msg, EAP_SIM_AT_PERMANENT_ID_REQ, 0,
+ NULL, 0);
+ }
} else {
/*
* RFC 4186, Chap. 4.2.4 recommends that identity from EAP is
@@ -131,12 +140,19 @@ static int eap_sim_build_encr(struct eap_sm *sm, struct eap_sim_data *data,
const u8 *nonce_s)
{
os_free(data->next_pseudonym);
- data->next_pseudonym =
- eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv, 0);
+ if (nonce_s == NULL) {
+ data->next_pseudonym =
+ eap_sim_db_get_next_pseudonym(sm->eap_sim_db_priv,
+ EAP_SIM_DB_SIM);
+ } else {
+ /* Do not update pseudonym during re-authentication */
+ data->next_pseudonym = NULL;
+ }
os_free(data->next_reauth_id);
if (data->counter <= EAP_SIM_MAX_FAST_REAUTHS) {
data->next_reauth_id =
- eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv, 0);
+ eap_sim_db_get_next_reauth_id(sm->eap_sim_db_priv,
+ EAP_SIM_DB_SIM);
} else {
wpa_printf(MSG_DEBUG, "EAP-SIM: Max fast re-authentication "
"count exceeded - force full authentication");
@@ -616,11 +632,6 @@ static void eap_sim_process_reauth(struct eap_sm *sm,
identity_len = id2_len;
}
- if (data->next_pseudonym) {
- eap_sim_db_add_pseudonym(sm->eap_sim_db_priv, identity,
- identity_len, data->next_pseudonym);
- data->next_pseudonym = NULL;
- }
if (data->next_reauth_id) {
eap_sim_db_add_reauth(sm->eap_sim_db_priv, identity,
identity_len, data->next_reauth_id,
diff --git a/src/eap_server/eap_sim_db.c b/src/eap_server/eap_sim_db.c
index 9db26dc..ce3238c 100644
--- a/src/eap_server/eap_sim_db.c
+++ b/src/eap_server/eap_sim_db.c
@@ -1,6 +1,6 @@
/*
* hostapd / EAP-SIM database/authenticator gateway
- * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2010, 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -647,7 +647,8 @@ eap_sim_db_get_pseudonym(struct eap_sim_db_data *data, const u8 *identity,
if (identity_len == 0 ||
(identity[0] != EAP_SIM_PSEUDONYM_PREFIX &&
- identity[0] != EAP_AKA_PSEUDONYM_PREFIX))
+ identity[0] != EAP_AKA_PSEUDONYM_PREFIX &&
+ identity[0] != EAP_AKA_PRIME_PSEUDONYM_PREFIX))
return NULL;
/* Remove possible realm from identity */
@@ -685,7 +686,8 @@ eap_sim_db_get_pseudonym_id(struct eap_sim_db_data *data, const u8 *identity,
if (identity_len == 0 ||
(identity[0] != EAP_SIM_PERMANENT_PREFIX &&
- identity[0] != EAP_AKA_PERMANENT_PREFIX))
+ identity[0] != EAP_AKA_PERMANENT_PREFIX &&
+ identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX))
return NULL;
p = data->pseudonyms;
@@ -710,7 +712,8 @@ eap_sim_db_get_reauth(struct eap_sim_db_data *data, const u8 *identity,
if (identity_len == 0 ||
(identity[0] != EAP_SIM_REAUTH_ID_PREFIX &&
- identity[0] != EAP_AKA_REAUTH_ID_PREFIX))
+ identity[0] != EAP_AKA_REAUTH_ID_PREFIX &&
+ identity[0] != EAP_AKA_PRIME_REAUTH_ID_PREFIX))
return NULL;
/* Remove possible realm from identity */
@@ -777,8 +780,9 @@ eap_sim_db_get_reauth_id(struct eap_sim_db_data *data, const u8 *identity,
* @identity_len: Length of identity in bytes
* Returns: 0 if the user is found or -1 on failure
*
- * In most cases, the user name is ['0','1'] | IMSI, i.e., 1 followed by the
- * IMSI in ASCII format, ['2','3'] | pseudonym, or ['4','5'] | reauth_id.
+ * In most cases, the user name is ['0','1','6'] | IMSI, i.e., 1 followed by
+ * the IMSI in ASCII format for EAP-SIM, ['2','3','7'] | pseudonym, or
+ * ['4','5','7'] | reauth_id.
*/
int eap_sim_db_identity_known(void *priv, const u8 *identity,
size_t identity_len)
@@ -789,21 +793,24 @@ int eap_sim_db_identity_known(void *priv, const u8 *identity,
return -1;
if (identity[0] == EAP_SIM_PSEUDONYM_PREFIX ||
- identity[0] == EAP_AKA_PSEUDONYM_PREFIX) {
+ identity[0] == EAP_AKA_PSEUDONYM_PREFIX ||
+ identity[0] == EAP_AKA_PRIME_PSEUDONYM_PREFIX) {
struct eap_sim_pseudonym *p =
eap_sim_db_get_pseudonym(data, identity, identity_len);
return p ? 0 : -1;
}
if (identity[0] == EAP_SIM_REAUTH_ID_PREFIX ||
- identity[0] == EAP_AKA_REAUTH_ID_PREFIX) {
+ identity[0] == EAP_AKA_REAUTH_ID_PREFIX ||
+ identity[0] == EAP_AKA_PRIME_REAUTH_ID_PREFIX) {
struct eap_sim_reauth *r =
eap_sim_db_get_reauth(data, identity, identity_len);
return r ? 0 : -1;
}
if (identity[0] != EAP_SIM_PERMANENT_PREFIX &&
- identity[0] != EAP_AKA_PERMANENT_PREFIX) {
+ identity[0] != EAP_AKA_PERMANENT_PREFIX &&
+ identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX) {
/* Unknown identity prefix */
return -1;
}
@@ -843,7 +850,7 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
/**
* eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym
* @priv: Private data pointer from eap_sim_db_init()
- * @aka: Using EAP-AKA instead of EAP-SIM
+ * @method: EAP method (SIM/AKA/AKA')
* Returns: Next pseudonym (allocated string) or %NULL on failure
*
* This function is used to generate a pseudonym for EAP-SIM. The returned
@@ -851,18 +858,31 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
* with eap_sim_db_add_pseudonym() once the authentication has been completed
* successfully. Caller is responsible for freeing the returned buffer.
*/
-char * eap_sim_db_get_next_pseudonym(void *priv, int aka)
+char * eap_sim_db_get_next_pseudonym(void *priv, enum eap_sim_db_method method)
{
struct eap_sim_db_data *data = priv;
- return eap_sim_db_get_next(data, aka ? EAP_AKA_PSEUDONYM_PREFIX :
- EAP_SIM_PSEUDONYM_PREFIX);
+ char prefix = EAP_SIM_REAUTH_ID_PREFIX;
+
+ switch (method) {
+ case EAP_SIM_DB_SIM:
+ prefix = EAP_SIM_PSEUDONYM_PREFIX;
+ break;
+ case EAP_SIM_DB_AKA:
+ prefix = EAP_AKA_PSEUDONYM_PREFIX;
+ break;
+ case EAP_SIM_DB_AKA_PRIME:
+ prefix = EAP_AKA_PRIME_PSEUDONYM_PREFIX;
+ break;
+ }
+
+ return eap_sim_db_get_next(data, prefix);
}
/**
* eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id
* @priv: Private data pointer from eap_sim_db_init()
- * @aka: Using EAP-AKA instead of EAP-SIM
+ * @method: EAP method (SIM/AKA/AKA')
* Returns: Next reauth_id (allocated string) or %NULL on failure
*
* This function is used to generate a fast re-authentication identity for
@@ -871,11 +891,24 @@ char * eap_sim_db_get_next_pseudonym(void *priv, int aka)
* has been completed successfully. Caller is responsible for freeing the
* returned buffer.
*/
-char * eap_sim_db_get_next_reauth_id(void *priv, int aka)
+char * eap_sim_db_get_next_reauth_id(void *priv, enum eap_sim_db_method method)
{
struct eap_sim_db_data *data = priv;
- return eap_sim_db_get_next(data, aka ? EAP_AKA_REAUTH_ID_PREFIX :
- EAP_SIM_REAUTH_ID_PREFIX);
+ char prefix = EAP_SIM_REAUTH_ID_PREFIX;
+
+ switch (method) {
+ case EAP_SIM_DB_SIM:
+ prefix = EAP_SIM_REAUTH_ID_PREFIX;
+ break;
+ case EAP_SIM_DB_AKA:
+ prefix = EAP_AKA_REAUTH_ID_PREFIX;
+ break;
+ case EAP_SIM_DB_AKA_PRIME:
+ prefix = EAP_AKA_PRIME_REAUTH_ID_PREFIX;
+ break;
+ }
+
+ return eap_sim_db_get_next(data, prefix);
}
@@ -1156,7 +1189,7 @@ void eap_sim_db_remove_reauth(void *priv, struct eap_sim_reauth *reauth)
* called once the results become available.
*
* In most cases, the user name is '0' | IMSI, i.e., 0 followed by the IMSI in
- * ASCII format.
+ * ASCII format for EAP-AKA and '6' | IMSI for EAP-AKA'.
*
* When using an external server for AKA authentication, this function can
* always start a request and return EAP_SIM_DB_PENDING immediately if
@@ -1178,7 +1211,8 @@ int eap_sim_db_get_aka_auth(void *priv, const u8 *identity,
char msg[40];
if (identity_len < 2 || identity == NULL ||
- identity[0] != EAP_AKA_PERMANENT_PREFIX) {
+ (identity[0] != EAP_AKA_PERMANENT_PREFIX &&
+ identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX)) {
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
identity, identity_len);
return EAP_SIM_DB_FAILURE;
@@ -1281,7 +1315,8 @@ int eap_sim_db_resynchronize(void *priv, const u8 *identity,
size_t i;
if (identity_len < 2 || identity == NULL ||
- identity[0] != EAP_AKA_PERMANENT_PREFIX) {
+ (identity[0] != EAP_AKA_PERMANENT_PREFIX &&
+ identity[0] != EAP_AKA_PRIME_PERMANENT_PREFIX)) {
wpa_hexdump_ascii(MSG_DEBUG, "EAP-SIM DB: unexpected identity",
identity, identity_len);
return -1;
diff --git a/src/eap_server/eap_sim_db.h b/src/eap_server/eap_sim_db.h
index abe185e..1f6375a 100644
--- a/src/eap_server/eap_sim_db.h
+++ b/src/eap_server/eap_sim_db.h
@@ -1,6 +1,6 @@
/*
* hostapd / EAP-SIM database/authenticator gateway
- * Copyright (c) 2005-2007, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2005-2008, 2012, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@@ -18,6 +18,15 @@
#define EAP_AKA_PERMANENT_PREFIX '0'
#define EAP_AKA_PSEUDONYM_PREFIX '2'
#define EAP_AKA_REAUTH_ID_PREFIX '4'
+#define EAP_AKA_PRIME_PERMANENT_PREFIX '6'
+#define EAP_AKA_PRIME_PSEUDONYM_PREFIX '7'
+#define EAP_AKA_PRIME_REAUTH_ID_PREFIX '8'
+
+enum eap_sim_db_method {
+ EAP_SIM_DB_SIM,
+ EAP_SIM_DB_AKA,
+ EAP_SIM_DB_AKA_PRIME
+};
void * eap_sim_db_init(const char *config,
void (*get_complete_cb)(void *ctx, void *session_ctx),
@@ -36,9 +45,11 @@ int eap_sim_db_get_gsm_triplets(void *priv, const u8 *identity,
int eap_sim_db_identity_known(void *priv, const u8 *identity,
size_t identity_len);
-char * eap_sim_db_get_next_pseudonym(void *priv, int aka);
+char * eap_sim_db_get_next_pseudonym(void *priv,
+ enum eap_sim_db_method method);
-char * eap_sim_db_get_next_reauth_id(void *priv, int aka);
+char * eap_sim_db_get_next_reauth_id(void *priv,
+ enum eap_sim_db_method method);
int eap_sim_db_add_pseudonym(void *priv, const u8 *identity,
size_t identity_len, char *pseudonym);