[MERGED] 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
Mon Oct 9 10:18:08 UTC 2017


Max has submitted this change and it was merged.

Change subject: Add function to generate random identifier
......................................................................


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 failure is always
returned.

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 for example)
instead.

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, 63 insertions(+), 8 deletions(-)

Approvals:
  Harald Welte: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/configure.ac b/configure.ac
index 33c151e..d9390cf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,9 @@
 AC_PATH_PROG(DOXYGEN,doxygen,false)
 AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false && test "x$doxygen" = "xyes")
 
+# 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 bfcef08..83e29ca 100644
--- a/include/osmocom/gsm/gsm_utils.h
+++ b/include/osmocom/gsm/gsm_utils.h
@@ -38,6 +38,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) */
@@ -60,6 +63,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);
+
 /*!
  * 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 477f076..f572c64 100644
--- a/src/gsm/gsm_utils.c
+++ b/src/gsm/gsm_utils.c
@@ -91,8 +91,17 @@
 #include <errno.h>
 #include <ctype.h>
 #include <inttypes.h>
+#include <time.h>
+#include <unistd.h>
 
 #include "../../config.h"
+
+/* FIXME: this can be removed once we bump glibc requirements to 2.25: */
+#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
+#include <linux/random.h>
+#elif HAVE_DECL_SYS_GETRANDOM
+#include <sys/syscall.h>
+#endif
 
 /* ETSI GSM 03.38 6.2.1 and 6.2.1.1 default alphabet
  * Greek symbols at hex positions 0x10 and 0x12-0x1a
@@ -387,6 +396,45 @@
 	return y;
 }
 
+/*! Generate random identifier
+ *  We use /dev/urandom (default when GRND_RANDOM flag is not set).
+ *  Both /dev/(u)random numbers are coming from the same CSPRNG anyway (at least on GNU/Linux >= 4.8).
+ *  See also RFC4086.
+ *  \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;
+
+#if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 25)
+	rc = getrandom(out, len, GRND_NONBLOCK);
+#elif HAVE_DECL_SYS_GETRANDOM
+#pragma message ("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
+#pragma message ("Secure random unavailable: calls to osmo_get_rand_id() will always fail!")
+	return -ENOTSUP;
+#endif
+	/* getrandom() failed entirely: */
+	if (rc < 0)
+		return -errno;
+
+	/* getrandom() failed partially due to signal interruption:
+	   this should never happen (according to getrandom(2)) as long as OSMO_MAX_RAND_ID_LEN < 256
+	   because we do not set GRND_RANDOM but it's better to be paranoid and check anyway */
+	if (rc != len)
+               return -EAGAIN;
+
+	return 0;
+}
+
 /*! Build the RSL uplink measurement IE (3GPP TS 08.58 § 9.3.25)
  *  \param[in] mru Unidirectional measurement report structure
  *  \param[in] dtxd_used Indicates if DTXd was used during measurement report
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index 95b2ca9..5598859 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 1f5c838..9d1215c 100644
--- a/utils/osmo-auc-gen.c
+++ b/utils/osmo-auc-gen.c
@@ -34,6 +34,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)
 {
@@ -247,14 +248,11 @@
 	}
 
 	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);
+		rc = osmo_get_rand_id(_rand, 16);
+		if (rc < 0) {
+			fprintf(stderr, "\nError: unable to obtain secure random numbers: %s!\n",
+				strerror(-rc));
+			exit(3);
 		}
 	}
 

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I0241b814ea4c4ce1458f7ad76e31d390383c2048
Gerrit-PatchSet: 13
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>
Gerrit-Reviewer: tnt <tnt at 246tNt.com>



More information about the gerrit-log mailing list