[PATCH] libosmocore[master]: Add function to generate random identifier

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/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Fri Jun 9 12:26:48 UTC 2017


Hello Harald Welte, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/1526

to look at the new patch set (#3).

Add function to generate random identifier

The function is a wrapper on top of getrandom() (if available via glibc) or
corresponding syscall. If neither is available than insecure random
generation is used as a fallback (which is clearly indicated to the caller).

It's intended to generate small random data good enough for session
identifiers and keys. To generate long-term cryptographic keys it's
better to use special crypto libraries like GnuTLS instead. The size of
the output is deliberately limited to decrease the chance of entropy
pool depletion. It's still possible via successive calls but the caller
can find a way to deplete the entropy anyway so it's not our concern.

As an example it's used to replace old insecure random number generator
in osmo-auc-gen utility.

Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048
Related: OS#1694
---
M configure.ac
M include/osmocom/gsm/gsm_utils.h
M src/gsm/gsm_utils.c
M src/gsm/libosmogsm.map
M utils/osmo-auc-gen.c
5 files changed, 73 insertions(+), 9 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/26/1526/3

diff --git a/configure.ac b/configure.ac
index 04d126e..b152b13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -62,6 +62,9 @@
 AC_PATH_PROG(DOXYGEN,doxygen,false)
 AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false)
 
+# check for syscal fallback on glibc < 2.25 - can be removed once glibc version requirement is bumped
+AC_CHECK_DECLS([SYS_getrandom], [], [], [[#include <sys/syscall.h>]])
+
 # The following test is taken from WebKit's webkit.m4
 saved_CFLAGS="$CFLAGS"
 CFLAGS="$CFLAGS -fvisibility=hidden "
diff --git a/include/osmocom/gsm/gsm_utils.h b/include/osmocom/gsm/gsm_utils.h
index 1ffe579..5429226 100644
--- a/include/osmocom/gsm/gsm_utils.h
+++ b/include/osmocom/gsm/gsm_utils.h
@@ -37,6 +37,9 @@
 
 #define GSM_MAX_FN	(26*51*2048)
 
+/* Max length of random identifier which can be requested via osmo_get_rand_id() */
+#define OSMO_MAX_RAND_ID_LEN 16
+
 struct gsm_time {
 	uint32_t	fn;	/* FN count */
 	uint16_t	t1;	/* FN div (26*51) */
@@ -59,6 +62,8 @@
 const char *gsm_band_name(enum gsm_band band);
 enum gsm_band gsm_band_parse(const char *mhz);
 
+int osmo_get_rand_id(uint8_t *out, size_t len);
+
 /*!
  * \brief Decode a sequence of GSM 03.38 encoded 7 bit characters.
  *
diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c
index 7365ab7..7e9111d 100644
--- a/src/gsm/gsm_utils.c
+++ b/src/gsm/gsm_utils.c
@@ -69,6 +69,7 @@
 #include <osmocom/gsm/meas_rep.h>
 #include <osmocom/gsm/protocol/gsm_04_08.h>
 
+#include <unistd.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
@@ -76,6 +77,10 @@
 #include <stdio.h>
 #include <errno.h>
 #include <ctype.h>
+#include <time.h>
+
+#include <linux/random.h>
+#include <sys/syscall.h>
 
 #include "../../config.h"
 
@@ -662,6 +667,62 @@
 	return arfcn;
 }
 
+static inline void fallback_insecure_rand(uint8_t *out, size_t len)
+{
+	int i;
+
+	srand(time(NULL));
+
+	for (i = 0; i < len; out[i++] = rand());
+}
+
+/*! \brief Generate random identifier
+ *  \param[out] out Buffer to be filled with random data
+ *  \param[in] len Number of random bytes required
+ *  \returns 0 on success, or a negative error code on error.
+ */
+int osmo_get_rand_id(uint8_t *out, size_t len)
+{
+	int rc;
+
+	/* this function is intended for generating short identifiers only, not arbitrary-length random data */
+	if (len > OSMO_MAX_RAND_ID_LEN)
+		return -E2BIG;
+
+	/* we use /dev/urandom (default when GRND_RANDOM flag is not set) which is fine as (at least on GNU/Linux >= 4.8)
+	   both /dev/(u)random numbers are coming from the same CSPRNG anyway - see also RFC4086 */
+#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
+	rc = getrandom(out, len, GRND_NONBLOCK);
+#elif HAVE_DECL_SYS_GETRANDOM
+#warning "Using direct syscall access for getrandom(): consider upgrading to glibc >= 2.25"
+	/* FIXME: this can be removed once we bump glibc requirements to 2.25 */
+	rc = syscall(SYS_getrandom, out, len, GRND_NONBLOCK);
+#else
+#warning "Insecure random fallback is used: no getrandom syscall available!"
+	/* Fallback for systems without getrandom() syscall */
+	rc = 0;
+#endif
+	if (rc < 0) { /* getrandom() failed entirely */
+		switch (errno) {
+		case EAGAIN: /* the requested entropy is not available: fallback to insecure generator and let
+				application decide if it's OK with */
+			fallback_insecure_rand(out, len);
+		default: /* intentional fall-through */
+			return -errno;
+		}
+	}
+
+	if (rc != len) { /* the system call was interrupted by a signal: this should not actually happen
+			    (according to getrandom(2)) as long as OSMO_MAX_RAND_ID_LEN < 256 because we do not set
+			    GRND_RANDOM but let's be paranoid and check/fallback anyway */
+		fallback_insecure_rand(out + rc, len);
+
+		return -EAGAIN;
+	}
+
+	return 0;
+}
+
 void gsm_fn2gsmtime(struct gsm_time *time, uint32_t fn)
 {
 	time->fn = fn;
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 8fb9878..a3e8420 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -39,6 +39,7 @@
 
 osmo_sitype_strs;
 osmo_c4;
+osmo_get_rand_id;
 bitvec_add_range1024;
 comp128;
 comp128v2;
diff --git a/utils/osmo-auc-gen.c b/utils/osmo-auc-gen.c
index 6b1e623..eba1663 100644
--- a/utils/osmo-auc-gen.c
+++ b/utils/osmo-auc-gen.c
@@ -33,6 +33,7 @@
 
 #include <osmocom/crypt/auth.h>
 #include <osmocom/core/utils.h>
+#include <osmocom/gsm/gsm_utils.h>
 
 static void dump_triplets_dat(struct osmo_auth_vector *vec)
 {
@@ -224,15 +225,8 @@
 	}
 
 	if (!rand_is_set) {
-		int i;
-		printf("WARNING: We're using really weak random numbers!\n\n");
-		srand(time(NULL));
-
-		for (i = 0; i < 4; ++i) {
-			uint32_t r;
-			r = rand();
-			memcpy(&_rand[i*4], &r, 4);
-		}
+		if (osmo_get_rand_id(_rand, 16) < 0)
+			printf("WARNING: We're using really weak random numbers!\n\n");
 	}
 
 	if (test_aud.type == OSMO_AUTH_TYPE_NONE ||

-- 
To view, visit https://gerrit.osmocom.org/1526
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048
Gerrit-PatchSet: 3
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Holger Freyther <holger at freyther.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr at sysmocom.de>



More information about the gerrit-log mailing list