From ffd9968d3ac369e2d60f086f1928b0860ba6e6ca Mon Sep 17 00:00:00 2001 From: Daniel Willmann Date: Fri, 18 Mar 2016 13:54:32 +0100 Subject: libiu: Change gprs_transp_upd_key to be useful for CS as well gprs_transp_upd_key only sends a security mode command which is needed for CS as well so change it. Make sure it is called after the UE is authenticated in Iu mode. --- openbsc/include/openbsc/gprs_sgsn.h | 1 + openbsc/include/openbsc/iu.h | 1 + openbsc/src/gprs/gprs_gmm.c | 10 +++--- openbsc/src/libiu/iu.c | 64 +++++++++++++++++-------------------- 4 files changed, 37 insertions(+), 39 deletions(-) diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h index 4f34f1b88..ca47d134b 100644 --- a/openbsc/include/openbsc/gprs_sgsn.h +++ b/openbsc/include/openbsc/gprs_sgsn.h @@ -148,6 +148,7 @@ struct sgsn_mm_ctx { /* Voice Support Match Indicator */ void *ue_ctx; struct service_info service; + int integrity_active; } iu; /* VLR number */ uint32_t new_sgsn_addr; diff --git a/openbsc/include/openbsc/iu.h b/openbsc/include/openbsc/iu.h index 4d35b2076..3bbdc9753 100644 --- a/openbsc/include/openbsc/iu.h +++ b/openbsc/include/openbsc/iu.h @@ -37,3 +37,4 @@ int iu_tx(struct msgb *msg, uint8_t sapi); int iu_rab_act_cs(struct ue_conn_ctx *ue_ctx, uint32_t rtp_ip, uint16_t rtp_port); int iu_rab_act_ps(uint8_t rab_id, struct sgsn_pdp_ctx *pdp); int iu_rab_deact(struct ue_conn_ctx *ue_ctx, uint8_t rab_id); +int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp); diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index e96dbcdc8..922c65ab1 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -63,8 +63,6 @@ #define PTMSI_ALLOC -int gprs_transp_upd_key(struct sgsn_mm_ctx *mm); - extern struct sgsn_instance *sgsn; static const struct tlv_definition gsm48_gmm_att_tlvdef = { @@ -117,11 +115,14 @@ int sgsn_ranap_iu_event(struct ue_conn_ctx *ctx, int type, void *data) rc = sgsn_ranap_rab_ass_resp(mm, (RANAP_RAB_SetupOrModifiedItemIEs_t *)data); break; case IU_EVENT_IU_RELEASE: + mm->iu.integrity_active = 0; /* Clean up ue_conn_ctx here */ LOGMMCTXP(LOGL_INFO, mm, "IU release\n", type); break; case IU_EVENT_SECURITY_MODE_COMPLETE: /* Continue authentication here */ + mm->iu.integrity_active = 1; + rc = gsm48_gmm_authorize(mm); break; default: LOGP(DRANAP, LOGL_NOTICE, "Unknown event received: %i\n", type); @@ -572,8 +573,6 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx, /* Check if we can let the mobile station enter */ rc = gsm48_gmm_authorize(ctx); - gprs_transp_upd_key(ctx); - return rc; } @@ -753,6 +752,9 @@ static int gsm48_gmm_authorize(struct sgsn_mm_ctx *ctx) } /* The MS is authorized */ + if (ctx->ran_type == MM_CTX_T_UTRAN_Iu && !ctx->iu.integrity_active) { + return iu_tx_sec_mode_cmd(ctx->iu.ue_ctx, &ctx->auth_triplet); + } switch (ctx->pending_req) { case 0: diff --git a/openbsc/src/libiu/iu.c b/openbsc/src/libiu/iu.c index 2381c3c1c..a0d79793e 100644 --- a/openbsc/src/libiu/iu.c +++ b/openbsc/src/libiu/iu.c @@ -116,42 +116,36 @@ int iu_rab_deact(struct ue_conn_ctx *ue_ctx, uint8_t rab_id) return -1; } -int gprs_transp_upd_key(struct sgsn_mm_ctx *mm) +int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp) { - struct gsm_auth_tuple *tp = &mm->auth_triplet; - - if (mm->ran_type == MM_CTX_T_UTRAN_Iu) { - struct ue_conn_ctx *uectx; - struct osmo_scu_prim *prim; - struct msgb *msg; - uint8_t ik[16]; - uint8_t ck[16]; - unsigned int i; - - uectx = mm->iu.ue_ctx; - - /* C4 function to dervie CK from Kc */ - memcpy(ck, tp->kc, 8); - memcpy(ck+8, tp->kc, 8); - - /* C5 function to derive IK from Kc */ - for (i = 0; i < 4; i++) - ik[i] = tp->kc[i] ^ tp->kc[i+4]; - memcpy(ik+4, tp->kc, 8); - for (i = 12; i < 16; i++) - ik[i] = ik[i-12]; - - /* crate RANAP message */ - msg = ranap_new_msg_sec_mod_cmd(ik, NULL); - msg->l2h = msg->data; - /* wrap RANAP message in SCCP N-DATA.req */ - prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); - prim->u.data.conn_id = uectx->conn_id; - osmo_prim_init(&prim->oph, SCCP_SAP_USER, - OSMO_SCU_PRIM_N_DATA, - PRIM_OP_REQUEST, msg); - osmo_sua_user_link_down(uectx->link, &prim->oph); - } + struct osmo_scu_prim *prim; + struct msgb *msg; + uint8_t ik[16]; + uint8_t ck[16]; + unsigned int i; + + /* C4 function to dervie CK from Kc */ + memcpy(ck, tp->kc, 8); + memcpy(ck+8, tp->kc, 8); + + /* C5 function to derive IK from Kc */ + for (i = 0; i < 4; i++) + ik[i] = tp->kc[i] ^ tp->kc[i+4]; + memcpy(ik+4, tp->kc, 8); + for (i = 12; i < 16; i++) + ik[i] = ik[i-12]; + + /* crate RANAP message */ + msg = ranap_new_msg_sec_mod_cmd(ik, NULL); + msg->l2h = msg->data; + /* wrap RANAP message in SCCP N-DATA.req */ + prim = (struct osmo_scu_prim *) msgb_push(msg, sizeof(*prim)); + prim->u.data.conn_id = uectx->conn_id; + osmo_prim_init(&prim->oph, SCCP_SAP_USER, + OSMO_SCU_PRIM_N_DATA, + PRIM_OP_REQUEST, msg); + osmo_sua_user_link_down(uectx->link, &prim->oph); + return 0; } -- cgit v1.2.3