aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/bssap.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2009-11-14 18:32:17 +0100
committerHolger Hans Peter Freyther <zecke@selfish.org>2009-11-20 17:35:46 +0100
commitf8b9d844c1aa93366a828836e1923d32fd0f9d4f (patch)
tree7e9c9fbdce8d9ce95ea9dcca9dea206288a5b794 /openbsc/src/bssap.c
parent58ec07d580d1e3e93908e6383b5b1f969eba39cc (diff)
[bssap] Pick the A5/0 vs A5/1 setting from the gsm_network
Follow the configuration of the gsm network. If the Cipher Mode Request does not allow our preferred format we will reject it. Otherwise send the cipher mode command to the mobile station. This code is mostly untested.
Diffstat (limited to 'openbsc/src/bssap.c')
-rw-r--r--openbsc/src/bssap.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/openbsc/src/bssap.c b/openbsc/src/bssap.c
index ffc549852..26ab998fa 100644
--- a/openbsc/src/bssap.c
+++ b/openbsc/src/bssap.c
@@ -56,6 +56,8 @@ static const struct tlv_definition bss_att_tlvdef = {
[GSM0808_IE_CONFIG_EVO_INDI] = { TLV_TYPE_TV },
[GSM0808_IE_LSA_ACCESS_CTRL_SUPPR] = { TLV_TYPE_TV },
[GSM0808_IE_SERVICE_HANDOVER] = { TLV_TYPE_TV},
+ [GSM0808_IE_ENCRYPTION_INFORMATION] = { TLV_TYPE_TLV },
+ [GSM0808_IE_CIPHER_RESPONSE_MODE] = { TLV_TYPE_TV },
},
};
@@ -191,8 +193,13 @@ static int bssmap_handle_clear_command(struct sccp_connection *conn,
static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
struct msgb *msg, unsigned int payload_length)
{
+ u_int16_t len;
+ struct gsm_network *network = NULL;
+ const u_int8_t *data;
+ struct tlv_parsed tp;
struct msgb *resp;
int reject_cause = -1;
+ int include_imeisv = 1;
/* HACK: Sending A5/0 to the MS */
if (!msg->lchan || !msg->lchan->msc_data) {
@@ -207,10 +214,43 @@ static int bssmap_handle_cipher_mode(struct sccp_connection *conn,
msg->lchan->msc_data->ciphering_handled = 1;
- /* FIXME: parse the message. TLVP */
-#warning "Need to handle cipher mode properly"
+ tlv_parse(&tp, &bss_att_tlvdef, msg->l4h + 1, payload_length - 1, 0, 0);
+ if (!TLVP_PRESENT(&tp, GSM0808_IE_ENCRYPTION_INFORMATION)) {
+ DEBUGP(DMSC, "IE Encryption Information missing.\n");
+ goto reject;
+ }
+
+ /*
+ * check if our global setting is allowed
+ * - Currently we check for A5/0 and A5/1
+ * - Copy the key if that is necessary
+ * - Otherwise reject
+ */
+ len = TLVP_LEN(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
+ if (len < 1) {
+ DEBUGP(DMSC, "IE Encryption Information is too short.\n");
+ goto reject;
+ }
+
+ network = msg->lchan->ts->trx->bts->network;
+ data = TLVP_VAL(&tp, GSM0808_IE_ENCRYPTION_INFORMATION);
+
+ if (network->a5_encryption == 0 && (data[0] & 0x1) == 0x1) {
+ msg->lchan->encr.alg_id = RSL_ENC_ALG_A5(0);
+ } else if (network->a5_encryption != 0 && (data[0] & 0x2) == 0x2) {
+ msg->lchan->encr.alg_id = RSL_ENC_ALG_A5(1);
+ msg->lchan->encr.key_len = len - 1;
+ memcpy(msg->lchan->encr.key, &data[1], len - 1);
+ } else {
+ DEBUGP(DMSC, "Can not select encryption...\n");
+ goto reject;
+ }
+
+ if (TLVP_PRESENT(&tp, GSM0808_IE_CIPHER_RESPONSE_MODE)) {
+ include_imeisv = TLVP_VAL(&tp, GSM0808_IE_CIPHER_RESPONSE_MODE)[0] & 0x1;
+ }
- return gsm48_send_rr_ciph_mode(msg->lchan, 1);
+ return gsm48_send_rr_ciph_mode(msg->lchan, include_imeisv);
reject:
resp = bssmap_create_cipher_reject(reject_cause);