diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2017-12-18 01:23:42 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-12-18 23:06:25 +0000 |
commit | 5282171bc3e57d2e60eed873ef66be0fffa1d1d6 (patch) | |
tree | 4898582e3c9e650bc21d4f5b9770b31d2a867569 | |
parent | 7fca2ce9297ddb23dacf5e9dfbdec370f6afc377 (diff) |
fix GSM-Milenage in presence of 2G keys
In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth
tokens. tuple->vec.kc was calculated from the GSM algorithm and is not
necessarily a match for the UMTS AKA tokens.
So far we were always sending the Kc retrieved from osmo-hlr. If the 2G auth
algo is set to milenage, the 2G Kc coincides with the one derived from 3G
tokens, but if 2G is set to a different algorithm, the Kc received from the
osmo-hlr is not usable for ciphering when UMTS AKA was used for authentication
(on R99 capable GERAN and MS).
Implementation: To decide whether to use UMTS AKA derived Kc or the Kc from the
auth vector, use the umts_aka flag added to set_ciph_mode() in a previous
patch. Use osmo_auth_c3() to derive the GSM AKA Kc from the UMTS AKA CK and KI.
Related: OS#2745
Requires: I85a1d6ae95ad9e5ce9524ef7fc06414848afc2aa (libosmocore)
Change-Id: If04e405426c55a81341747a9b450a69188525d5c
-rw-r--r-- | src/libmsc/gsm_04_08.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index 472acf00d..e370962ea 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -3421,7 +3421,13 @@ static int msc_vlr_set_ciph_mode(void *msc_conn_ref, ei.perm_algo[0] = vlr_ciph_to_gsm0808_alg_id(ciph); ei.perm_algo_len = 1; - memcpy(ei.key, tuple->vec.kc, sizeof(tuple->vec.kc)); + /* In case of UMTS AKA, the Kc for ciphering must be derived from the 3G auth + * tokens. tuple->vec.kc was calculated from the GSM algorithm and is not + * necessarily a match for the UMTS AKA tokens. */ + if (umts_aka) + osmo_auth_c3(ei.key, tuple->vec.ck, tuple->vec.ik); + else + memcpy(ei.key, tuple->vec.kc, sizeof(tuple->vec.kc)); ei.key_len = sizeof(tuple->vec.kc); return a_iface_tx_cipher_mode(conn, &ei, retrieve_imeisv); |