libvlr: Allow 2G auth tuples to be re-used without going through AUTH
If the key_seq we get in the first messages matches the last_tuple, then both we and the MS already know the key to use and we don't need the AUTH REQUEST/RESPONSE cycle. Security wise ... not so good, and so IMHO the 'auth required' option in the MSC should always be set. But this allows to turn on ciphering on a channel without doing any MM transaction, and so the MS doesn't turn on the T3240 timer which allows to have a ciphered silent-call channel that won't timeout. Change-Id: Ief840a2ae7a0ffd2bf0bf726f209a79e3f787646 Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
parent
31f4c1f927
commit
da9f37ed20
|
@ -303,6 +303,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
|
|||
const struct osmo_location_area_id *new_lai,
|
||||
bool authentication_required,
|
||||
bool ciphering_required,
|
||||
uint8_t key_seq,
|
||||
bool is_r99, bool is_utran,
|
||||
bool assign_tmsi);
|
||||
|
||||
|
@ -446,6 +447,7 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
|
|||
const struct osmo_location_area_id *lai,
|
||||
bool authentication_required,
|
||||
bool ciphering_required,
|
||||
uint8_t key_seq,
|
||||
bool is_r99, bool is_utran);
|
||||
|
||||
void vlr_parq_cancel(struct osmo_fsm_inst *fi,
|
||||
|
|
|
@ -433,6 +433,7 @@ int mm_rx_loc_upd_req(struct ran_conn *conn, struct msgb *msg)
|
|||
&old_lai, &new_lai,
|
||||
is_utran || conn->network->authentication_required,
|
||||
is_utran || conn->network->a5_encryption_mask > 0x01,
|
||||
lu->key_seq,
|
||||
classmark1_is_r99(&lu->classmark1),
|
||||
is_utran,
|
||||
net->vlr->cfg.assign_tmsi);
|
||||
|
@ -820,6 +821,7 @@ int gsm48_rx_mm_serv_req(struct ran_conn *conn, struct msgb *msg)
|
|||
VLR_PR_ARQ_T_CM_SERV_REQ, mi-1, &lai,
|
||||
is_utran || conn->network->authentication_required,
|
||||
is_utran || conn->network->a5_encryption_mask > 0x01,
|
||||
req->cipher_key_seq,
|
||||
classmark2_is_r99(classmark2, classmark2_len),
|
||||
is_utran);
|
||||
|
||||
|
@ -1178,6 +1180,8 @@ static int gsm48_rx_rr_pag_resp(struct ran_conn *conn, struct msgb *msg)
|
|||
{
|
||||
struct gsm_network *net = conn->network;
|
||||
struct gsm48_hdr *gh = msgb_l3(msg);
|
||||
struct gsm48_pag_resp *pr =
|
||||
(struct gsm48_pag_resp *)gh->data;
|
||||
uint8_t classmark2_len = gh->data[1];
|
||||
uint8_t *classmark2 = gh->data+2;
|
||||
uint8_t *mi_lv = classmark2 + classmark2_len;
|
||||
|
@ -1209,6 +1213,7 @@ static int gsm48_rx_rr_pag_resp(struct ran_conn *conn, struct msgb *msg)
|
|||
VLR_PR_ARQ_T_PAGING_RESP, mi_lv, &lai,
|
||||
is_utran || conn->network->authentication_required,
|
||||
is_utran || conn->network->a5_encryption_mask > 0x01,
|
||||
pr->key_seq,
|
||||
classmark2_is_r99(classmark2, classmark2_len),
|
||||
is_utran);
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ struct proc_arq_priv {
|
|||
struct osmo_location_area_id lai;
|
||||
bool authentication_required;
|
||||
bool ciphering_required;
|
||||
uint8_t key_seq;
|
||||
bool is_r99;
|
||||
bool is_utran;
|
||||
bool implicitly_accepted_parq_by_ciphering_cmd;
|
||||
|
@ -316,7 +317,8 @@ static bool is_auth_required(struct proc_arq_priv *par)
|
|||
/* The cases where the authentication procedure should be used
|
||||
* are defined in 3GPP TS 33.102 */
|
||||
/* For now we use a default value passed in to vlr_lu_fsm(). */
|
||||
return par->authentication_required || par->ciphering_required;
|
||||
return par->authentication_required ||
|
||||
(par->ciphering_required && !auth_try_reuse_tuple(par->vsub, par->key_seq));
|
||||
}
|
||||
|
||||
/* after the IMSI is known */
|
||||
|
@ -528,6 +530,7 @@ static const struct osmo_fsm_state proc_arq_vlr_states[] = {
|
|||
.out_state_mask = S(PR_ARQ_S_DONE) |
|
||||
S(PR_ARQ_S_WAIT_OBTAIN_IMSI) |
|
||||
S(PR_ARQ_S_WAIT_AUTH) |
|
||||
S(PR_ARQ_S_WAIT_CIPH) |
|
||||
S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
|
||||
S(PR_ARQ_S_WAIT_SUB_PRES) |
|
||||
S(PR_ARQ_S_WAIT_TRACE_SUB) |
|
||||
|
@ -540,6 +543,7 @@ static const struct osmo_fsm_state proc_arq_vlr_states[] = {
|
|||
.in_event_mask = S(PR_ARQ_E_ID_IMSI),
|
||||
.out_state_mask = S(PR_ARQ_S_DONE) |
|
||||
S(PR_ARQ_S_WAIT_AUTH) |
|
||||
S(PR_ARQ_S_WAIT_CIPH) |
|
||||
S(PR_ARQ_S_WAIT_UPD_LOC_CHILD) |
|
||||
S(PR_ARQ_S_WAIT_SUB_PRES) |
|
||||
S(PR_ARQ_S_WAIT_TRACE_SUB) |
|
||||
|
@ -637,6 +641,7 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
|
|||
const struct osmo_location_area_id *lai,
|
||||
bool authentication_required,
|
||||
bool ciphering_required,
|
||||
uint8_t key_seq,
|
||||
bool is_r99, bool is_utran)
|
||||
{
|
||||
struct osmo_fsm_inst *fi;
|
||||
|
@ -660,6 +665,7 @@ vlr_proc_acc_req(struct osmo_fsm_inst *parent,
|
|||
par->parent_event_data = parent_event_data;
|
||||
par->authentication_required = authentication_required;
|
||||
par->ciphering_required = ciphering_required;
|
||||
par->key_seq = key_seq;
|
||||
par->is_r99 = is_r99;
|
||||
par->is_utran = is_utran;
|
||||
|
||||
|
|
|
@ -629,3 +629,18 @@ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
|
|||
|
||||
return fi;
|
||||
}
|
||||
|
||||
bool auth_try_reuse_tuple(struct vlr_subscr *vsub, uint8_t key_seq)
|
||||
{
|
||||
int max_reuse_count = vsub->vlr->cfg.auth_tuple_max_reuse_count;
|
||||
struct vlr_auth_tuple *at = vsub->last_tuple;
|
||||
|
||||
if (!at)
|
||||
return false;
|
||||
if ((max_reuse_count >= 0) && (at->use_count > max_reuse_count))
|
||||
return false;
|
||||
if (at->key_seq != key_seq)
|
||||
return false;
|
||||
at->use_count++;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -35,3 +35,5 @@ struct osmo_fsm_inst *auth_fsm_start(struct vlr_subscr *vsub,
|
|||
uint32_t parent_term_event,
|
||||
bool is_r99,
|
||||
bool is_utran);
|
||||
|
||||
bool auth_try_reuse_tuple(struct vlr_subscr *vsub, uint8_t key_seq);
|
||||
|
|
|
@ -685,6 +685,7 @@ struct lu_fsm_priv {
|
|||
struct osmo_location_area_id new_lai;
|
||||
bool authentication_required;
|
||||
bool ciphering_required;
|
||||
uint8_t key_seq;
|
||||
bool is_r99;
|
||||
bool is_utran;
|
||||
bool assign_tmsi;
|
||||
|
@ -705,7 +706,8 @@ static bool is_auth_required(struct lu_fsm_priv *lfp)
|
|||
/* The cases where the authentication procedure should be used
|
||||
* are defined in 3GPP TS 33.102 */
|
||||
/* For now we use a default value passed in to vlr_lu_fsm(). */
|
||||
return lfp->authentication_required || lfp->ciphering_required;
|
||||
return lfp->authentication_required ||
|
||||
(lfp->ciphering_required && !auth_try_reuse_tuple(lfp->vsub, lfp->key_seq));
|
||||
}
|
||||
|
||||
/* Determine if ciphering is required */
|
||||
|
@ -1316,6 +1318,7 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
|
|||
S(VLR_ULA_S_WAIT_PVLR) |
|
||||
S(VLR_ULA_S_WAIT_IMSI) |
|
||||
S(VLR_ULA_S_WAIT_AUTH) |
|
||||
S(VLR_ULA_S_WAIT_CIPH) |
|
||||
S(VLR_ULA_S_WAIT_HLR_UPD) |
|
||||
S(VLR_ULA_S_DONE),
|
||||
.name = OSMO_STRINGIFY(VLR_ULA_S_IDLE),
|
||||
|
@ -1326,6 +1329,7 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
|
|||
.out_state_mask = S(VLR_ULA_S_WAIT_PVLR) |
|
||||
S(VLR_ULA_S_WAIT_IMSI) |
|
||||
S(VLR_ULA_S_WAIT_AUTH) |
|
||||
S(VLR_ULA_S_WAIT_CIPH) |
|
||||
S(VLR_ULA_S_WAIT_HLR_UPD) |
|
||||
S(VLR_ULA_S_DONE),
|
||||
.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMEISV),
|
||||
|
@ -1336,6 +1340,7 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
|
|||
S(VLR_ULA_E_SEND_ID_NACK),
|
||||
.out_state_mask = S(VLR_ULA_S_WAIT_IMSI) |
|
||||
S(VLR_ULA_S_WAIT_AUTH) |
|
||||
S(VLR_ULA_S_WAIT_CIPH) |
|
||||
S(VLR_ULA_S_DONE),
|
||||
.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_PVLR),
|
||||
.action = lu_fsm_wait_pvlr,
|
||||
|
@ -1360,6 +1365,7 @@ static const struct osmo_fsm_state vlr_lu_fsm_states[] = {
|
|||
[VLR_ULA_S_WAIT_IMSI] = {
|
||||
.in_event_mask = S(VLR_ULA_E_ID_IMSI),
|
||||
.out_state_mask = S(VLR_ULA_S_WAIT_AUTH) |
|
||||
S(VLR_ULA_S_WAIT_CIPH) |
|
||||
S(VLR_ULA_S_WAIT_HLR_UPD) |
|
||||
S(VLR_ULA_S_DONE),
|
||||
.name = OSMO_STRINGIFY(VLR_ULA_S_WAIT_IMSI),
|
||||
|
@ -1439,6 +1445,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
|
|||
const struct osmo_location_area_id *new_lai,
|
||||
bool authentication_required,
|
||||
bool ciphering_required,
|
||||
uint8_t key_seq,
|
||||
bool is_r99, bool is_utran,
|
||||
bool assign_tmsi)
|
||||
{
|
||||
|
@ -1462,6 +1469,7 @@ vlr_loc_update(struct osmo_fsm_inst *parent,
|
|||
lfp->parent_event_data = parent_event_data;
|
||||
lfp->authentication_required = authentication_required;
|
||||
lfp->ciphering_required = ciphering_required;
|
||||
lfp->key_seq = key_seq;
|
||||
lfp->is_r99 = is_r99;
|
||||
lfp->is_utran = is_utran;
|
||||
lfp->assign_tmsi = assign_tmsi;
|
||||
|
|
Loading…
Reference in New Issue