aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2016-07-06 11:33:04 +0200
committerHarald Welte <laforge@gnumonks.org>2016-07-16 21:04:01 +0000
commit5aa5196fbf07d5311bf4d99a90bff303989564f0 (patch)
treeae4debb697433075ecf2a9b56dff022627809a32 /openbsc
parent4011e728d22a9affbe41fb2bfc8e69c14bd706ab (diff)
SGSN: split GEA key management from TLLI
Move GEA key from TLLI assignment into separate function. Change-Id: I8a0bc907072dc19cd9535a28b5252dc0f05357cc Related: OS#1582
Diffstat (limited to 'openbsc')
-rw-r--r--openbsc/include/openbsc/gprs_llc.h9
-rw-r--r--openbsc/src/gprs/gprs_gmm.c17
-rw-r--r--openbsc/src/gprs/gprs_llc.c31
-rw-r--r--openbsc/src/gprs/gprs_sgsn.c2
4 files changed, 38 insertions, 21 deletions
diff --git a/openbsc/include/openbsc/gprs_llc.h b/openbsc/include/openbsc/gprs_llc.h
index 8cd0c2621..f9a6dec70 100644
--- a/openbsc/include/openbsc/gprs_llc.h
+++ b/openbsc/include/openbsc/gprs_llc.h
@@ -155,7 +155,10 @@ struct gprs_llc_llme {
/* Crypto parameters */
enum gprs_ciph_algo algo;
- uint8_t kc[8];
+ uint8_t kc[16];
+ uint8_t cksn;
+ /* 3GPP TS 44.064 ยง 8.9.2: */
+ uint32_t iov_ui;
/* over which BSSGP BTS ctx do we need to transmit */
uint16_t bvci;
@@ -216,8 +219,7 @@ int gprs_llgmm_reset_oldmsg(struct msgb* oldmsg, uint8_t sapi);
/* 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);
int gprs_llgmm_unassign(struct gprs_llc_llme *llme);
int gprs_llc_init(const char *cipher_plugin_path);
@@ -240,6 +242,7 @@ static inline int gprs_llc_is_retransmit(uint16_t nu, uint16_t vur)
}
/* LLC low level functions */
+void gprs_llme_copy_key(struct sgsn_mm_ctx *mm, struct gprs_llc_llme *llme);
/* parse a GPRS LLC header, also check for invalid frames */
int gprs_llc_hdr_parse(struct gprs_llc_hdr_parsed *ghp,
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);
}
}