aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_llc.c
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/src/gprs/gprs_llc.c
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/src/gprs/gprs_llc.c')
-rw-r--r--openbsc/src/gprs/gprs_llc.c31
1 files changed, 22 insertions, 9 deletions
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 */