aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-09-13 03:23:07 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-09-17 02:08:07 +0200
commit3117b701c8d4645215896c459d6c608358a0a51b (patch)
tree3705f3a91244b28b9fff52cb57a252363f221226 /include
parentd28ea6c8c32b2e3d4505e324c322a31620ce175b (diff)
A5/n Ciph: request Classmark Update if missing
When the VLR requests a Ciphering Mode with vlr_ops.set_ciph_mode(), and if we need a ciph algo flag from a Classmark information that is not yet known (usually CM 2 during LU), send a BSSMAP Classmark Request to get it. To manage the intermission of the Classmark Request, add - msc_classmark_request_then_cipher_mode_cmd(), - state SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE, - event SUBSCR_CONN_E_CLASSMARK_UPDATE. From state AUTH_CIPH, switch to state WAIT_CLASSMARK_UPDATE. Once the BSSMAP Classmark Response, is received, switch back to SUBSCR_CONN_S_AUTH_CIPH and re-initiate Ciphering Mode. To be able to re-enter the Ciphering Mode algo decision, factor it out into msc_geran_set_cipher_mode(). Rationale: In the following commit, essentially we stopped supporting A5/3 ciphering: commit 71330720b6efdda2fcfd3e9c0cb45f89e32e5670 "MSC: Intersect configured A5 algorithms with MS-supported ones" Change-Id: Id124923ee52a357cb7d3e04d33f585214774f3a3 A5/3 was no longer supported because from that commit on, we strictly checked the MS-supported ciphers, but we did not have Classmark 2 available during Location Updating. This patch changes that: when Classmark 2 is missing, actively request it by a BSSMAP Classmark Request; continue Ciphering only after the Response. Always request missing Classmark, even if a lesser cipher were configured available. If the Classmark Update response fails to come in, cause an attach failure. Instead, we could attempt to use a lesser cipher that is also enabled. That is left as a future feature, should that become relevant. I think it's unlikely. Technically, we could now end up requesting a Classmark Updating both during LU (vlr_lu_fsm) and CM Service/Paging Response (proc_arq_fsm), but in practice the only time we lack a Classmark is: during Location Updating with A5/3 enabled. A5/1 support is indicated in CM1 which is always available, and A5/3 support is indicated in CM2, which is always available during CM Service Request as well as Paging Response. So this patch has practical relevance only for Location Updating. For networks that permit only A5/3, this patch fixes Location Updating. For networks that support A5/3 and A5/1, so far we always used A5/1 during LU, and after this patch we request CM2 and likely use A5/3 instead. In msc_vlr_test_gsm_ciph, verify that requesting Classmark 2 for A5/3 works during LU. Also verify that the lack of a Classmark Response results in attach failure. In msc_vlr_test_gsm_ciph, a hacky unit test fakes a situation where a CM2 is missing during proc_arq_fsm and proves that that code path works, even though the practical relevance is currently zero. It would only become interesting if ciphering algorithms A5/4 and higher became relevant, because support of those would be indicated in Classmark 3, which would always require a Classmark Request. Related: OS#3043 Depends: I4a2e1d3923e33912579c4180aa1ff8e8f5abb7e7 (libosmocore) Change-Id: I73c7cb6a86624695bd9c0f59abb72e2fdc655131
Diffstat (limited to 'include')
-rw-r--r--include/osmocom/msc/a_iface.h2
-rw-r--r--include/osmocom/msc/gsm_data.h7
-rw-r--r--include/osmocom/msc/osmo_msc.h6
3 files changed, 15 insertions, 0 deletions
diff --git a/include/osmocom/msc/a_iface.h b/include/osmocom/msc/a_iface.h
index 217011d2e..9a758d36b 100644
--- a/include/osmocom/msc/a_iface.h
+++ b/include/osmocom/msc/a_iface.h
@@ -78,6 +78,8 @@ int a_iface_tx_assignment(const struct gsm_trans *trans);
/* Send clear command via A-interface */
int a_iface_tx_clear_cmd(struct gsm_subscriber_connection *conn);
+int a_iface_tx_classmark_request(const struct gsm_subscriber_connection *conn);
+
/* Clear all subscriber connections on a specified BSC
* (Helper function for a_iface_bssap.c) */
void a_clear_all(struct osmo_sccp_user *scu, const struct osmo_sccp_addr *bsc_addr);
diff --git a/include/osmocom/msc/gsm_data.h b/include/osmocom/msc/gsm_data.h
index ffe3afc6b..70ac93440 100644
--- a/include/osmocom/msc/gsm_data.h
+++ b/include/osmocom/msc/gsm_data.h
@@ -130,6 +130,13 @@ struct gsm_subscriber_connection {
uint16_t lac;
struct gsm_encr encr;
+ /* "Temporary" storage for the case the VLR asked for Cipher Mode Command, but the MSC still
+ * wants to request a Classmark Update first. */
+ struct {
+ bool umts_aka;
+ bool retrieve_imeisv;
+ } geran_set_cipher_mode;
+
/* N(SD) expected in the received frame, per flow (TS 24.007 11.2.3.2.3.2.2) */
uint8_t n_sd_next[4];
diff --git a/include/osmocom/msc/osmo_msc.h b/include/osmocom/msc/osmo_msc.h
index 7b3702abc..3ffb65c91 100644
--- a/include/osmocom/msc/osmo_msc.h
+++ b/include/osmocom/msc/osmo_msc.h
@@ -16,6 +16,8 @@ enum subscr_conn_fsm_event {
SUBSCR_CONN_E_INVALID = 0,
/* Accepted the initial Complete Layer 3 (starting to evaluate Authentication and Ciphering) */
SUBSCR_CONN_E_COMPLETE_LAYER_3,
+ /* Received Classmark Update, typically neede for Ciphering Mode Command */
+ SUBSCR_CONN_E_CLASSMARK_UPDATE,
/* LU or Process Access FSM has determined that this conn is good */
SUBSCR_CONN_E_ACCEPTED,
/* received first reply from MS in "real" CC, SMS, USSD communication */
@@ -33,6 +35,7 @@ enum subscr_conn_fsm_event {
enum subscr_conn_fsm_state {
SUBSCR_CONN_S_NEW,
SUBSCR_CONN_S_AUTH_CIPH,
+ SUBSCR_CONN_S_WAIT_CLASSMARK_UPDATE,
SUBSCR_CONN_S_ACCEPTED,
SUBSCR_CONN_S_COMMUNICATING,
SUBSCR_CONN_S_RELEASING,
@@ -62,6 +65,9 @@ int msc_compl_l3(struct gsm_subscriber_connection *conn,
struct msgb *msg, uint16_t chosen_channel);
void msc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id,
struct msgb *msg);
+int msc_classmark_request_then_cipher_mode_cmd(struct gsm_subscriber_connection *conn, bool umts_aka,
+ bool retrieve_imeisv);
+int msc_geran_set_cipher_mode(struct gsm_subscriber_connection *conn, bool umts_aka, bool retrieve_imeisv);
void msc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
struct msgb *msg, uint8_t alg_id);
void msc_rx_sec_mode_compl(struct gsm_subscriber_connection *conn);