Direct Entropy Injection in ML-KEM: Understanding MakeKeyWithRandom and DRBG Bypass

At Crypta Labs, we are interested in direct applications of quantum random number generators (QRNG). This interest led us to explore how we can use our QRNG entropy directly in cryptographic operations, without intermediate processing layers.

As we transition to post-quantum cryptography (PQC), it’s important to understand the need for randomness in these new algorithms. Post-quantum cryptographic operations, such as ML-KEM (formerly Kyber), require high-quality random bytes for key generation and other operations. Understanding how to properly inject this randomness is crucial for both security and performance.

The wolfCrypt library provides a function that allows direct use of randomness, bypassing the DRBG layer entirely. The wc_KyberKey_MakeKeyWithRandom() function accepts random bytes directly, which was exactly what we needed for our QRNG integration. In this post, we’ll share what we learned about how this function works and why it was the right choice for our use case.

The Three Approaches: Standard DRBG, DRBG Seeded with QRNG, and Direct QRNG

Standard Approach: Using DRBG

The traditional approach in wolfSSL uses a DRBG (Deterministic Random Bit Generator) for randomness:

WC_RNG rng;
wc_InitRng(&rng);
wc_KyberKey_MakeKey(&key, &rng);

In this approach, the DRBG is initialized and seeded (typically from system entropy sources). When wc_KyberKey_MakeKey() is called, it internally calls wc_RNG_GenerateBlock() to generate random bytes. The DRBG processes the entropy through its deterministic algorithm, and the resulting bytes are used for key generation.

This approach provides the security benefits of a DRBG, including forward secrecy and resistance to state compromise. It’s the standard, well-tested method for most use cases.

DRBG Seeded with QRNG (Callback Approach)

At Crypta Labs, we also implemented a callback approach that seeds the DRBG with our QRNG entropy. This method follows FIPS 140-3 standards while leveraging our quantum entropy source. Here’s how it works:

The callback function (qrng_seed_cb) is called by wolfSSL’s DRBG whenever it needs entropy for seeding or reseeding. Our callback retrieves fresh quantum randomness from our QRNG hardware and provides it to the DRBG:

static int qrng_seed_cb(OS_Seed* os, byte* seed, word32 sz)
{
    int ret;
    int wait = 0;
    const int MAX_WAIT = 1000;
    (void)os;
    if (seed == NULL || sz == 0)
        return BAD_FUNC_ARG;
    while ((int)qrng_qps_ready_bytes(&hqps1) < (int)sz) {
        ret = qrng_qps_generate(&hqps1, 0);
        if (ret != 0 && ret != QRNG_BUSY)
            return RNG_FAILURE_E;
        if (++wait > MAX_WAIT)
            return RNG_FAILURE_E;
        if (ret == QRNG_BUSY)
            HAL_Delay(1);
    }
    ret = qrng_qps_random_get(&hqps1, seed, sz);
    if (ret != 0)
        return RNG_FAILURE_E;
    return 0;
}

int qrng_wolfssl_seed_register(void)
{
#ifdef WC_RNG_SEED_CB
    {
        int ret = wc_SetSeed_Cb(qrng_seed_cb);
        if (ret == 0) g_qrng_seed_cb_registered = 1;
        return ret;
    }
#else
    nucleo_Output("QRNG callback registration skipped - WC_RNG_SEED_CB not defined\n");
    return 0;
#endif
}

This approach provides the best of both worlds: the security properties and FIPS 140-3 compliance of a DRBG, combined with quantum entropy from our QRNG hardware. The DRBG still performs its deterministic processing and state management, but the entropy source is our quantum random number generator rather than system entropy sources.

We can also manually reseed the DRBG with QRNG entropy before each operation for additional security:

byte reseed[32];
qrng_qps_random_get(&hqps1, reseed, sizeof(reseed));
wc_RNG_DRBG_Reseed(&rng, reseed, sizeof(reseed));
wc_KyberKey_MakeKey(&key, &rng);

Direct Approach: Bypassing DRBG

The alternative approach uses wc_KyberKey_MakeKeyWithRandom(), which is what we implemented:

byte rand[KYBER_MAKEKEY_RAND_SZ];
qrng_qps_random_get(&hqps1, rand, KYBER_MAKEKEY_RAND_SZ);
// ... obtain random bytes from QRNG source ...
wc_KyberKey_MakeKeyWithRandom(&key, rand, KYBER_MAKEKEY_RAND_SZ);

This function completely bypasses the DRBG and uses the provided bytes directly as entropy. There’s no intermediate processing layer – the bytes go straight from your entropy source to the key generation algorithm. In our QRNG implementation, we do not perform entropy expansion in the conditioning component. We consider the quality of our conditioned data suitable for direct usage in cryptographic operations. However, it is important to note that this approach is not an officially recognized standard, unlike the FIPS 140-3 compliant DRBG approach.

How MakeKeyWithRandom Works

After examining the wolfSSL source code, we found that wc_KyberKey_MakeKeyWithRandom() takes the random bytes provided and uses them directly. Unlike wc_KyberKey_MakeKey(), this function never calls wc_RNG_GenerateBlock() or performs any DRBG processing. The bytes are immediately processed through the ML-KEM key generation algorithm.

In the source code:

const byte* d = rand;  // Directly uses the passed random bytes
// ... processes d through hash functions ...
const byte* z = rand + KYBER_SYM_SZ;  // Uses second part directly

The function extracts two parts from the random buffer: the first 32 bytes (d) are used as the seed for generating the public matrix, and the next 32 bytes (z) are used as the noise seed for generating the error vector. No DRBG is involved in this process – the provided bytes are used directly as entropy.

