random

Updated: April 19, 2023

Generator of secure random data

Note:
  • The slogger2 daemon must be running before you start random.
  • You must be root or have the right abilities to start this service.

Syntax:

random [-hpStv] [-i #] [-l library[:init_string]] [-m mode] [-s path] [-U string]

Runs on:

QNX Neutrino

Options:

-h
Show the usage message.
-i#
Use interrupt number # as a source for entropy. You may specify more than one interrupt, to a maximum of 32.
-l library[:init_string]
Load the specified library either to use it as the only source of entropy or to get more entropy if another source is specified. The value of init_string depends on the library. See devr-drng.so, devr-file.so, and devr-virtio.so for the values those libraries use.
-m mode
Specify the permissions, in octal, for the entry under /dev.

The default permissions on these files are 0664, to allow non-root users to contribute entropy.

-p
Poll system information from /proc for entropy.
-S
The file specified by -s path is on a filesystem or resource manager that depends on random (e.g., an ecryption-enabled Power-Safe filesystem). When this option is specified, the startup sequence delays any create or write operations.
-s path
Save the state of the service in the given file, so that it can be reloaded when random is next started.

The state is saved whenever you write to the /dev/random or /dev/urandom resource manager, or after 8192 reseedings.

-t
Use the high-performance clock as an entropy source.
-U string
(QNX Neutrino 6.6 or later) Once running, run as the specified user, so that the program doesn't need to run as root. The string can be in one of these forms:
  • uid[:gid[,sup_gid]*]
  • user_name[,sup_gid]*

In the second form, the primary group is the one specified for user_name in /etc/passwd.

-v
Increase logging verbosity. Not recommended when security is important.

Description:

The random service runs in the background providing a source of secure, pseudo-random data suitable for encryption and security. The service builds its internal pool of pseudo-random data from entropy sources specified when it is started. These sources may include timers, interrupts, and detailed system runtime information. The service makes this random data available by providing device entries that any application can read:

These device entries provide the same functionality.

The user controls all of the sources to be used to collect entropy by specifying source options on the command line.

Note:

Using interrupts as sources imposes an overhead on system performance. When using the -i option, you might want to minimize the impact of this overhead by specifying only one or two interrupts from low interrupt rate devices such as disk drivers and input/serial devices.

This program uses the QNX Cryptography Library (qcrypto) for cryptography services. Make sure qcrypto is correctly configured before you try to use random. For example, you will need a qcrypto library configuration file and an appropriate qcrypto library plugin. For detailed information, see “QNX Cryptography Library” in the System Security Guide.

Random service entropy libraries

Currently, QNX Neutrino provides the following libraries that obtain entropy for use by random: devr-drng.so, devr-file.so, and devr-virtio.so.

Creating your own library

If you create your own entropy library, it needs to implement the random_source_init() and random_source_stop() functions.

The random_source_init() function allows random to give the entropy callback function pointer to the entropy source, and allows the entropy source do any initialization it needs to do:

entropy_return_status random_source_init(unsigned int id,
                                         random_add_entropy_fn pfn,
                                         const char *context);

where id is the identifier for the entropy source, pfn is the random_add_entropy_fn callback function that all entropy libraries must use to add entropy to random, and context is a pointer to a character string that provides options for the DLL (see the -l option description for the format to use with this string). If no option string was provided, context points to an empty string.

Within five seconds after initialization, the entropy source needs to provide entropy using the random_add_entropy_fn function provided by random_source_init(). After it's initialized, the entropy source can call the random_add_entropy_fn function whenever it wants to contribute entropy to random.

To allow the entropy source to shut down cleanly, call random_source_stop() when random is about to shut down:

void random_source_stop(void);

random_add_entropy_fn

The random_add_entropy_fn function prototype has the following syntax:

typedef void (*random_add_entropy_fn)(unsigned int id,
                                      void const *buffer,
                                      uint32_t size);

where id is the identifier for the entropy source, buffer is a pointer to a buffer that contains the entropy to add (can be NULL if size is zero), and size is the size of the buffer in bytes.

While the quality and size of the entropy is largely arbitrary, don't add large volumes of low-quality entropy directly. Instead, hash them using a cryptographic hash and add the hash.

The random_add_entropy_fn function is thread safe.

Calling random_add_entropy_fn

Because the first call to random_add_entropy_fn is guaranteed to be used as part of the initial seeding of the pseudo-random number generator (PRNG), you can use it to ensure the quality of data provided by random on startup.

Call this function within five seconds of calling random_source_init() being called; otherwise, random will not start. If entropy is not immediately available, you can call random_add_entropy_fn with a size of zero.

In all cases, the initial call to random_add_entropy_fn should be delayed until the library has completed all privileged operations that are needed only during start-up.

Examples:

Start the random service using three PC interrupts as sources:

random -i12 -i14 -i15

From an application, read 4 bytes of random data like this:

int data;
int fd;

fd = open( "/dev/random", O_RDWR );
if( fd == -1 )
{
    exit( 1 );
}

read( fd, &data, sizeof( data ) );

close( fd );

Exit status:

0
The random data is available from /dev/random and /dev/urandom.
Any other value
An error occurred; /dev/random and /dev/urandom aren't created.

Errors:

If an error occurs, random sends a description of the error to slogger2 and doesn't create /dev/random or /dev/urandom.

Contributing author:

The random service uses the core algorithm from the Fortuna PRNG devised by Bruce Schneier and Niels Ferguson.

Caveats:

The random service doesn't work unless you specify at least one source for entropy, using the -p, -t, -i, or -l options.