Skip to content

Latest commit

 

History

History
220 lines (151 loc) · 8.37 KB

File metadata and controls

220 lines (151 loc) · 8.37 KB

ssfprng — Pseudo Random Number Generator

SSF | Cryptography

Cryptographically secure capable PRNG based on AES-CTR mode with a 128-bit seed.

Each call to SSFPRNGGetRandom() internally encrypts a monotonically increasing 64-bit counter (zero-padded to 128 bits) with the stored entropy as the AES-128 key, producing up to 16 bytes of pseudo-random output. Security depends entirely on the quality of the entropy supplied to SSFPRNGInitContext().

Dependencies | Notes | Configuration | API Summary | Function Reference

Dependencies

Notes

  • Timing attack warning: This implementation relies on the timing-attack-vulnerable ssfaes block cipher. Do not use in production environments where an attacker can observe precise execution times.
  • Cryptographic security depends entirely on the quality of the entropy provided to SSFPRNGInitContext(). Weak or predictable entropy produces weak output.
  • Each SSFPRNGGetRandom() call advances the internal counter by one regardless of randomSize; unused bytes from the AES block are discarded.
  • Re-seed with SSFPRNGReInitContext() when there is concern about the 64-bit counter eventually exhausting its period or when fresh entropy becomes available.
  • The PRNG is not thread-safe; use separate contexts per thread or protect access with a mutex.
  • Call SSFPRNGDeInitContext() when finished to clear the seed material from memory.

Configuration

This module has no compile-time configuration options in ssfoptions.h.

API Summary

Definitions

Symbol Kind Description
SSF_PRNG_ENTROPY_SIZE Constant 16 — required size in bytes of the entropy buffer passed to SSFPRNGInitContext() and SSFPRNGReInitContext()
SSF_PRNG_RANDOM_MAX_SIZE Constant 16 — maximum number of bytes that can be requested in a single SSFPRNGGetRandom() call
SSFPRNGContext_t Struct PRNG context holding the entropy seed, internal counter, and state marker. Treat as opaque; pass by pointer to all API functions.

Functions

Function Description
e.g. void SSFPRNGInitContext(context, entropy, entropyLen) Initialize a PRNG context with 16 bytes of entropy
e.g. void SSFPRNGReInitContext(context, entropy, entropyLen) Re-seed an existing context with fresh entropy (alias for SSFPRNGInitContext)
e.g. void SSFPRNGDeInitContext(context) De-initialize a context and clear its internal state
e.g. void SSFPRNGGetRandom(context, random, randomSize) Generate 1–16 bytes of pseudo-random data

Function Reference

void SSFPRNGInitContext(SSFPRNGContext_t *context, const uint8_t *entropy, size_t entropyLen);

Initializes a PRNG context using entropy as the 128-bit AES key and resets the internal counter to zero. May also be called on an already-initialized context to re-seed it; the behaviour is identical to SSFPRNGReInitContext(). After this call the context is ready for use with SSFPRNGGetRandom().

Parameter Direction Type Description
context out SSFPRNGContext_t * Pointer to the context to initialize. Must not be NULL.
entropy in const uint8_t * Pointer to SSF_PRNG_ENTROPY_SIZE (16) bytes of entropy. Must not be NULL. The quality of the PRNG output depends entirely on the quality of this data.
entropyLen in size_t Must equal SSF_PRNG_ENTROPY_SIZE (16).

Returns: Nothing.

Example:

uint8_t         entropy[SSF_PRNG_ENTROPY_SIZE];
SSFPRNGContext_t ctx;

/* Obtain 16 bytes of true entropy from a hardware source */
/* entropy <--- hardware RNG or other true entropy source */

SSFPRNGInitContext(&ctx, entropy, sizeof(entropy));
/* ctx is ready; call SSFPRNGGetRandom() to produce random bytes */

#define SSFPRNGReInitContext SSFPRNGInitContext

Alias for SSFPRNGInitContext(). Re-seeds an existing context with fresh entropy and resets the internal counter. Functionally identical to SSFPRNGInitContext(); the separate name improves readability at re-seed call sites. Parameters and return value are the same as SSFPRNGInitContext().

Example:

uint8_t         entropy[SSF_PRNG_ENTROPY_SIZE];
SSFPRNGContext_t ctx;

/* entropy <--- hardware RNG */
SSFPRNGInitContext(&ctx, entropy, sizeof(entropy));

/* ... generate many random values ... */

/* Re-seed with fresh entropy to reset the counter and update the key */
/* entropy <--- hardware RNG */
SSFPRNGReInitContext(&ctx, entropy, sizeof(entropy));
/* ctx counter reset to zero; subsequent calls use the new seed */

void SSFPRNGDeInitContext(SSFPRNGContext_t *context);

De-initializes a PRNG context, zeroing the entropy seed, counter, and state marker. Call this when the context is no longer needed so that seed material does not remain in memory. After this call, SSFPRNGGetRandom() must not be used until SSFPRNGInitContext() is called again.

Parameter Direction Type Description
context in-out SSFPRNGContext_t * Pointer to an initialized context to de-initialize. Must not be NULL.

Returns: Nothing.

Example:

uint8_t         entropy[SSF_PRNG_ENTROPY_SIZE];
SSFPRNGContext_t ctx;

/* entropy <--- hardware RNG */
SSFPRNGInitContext(&ctx, entropy, sizeof(entropy));
/* ... use ctx ... */
SSFPRNGDeInitContext(&ctx);
/* ctx internal state zeroed; entropy seed no longer in memory */

void SSFPRNGGetRandom(SSFPRNGContext_t *context, uint8_t *random, size_t randomSize);

Generates randomSize pseudo-random bytes into random. Internally, encrypts the current 64-bit counter (zero-padded to 128 bits) with the stored entropy as the AES-128 key, writes the first randomSize bytes of the result to random, then increments the counter. Unused bytes from the AES block are discarded; the counter always advances by one per call.

Parameter Direction Type Description
context in-out SSFPRNGContext_t * Pointer to an initialized context. Must not be NULL.
random out uint8_t * Buffer receiving the pseudo-random bytes. Must not be NULL.
randomSize in size_t Number of bytes to generate. Must be between 1 and SSF_PRNG_RANDOM_MAX_SIZE (16) inclusive.

Returns: Nothing.

Example:

uint8_t         entropy[SSF_PRNG_ENTROPY_SIZE];
SSFPRNGContext_t ctx;
uint8_t random16[SSF_PRNG_RANDOM_MAX_SIZE];
uint8_t random8[8];
uint8_t random1[1];

/* entropy <--- hardware RNG */
SSFPRNGInitContext(&ctx, entropy, sizeof(entropy));

/* Generate a full 16-byte block */
SSFPRNGGetRandom(&ctx, random16, sizeof(random16));

/* Generate any size from 1 to SSF_PRNG_RANDOM_MAX_SIZE; counter advances by 1 each call */
SSFPRNGGetRandom(&ctx, random8, sizeof(random8));
SSFPRNGGetRandom(&ctx, random1, sizeof(random1));

SSFPRNGDeInitContext(&ctx);