From 703638e79a7c78c5794acf6d1c15885e314354b2 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Thu, 14 Dec 2017 05:30:16 +0100 Subject: cosmetic: move translation of vlr_ciph into msc_vlr_set_ciph_mode() a_iface_tx_cipher_mode() is a bit too far away from the VLR to be handling its ciphering enums. Instead, construct the gsm0808_encrypt_info in the msc_vlr_set_ciph_mode() callback. Greatly simplify the sanity checking code: a_iface_tx_cipher_mode() no longer needs to re-verify the presence of the gsm0808_encrypt_info contents. Change-Id: Id46f9a513b555d0a481f7124c9984c2b5b196b3e --- include/osmocom/msc/a_iface.h | 3 ++- src/libmsc/a_iface.c | 32 ++++++-------------------------- src/libmsc/gsm_04_08.c | 18 ++++++++++++++++-- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/include/osmocom/msc/a_iface.h b/include/osmocom/msc/a_iface.h index f0da248b7..74172984d 100644 --- a/include/osmocom/msc/a_iface.h +++ b/include/osmocom/msc/a_iface.h @@ -22,6 +22,7 @@ #include #include +#include /* A struct to keep a context information about the BSCs we are associated with */ struct bsc_context { @@ -57,7 +58,7 @@ int a_iface_tx_dtap(struct msgb *msg); /* Send Cipher mode command via A-interface */ int a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn, - int cipher, const uint8_t *key, int len, int include_imeisv); + struct gsm0808_encrypt_info *ei, int include_imeisv); /* Page a subscriber via A-interface */ int a_iface_tx_paging(const char *imsi, uint32_t tmsi, uint16_t lac); diff --git a/src/libmsc/a_iface.c b/src/libmsc/a_iface.c index 69b4c0991..cdd8d892b 100644 --- a/src/libmsc/a_iface.c +++ b/src/libmsc/a_iface.c @@ -170,38 +170,18 @@ int a_iface_tx_dtap(struct msgb *msg) /* Send Cipher mode command via A-interface */ int a_iface_tx_cipher_mode(const struct gsm_subscriber_connection *conn, - int cipher, const uint8_t *key, int len, int include_imeisv) + struct gsm0808_encrypt_info *ei, int include_imeisv) { /* TODO generalize for A- and Iu interfaces, don't name after 08.08 */ struct msgb *msg_resp; - struct gsm0808_encrypt_info ei; - - OSMO_ASSERT(conn); - uint8_t crm = 0x01; - uint8_t *crm_ptr = NULL; - LOGPCONN(conn, LOGL_DEBUG, "Cipher Mode Command to BSC, cipher=%d key=%s\n", - cipher, osmo_hexdump_nospc(key, len)); - - /* Setup encryption information */ - if (len > ENCRY_INFO_KEY_MAXLEN || !key) { - LOGP(DMSC, LOGL_ERROR, - "Cipher mode command message could not be generated due to invalid key! (conn_id=%i)\n", - conn->a.conn_id); - return -EINVAL; - } else { - memcpy(&ei.key, key, len); - ei.key_len = len; - } - - if (include_imeisv) - crm_ptr = &crm; - - ei.perm_algo[0] = vlr_ciph_to_gsm0808_alg_id(cipher); - ei.perm_algo_len = 1; + OSMO_ASSERT(conn); + LOGPCONN(conn, LOGL_DEBUG, "Cipher Mode Command to BSC, %u ciphers (%s)", + ei->perm_algo_len, osmo_hexdump_nospc(ei->perm_algo, ei->perm_algo_len)); + LOGPC(DMSC, LOGL_DEBUG, " key %s\n", osmo_hexdump_nospc(ei->key, ei->key_len)); - msg_resp = gsm0808_create_cipher(&ei, crm_ptr); + msg_resp = gsm0808_create_cipher(ei, include_imeisv ? &crm : NULL); LOGP(DMSC, LOGL_DEBUG, "N-DATA.req(%u, %s)\n", conn->a.conn_id, osmo_hexdump(msg_resp->data, msg_resp->len)); return osmo_sccp_tx_data_msg(conn->a.scu, conn->a.conn_id, msg_resp); diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c index d71b48bd8..d2c56c5a8 100644 --- a/src/libmsc/gsm_04_08.c +++ b/src/libmsc/gsm_04_08.c @@ -3381,6 +3381,10 @@ static int msc_vlr_tx_cm_serv_rej(void *msc_conn_ref, enum vlr_proc_arq_result r return msc_gsm48_tx_mm_serv_rej(conn, cause); } +/* For msc_vlr_set_ciph_mode() */ +osmo_static_assert(sizeof(((struct gsm0808_encrypt_info*)0)->key) >= sizeof(((struct osmo_auth_vector*)0)->kc), + gsm0808_encrypt_info_key_fits_osmo_auth_vec_kc); + /* VLR asks us to start using ciphering */ static int msc_vlr_set_ciph_mode(void *msc_conn_ref, enum vlr_ciph ciph, @@ -3410,8 +3414,18 @@ static int msc_vlr_set_ciph_mode(void *msc_conn_ref, case RAN_GERAN_A: DEBUGP(DMM, "-> CIPHER MODE COMMAND %s\n", vlr_subscr_name(conn->vsub)); - return a_iface_tx_cipher_mode(conn, ciph, tuple->vec.kc, 8, - retrieve_imeisv); + { + struct gsm0808_encrypt_info ei; + + 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)); + ei.key_len = sizeof(tuple->vec.kc); + + return a_iface_tx_cipher_mode(conn, &ei, retrieve_imeisv); + } + case RAN_UTRAN_IU: #ifdef BUILD_IU DEBUGP(DMM, "-> SECURITY MODE CONTROL %s\n", -- cgit v1.2.3