diff --git a/include/osmocom/bsc/gsm_08_08.h b/include/osmocom/bsc/gsm_08_08.h index da5e2f1ac..07f08214d 100644 --- a/include/osmocom/bsc/gsm_08_08.h +++ b/include/osmocom/bsc/gsm_08_08.h @@ -7,7 +7,7 @@ struct gsm_subscriber_connection; void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause); -void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr); +void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_a5_n); int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel); void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg); void bsc_cm_update(struct gsm_subscriber_connection *conn, diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h index 4fe97a28b..fcd888367 100644 --- a/include/osmocom/bsc/gsm_data.h +++ b/include/osmocom/bsc/gsm_data.h @@ -546,6 +546,7 @@ struct om2k_mo { * These macros convert from n to the other representations: */ #define ALG_A5_NR_TO_RSL(A5_N) ((A5_N) >= 0 ? (A5_N)+1 : 0) +#define ALG_A5_NR_TO_BSSAP(A5_N) ALG_A5_NR_TO_RSL(A5_N) #define ALG_A5_NR_TO_PERM_ALG_BITS(A5_N) ((A5_N) >= 0 ? 1<<(A5_N) : 0) /* Up to 16 SI2quater are multiplexed; each fits 3 EARFCNS, so the practical maximum is 3*16. @@ -608,7 +609,7 @@ enum lchan_sapi_state { #define MAX_A5_KEY_LEN (128/8) struct gsm_encr { - uint8_t alg_id; + uint8_t alg_a5_n; /* N: 0 (A5/0), 1 (A5/1), ... 7 (A5/7) */ uint8_t key_len; uint8_t key[MAX_A5_KEY_LEN]; bool kc128_present; diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c index a49cc6529..66818759e 100644 --- a/src/osmo-bsc/abis_rsl.c +++ b/src/osmo-bsc/abis_rsl.c @@ -159,13 +159,13 @@ static void pad_macblock(uint8_t *out, const uint8_t *in, int len) * 'out' must provide room for 17 bytes. */ static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan) { - *out++ = lchan->encr.alg_id & 0xff; - switch (lchan->encr.alg_id) { + out[0] = ALG_A5_NR_TO_RSL(lchan->encr.alg_a5_n); + switch (out[0]) { case GSM0808_ALG_ID_A5_1: case GSM0808_ALG_ID_A5_2: case GSM0808_ALG_ID_A5_3: if (!lchan->encr.key_len) { - LOG_LCHAN(lchan, LOGL_ERROR, "A5/%d encryption chosen, but missing Kc\n", lchan->encr.alg_id); + LOG_LCHAN(lchan, LOGL_ERROR, "A5/%d encryption chosen, but missing Kc\n", lchan->encr.alg_a5_n); return -EINVAL; } /* fall through */ @@ -177,7 +177,7 @@ static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan) * even for A5/0. Currently our ttcn3 test suite does expect the key to be present also for A5/0, see * f_cipher_mode() in bsc/MSC_ConnectionHandler.ttcn. */ if (lchan->encr.key_len) - memcpy(out, lchan->encr.key, lchan->encr.key_len); + memcpy(&out[1], lchan->encr.key, lchan->encr.key_len); return 1 + lchan->encr.key_len; case GSM0808_ALG_ID_A5_4: @@ -185,11 +185,11 @@ static int build_encr_info(uint8_t *out, struct gsm_lchan *lchan) LOG_LCHAN(lchan, LOGL_ERROR, "A5/4 encryption chosen, but missing Kc128\n"); return -EINVAL; } - memcpy(out, lchan->encr.kc128, sizeof(lchan->encr.kc128)); + memcpy(&out[1], lchan->encr.kc128, sizeof(lchan->encr.kc128)); return 1 + sizeof(lchan->encr.kc128); default: - LOG_LCHAN(lchan, LOGL_ERROR, "A5/%d encryption not supported\n", lchan->encr.alg_id); + LOG_LCHAN(lchan, LOGL_ERROR, "A5/%d encryption not supported\n", lchan->encr.alg_a5_n); return -EINVAL; } } @@ -660,7 +660,7 @@ int rsl_tx_chan_activ(struct gsm_lchan *lchan, uint8_t act_type, uint8_t ho_ref) msg->l3h = len + 1; *len = msgb_l3len(msg); - if (lchan->encr.alg_id > ALG_A5_NR_TO_RSL(0)) { + if (lchan->encr.alg_a5_n > 0) { uint8_t encr_info[MAX_A5_KEY_LEN+2]; rc = build_encr_info(encr_info, lchan); if (rc > 0) @@ -764,7 +764,7 @@ int rsl_chan_mode_modify_req(struct gsm_lchan *lchan) msgb_tlv_put(msg, RSL_IE_CHAN_MODE, sizeof(cm), (uint8_t *) &cm); - if (lchan->encr.alg_id > ALG_A5_NR_TO_RSL(0)) { + if (lchan->encr.alg_a5_n > 0) { uint8_t encr_info[MAX_A5_KEY_LEN+2]; rc = build_encr_info(encr_info, lchan); if (rc > 0) diff --git a/src/osmo-bsc/assignment_fsm.c b/src/osmo-bsc/assignment_fsm.c index 0243058b3..8d5e84115 100644 --- a/src/osmo-bsc/assignment_fsm.c +++ b/src/osmo-bsc/assignment_fsm.c @@ -226,7 +226,7 @@ static void send_assignment_complete(struct gsm_subscriber_connection *conn) resp = gsm0808_create_ass_compl2(lchan->abis_ip.ass_compl.rr_cause, chosen_channel, - lchan->encr.alg_id, perm_spch, + ALG_A5_NR_TO_BSSAP(lchan->encr.alg_a5_n), perm_spch, addr_local_p, sc_ptr, NULL, lcls_get_status(conn)); if (!resp) { diff --git a/src/osmo-bsc/gsm_04_08_rr.c b/src/osmo-bsc/gsm_04_08_rr.c index 368ad733c..d1d61d67b 100644 --- a/src/osmo-bsc/gsm_04_08_rr.c +++ b/src/osmo-bsc/gsm_04_08_rr.c @@ -368,16 +368,14 @@ int gsm48_send_rr_ciph_mode(struct gsm_lchan *lchan, int want_imeisv) { struct msgb *msg = gsm48_msgb_alloc_name("GSM 04.08 CIPH"); struct gsm48_hdr *gh; - uint8_t ciph_mod_set; + uint8_t ciph_mod_set = 0x00; msg->lchan = lchan; DEBUGP(DRR, "TX CIPHERING MODE CMD\n"); - if (lchan->encr.alg_id <= ALG_A5_NR_TO_RSL(0)) - ciph_mod_set = 0; - else - ciph_mod_set = (lchan->encr.alg_id-2)<<1 | 1; + if (lchan->encr.alg_a5_n > 0) + ciph_mod_set = (lchan->encr.alg_a5_n - 1) << 1 | 0x01; gh = (struct gsm48_hdr *) msgb_put(msg, sizeof(*gh) + 1); gh->proto_discr = GSM48_PDISC_RR; @@ -592,9 +590,8 @@ struct msgb *gsm48_make_ho_cmd(const struct gsm_lchan *new_lchan, * Shall be included in the case of inter-RAT handover. */ if (ho_scope & HO_INTER_BSC_IN) { uint8_t cms = 0x00; - /* This formula copied from gsm48_send_rr_ciph_mode() */ - if (new_lchan->encr.alg_id > ALG_A5_NR_TO_RSL(0)) - cms = (new_lchan->encr.alg_id - 2) << 1 | 1; + if (new_lchan->encr.alg_a5_n > 0) + cms = (new_lchan->encr.alg_a5_n - 1) << 1 | 1; /* T (4 bit) + V (4 bit), see 3GPP TS 44.018, 10.5.2.9 */ msgb_v_put(msg, GSM48_IE_CIP_MODE_SET | (cms & 0x0f)); } @@ -1014,7 +1011,7 @@ static void dispatch_dtap(struct gsm_subscriber_connection *conn, osmo_fsm_inst_dispatch(conn->ho.fi, HO_EV_RR_HO_FAIL, msg); break; case GSM48_MT_RR_CIPH_M_COMPL: - bsc_cipher_mode_compl(conn, msg, conn->lchan->encr.alg_id); + bsc_cipher_mode_compl(conn, msg, conn->lchan->encr.alg_a5_n); break; case GSM48_MT_RR_ASS_COMPL: if (conn->assignment.fi) diff --git a/src/osmo-bsc/gsm_08_08.c b/src/osmo-bsc/gsm_08_08.c index a99db4316..6d6f57c51 100644 --- a/src/osmo-bsc/gsm_08_08.c +++ b/src/osmo-bsc/gsm_08_08.c @@ -85,7 +85,7 @@ void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, } /*! MS->MSC: Tell MSC that ciphering has been enabled. */ -void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr) +void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_a5_n) { int rc; struct msgb *resp; @@ -94,7 +94,7 @@ void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb * return; LOGP(DMSC, LOGL_DEBUG, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n"); - resp = gsm0808_create_cipher_complete(msg, chosen_encr); + resp = gsm0808_create_cipher_complete(msg, ALG_A5_NR_TO_BSSAP(chosen_a5_n)); rate_ctr_inc(rate_ctr_group_get_ctr(conn->sccp.msc->msc_ctrs, MSC_CTR_BSSMAP_TX_DT1_CIPHER_COMPLETE)); rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_TX_SCCP, resp); if (rc != 0) diff --git a/src/osmo-bsc/handover_fsm.c b/src/osmo-bsc/handover_fsm.c index 488f370e9..a4221c4bc 100644 --- a/src/osmo-bsc/handover_fsm.c +++ b/src/osmo-bsc/handover_fsm.c @@ -756,7 +756,7 @@ void handover_start_inter_bsc_in(struct gsm_subscriber_connection *conn, } /* Put encryption info in the chan activation info */ - info.encr.alg_id = ALG_A5_NR_TO_RSL(chosen_a5_n); + info.encr.alg_a5_n = chosen_a5_n; if (chosen_a5_n > 0) { if (req->ei.key_len > sizeof(info.encr.key)) { ho_fail(HO_RESULT_ERROR, "Encryption Information IE key length is too large: %u", @@ -933,7 +933,7 @@ static void send_handover_performed(struct gsm_subscriber_connection *conn) ho_perf_params.chosen_channel_present = true; /* Chosen Encryption Algorithm 3.2.2.44 */ - ho_perf_params.chosen_encr_alg = lchan->encr.alg_id; + ho_perf_params.chosen_encr_alg = ALG_A5_NR_TO_BSSAP(lchan->encr.alg_a5_n); ho_perf_params.chosen_encr_alg_present = true; if (ho->new_lchan->activate.info.requires_voice_stream) { diff --git a/src/osmo-bsc/lchan_fsm.c b/src/osmo-bsc/lchan_fsm.c index 84f8dc5ef..00bb605c4 100644 --- a/src/osmo-bsc/lchan_fsm.c +++ b/src/osmo-bsc/lchan_fsm.c @@ -750,7 +750,7 @@ static void lchan_fsm_wait_ts_ready_onenter(struct osmo_fsm_inst *fi, uint32_t p : "none", gsm_lchant_name(lchan->type), gsm48_chan_mode_name(lchan->activate.ch_mode_rate.chan_mode), - (lchan->activate.info.encr.alg_id ? : 1)-1, + lchan->activate.info.encr.alg_a5_n, lchan->activate.info.encr.key_len ? osmo_hexdump_nospc(lchan->activate.info.encr.key, lchan->activate.info.encr.key_len) : "none"); diff --git a/src/osmo-bsc/osmo_bsc_bssap.c b/src/osmo-bsc/osmo_bsc_bssap.c index df22a0974..7f8c8a18a 100644 --- a/src/osmo-bsc/osmo_bsc_bssap.c +++ b/src/osmo-bsc/osmo_bsc_bssap.c @@ -532,7 +532,7 @@ static int bssmap_handle_cipher_mode(struct gsm_subscriber_connection *conn, goto reject; } - conn->lchan->encr.alg_id = ALG_A5_NR_TO_RSL(chosen_cipher); + conn->lchan->encr.alg_a5_n = chosen_cipher; if (enc_key_len) { conn->lchan->encr.key_len = enc_key_len; memcpy(conn->lchan->encr.key, enc_key, enc_key_len); @@ -1436,7 +1436,7 @@ int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn, struct .l3_info_len = rr_ho_command->len, .chosen_channel_present = true, .chosen_channel = gsm0808_chosen_channel(new_lchan->type, new_lchan->current_ch_mode_rate.chan_mode), - .chosen_encr_alg = new_lchan->encr.alg_id, + .chosen_encr_alg = ALG_A5_NR_TO_BSSAP(new_lchan->encr.alg_a5_n), .chosen_speech_version = gsm0808_permitted_speech(new_lchan->type, new_lchan->current_ch_mode_rate.chan_mode), }; @@ -1506,7 +1506,7 @@ enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection struct gsm0808_handover_complete params = { .chosen_encr_alg_present = true, - .chosen_encr_alg = lchan->encr.alg_id, + .chosen_encr_alg = ALG_A5_NR_TO_BSSAP(lchan->encr.alg_a5_n), .chosen_channel_present = true, .chosen_channel = gsm0808_chosen_channel(lchan->type, lchan->current_ch_mode_rate.chan_mode), diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c index dd2f16aea..c01b6ee83 100644 --- a/tests/handover/handover_test.c +++ b/tests/handover/handover_test.c @@ -1685,7 +1685,7 @@ void trau_send_frame() {} /* Stub */ int osmo_bsc_sigtran_open_conn(struct gsm_subscriber_connection *conn, struct msgb *msg) { return 0; } void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, uint8_t dlci, enum gsm0808_cause cause) {} -void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_encr) {} +void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn, struct msgb *msg, uint8_t chosen_a5_n) {} int bsc_compl_l3(struct gsm_lchan *lchan, struct msgb *msg, uint16_t chosen_channel) { return 0; } void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg) {}