summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/l1ctl_proto.h6
-rw-r--r--src/host/layer23/include/osmocom/bb/common/l1ctl.h3
-rw-r--r--src/host/layer23/include/osmocom/bb/mobile/subscriber.h2
-rw-r--r--src/host/layer23/src/common/l1ctl.c22
-rw-r--r--src/host/layer23/src/mobile/gsm48_rr.c17
-rw-r--r--src/target/firmware/layer1/l23_api.c17
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;