From 5aa5196fbf07d5311bf4d99a90bff303989564f0 Mon Sep 17 00:00:00 2001 From: Max Date: Wed, 6 Jul 2016 11:33:04 +0200 Subject: SGSN: split GEA key management from TLLI Move GEA key from TLLI assignment into separate function. Change-Id: I8a0bc907072dc19cd9535a28b5252dc0f05357cc Related: OS#1582 --- openbsc/src/gprs/gprs_gmm.c | 17 +++++++++-------- openbsc/src/gprs/gprs_llc.c | 31 ++++++++++++++++++++++--------- openbsc/src/gprs/gprs_sgsn.c | 2 +- 3 files changed, 32 insertions(+), 18 deletions(-) (limited to 'openbsc/src/gprs') diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c index 7f10b0712..492c766c2 100644 --- a/openbsc/src/gprs/gprs_gmm.c +++ b/openbsc/src/gprs/gprs_gmm.c @@ -976,8 +976,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg, ctx->gb.tlli_new = gprs_tmsi2tlli(ctx->p_tmsi, TLLI_LOCAL); /* Inform LLC layer about new TLLI but keep old active */ - gprs_llgmm_assign(ctx->gb.llme, ctx->gb.tlli, ctx->gb.tlli_new, - GPRS_ALGO_GEA0, NULL); + if (ctx->is_authenticated) + gprs_llme_copy_key(ctx, ctx->gb.llme); + + gprs_llgmm_assign(ctx->gb.llme, ctx->gb.tlli, ctx->gb.tlli_new); } ctx->pending_req = GSM48_MT_GMM_ATTACH_REQ; @@ -1276,8 +1278,7 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg, /* Inform LLC layer about new TLLI but keep old active */ gprs_llgmm_assign(mmctx->gb.llme, mmctx->gb.tlli, - mmctx->gb.tlli_new, GPRS_ALGO_GEA0, - NULL); + mmctx->gb.tlli_new); } /* Look at PDP Context Status IE and see if MS's view of @@ -1412,9 +1413,9 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { /* Unassign the old TLLI */ mmctx->gb.tlli = mmctx->gb.tlli_new; + gprs_llme_copy_key(mmctx, mmctx->gb.llme); gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, - mmctx->gb.tlli_new, - GPRS_ALGO_GEA0, NULL); + mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; rc = 0; @@ -1435,8 +1436,8 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg, if (mmctx->ran_type == MM_CTX_T_GERAN_Gb) { /* Unassign the old TLLI */ mmctx->gb.tlli = mmctx->gb.tlli_new; - gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, mmctx->gb.tlli_new, - GPRS_ALGO_GEA0, NULL); + gprs_llgmm_assign(mmctx->gb.llme, 0xffffffff, + mmctx->gb.tlli_new); } mmctx->mm_state = GMM_REGISTERED_NORMAL; rc = 0; diff --git a/openbsc/src/gprs/gprs_llc.c b/openbsc/src/gprs/gprs_llc.c index 64d22b374..b271e21ca 100644 --- a/openbsc/src/gprs/gprs_llc.c +++ b/openbsc/src/gprs/gprs_llc.c @@ -236,6 +236,7 @@ static struct gprs_llc_llme *llme_alloc(uint32_t tlli) llme->old_tlli = 0xffffffff; llme->state = GPRS_LLMS_UNASSIGNED; llme->age_timestamp = GPRS_LLME_RESET_AGE; + llme->cksn = GSM_KEY_SEQ_INVAL; for (i = 0; i < ARRAY_SIZE(llme->lle); i++) lle_init(llme, i); @@ -366,6 +367,8 @@ int gprs_llc_tx_ui(struct msgb *msg, uint8_t sapi, int command, return -EFBIG; } + gprs_llme_copy_key(mmctx, lle->llme); + /* Update LLE's (BVCI, NSEI) tuple */ lle->llme->bvci = msgb_bvci(msg); lle->llme->nsei = msgb_nsei(msg); @@ -687,18 +690,29 @@ int gprs_llc_rcvmsg(struct msgb *msg, struct tlv_parsed *tv) return rc; } +/* Propagate crypto parameters MM -> LLME */ +void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme) +{ + if (!mm) + return; + if (mm->ciph_algo != GPRS_ALGO_GEA0) { + llme->algo = mm->ciph_algo; + if (llme->cksn != mm->auth_triplet.key_seq && + mm->auth_triplet.key_seq != GSM_KEY_SEQ_INVAL) { + memcpy(llme->kc, mm->auth_triplet.vec.kc, + gprs_cipher_key_length(mm->ciph_algo)); + llme->cksn = mm->auth_triplet.key_seq; + } + } else + llme->cksn = GSM_KEY_SEQ_INVAL; +} + /* 04.64 Chapter 7.2.1.1 LLGMM-ASSIGN */ int gprs_llgmm_assign(struct gprs_llc_llme *llme, - uint32_t old_tlli, uint32_t new_tlli, - enum gprs_ciph_algo alg, const uint8_t *kc) + uint32_t old_tlli, uint32_t new_tlli) { unsigned int i; - /* Update the crypto parameters */ - llme->algo = alg; - if (alg != GPRS_ALGO_GEA0) - memcpy(llme->kc, kc, sizeof(llme->kc)); - if (old_tlli == 0xffffffff && new_tlli != 0xffffffff) { /* TLLI Assignment 8.3.1 */ /* New TLLI shall be assigned and used when (re)transmitting LLC frames */ @@ -748,8 +762,7 @@ int gprs_llgmm_assign(struct gprs_llc_llme *llme, /* TLLI unassignment */ int gprs_llgmm_unassign(struct gprs_llc_llme *llme) { - return gprs_llgmm_assign(llme, llme->tlli, 0xffffffff, GPRS_ALGO_GEA0, - NULL); + return gprs_llgmm_assign(llme, llme->tlli, 0xffffffff); } /* Chapter 7.2.1.2 LLGMM-RESET.req */ diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c index 98439de21..711887e08 100644 --- a/openbsc/src/gprs/gprs_sgsn.c +++ b/openbsc/src/gprs/gprs_sgsn.c @@ -244,7 +244,7 @@ void sgsn_mm_ctx_cleanup_free(struct sgsn_mm_ctx *mm) if (llme) { /* TLLI unassignment, must be called after sgsn_mm_ctx_free */ - gprs_llgmm_assign(llme, tlli, 0xffffffff, GPRS_ALGO_GEA0, NULL); + gprs_llgmm_assign(llme, tlli, 0xffffffff); } } -- cgit v1.2.3