aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2017-12-14 05:16:10 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2017-12-14 21:39:49 +0100
commit7abe7ae2d003627df48bbe295cd51c417532a669 (patch)
tree6ea1d46cf45668ae012a608ff00d2853d2dea18a
parent8c6301cf0d6405d13cdb426bfea2ddb13ca64b70 (diff)
fix bssmap_handle_cipher_mode()'s encryption decision
Properly match up any A5/N with the MSC's list of permitted algos. Properly set the reject cause in case of mismatching algorithm choices. Actually allow choosing A5/1 thru 3 as configured on the VTY, by passing a5_encryption through to gsm0808_cipher_mode() (instead of a hardcoded 1). Properly handle failure rc of gsm0808_cipher_mode() by sending a reject message. Cosmetically clarify which GSM0808_IE_ENCRYPTION_INFORMATION bits mean what by means of local variables; add some comments on expected encryption formats; add comment that the BSC should be able to have more than one a5_encryption. Related: OS#2745 OS#2755 Change-Id: Ide8a615905555e35be4584b458d4d40345686175
-rw-r--r--src/osmo-bsc/osmo_bsc_bssap.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c
index 051b74e60..4fd43aa9a 100644
--- a/src/osmo-bsc/osmo_bsc_bssap.c
+++ b/src/osmo-bsc/osmo_bsc_bssap.c
@@ -397,6 +397,10 @@ static int bssmap_handle_cipher_mode(struct osmo_bsc_sccp_con *conn,
struct msgb *resp;
int reject_cause = -1;
int include_imeisv = 1;
+ uint8_t *enc_key;
+ uint16_t enc_key_len;
+ uint8_t enc_bits_bsc;
+ uint8_t enc_bits_msc;
if (!conn->conn) {
LOGP(DMSC, LOGL_ERROR, "No lchan/msc_data in cipher mode command.\n");
@@ -430,19 +434,38 @@ static int bssmap_handle_cipher_mode(struct osmo_bsc_sccp_con *conn,
network = conn->conn->bts->network;
data = TLVP_VAL(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
+ enc_bits_msc = data[0];
+ enc_key = &data[1];
+ enc_key_len = len - 1;
if (TLVP_PRESENT(&tp, GSM0808_IE_CIPHER_RESPONSE_MODE))
include_imeisv = TLVP_VAL(&tp, GSM0808_IE_CIPHER_RESPONSE_MODE)[0] & 0x1;
- if (network->a5_encryption == 0 && (data[0] & 0x1) == 0x1) {
- gsm0808_cipher_mode(conn->conn, 0, NULL, 0, include_imeisv);
- } else if (network->a5_encryption != 0 && (data[0] & 0x2) == 0x2) {
- gsm0808_cipher_mode(conn->conn, 1, &data[1], len - 1, include_imeisv);
- } else {
- LOGP(DMSC, LOGL_ERROR, "Can not select encryption...\n");
+ /* FIXME: match up the list of permitted ciphering algorithms received from the MSC with a list
+ * of ciphering algorithms configured for this BSC (the config of more than one is TODO). Finally
+ * pick one of the remaining options. */
+
+ /* Identical to the GSM0808_IE_ENCRYPTION_INFORMATION above:
+ * a5_encryption == 0 --> 0x01
+ * a5_encryption == 1 --> 0x02
+ * a5_encryption == 2 --> 0x04 ... */
+ enc_bits_bsc = 1 << network->a5_encryption;
+ enc_bits_msc = data[0];
+
+ if (!(enc_bits_msc & enc_bits_bsc)) {
+ LOGP(DMSC, LOGL_ERROR, "MSC does not permit A5/%d (permitted algorithms mask: 0x%x)\n",
+ network->a5_encryption, enc_bits_msc);
+ reject_cause = GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED;
goto reject;
}
+ /* To complete the confusion, gsm0808_cipher_mode again expects the encryption as a number
+ * from 0 to 7. */
+ if (gsm0808_cipher_mode(conn->conn, network->a5_encryption, enc_key, enc_key_len,
+ include_imeisv)) {
+ reject_cause = GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC;
+ goto reject;
+ }
return 0;
reject: