diff options
author | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2016-03-21 22:27:15 +0100 |
---|---|---|
committer | Neels Hofmeyr <nhofmeyr@sysmocom.de> | 2016-03-22 19:54:09 +0100 |
commit | debb0e386871e64a769d7414b71bedec09d7e76a (patch) | |
tree | 4c2dcaec7f22257e2d650ceacc5759805f5853f7 | |
parent | d025a3cfbb53f690a4ebbd628cafda81c1b34bc7 (diff) |
cscn: implement integrity protection
Upon authentication response, initiate integrity protection for Iu by sending a
Security Mode Command (IK), with hardcoded auth tuple so far.
Implement RANAP event handling to receive Security Mode Complete message,
adding stubs for the other events; in new files osmo-cscn/iucs_ranap.[hc] to
keep RANAP dependencies separate, and particularly out of libmsc.
Upon receiving Security Mode Complete, call the security operation callback
(conn->sec_operation->cb) to complete the Location Update.
Introduce enum integrity_protection_state constants to indicate integrity
protection, record in gsm_subscriber_conn.iu.integrity_protection.
Make subscr_conn_lookup_iu() non-static and declare in iu_cs.h to be able to
call from iucs_ranap.c's Security Mode Complete event.
Implement dummy iu_tx_sec_mode_cmd() to allow tests to build without RANAP
dependencies.
In cscn_main.c, call iucs_rx_ranap_event(), to populate the struct gsm_network
struct with cscn_network explicitly (don't share cscn_network across
compilation scopes because it's ugly).
-rw-r--r-- | openbsc/include/openbsc/gsm_data.h | 7 | ||||
-rw-r--r-- | openbsc/include/openbsc/iu_cs.h | 2 | ||||
-rw-r--r-- | openbsc/src/libmsc/gsm_04_08.c | 25 | ||||
-rw-r--r-- | openbsc/src/libmsc/iu_cs.c | 6 | ||||
-rw-r--r-- | openbsc/src/osmo-cscn/Makefile.am | 7 | ||||
-rw-r--r-- | openbsc/src/osmo-cscn/cscn_main.c | 6 | ||||
-rw-r--r-- | openbsc/src/osmo-cscn/iucs_ranap.c | 110 | ||||
-rw-r--r-- | openbsc/src/osmo-cscn/iucs_ranap.h | 7 | ||||
-rw-r--r-- | openbsc/tests/libiudummy/iudummy.c | 6 |
9 files changed, 167 insertions, 9 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h index ce16c72b5..0a450d754 100644 --- a/openbsc/include/openbsc/gsm_data.h +++ b/openbsc/include/openbsc/gsm_data.h @@ -105,6 +105,12 @@ enum interface_type { IFACE_IU = 1 /* Iu-interface for UMTS aka 3G (IuCS or IuPS) */ }; +enum integrity_protection_state { + INTEGRITY_PROTECTION_NONE = 0, + INTEGRITY_PROTECTION_IK = 1, + INTEGRITY_PROTECTION_IK_CK = 2, +}; + /* mobile subscriber data */ struct gsm_subscriber_connection { struct llist_head entry; @@ -151,6 +157,7 @@ struct gsm_subscriber_connection { /* which Iu-CS connection, if any. */ struct { struct ue_conn_ctx *ue_ctx; + int integrity_protection; } iu; #else diff --git a/openbsc/include/openbsc/iu_cs.h b/openbsc/include/openbsc/iu_cs.h index 60ff92d25..fb5b6972a 100644 --- a/openbsc/include/openbsc/iu_cs.h +++ b/openbsc/include/openbsc/iu_cs.h @@ -6,3 +6,5 @@ struct gsm_subscriber_connection *subscr_conn_allocate_iu(struct gsm_network *ne uint8_t link_id, uint32_t conn_id); +struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network, + struct ue_conn_ctx *ue); diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c index a6010463b..801931f74 100644 --- a/openbsc/src/libmsc/gsm_04_08.c +++ b/openbsc/src/libmsc/gsm_04_08.c @@ -64,6 +64,7 @@ #include <osmocom/gsm/tlv.h> #include <openbsc/msc_ifaces.h> +#include <openbsc/iu.h> #include <assert.h> @@ -405,7 +406,7 @@ int gsm0408_authorize(struct gsm_subscriber_connection *conn) " no location update operation pending\n"); return 0; } - + if (authorize_subscriber(conn->loc_operation, conn->subscr)) return gsm48_secure_channel(conn, conn->loc_operation->key_seq, _gsm0408_authorize_sec_cb, NULL); @@ -1156,6 +1157,28 @@ static int gsm48_rx_mm_auth_resp(struct gsm_subscriber_connection *conn, struct return gsm0808_cipher_mode(conn, net->a5_encryption, conn->sec_operation->atuple.kc, 8, 0); + if (conn->via_iface == IFACE_IU + && !conn->iu.integrity_protection) { + LOGP(DIUCS, LOGL_DEBUG, + "Requesting integrity protection for %s\n", + subscr_name(conn->subscr)); + + /* send Security Mode Command (IK) to start integrity + * protection */ + + /* DEV HACK: hardcoded auth tuple */ + /* instead, employ auth_get_tuple_for_subscr() */ + struct gsm_auth_tuple tp; + tp = (struct gsm_auth_tuple) { + .key_seq = 0, + .rand = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }, + .sres = { 0x61, 0xb5, 0x69, 0xf5 }, + .kc = { 0xd9, 0xd9, 0xc2, 0xed, 0x62, 0x7d, 0x68, 0x00 }, + }; + + return iu_tx_sec_mode_cmd(conn->iu.ue_ctx, &tp, 0); + } + /* Only authentication requested, and we're done. */ if (!cb) return 0; diff --git a/openbsc/src/libmsc/iu_cs.c b/openbsc/src/libmsc/iu_cs.c index 8d1878dc3..946d89ad5 100644 --- a/openbsc/src/libmsc/iu_cs.c +++ b/openbsc/src/libmsc/iu_cs.c @@ -74,8 +74,9 @@ static inline void log_subscribers(struct gsm_network *network) /* Return an existing IuCS subscriber connection record for the given link and * connection IDs, or return NULL if not found. */ -static struct gsm_subscriber_connection *subscr_conn_lookup_iu(struct gsm_network *network, - struct ue_conn_ctx *ue) +struct gsm_subscriber_connection *subscr_conn_lookup_iu( + struct gsm_network *network, + struct ue_conn_ctx *ue) { struct gsm_subscriber_connection *conn; @@ -143,4 +144,3 @@ int gsm0408_rcvmsg_iucs(struct gsm_network *network, struct msgb *msg) return rc; } - diff --git a/openbsc/src/osmo-cscn/Makefile.am b/openbsc/src/osmo-cscn/Makefile.am index 66109ff38..545decb47 100644 --- a/openbsc/src/osmo-cscn/Makefile.am +++ b/openbsc/src/osmo-cscn/Makefile.am @@ -1,4 +1,5 @@ -AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir) \ + -DCOMPILING_LIBMSC=1 AM_CFLAGS=-Wall $(COVERAGE_CFLAGS) \ $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) \ $(LIBOSMOCTRL_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(LIBSMPP34_CFLAGS) \ @@ -8,7 +9,9 @@ AM_LDFLAGS = $(COVERAGE_LDFLAGS) bin_PROGRAMS = osmo-cscn -osmo_cscn_SOURCES = cscn_main.c +noinst_HEADERS = iucs_ranap.h + +osmo_cscn_SOURCES = cscn_main.c iucs_ranap.c osmo_cscn_LDADD = \ $(top_builddir)/src/libiu/libiu.a \ diff --git a/openbsc/src/osmo-cscn/cscn_main.c b/openbsc/src/osmo-cscn/cscn_main.c index 80b98731b..2b1b505a6 100644 --- a/openbsc/src/osmo-cscn/cscn_main.c +++ b/openbsc/src/osmo-cscn/cscn_main.c @@ -71,6 +71,8 @@ #include <openbsc/iu.h> #include <openbsc/iu_cs.h> +#include "iucs_ranap.h" + static const char * const osmocscn_copyright = "OsmoCSCN - Osmocom Circuit-Switched Core Network implementation\r\n" "Copyright (C) 2016 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>\r\n" @@ -327,11 +329,9 @@ static int rx_iu_event(struct ue_conn_ctx *ctx, enum iu_event_type type, { DEBUGP(DIUCS, "got Iu-CS event %u\n", type); - /* TODO: Handle RAB assignment response for UE */ - return 0; + return iucs_rx_ranap_event(cscn_network, ctx, type, data); } - int main(int argc, char **argv) { int rc; diff --git a/openbsc/src/osmo-cscn/iucs_ranap.c b/openbsc/src/osmo-cscn/iucs_ranap.c new file mode 100644 index 000000000..078783f12 --- /dev/null +++ b/openbsc/src/osmo-cscn/iucs_ranap.c @@ -0,0 +1,110 @@ +/* Implementation of RANAP messages to/from an MSC via an Iu-CS interface. + * This keeps direct RANAP dependencies out of libmsc. */ + +/* (C) 2016 by sysmocom s.m.f.c. GmbH <info@sysmocom.de> + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include <osmocom/core/logging.h> + +#include <osmocom/ranap/ranap_ies_defs.h> + +#include <openbsc/debug.h> +#include <openbsc/gsm_data.h> +#include <openbsc/gsm_subscriber.h> +#include <openbsc/iu.h> +#include <openbsc/iu_cs.h> + +#include "iucs_ranap.h" + +/* To continue authorization after a Security Mode Complete */ +int gsm0408_authorize(struct gsm_subscriber_connection *conn); + +static int iucs_rx_rab_assign(struct gsm_subscriber_connection *conn, + RANAP_RAB_SetupOrModifiedItemIEs_t *setup_ies) +{ + uint8_t rab_id; + RANAP_RAB_SetupOrModifiedItem_t *item = &setup_ies->raB_SetupOrModifiedItem; + + rab_id = item->rAB_ID.buf[0]; + + LOGP(DIUCS, LOGL_NOTICE, "Received RAB assignment event for %s" + " rab_id=%hhd\n", subscr_name(conn->subscr), rab_id); + /* TODO do stuff like in sgsn_ranap_rab_ass_resp() */ + + return 0; +} + +int iucs_rx_sec_mode_compl(struct gsm_subscriber_connection *conn, + RANAP_SecurityModeCompleteIEs_t *ies) +{ + gsm_cbfn *cb; + + OSMO_ASSERT(conn->via_iface == IFACE_IU); + + /* TODO evalute ies */ + + if (conn->iu.integrity_protection) + LOGP(DIUCS, LOGL_NOTICE, "Integrity Protection" + " was already enabled for %s\n", + subscr_name(conn->subscr)); + + conn->iu.integrity_protection = INTEGRITY_PROTECTION_IK; + + cb = conn->sec_operation->cb; + if (!cb) + return 0; + return cb(GSM_HOOK_RR_SECURITY, GSM_SECURITY_SUCCEEDED, + NULL, conn, conn->sec_operation->cb_data); +} + +int iucs_rx_ranap_event(struct gsm_network *network, + struct ue_conn_ctx *ue_ctx, int type, void *data) +{ + struct gsm_subscriber_connection *conn; + + conn = subscr_conn_lookup_iu(network, ue_ctx); + + if (!conn) { + LOGP(DRANAP, LOGL_NOTICE, "Cannot find subscriber for IU event %u\n", type); + return -1; + } + + switch (type) { + case IU_EVENT_IU_RELEASE: + LOGP(DIUCS, LOGL_INFO, "IuCS release for %s\n", + subscr_name(conn->subscr)); + msc_subscr_con_free(conn); + return 0; + + case IU_EVENT_SECURITY_MODE_COMPLETE: + LOGP(DIUCS, LOGL_INFO, "IuCS security mode complete for %s\n", + subscr_name(conn->subscr)); + return iucs_rx_sec_mode_compl(conn, + (RANAP_SecurityModeCompleteIEs_t*)data); + case IU_EVENT_RAB_ASSIGN: + return iucs_rx_rab_assign(conn, + (RANAP_RAB_SetupOrModifiedItemIEs_t*)data); + default: + LOGP(DIUCS, LOGL_NOTICE, "Unknown message received:" + " RANAP event: %i\n", type); + return -1; + } +} + diff --git a/openbsc/src/osmo-cscn/iucs_ranap.h b/openbsc/src/osmo-cscn/iucs_ranap.h new file mode 100644 index 000000000..c9fb255d3 --- /dev/null +++ b/openbsc/src/osmo-cscn/iucs_ranap.h @@ -0,0 +1,7 @@ +#pragma once + +struct ue_conn_ctx; + +int iucs_rx_ranap_event(struct gsm_network *network, + struct ue_conn_ctx *ue_ctx, int type, void *data); + diff --git a/openbsc/tests/libiudummy/iudummy.c b/openbsc/tests/libiudummy/iudummy.c index 7c5129b33..770bccaa9 100644 --- a/openbsc/tests/libiudummy/iudummy.c +++ b/openbsc/tests/libiudummy/iudummy.c @@ -15,3 +15,9 @@ int iu_tx(struct msgb *msg, uint8_t sapi) return 0; } +int iu_tx_sec_mode_cmd(struct ue_conn_ctx *uectx, struct gsm_auth_tuple *tp, + int send_ck) +{ + LOGP(DLGLOBAL, LOGL_INFO, "iu_tx_sec_mode_cmd() dummy called, NOT transmitting Security Mode Command\n"); + return 0; +} |