Skip to content

Commit

Permalink
Use crypto safe random numbers (#2738)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmfotokite authored Jul 30, 2021
1 parent fb11615 commit dca2068
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 31 deletions.
6 changes: 6 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -610,9 +610,11 @@ janus_pp_rec_CFLAGS = \
-I$(top_builddir)/postprocessing \
$(LIBCURL_CFLAGS) \
$(POST_PROCESSING_CFLAGS) \
$(BORINGSSL_CFLAGS) \
$(NULL)

janus_pp_rec_LDADD = \
$(BORINGSSL_LIBS) \
$(POST_PROCESSING_LIBS) \
$(LIBCURL_LDFLAGS) $(LIBCURL_LIBS) \
$(NULL)
Expand All @@ -637,9 +639,11 @@ mjr2pcap_SOURCES = \
mjr2pcap_CFLAGS = \
$(AM_CFLAGS) \
$(POST_PROCESSING_CFLAGS) \
$(BORINGSSL_CFLAGS) \
$(NULL)

mjr2pcap_LDADD = \
$(BORINGSSL_LIBS) \
$(POST_PROCESSING_LIBS) \
$(POST_PROCESSING_MANUAL_LIBS) \
$(NULL)
Expand All @@ -659,9 +663,11 @@ pcap2mjr_CFLAGS = \
-I$(top_builddir)/postprocessing \
$(POST_PROCESSING_CFLAGS) \
$(PCAP_CFLAGS) \
$(BORINGSSL_CFLAGS) \
$(NULL)

pcap2mjr_LDADD = \
$(BORINGSSL_LIBS) \
$(POST_PROCESSING_LIBS) \
$(POST_PROCESSING_MANUAL_LIBS) \
$(PCAP_LIBS) \
Expand Down
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,8 @@ AS_IF([test "x$enable_post_processing" = "xyes"],
[
glib-2.0 >= $glib_version
jansson >= $jansson_version
libssl >= $ssl_version
libcrypto
libavutil
libavcodec
libavformat
Expand Down
5 changes: 5 additions & 0 deletions fuzzers/rtcp_fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ gboolean janus_log_colors = FALSE;
char *janus_log_global_prefix = NULL;
int lock_debug = 0;

/* This is to avoid linking with openSSL */
int RAND_bytes(uint8_t *key, int len) {
return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
/* Sanity Checks */
/* Max UDP payload with MTU=1500 */
Expand Down
5 changes: 5 additions & 0 deletions fuzzers/sdp_fuzzer.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ char *janus_log_global_prefix = NULL;
int lock_debug = 0;
int refcount_debug = 0;

/* This is to avoid linking with openSSL */
int RAND_bytes(uint8_t *key, int len) {
return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
/* Since we're fuzzing SDP, and that in our case SDP always comes
* from a Jansson call, this will need to be a valid string */
Expand Down
5 changes: 5 additions & 0 deletions janus.c
Original file line number Diff line number Diff line change
Expand Up @@ -5046,6 +5046,11 @@ gint main(int argc, char *argv[])
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
/* Check if random pool looks ok (this does not give any guarantees for later, though) */
if(RAND_status() != 1) {
JANUS_LOG(LOG_FATAL, "Random pool is not properly seeded, cannot generate random numbers\n");
exit(1);
}
/* ... and DTLS-SRTP in particular */
const char *dtls_ciphers = NULL;
item = janus_config_get(config, config_certs, janus_config_type_item, "dtls_ciphers");
Expand Down
5 changes: 0 additions & 5 deletions plugins/janus_nosip.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,11 +786,6 @@ int janus_nosip_init(janus_callbacks *callback, const char *config_path) {
}
JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);

#ifdef HAVE_SRTP_2
/* Init randomizer (for randum numbers in SRTP) */
RAND_poll();
#endif

sessions = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)janus_nosip_session_destroy);
messages = g_async_queue_new_full((GDestroyNotify) janus_nosip_message_free);
/* This is the callback we'll need to invoke to contact the Janus core */
Expand Down
5 changes: 0 additions & 5 deletions plugins/janus_sip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1924,11 +1924,6 @@ int janus_sip_init(janus_callbacks *callback, const char *config_path) {
}
JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);

#ifdef HAVE_SRTP_2
/* Init randomizer (for randum numbers in SRTP) */
RAND_poll();
#endif

/* Setup sofia */
su_init();
if(notify_events && callback->events_is_enabled()) {
Expand Down
35 changes: 19 additions & 16 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <inttypes.h>

#include <zlib.h>
#include <openssl/rand.h>

#include "utils.h"
#include "debug.h"
Expand Down Expand Up @@ -71,23 +72,25 @@ gboolean janus_strcmp_const_time(const void *str1, const void *str2) {
}

guint32 janus_random_uint32(void) {
return g_random_int();
guint32 ret = 0;
if(RAND_bytes((void *)&ret, sizeof(ret)) != 1) {
JANUS_LOG(LOG_WARN, "Safe RAND_bytes() failed, falling back to unsafe PRNG\n");
return g_random_int();
}
return ret;
}

guint64 janus_random_uint64_full(void) {
guint64 ret = 0;
if(RAND_bytes((void *)&ret, sizeof(ret)) != 1) {
JANUS_LOG(LOG_WARN, "Safe RAND_bytes() failed, falling back to unsafe PRNG\n");
return (g_random_int() << 32) | g_random_int();
}
return ret;
}

guint64 janus_random_uint64(void) {
/*
* FIXME This needs to be improved, and use something that generates
* more strongly random stuff... using /dev/urandom is probably not
* a good idea, as we don't want to make it harder to cross compile Janus
*
* TODO Look into what libssl and/or libcrypto provide in that respect
*
* PS: JavaScript only supports integer up to 2^53, so we need to
* make sure the number is below 9007199254740992 for safety
*/
guint64 num = g_random_int() & 0x1FFFFF;
num = (num << 32) | g_random_int();
return num;
return janus_random_uint64_full() & 0x1FFFFFFFFFFFFF;
}

char *janus_random_uuid(void) {
Expand All @@ -100,8 +103,8 @@ char *janus_random_uuid(void) {
const char *template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
const char *samples = "0123456789abcdef";
union { unsigned char b[16]; uint64_t word[2]; } rnd;
rnd.word[0] = janus_random_uint64();
rnd.word[1] = janus_random_uint64();
rnd.word[0] = janus_random_uint64_full();
rnd.word[1] = janus_random_uint64_full();
/* Generate the string */
char uuid[37], *dst = uuid;
const char *p = template;
Expand Down
31 changes: 26 additions & 5 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,37 @@ gboolean janus_is_true(const char *value);
gboolean janus_strcmp_const_time(const void *str1, const void *str2);

/*! \brief Helper to generate random 32-bit unsigned integers (useful for SSRCs, etc.)
* @note Currently just wraps g_random_int()
* @returns A random 32-bit unsigned integer */
* @note Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random 32-bit unsigned integer */
guint32 janus_random_uint32(void);

/*! \brief Helper to generate random 64-bit unsigned integers (useful for Janus IDs)
* @returns A random 64-bit unsigned integer */
/*! \brief Helper to generate random 64-bit unsigned integers
* @note Unlike janus_random_uint64(), which actually only generates 52 bits, this
* generates the full 64 bits. See the janus_random_uint64() docstring for details.
* Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random 52-bit unsigned integer */
guint64 janus_random_uint64_full(void);

/*! \brief Helper to generate random 52 bit unsigned integers
* @note The reason for 52 instead of 64 bits: Javascript does not have real integers,
* its builtin "number" type is a float64. Thus, only integer values up to
* <code>Number.MAX_SAFE_INTEGER == 2^53 - 1 == 9007199254740991</code>
* can be safely represented in Javascript. This method returns such numbers.
* Use this method instead of janus_random_uint64_full() whenever you generate numbers which
* might end up in Javascript (via JSON API).
* This method is called janus_random_uint64() instead of janus_random_uint52() (or similar)
* for backwards compatibility.
* Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random 64-bit unsigned integer */
guint64 janus_random_uint64(void);

/*! \brief Helper to generate random UUIDs (needed by some plugins)
* @returns A random UUID string, which must be deallocated with \c g_free */
* Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random UUID string, which must be deallocated with \c g_free */
char *janus_random_uuid(void);

/*! \brief Helper to generate an allocated copy of a guint64 number
Expand Down

0 comments on commit dca2068

Please sign in to comment.