optional auth wip

Change-Id: I8ec126b4015d3a6776b60df7d79e4b43428ae0f5
Neels Hofmeyr 2 months ago
parent e28ea985d2
commit 37e6e72325
  1. 10
      include/osmocom/msc/vlr.h
  2. 18
      src/libmsc/gsm_04_08.c
  3. 10
      src/libmsc/msc_a.c
  4. 11
      src/libvlr/vlr_auth_fsm.c
  5. 29
      src/libvlr/vlr_lu_fsm.c

@ -288,6 +288,13 @@ static inline const char *vlr_ciph_name(enum vlr_ciph val)
return get_value_string(vlr_ciph_names, val);
}
struct vlr_auth_ciph {
bool is_utran;
bool auth_required;
uint8_t a5_encryption_mask;
uint8_t uea_encryption_mask;
};
/* Location Updating request */
struct osmo_fsm_inst *
vlr_loc_update(struct osmo_fsm_inst *parent,
@ -298,8 +305,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
const struct osmo_location_area_id *old_lai,
const struct osmo_location_area_id *new_lai,
bool authentication_required,
bool ciphering_required,
const struct vlr_auth_ciph *auth_ciph,
uint8_t key_seq,
bool is_r99, bool is_utran,
bool assign_tmsi);

@ -408,16 +408,28 @@ static int mm_rx_loc_upd_req(struct msc_a *msc_a, struct msgb *msg)
gsm48_decode_lai2(&lu->lai, &old_lai);
LOG_MSC_A_CAT(msc_a, DMM, LOGL_DEBUG, "USIM: old LAI: %s\n", osmo_lai_name(&old_lai));
is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
if (!is_utran && !net->a5_encryption_mask) {
LOG_MSC_A(msc_a, LOGL_ERROR, "No A5 algorithm is enabled (no A5/0, nor any A5/n > 0)\n");
return -ENOTSUP;
}
if (is_utran && !net->uea_encryption_mask) {
LOG_MSC_A(msc_a, LOGL_ERROR, "No UEA algorithm is enabled (no UEA0, nor any UEAn > 0)\n");
return -ENOTSUP;
}
msc_a_get(msc_a, __func__);
msc_a_get(msc_a, MSC_A_USE_LOCATION_UPDATING);
is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
lu_fsm = vlr_loc_update(msc_a->c.fi,
MSC_A_EV_AUTHENTICATED, MSC_A_EV_CN_CLOSE, NULL,
net->vlr, msc_a, vlr_lu_type, tmsi, imsi,
&old_lai, &msc_a->via_cell.lai,
is_utran || net->authentication_required,
msc_a_require_ciphering(msc_a),
is_utran,
net->authentication_required,
net->a5_encryption_mask,
net->uea_encryption_mask,
lu->key_seq,
osmo_gsm48_classmark1_is_r99(&lu->classmark1),
is_utran,

@ -108,16 +108,6 @@ struct msc_a *msc_a_fi_priv(struct osmo_fsm_inst *fi)
return fi->priv;
}
bool msc_a_require_ciphering(const struct msc_a *msc_a)
{
struct gsm_network *net = msc_a_net(msc_a);
bool is_utran = (msc_a->c.ran->type == OSMO_RAT_UTRAN_IU);
if (is_utran)
return net->uea_encryption_mask > (1 << OSMO_UTRAN_UEA0);
else
return net->a5_encryption_mask > 0x1;
}
static void update_counters(struct osmo_fsm_inst *fi, bool conn_accepted)
{
struct msc_a *msc_a = fi->priv;

@ -49,6 +49,7 @@ struct auth_fsm_priv {
bool is_r99;
bool is_utran;
bool auth_requested;
bool auth_mandatory;
int auth_tuple_max_reuse_count; /* see vlr->cfg instead */
};
@ -344,6 +345,12 @@ static void auth_fsm_wait_ai(struct osmo_fsm_inst *fi, uint32_t event,
|| (event == VLR_AUTH_E_HLR_SAI_NACK &&
gsup->cause != GMM_CAUSE_IMSI_UNKNOWN)
|| (event == VLR_AUTH_E_HLR_SAI_ABORT)) {
/* We have no auth tuples. If Authentication is optional i.e. A5/0 is allowed, continue without
* authentication. */
if (!afp->auth_mandatory) {
}
if (vsub->vlr->cfg.auth_reuse_old_sets_on_error
&& vlr_subscr_has_auth_tuple(vsub, -1)) {
/* To re-use an old tuple, disable the max_reuse_count
@ -595,7 +602,8 @@ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
struct osmo_fsm_inst *parent,
uint32_t parent_term_event,
bool is_r99,
bool is_utran)
bool is_utran,
bool auth_mandatory)
{
struct osmo_fsm_inst *fi;
struct auth_fsm_priv *afp;
@ -618,6 +626,7 @@ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
afp->by_imsi = true;
afp->is_r99 = is_r99;
afp->is_utran = is_utran;
afp->auth_mandatory = auth_mandatory || is_utran;
fi->priv = afp;
vsub->auth_fsm = fi;

@ -676,6 +676,7 @@ struct lu_fsm_priv {
struct osmo_location_area_id old_lai;
struct osmo_location_area_id new_lai;
bool authentication_required;
uint8_t a5_encryption_mask;
bool ciphering_required;
uint8_t key_seq;
bool is_r99;
@ -1465,6 +1466,21 @@ static inline struct lu_fsm_priv *lu_fsm_fi_priv(struct osmo_fsm_inst *fi)
return (struct lu_fsm_priv*)fi->priv;
}
static bool require_ciphering(const struct vlr_auth_ciph *auth_ciph)
{
if (auth_ciph->is_utran)
return (auth_ciph->uea_encryption_mask && (1 << OSMO_UTRAN_UEA0)) == 0;
else
return (auth_ciph->a5_encryption_mask & GSM0808_ALG_ID_A5_0) == 0;
}
static bool require_auth(const struct vlr_auth_ciph *auth_ciph)
{
if (auth_ciph->is_utran)
return true;
return require_ciphering(auth_ciph);
}
struct osmo_fsm_inst *
vlr_loc_update(struct osmo_fsm_inst *parent,
uint32_t parent_event_success,
@ -1474,19 +1490,23 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
enum vlr_lu_type type, uint32_t tmsi, const char *imsi,
const struct osmo_location_area_id *old_lai,
const struct osmo_location_area_id *new_lai,
bool authentication_required,
bool ciphering_required,
const struct vlr_auth_ciph *auth_ciph,
uint8_t key_seq,
bool is_r99, bool is_utran,
bool assign_tmsi)
{
struct osmo_fsm_inst *fi;
struct lu_fsm_priv *lfp;
const char *auth_ciph_str;
fi = osmo_fsm_inst_alloc_child(&vlr_lu_fsm, parent, parent_event_failure);
if (!fi)
return NULL;
/* If A5/0 is not permitted, authentication is required. */
if (!(a5_encryption_mask & GSM0808_ALG_ID_A5_0))
authentication_required = true;
lfp = talloc_zero(fi, struct lu_fsm_priv);
lfp->vlr = vlr;
lfp->msc_conn_ref = msc_conn_ref;
@ -1498,8 +1518,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
lfp->parent_event_success = parent_event_success;
lfp->parent_event_failure = parent_event_failure;
lfp->parent_event_data = parent_event_data;
lfp->authentication_required = authentication_required;
lfp->ciphering_required = ciphering_required;
lfp->auth_ciph = *auth_ciph;
lfp->key_seq = key_seq;
lfp->is_r99 = is_r99;
lfp->is_utran = is_utran;
@ -1511,6 +1530,8 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
}
fi->priv = lfp;
if (authentication_required || (a5_encryption_mask & GSM0808_ALG_ID_A5_0) == 0) {
}
LOGPFSM(fi, "rev=%s net=%s%s%s\n",
is_r99 ? "R99" : "GSM",
is_utran ? "UTRAN" : "GERAN",

Loading…
Cancel
Save