+
+/* Returns random number binary data. */
+
+unsigned char *silc_rng_get_rn_data(SilcRng rng, SilcUInt32 len)
+{
+ int i;
+ unsigned char *data;
+
+ data = silc_calloc(len + 1, sizeof(*data));
+
+ for (i = 0; i < len; i++)
+ data[i] = silc_rng_get_byte(rng);
+
+ return data;
+}
+
+/* Global RNG. This is global RNG that application can initialize so
+ that any part of code anywhere can use RNG without having to allocate
+ new RNG object everytime. If this is not initialized then these routines
+ will fail. Note: currently in SILC applications always initialize this. */
+
+SilcRng global_rng = NULL;
+
+/* Initialize global RNG. If `rng' is provided it is set as the global
+ RNG object (it can be allocated by the application for example). */
+
+bool silc_rng_global_init(SilcRng rng)
+{
+ if (rng)
+ global_rng = rng;
+ else
+ global_rng = silc_rng_alloc();
+
+ return TRUE;
+}
+
+/* Uninitialize global RNG */
+
+bool silc_rng_global_uninit(void)
+{
+ if (global_rng) {
+ silc_rng_free(global_rng);
+ global_rng = NULL;
+ }
+
+ return TRUE;
+}
+
+/* These are analogous to the functions above. */
+
+SilcUInt8 silc_rng_global_get_byte(void)
+{
+ return global_rng ? silc_rng_get_byte(global_rng) : 0;
+}
+
+/* Return random byte as fast as possible. Reads from /dev/urandom if
+ available. If not then return from normal RNG (not so fast). */
+
+SilcUInt8 silc_rng_global_get_byte_fast(void)
+{
+#ifndef SILC_WIN32
+ unsigned char buf[1];
+
+ if (!global_rng)
+ return 0;
+
+ if (global_rng->fd_devurandom == -1) {
+ global_rng->fd_devurandom = open("/dev/urandom", O_RDONLY);
+ if (global_rng < 0)
+ return silc_rng_global_get_byte();
+ fcntl(global_rng->fd_devurandom, F_SETFL, O_NONBLOCK);
+ }
+
+ if (read(global_rng->fd_devurandom, buf, sizeof(buf)) < 0)
+ return silc_rng_global_get_byte();
+
+ return buf[0];
+#else
+ return silc_rng_global_get_byte();
+#endif
+}
+
+SilcUInt16 silc_rng_global_get_rn16(void)
+{
+ return global_rng ? silc_rng_get_rn16(global_rng) : 0;
+}
+
+SilcUInt32 silc_rng_global_get_rn32(void)
+{
+ return global_rng ? silc_rng_get_rn32(global_rng) : 0;
+}
+
+unsigned char *silc_rng_global_get_rn_string(SilcUInt32 len)
+{
+ return global_rng ? silc_rng_get_rn_string(global_rng, len) : NULL;
+}
+
+unsigned char *silc_rng_global_get_rn_data(SilcUInt32 len)
+{
+ return global_rng ? silc_rng_get_rn_data(global_rng, len) : NULL;
+}
+
+void silc_rng_global_add_noise(unsigned char *buffer, SilcUInt32 len)
+{
+ if (global_rng)
+ silc_rng_add_noise(global_rng, buffer, len);
+}