summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Willmann <dwillmann@sysmocom.de>2016-03-18 13:54:32 +0100
committerDaniel Willmann <dwillmann@sysmocom.de>2016-03-18 13:58:20 +0100
commitffd9968d3ac369e2d60f086f1928b0860ba6e6ca (patch)
tree629bfb32e7e36b67bdd833acb8e6560c7fa449ea
parentdeb227b98e4136f873f76ea3362bfb74673f48bc (diff)
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.
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h1
-rw-r--r--openbsc/include/openbsc/iu.h1
-rw-r--r--openbsc/src/gprs/gprs_gmm.c10
-rw-r--r--openbsc/src/libiu/iu.c64
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;
}