diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/gsm/gsm_utils.c | 48 | ||||
| -rw-r--r-- | src/gsm/libosmogsm.map | 1 | 
2 files changed, 49 insertions, 0 deletions
diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c index 477f076d..f572c643 100644 --- a/src/gsm/gsm_utils.c +++ b/src/gsm/gsm_utils.c @@ -91,9 +91,18 @@  #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   * left out as they can't be handled with a char and @@ -387,6 +396,45 @@ int gsm_7bit_encode_n_ussd(uint8_t *result, size_t n, const char *data, int *oct  	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 95b2ca9f..5598859a 100644 --- a/src/gsm/libosmogsm.map +++ b/src/gsm/libosmogsm.map @@ -39,6 +39,7 @@ abis_nm_get_sw_desc_len;  osmo_sitype_strs;  osmo_c4; +osmo_get_rand_id;  bitvec_add_range1024;  comp128;  comp128v2;  | 
