diff options
author | Neels Hofmeyr <neels@hofmeyr.de> | 2019-03-15 02:48:39 +0100 |
---|---|---|
committer | Neels Hofmeyr <neels@hofmeyr.de> | 2019-04-08 16:26:28 +0200 |
commit | c15f6cd640bef63d8d52eaf4a187645ca95d0765 (patch) | |
tree | b3e7142b3a0c94006da7128f351db511975e9055 /src | |
parent | 58cf1b1f66ee20ca42ad2af064ab2bcc5f03f653 (diff) |
Handover Request: also parse Chosen Algorithm IE, pass to lchan activation
During inter-BSC-incoming, the MSC sends the chosen encryption algorithm in the
Handover Request message. Actually parse this Chosen Encryption Algorithm IE.
Place the chosen algorithm and the CK into lchan_activate_info->encr so that
the new lchan will use the same ciphering on this new BSS as it did on the old
BSS.
Change-Id: I5b269f50bd2092516bfdf87746196983d3ac49d1
Diffstat (limited to 'src')
-rw-r--r-- | src/osmo-bsc/handover_fsm.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c index 9c86b7090..421c32efb 100644 --- a/src/osmo-bsc/handover_fsm.c +++ b/src/osmo-bsc/handover_fsm.c @@ -432,6 +432,17 @@ static bool parse_ho_request(struct gsm_subscriber_connection *conn, const struc "Missing mandatory IE: 3GPP mandates either Classmark Information 1 or 2" " in BSSMAP Handover Request, but neither are present. Will continue without.\n"); + if ((e = TLVP_GET(tp, GSM0808_IE_CHOSEN_ENCR_ALG))) { + req->chosen_encr_alg = e->val[0]; + if (req->chosen_encr_alg < 1 || req->chosen_encr_alg > 8) + LOG_HO(conn, LOGL_ERROR, "Chosen Encryption Algorithm (Serving) is invalid: %u\n", + req->chosen_encr_alg); + } + + LOG_HO(conn, LOGL_DEBUG, "Handover Request encryption info: chosen=A5/%u key=%s\n", + (req->chosen_encr_alg ? : 1) - 1, req->ei.key_len? + osmo_hexdump_nospc(req->ei.key, req->ei.key_len) : "none"); + if (TLVP_PRESENT(tp, GSM0808_IE_AOIP_TRASP_ADDR)) { int rc; unsigned int u; @@ -611,6 +622,24 @@ void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn, .msc_assigned_cic = req->msc_assigned_cic, }; + if (req->chosen_encr_alg) { + info.encr.alg_id = req->chosen_encr_alg; + if (info.encr.alg_id > 1 && !req->ei.key_len) { + ho_fail(HO_RESULT_ERROR, "Chosen Encryption Algorithm (Serving) reflects A5/%u" + " but there is no key (Encryption Information)", info.encr.alg_id - 1); + return; + } + } + + if (req->ei.key_len) { + if (req->ei.key_len > sizeof(info.encr.key)) { + ho_fail(HO_RESULT_ERROR, "Encryption Information IE key length is too large: %u\n", + req->ei.key_len); + } + memcpy(info.encr.key, req->ei.key, req->ei.key_len); + info.encr.key_len = req->ei.key_len; + } + lchan_activate(ho->new_lchan, &info); } |