Interestingly, the standard wc_KyberKey_MakeKey() function follows the same internal structure. It generates 64 bytes of randomness through the DRBG (32 bytes at a time via two calls to wc_RNG_GenerateBlock()), then calls wc_KyberKey_MakeKeyWithRandom() internally with those bytes. The only difference is the source of the randomness – system entropy through DRBG versus direct QRNG entropy.

Crypta Labs’ Flexible Quantum Entropy Integration

At Crypta Labs, we explored all three approaches. The DRBG seeded with QRNG (callback approach) provides FIPS 140-3 compliance while using quantum entropy, which is ideal for applications requiring certified security standards. However, for our direct QRNG integration use case, we chose to bypass the DRBG entirely for the following reasons:

  1. Quantum Random Number Generators (QRNG)
    Our primary motivation was to use our QRNG hardware’s quantum randomness directly without an intermediate DRBG layer. We use a vetted conditioning component that does not perform entropy expansion. We consider the conditioning process sufficient for our cryptographic operations, as it allows us to claim full entropy on the bits we generate as per NIST 800-90B stadards.

    Again, here’s our implementation:

    byte rand[KYBER_MAKEKEY_RAND_SZ];
    qrng_qps_random_get(&hqps1, rand, KYBER_MAKEKEY_RAND_SZ);
    wc_KyberKey_MakeKeyWithRandom(&key, rand, KYBER_MAKEKEY_RAND_SZ);
    

    This approach provides:

    • Elimination of DRBG processing overhead
    • Direct use of quantum randomness that aligns with our security model
    • Precise control over the entropy source
    • Seamless integration with our QRNG hardware
    • Full entropy claims enabled by our conditioning component that combined with the fact we don’t expand entropy, eliminate the need for additional DRBG processing
  2. Performance Optimization
    Our benchmarks show a small but consistent performance advantage when bypassing the DRBG. For ML-KEM-512 key generation, we observed approximately 2% faster operations (4.520 ms vs 4.620 ms). While the improvement is modest, it becomes noticeable when performing many key generation operations. Additionally, we generate fresh randomness on demand from our QRNG hardware, rather than drawing from a system entropy pool. This ensures predictable throughput and eliminates any dependency on the state of system entropy sources, which can be shared with other processes or have variable availability.
  3. Custom Entropy Sources
    Since we have specialized entropy sources (our QRNG hardware), we can inject them directly without routing through the DRBG layer.

Security Considerations

When using MakeKeyWithRandom, we are responsible for ensuring the quality and security of our entropy source:

  1. Entropy Quality: The bytes we provide must be truly random and unpredictable. Weak entropy results in weak keys, so we ensure our QRNG provides high-quality quantum randomness. We’ve tested it thoroughly, and our conditioning component validates the entropy quality.
  2. Entropy Quantity: We must provide exactly KYBER_MAKEKEY_RAND_SZ bytes. The function validates this and returns an error if the length is incorrect, which prevents generating keys with insufficient entropy.
  3. Forward Secrecy Through Independence: Unlike DRBG-based approaches that maintain persistent state, we use fresh quantum randomness for each operation, making each output independent. Our conditioning component ensures full entropy. Since each key generation uses independent quantum entropy after conditioning, past outputs cannot predict future outputs – providing equivalent forward secrecy through independence rather than state evolution.
  4. State Management: The DRBG provides automatic state management and reseeding. With direct entropy injection, we must manage entropy freshness ourselves. We handle this by generating fresh quantum randomness for each key generation operation, ensuring each output is independent and unpredictable.

Comparison: The Three Approaches

Mode Standard DRBG (System Entropy) DRBG Seeded with QRNG (Callback Approach) Direct QRNG (Bypass DRBG)
DRBG Usage Yes – uses DRBG internally Yes – uses DRBG, seeded with QRNG No – bypasses DRBG completely
Entropy Source System entropy (/dev/urandom, hardware RNG) QRNG hardware via seed callback QRNG hardware via seed callback
Random Generation Calls wc_RNG_GenerateBlock() Calls wc_RNG_GenerateBlock(), seeded by QRNG callback Uses provided bytes directly
FIPS 140-3 Compliance Yes – standard DRBG approach Yes – DRBG with QRNG entropy source if QRNG with the ESV certificate No – not officially recognized standard
Security Properties Forward secrecy via state evolution, state management Forward secrecy via state evolution, state management, quantum entropy Forward secrecy via independence, depends on entropy source quality
Performance DRBG overhead DRBG overhead, QRNG not slower than system entropy Lower overhead, direct processing
Entropy Expansion Yes – DRBG performs entropy expansion Yes – DRBG performs entropy expansion No – no entropy expansion in conditioning
Flexibility Limited to DRBG sources Any entropy source via callback Any entropy source

Similar Functions: Encapsulation

The same pattern exists for encapsulation operations. There’s wc_KyberKey_Encapsulate() that uses a DRBG via WC_RNG, and wc_KyberKey_EncapsulateWithRandom() that bypasses the DRBG and uses provided bytes directly. The same principle applies – direct entropy injection bypasses the DRBG layer.

The approach presented in this post requires ensuring that the entropy source provides high-quality, unpredictable randomness. Our QRNG hardware provides quantum randomness, which meets this requirement. For applications requiring FIPS 140-3 compliance, the DRBG seeded with QRNG with the ESV certification approach provides the best balance of quantum entropy and certified security standards.

Understanding all three approaches enabled us to make informed decisions based on our specific security requirements, performance constraints, and entropy source characteristics. For Crypta Labs, the direct entropy injection approach enabled us to fully leverage our quantum random number generation capabilities in post-quantum cryptographic operations.

If you have questions about any of the above, please contact us at facts@wolfssl.com or call us at +1 425 245 8247.

Download wolfSSL Now