diff options
-rw-r--r-- | include/l1ctl_proto.h | 6 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/l1ctl.h | 3 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/subscriber.h | 2 | ||||
-rw-r--r-- | src/host/layer23/src/common/l1ctl.c | 22 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/gsm48_rr.c | 17 | ||||
-rw-r--r-- | src/target/firmware/layer1/l23_api.c | 17 |
6 files changed, 63 insertions, 4 deletions
diff --git a/include/l1ctl_proto.h b/include/l1ctl_proto.h index 9997450a..d76614b2 100644 --- a/include/l1ctl_proto.h +++ b/include/l1ctl_proto.h @@ -46,6 +46,7 @@ enum { L1CTL_DM_REL_REQ, L1CTL_PARAM_REQ, L1CTL_DM_FREQ_REQ, + L1CTL_CRYPTO_REQ, }; enum ccch_mode { @@ -199,6 +200,11 @@ struct l1ctl_dm_freq_req { }; } __attribute__((packed)); +struct l1ctl_crypto_req { + uint8_t algo; + uint8_t key[0]; +} __attribute__((packed)); + struct l1ctl_pm_req { uint8_t type; uint8_t padding[3]; diff --git a/src/host/layer23/include/osmocom/bb/common/l1ctl.h b/src/host/layer23/include/osmocom/bb/common/l1ctl.h index bfcacd3f..01a49b20 100644 --- a/src/host/layer23/include/osmocom/bb/common/l1ctl.h +++ b/src/host/layer23/include/osmocom/bb/common/l1ctl.h @@ -16,6 +16,9 @@ int l1ctl_tx_data_req(struct osmocom_ms *ms, struct msgb *msg, uint8_t chan_nr, /* Transmit L1CTL_PARAM_REQ */ int l1ctl_tx_param_req(struct osmocom_ms *ms, uint8_t ta, uint8_t tx_power); +int l1ctl_tx_crypto_req(struct osmocom_ms *ms, uint8_t algo, uint8_t *key, + uint8_t len); + /* Transmit L1CTL_RACH_REQ */ int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint8_t fn51, uint8_t mf_off); diff --git a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h index aebb7a8b..72d4dc8a 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/subscriber.h +++ b/src/host/layer23/include/osmocom/bb/mobile/subscriber.h @@ -52,7 +52,7 @@ struct gsm_subscriber { /* key */ uint8_t key_seq; /* ciphering key sequence number */ - uint8_t key[64]; /* 64 bit */ + uint8_t key[8]; /* 64 bit */ /* other */ struct llist_head plmn_list; /* PLMN Selector field */ diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c index b8e332f7..a5d61694 100644 --- a/src/host/layer23/src/common/l1ctl.c +++ b/src/host/layer23/src/common/l1ctl.c @@ -317,6 +317,28 @@ int l1ctl_tx_param_req(struct osmocom_ms *ms, uint8_t ta, uint8_t tx_power) return osmo_send_l1(ms, msg); } +/* Transmit L1CTL_CRYPTO_REQ */ +int l1ctl_tx_crypto_req(struct osmocom_ms *ms, uint8_t algo, uint8_t *key, + uint8_t len) +{ + struct msgb *msg; + struct l1ctl_info_ul *ul; + struct l1ctl_crypto_req *req; + + msg = osmo_l1_alloc(L1CTL_CRYPTO_REQ); + if (!msg) + return -1; + + DEBUGP(DL1C, "CRYPTO Req. algo=%d, len=%d\n", algo, len); + ul = (struct l1ctl_info_ul *) msgb_put(msg, sizeof(*ul)); + req = (struct l1ctl_crypto_req *) msgb_put(msg, sizeof(*req) + len); + req->algo = algo; + if (len) + memcpy(req->key, key, len); + + return osmo_send_l1(ms, msg); +} + /* Transmit L1CTL_RACH_REQ */ int l1ctl_tx_rach_req(struct osmocom_ms *ms, uint8_t ra, uint8_t fn51, uint8_t mf_off) diff --git a/src/host/layer23/src/mobile/gsm48_rr.c b/src/host/layer23/src/mobile/gsm48_rr.c index 7a563acf..5b53b9ce 100644 --- a/src/host/layer23/src/mobile/gsm48_rr.c +++ b/src/host/layer23/src/mobile/gsm48_rr.c @@ -826,6 +826,7 @@ static int gsm48_rr_tx_cip_mode_cpl(struct osmocom_ms *ms, uint8_t cr) static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg) { struct gsm48_rrlayer *rr = &ms->rrlayer; + struct gsm_subscriber *subscr = &ms->subscr; struct gsm_support *sup = &ms->support; struct gsm48_hdr *gh = msgb_l3(msg); struct gsm48_cip_mode_cmd *cm = (struct gsm48_cip_mode_cmd *)gh->data; @@ -854,7 +855,7 @@ static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg) /* 3.4.7.2 */ if (rr->cipher_on && sc) { - LOGP(DRR, LOGL_NOTICE, "chiphering already applied.\n"); + LOGP(DRR, LOGL_NOTICE, "chiphering already applied\n"); return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_PROT_ERROR_UNSPC); } @@ -870,11 +871,21 @@ static int gsm48_rr_rx_cip_mode_cmd(struct osmocom_ms *ms, struct msgb *msg) return gsm48_rr_tx_rr_status(ms, GSM48_RR_CAUSE_CHAN_MODE_UNACCT); + /* check if we have no key */ + if (sc && subscr->key_seq == 7) { + LOGP(DRR, LOGL_NOTICE, "no key available\n"); + return gsm48_rr_tx_rr_status(ms, + GSM48_RR_CAUSE_PROT_ERROR_UNSPC); + } + /* change to ciphering */ -#warning FIXME: cyphering command rr->cipher_on = sc, rr->cipher_type = alg_id; + if (sc) + l1ctl_tx_crypto_req(ms, alg_id + 1, subscr->key, 8); + else + l1ctl_tx_crypto_req(ms, 0, NULL, 0); - /* response */ + /* response (using the new mode) */ return gsm48_rr_tx_cip_mode_cpl(ms, cr); } diff --git a/src/target/firmware/layer1/l23_api.c b/src/target/firmware/layer1/l23_api.c index 8cd8ad00..e103a78c 100644 --- a/src/target/firmware/layer1/l23_api.c +++ b/src/target/firmware/layer1/l23_api.c @@ -201,6 +201,20 @@ static void l1ctl_rx_dm_est_req(struct msgb *msg) l1a_mftask_set(1 << chan_nr2mf_task(ul->chan_nr)); } +/* receive a L1CTL_CRYPTO_REQ from L23 */ +static void l1ctl_rx_crypto_req(struct msgb *msg) +{ + struct l1ctl_hdr *l1h = (struct l1ctl_hdr *) msg->data; + struct l1ctl_info_ul *ul = (struct l1ctl_info_ul *) l1h->data; + struct l1ctl_crypto_req *cr = (struct l1ctl_crypto_req *) ul->payload; + uint8_t key_len = msg->len - sizeof(*l1h) - sizeof(*ul) - sizeof(*cr); + + printd("L1CTL_CRYPTO_REQ (algo=A5/%u, len=%u)\n", cr->algo, key_len); + + // for dieter: (cr->alog, cr->key, key_len); + +} + /* receive a L1CTL_DM_REL_REQ from L23 */ static void l1ctl_rx_dm_rel_req(struct msgb *msg) { @@ -389,6 +403,9 @@ static void l1a_l23_rx_cb(uint8_t dlci, struct msgb *msg) case L1CTL_PARAM_REQ: l1ctl_rx_param_req(msg); break; + case L1CTL_CRYPTO_REQ: + l1ctl_rx_crypto_req(msg); + break; case L1CTL_RACH_REQ: l1ctl_rx_rach_req(msg); break; |