[PATCH 8/8] nat: After we identified the bsc check the key

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Holger Hans Peter Freyther holger at freyther.de
Mon Jun 15 09:55:42 UTC 2015


From: Holger Hans Peter Freyther <holger at moiji-mobile.com>

We are using the token to find the right bsc_config and
then we can use the last_rand of the bsc_connection to
calculate the expected result and try to compare it with
a time constant(???) memcmp.
---
 openbsc/include/openbsc/bsc_nat.h      |  2 ++
 openbsc/src/osmo-bsc_nat/bsc_nat.c     | 61 ++++++++++++++++++++++++++++++++--
 openbsc/src/osmo-bsc_nat/bsc_nat_vty.c | 32 ++++++++++++++++--
 3 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/openbsc/include/openbsc/bsc_nat.h b/openbsc/include/openbsc/bsc_nat.h
index c313e52..72773a9 100644
--- a/openbsc/include/openbsc/bsc_nat.h
+++ b/openbsc/include/openbsc/bsc_nat.h
@@ -148,6 +148,8 @@ enum bsc_cfg_ctr {
 struct bsc_config {
 	struct llist_head entry;
 
+	uint8_t key[16];
+	uint8_t key_present;
 	char *token;
 	int nr;
 
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat.c b/openbsc/src/osmo-bsc_nat/bsc_nat.c
index 9837709..581193e 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat.c
@@ -51,6 +51,8 @@
 #include <osmocom/ctrl/control_cmd.h>
 #include <osmocom/ctrl/control_if.h>
 
+#include <osmocom/crypt/auth.h>
+
 #include <osmocom/core/application.h>
 #include <osmocom/core/talloc.h>
 
@@ -993,11 +995,57 @@ static void ipaccess_close_bsc(void *data)
 	bsc_close_connection(conn);
 }
 
+/* Wishful thinking to generate a constant time compare */
+static int constant_time_cmp(const uint8_t *exp, const uint8_t *rel, const int count)
+{
+	int x = 0, i;
+
+	for (i = 0; i < count; ++i)
+		x |= exp[i] ^ rel[i];
+
+	return x != 0;
+}
+
+static int verify_key(struct bsc_connection *conn, struct bsc_config *conf, const uint8_t *key, const int keylen)
+{
+	struct osmo_auth_vector vec;
+
+	struct osmo_sub_auth_data auth = {
+		.type		= OSMO_AUTH_TYPE_GSM,
+		.algo		= OSMO_AUTH_ALG_MILENAGE,
+	};
+
+	/* expect a specific keylen */
+	if (keylen != 8) {
+		LOGP(DNAT, LOGL_ERROR, "Key length is wrong: %d for bsc nr %d\n",
+			keylen, conf->nr);
+		return 0;
+	}
+
+	memcpy(auth.u.umts.opc, conf->key, 16);
+	memcpy(auth.u.umts.k, conf->key, 16);
+	memset(auth.u.umts.amf, 0, 2);
+	auth.u.umts.sqn = 0;
+
+	memset(&vec, 0, sizeof(vec));
+	osmo_auth_gen_vec(&vec, &auth, conn->last_rand);
+
+	if (vec.res_len != 8) {
+		LOGP(DNAT, LOGL_ERROR, "Res length is wrong: %d for bsc nr %d\n",
+			keylen, conf->nr);
+		return 0;
+	}
+
+	return constant_time_cmp(vec.res, key, 8) == 0;
+}
+
 static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc)
 {
 	struct bsc_config *conf;
 	const char *token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
 	int len = TLVP_LEN(tvp, IPAC_IDTAG_UNITNAME);
+	const uint8_t *xres = TLVP_VAL(tvp, 0x24);
+	const int xlen = TLVP_LEN(tvp, 0x24);
 
 	if (bsc->cfg) {
 		LOGP(DNAT, LOGL_ERROR, "Reauth on fd %d bsc nr %d\n",
@@ -1033,6 +1081,15 @@ static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc
 		return;
 	}
 
+	/* We have set a key and expect it to be present */
+	if (conf->key_present && !verify_key(bsc, conf, xres, xlen - 1)) {
+		LOGP(DNAT, LOGL_ERROR,
+			"Wrong key for bsc nr %d fd: %d.\n", conf->nr,
+			bsc->write_queue.bfd.fd);
+		bsc_close_connection(bsc);
+		return;
+	}
+
 	rate_ctr_inc(&conf->stats.ctrg->ctr[BCFG_CTR_NET_RECONN]);
 	bsc->authenticated = 1;
 	bsc->cfg = conf;
@@ -1227,9 +1284,9 @@ exit:
 		if (msg->l2h[0] == IPAC_MSGT_ID_RESP && msgb_l2len(msg) > 2) {
 			struct tlv_parsed tvp;
 			int ret;
-			ret = ipa_ccm_idtag_parse(&tvp,
+			ret = ipa_ccm_idtag_parse_off(&tvp,
 					     (unsigned char *) msg->l2h + 2,
-					     msgb_l2len(msg) - 2);
+					     msgb_l2len(msg) - 2, 0);
 			if (ret < 0) {
 				LOGP(DNAT, LOGL_ERROR, "ignoring IPA response "
 					"message with malformed TLVs\n");
diff --git a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
index 821e522..981168c 100644
--- a/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
+++ b/openbsc/src/osmo-bsc_nat/bsc_nat_vty.c
@@ -1,6 +1,6 @@
 /* OpenBSC NAT interface to quagga VTY */
-/* (C) 2010-2013 by Holger Hans Peter Freyther
- * (C) 2010-2013 by On-Waves
+/* (C) 2010-2015 by Holger Hans Peter Freyther
+ * (C) 2010-2015 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -151,6 +151,8 @@ static void config_write_bsc_single(struct vty *vty, struct bsc_config *bsc)
 {
 	vty_out(vty, " bsc %u%s", bsc->nr, VTY_NEWLINE);
 	vty_out(vty, "  token %s%s", bsc->token, VTY_NEWLINE);
+	if (bsc->key_present)
+		vty_out(vty, "  auth-key %s%s", osmo_hexdump(bsc->key, 16), VTY_NEWLINE);
 	dump_lac(vty, &bsc->lac_list);
 	if (bsc->description)
 		vty_out(vty, "  description %s%s", bsc->description, VTY_NEWLINE);
@@ -814,6 +816,30 @@ DEFUN(cfg_bsc_token, cfg_bsc_token_cmd, "token TOKEN",
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_bsc_auth_key, cfg_bsc_auth_key_cmd,
+      "auth-key KEY",
+      "Authentication (secret) key configuration\n"
+      "Non null security key\n")
+{
+	struct bsc_config *conf = vty->index;
+
+	memset(conf->key, 0, sizeof(conf->key));
+	osmo_hexparse(argv[0], conf->key, sizeof(conf->key));
+	conf->key_present = 1;
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bsc_no_auth_key, cfg_bsc_no_auth_key_cmd,
+      "no auth-key",
+      NO_STR "Authentication (secret) key configuration\n")
+{
+	struct bsc_config *conf = vty->index;
+
+	memset(conf->key, 0, sizeof(conf->key));
+	conf->key_present = 0;
+	return CMD_SUCCESS;
+}
+
 DEFUN(cfg_bsc_lac, cfg_bsc_lac_cmd, "location_area_code <0-65535>",
       "Add the Location Area Code (LAC) of this BSC\n" "LAC\n")
 {
@@ -1202,6 +1228,8 @@ int bsc_nat_vty_init(struct bsc_nat *nat)
 	install_node(&bsc_node, config_write_bsc);
 	vty_install_default(NAT_BSC_NODE);
 	install_element(NAT_BSC_NODE, &cfg_bsc_token_cmd);
+	install_element(NAT_BSC_NODE, &cfg_bsc_auth_key_cmd);
+	install_element(NAT_BSC_NODE, &cfg_bsc_no_auth_key_cmd);
 	install_element(NAT_BSC_NODE, &cfg_bsc_lac_cmd);
 	install_element(NAT_BSC_NODE, &cfg_bsc_no_lac_cmd);
 	install_element(NAT_BSC_NODE, &cfg_bsc_paging_cmd);
-- 
2.3.5




More information about the OpenBSC mailing list