aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2011-07-07 11:48:00 +0200
committerHarald Welte <laforge@gnumonks.org>2011-07-07 11:50:45 +0200
commit540410c123d439a03f672726d64f6a6aec45a98d (patch)
tree475bdf9dce157492464a13f07bb818e4f663c878
parent39eadbbb17c8e634b2f641c2f6148f27a975f7de (diff)
RSL: implement RSL ENCR CMD, feed L3_INFO to LAPDm
This is not full encrpytion support, the bts-model part still needs to detect the ENCR CMD when de-queueing from LAPDm and enable the de-ciphering, detect the arrival of the first encrypted frame, etc, enable en-ciphering, ...
-rw-r--r--src/common/rsl.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/src/common/rsl.c b/src/common/rsl.c
index 5aa40f4a..a32c48ac 100644
--- a/src/common/rsl.c
+++ b/src/common/rsl.c
@@ -513,6 +513,21 @@ static void copy_sacch_si_to_lchan(struct gsm_lchan *lchan)
}
+static int encr_info2lchan(struct gsm_lchan *lchan,
+ const uint8_t *val, uint8_t len)
+{
+ if (len < 2)
+ return -EINVAL;
+
+ lchan->encr.alg_id = *val++;
+ lchan->encr.key_len = len -1;
+ if (lchan->encr.key_len > sizeof(lchan->encr.key))
+ lchan->encr.key_len = sizeof(lchan->encr.key);
+ memcpy(lchan->encr.key, val, lchan->encr.key_len);
+
+ return 0;
+}
+
/* 8.4.1 CHANnel ACTIVation is received */
static int rsl_rx_chan_activ(struct msgb *msg)
{
@@ -543,11 +558,9 @@ static int rsl_rx_chan_activ(struct msgb *msg)
if (TLVP_PRESENT(&tp, RSL_IE_ENCR_INFO)) {
uint8_t len = TLVP_LEN(&tp, RSL_IE_ENCR_INFO);
const uint8_t *val = TLVP_VAL(&tp, RSL_IE_ENCR_INFO);
- lchan->encr.alg_id = *val++;
- lchan->encr.key_len = len -1;
- if (lchan->encr.key_len > sizeof(lchan->encr.key))
- lchan->encr.key_len = sizeof(lchan->encr.key);
- memcpy(lchan->encr.key, val, lchan->encr.key_len);
+
+ if (encr_info2lchan(lchan, val, len) < 0)
+ return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT);
}
/* 9.3.9 Handover Reference */
@@ -632,6 +645,51 @@ static int rsl_rx_rf_chan_rel(struct msgb *msg)
return rc;
}
+/* 8.4.6 ENCRYPTION COMMAND */
+static int rsl_rx_encr_cmd(struct msgb *msg)
+{
+ struct gsm_lchan *lchan = msg->lchan;
+ struct abis_rsl_dchan_hdr *dch = msgb_l2(msg);
+ struct tlv_parsed tp;
+ uint8_t link_id;
+ const uint8_t *l3_content;
+
+ if (rsl_tlv_parse(&tp, msgb_l3(msg), msgb_l3len(msg)) < 0)
+ return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT);
+
+ if (!TLVP_PRESENT(&tp, RSL_IE_ENCR_INFO) ||
+ !TLVP_PRESENT(&tp, RSL_IE_L3_INFO) ||
+ !TLVP_PRESENT(&tp, RSL_IE_LINK_IDENT))
+ return rsl_tx_error_report(msg->trx, RSL_ERR_MAND_IE_ERROR);
+
+ /* 9.3.7 Encryption Information */
+ if (TLVP_PRESENT(&tp, RSL_IE_ENCR_INFO)) {
+ uint8_t len = TLVP_LEN(&tp, RSL_IE_ENCR_INFO);
+ const uint8_t *val = TLVP_VAL(&tp, RSL_IE_ENCR_INFO);
+
+ if (encr_info2lchan(lchan, val, len) < 0)
+ return rsl_tx_error_report(msg->trx, RSL_ERR_IE_CONTENT);
+ }
+
+ /* FIXME: check if the encryption algorithm sent by BSC is supported! */
+
+ /* 9.3.2 Link Identifier */
+ link_id = *TLVP_VAL(&tp, RSL_IE_LINK_IDENT);
+
+ /* pop the RSL dchan header */
+ l3_content = TLVP_VAL(&tp, RSL_IE_L3_INFO);
+ msgb_pull(msg, l3_content - msg->l2h);
+
+ /* push a fake RLL DATA REQ header */
+ rsl_rll_push_l3(msg, RSL_MT_DATA_REQ, dch->chan_nr, link_id, 1);
+
+ LOGP(DRSL, LOGL_INFO, "%s Fwd RSL ENCR CMD (Alg %u) to LAPDm\n",
+ gsm_lchan_name(lchan), lchan->encr.alg_id);
+
+ /* hand it into RSLms for transmission of L3_INFO to the MS */
+ return lapdm_rslms_recvmsg(msg, &lchan->lapdm_ch);
+}
+
/* 8.4.20 SACCH INFO MODify */
static int rsl_rx_sacch_inf_mod(struct msgb *msg)
{
@@ -1056,6 +1114,8 @@ static int rsl_rx_dchan(struct gsm_bts_trx *trx, struct msgb *msg)
ret = bts_model_rsl_deact_sacch(msg->lchan);
break;
case RSL_MT_ENCR_CMD:
+ ret = rsl_rx_encr_cmd(msg);
+ break;
case RSL_MT_MODE_MODIFY_REQ:
case RSL_MT_PHY_CONTEXT_REQ:
case RSL_MT_PREPROC_CONFIG: