gprs/gb_proxy: Use RAND_bytes for gbproxy TLLI/TMSI allocation

This change has some implications for the test case. It manipulated
bss_ptmsi_state and sgsn_tlli_state variables to make the output of
rand_r() and thus the TLLI/TMSI used predictable.
This possibility is gone when using RAND_bytes() so instead it is
overridden by a function that returns a deterministic sequence of values
(0x00dead00, 0x00dead01, ...). The test cases are adapted to expect
these values instead of the pseudo random values before.

The gbproxy_test stdout file changes as well, but only where the
TLLI/TMSI is displayed (in the hex dumps as well as the TLLI cache
entries).  All other output is the same.
This commit is contained in:
Daniel Willmann 2015-10-12 19:36:35 +02:00 committed by Holger Hans Peter Freyther
parent d1554ecb78
commit 537d480f39
6 changed files with 329 additions and 303 deletions

View File

@ -101,10 +101,6 @@ struct gbproxy_config {
/* IMSI checking/matching */
struct gbproxy_match matches[GBPROX_MATCH_LAST];
/* Used to generate identifiers */
unsigned bss_ptmsi_state;
unsigned sgsn_tlli_state;
};
struct gbproxy_patch_state {

View File

@ -2,7 +2,7 @@ AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS=-Wall -fno-strict-aliasing $(LIBOSMOCORE_CFLAGS) \
$(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(LIBOSMOCTRL_CFLAGS) \
$(LIBOSMOABIS_CFLAGS) $(LIBOSMOGB_CFLAGS) $(COVERAGE_CFLAGS) \
$(LIBCARES_CFLAGS)
$(LIBCARES_CFLAGS) $(LIBCRYPTO_CFLAGS)
OSMO_LIBS = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
$(LIBOSMOCTRL_LIBS) $(LIBOSMOGB_LIBS)
@ -20,7 +20,7 @@ osmo_gbproxy_SOURCES = gb_proxy.c gb_proxy_main.c gb_proxy_vty.c \
gb_proxy_patch.c gb_proxy_tlli.c gb_proxy_peer.c \
gprs_gb_parse.c gprs_llc_parse.c crc24.c gprs_utils.c
osmo_gbproxy_LDADD = $(top_builddir)/src/libcommon/libcommon.a \
$(OSMO_LIBS) -lrt
$(OSMO_LIBS) $(LIBCRYPTO_LIBS) -lrt
osmo_sgsn_SOURCES = gprs_gmm.c gprs_sgsn.c gprs_sndcp.c gprs_sndcp_vty.c \
sgsn_main.c sgsn_vty.c sgsn_libgtp.c \

View File

@ -50,6 +50,8 @@
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/gprs_utils.h>
#include <openssl/rand.h>
static const struct rate_ctr_desc global_ctr_description[] = {
{ "inv-bvci", "Invalid BVC Identifier " },
{ "inv-lai", "Invalid Location Area Identifier" },
@ -232,7 +234,11 @@ uint32_t gbproxy_make_bss_ptmsi(struct gbproxy_peer *peer,
bss_ptmsi = sgsn_ptmsi;
} else {
do {
bss_ptmsi = rand_r(&peer->cfg->bss_ptmsi_state);
if (RAND_bytes((uint8_t *) &bss_ptmsi, sizeof(bss_ptmsi)) != 1) {
bss_ptmsi = GSM_RESERVED_TMSI;
break;
}
bss_ptmsi = bss_ptmsi | 0xC0000000;
if (gbproxy_link_info_by_ptmsi(peer, bss_ptmsi))
@ -265,7 +271,11 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
} else {
do {
/* create random TLLI, 0b01111xxx... */
sgsn_tlli = rand_r(&peer->cfg->sgsn_tlli_state);
if (RAND_bytes((uint8_t *) &sgsn_tlli, sizeof(sgsn_tlli)) != 1) {
sgsn_tlli = 0;
break;
}
sgsn_tlli = (sgsn_tlli & 0x7fffffff) | 0x78000000;
if (gbproxy_link_info_by_any_sgsn_tlli(peer, sgsn_tlli))
@ -1365,8 +1375,6 @@ int gbproxy_init_config(struct gbproxy_config *cfg)
INIT_LLIST_HEAD(&cfg->bts_peers);
cfg->ctrg = rate_ctr_group_alloc(tall_bsc_ctx, &global_ctrg_desc, 0);
clock_gettime(CLOCK_REALTIME, &tp);
cfg->bss_ptmsi_state = tp.tv_sec + tp.tv_nsec;
cfg->sgsn_tlli_state = tp.tv_sec - tp.tv_nsec;
return 0;
}

View File

@ -7,6 +7,8 @@ EXTRA_DIST = gbproxy_test.ok
noinst_PROGRAMS = gbproxy_test
gbproxy_test_SOURCES = gbproxy_test.c
gbproxy_test_LDFLAGS = \
-Wl,--wrap=RAND_bytes
gbproxy_test_LDADD = \
$(top_builddir)/src/gprs/gb_proxy.o \
$(top_builddir)/src/gprs/gb_proxy_patch.o \
@ -22,4 +24,4 @@ gbproxy_test_LDADD = \
$(LIBOSMOCORE_LIBS) $(LIBOSMOGB_LIBS) \
$(LIBOSMOGSM_LIBS) $(LIBOSMOVTY_LIBS) \
$(LIBOSMOABIS_LIBS) $(LIBRARY_DL) \
-lrt
$(LIBCRYPTO_LIBS) -lrt

View File

@ -37,6 +37,8 @@
#include <openbsc/gsm_04_08_gprs.h>
#include <openbsc/debug.h>
#include <openssl/rand.h>
#define REMOTE_BSS_ADDR 0x01020304
#define REMOTE_SGSN_ADDR 0x05060708
@ -51,8 +53,37 @@ struct gbproxy_config gbcfg = {0};
struct llist_head *received_messages = NULL;
/* override, requires '-Wl,--wrap=RAND_bytes' */
int __real_RAND_bytes(unsigned char *buf, int num);
int mock_RAND_bytes(unsigned char *buf, int num);
int (*RAND_bytes_cb)(unsigned char *, int) =
&mock_RAND_bytes;
int __wrap_RAND_bytes(unsigned char *buf, int num)
{
return (*RAND_bytes_cb)(buf, num);
}
static int rand_seq_num = 0;
int mock_RAND_bytes(unsigned char *buf, int num)
{
uint32_t val;
OSMO_ASSERT(num == sizeof(val));
OSMO_ASSERT(__real_RAND_bytes(buf, num) == 1);
val = 0x00dead00 + rand_seq_num;
rand_seq_num++;
memcpy(buf, &val, num);
return 1;
}
static void cleanup_test()
{
rand_seq_num = 0;
}
static int dump_global(FILE *stream, int indent)
@ -1972,8 +2003,6 @@ static void test_gbproxy_ptmsi_assignment()
gbcfg.core_apn = talloc_zero_size(NULL, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 0;
gbcfg.bss_ptmsi_state = 0;
gbcfg.sgsn_tlli_state = 1;
configure_sgsn_peer(&sgsn_peer);
configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
@ -2174,15 +2203,15 @@ static void test_gbproxy_ptmsi_patching()
const uint32_t local_sgsn_tlli = 0xefe2b700;
const uint32_t local_sgsn_tlli2 = 0xe0987654;
const uint32_t local_sgsn_tlli3 = 0xe0543210;
const uint32_t random_sgsn_tlli = 0x7c69fb81;
const uint32_t random_sgsn_tlli = 0x78dead00;
const uint32_t unknown_sgsn_tlli = 0xeebadbad;
const uint32_t bss_ptmsi = 0xc00f7304;
const uint32_t bss_ptmsi2 = 0xe656aa1f;
const uint32_t bss_ptmsi3 = 0xead4775a;
const uint32_t local_bss_tlli = 0xc00f7304;
const uint32_t local_bss_tlli2 = 0xe656aa1f;
const uint32_t local_bss_tlli3 = 0xead4775a;
const uint32_t bss_ptmsi = 0xc0dead01;
const uint32_t bss_ptmsi2 = 0xc0dead02;
const uint32_t bss_ptmsi3 = 0xc0dead03;
const uint32_t local_bss_tlli = 0xc0dead01;
const uint32_t local_bss_tlli2 = 0xc0dead02;
const uint32_t local_bss_tlli3 = 0xc0dead03;
const uint32_t foreign_bss_tlli = 0x8000dead;
@ -2208,8 +2237,6 @@ static void test_gbproxy_ptmsi_patching()
gbcfg.core_apn = talloc_zero_size(NULL, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
gbcfg.bss_ptmsi_state = 0;
gbcfg.sgsn_tlli_state = 1;
configure_sgsn_peer(&sgsn_peer);
configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
@ -2505,10 +2532,10 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
const uint32_t sgsn_ptmsi = 0xefe2b700;
const uint32_t local_sgsn_tlli = 0xefe2b700;
const uint32_t random_sgsn_tlli = 0x7c69fb81;
const uint32_t random_sgsn_tlli = 0x78dead00;
const uint32_t bss_ptmsi = 0xc00f7304;
const uint32_t local_bss_tlli = 0xc00f7304;
const uint32_t bss_ptmsi = 0xc0dead01;
const uint32_t local_bss_tlli = 0xc0dead01;
const uint32_t foreign_bss_tlli = 0x8000dead;
@ -2529,8 +2556,6 @@ static void test_gbproxy_ptmsi_patching_bad_cases()
gbcfg.core_apn = talloc_zero_size(NULL, 100);
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
gbcfg.bss_ptmsi_state = 0;
gbcfg.sgsn_tlli_state = 1;
configure_sgsn_peer(&sgsn_peer);
configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
@ -2691,11 +2716,11 @@ static void test_gbproxy_imsi_acquisition()
const uint32_t sgsn_ptmsi = 0xefe2b700;
const uint32_t local_sgsn_tlli = 0xefe2b700;
const uint32_t random_sgsn_tlli = 0x7c69fb81;
const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
const uint32_t random_sgsn_tlli = 0x78dead00;
const uint32_t random_sgsn_tlli2 = 0x78dead02;
const uint32_t bss_ptmsi = 0xc00f7304;
const uint32_t local_bss_tlli = 0xc00f7304;
const uint32_t bss_ptmsi = 0xc0dead01;
const uint32_t local_bss_tlli = 0xc0dead01;
const uint32_t foreign_bss_tlli = 0x8000dead;
const uint32_t other_bss_tlli = 0x8000beef;
@ -2716,8 +2741,6 @@ static void test_gbproxy_imsi_acquisition()
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
gbcfg.acquire_imsi = 1;
gbcfg.bss_ptmsi_state = 0;
gbcfg.sgsn_tlli_state = 1;
configure_sgsn_peer(&sgsn_peer);
configure_bss_peers(bss_peer, ARRAY_SIZE(bss_peer));
@ -3002,22 +3025,22 @@ static void test_gbproxy_secondary_sgsn()
const uint32_t sgsn_ptmsi = 0xefe2b700;
const uint32_t local_sgsn_tlli = 0xefe2b700;
const uint32_t random_sgsn_tlli = 0x7c69fb81;
const uint32_t random_sgsn_tlli = 0x78dead00;
const uint32_t bss_ptmsi = 0xc00f7304;
const uint32_t local_bss_tlli = 0xc00f7304;
const uint32_t bss_ptmsi = 0xc0dead01;
const uint32_t local_bss_tlli = 0xc0dead01;
const uint32_t foreign_bss_tlli = 0x8000dead;
const uint32_t sgsn_ptmsi2 = 0xe0987654;
const uint32_t local_sgsn_tlli2 = 0xe0987654;
const uint32_t random_sgsn_tlli2 = 0x7eb52dfb;
const uint32_t bss_ptmsi2 = 0xe656aa1f;
const uint32_t local_bss_tlli2 = 0xe656aa1f;
const uint32_t random_sgsn_tlli2 = 0x78dead02;
const uint32_t bss_ptmsi2 = 0xc0dead03;
const uint32_t local_bss_tlli2 = 0xc0dead03;
const uint32_t foreign_bss_tlli2 = 0x8000beef;
const uint32_t random_sgsn_tlli3 = 0x7e23ef54;
const uint32_t bss_ptmsi3 = 0xead4775a;
const uint32_t local_bss_tlli3 = 0xead4775a;
const uint32_t random_sgsn_tlli3 = 0x78dead04;
const uint32_t bss_ptmsi3 = 0xc0dead05;
const uint32_t local_bss_tlli3 = 0xc0dead05;
const uint32_t foreign_bss_tlli3 = 0x8000feed;
const uint8_t imsi1[] = {0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18};
@ -3044,8 +3067,7 @@ static void test_gbproxy_secondary_sgsn()
gbcfg.core_apn_size = gprs_str_to_apn(gbcfg.core_apn, 100, "foo.bar");
gbcfg.patch_ptmsi = 1;
gbcfg.acquire_imsi = 1;
gbcfg.bss_ptmsi_state = 0;
gbcfg.sgsn_tlli_state = 1;
gbcfg.route_to_sgsn2 = 1;
gbcfg.nsip_sgsn2_nsei = SGSN2_NSEI;
@ -3518,8 +3540,6 @@ static void test_gbproxy_keep_info()
gbcfg.nsip_sgsn_nsei = SGSN_NSEI;
gbcfg.patch_ptmsi = 0;
gbcfg.acquire_imsi = 1;
gbcfg.bss_ptmsi_state = 0;
gbcfg.sgsn_tlli_state = 1;
gbcfg.core_mcc = 0;
gbcfg.core_mnc = 0;
gbcfg.core_apn = NULL;

File diff suppressed because it is too large Load Diff