Zephyr OS Random APIs: Keep Entropy Failure from Becoming a Silent Security Downgrade
A buffer that changes on each run is not evidence of cryptographically suitable randomness. In Zephyr OS, the general random API and the cryptographically secure API have different contracts, including different ways to report failure.
For firmware that creates a security-sensitive random value, inspect the selected generator and the caller's failure branch together. This article follows the v4.4.0 API and its hardware-entropy implementation. It does not certify an entropy source or claim that a statistical sample proves security.

Choose the contract before choosing the convenience wrapper
The versioned random interface explicitly excludes cryptographic security from sys_rand_get() and the small integer wrappers that use it. sys_rand_get() returns void. sys_csrand_get() instead returns a status and provides the cryptographically secure contract.
A hypothetical randomized retry delay and a secret token have different requirements. Reusing the convenient 32-bit helper because both consumers ask for a random number erases that difference. A type or variable name containing “nonce” does not change the generator behind the call.
At the integration boundary, identify which values depend on unpredictability, which depend on a protocol-specific uniqueness rule, and which are only non-security timing jitter. Follow the relevant protocol for the first two. Do not assume that generating fresh random bytes automatically satisfies every nonce-construction requirement.
Inspect the configured implementation's failure path
The tagged hardware-entropy backend checks the selected entropy device's readiness. When entropy retrieval fails, its non-cryptographic path can fill output using cycle-counter values. The cryptographic path does not use that fallback. Its public secure wrapper maps failure to -EIO.
There is also an earlier failure boundary: a device that is not ready makes the internal helper return before obtaining bytes. The void general-random wrapper does not expose that result to its caller. These observations apply to this backend and configuration, not to every Zephyr random generator.
Therefore, do not write a secure wrapper that catches the secure API's failure and retries through the general API. That would deliberately remove the property the caller requested. A changing fallback buffer would make the symptom less obvious without repairing the requirement.
Define what the caller may do after failure
If the secure call fails, do not consume the destination as a successfully generated value. Its contents may be old, partial or otherwise unsuitable; the caller should not assign meaning to them based on how they look. Prevent the operation that requires the value from proceeding until its defined recovery condition is met.
The recovery policy depends on the device. A test fixture might report an initialization failure, while a network feature might remain unavailable and retry through a bounded recovery path. Neither example implies that a product should become permanently unusable after one transient error. The important point is to preserve the required property rather than silently downgrade it.
Keep diagnostic output free of generated secrets. Reporting the selected backend, readiness outcome and API result can support diagnosis without printing the value the operation intended to protect.
Verify the branch, not just the byte distribution
In a disposable integration test, exercise successful generation separately from device-not-ready and entropy-read failure. Observe whether the security-sensitive consumer is blocked on failure and whether any fallback calls bypass that decision.
Review the build configuration as part of this check, including whether a test generator was selected. The interface identifies the test-generator option as testing-only. Record the actual product configuration before drawing conclusions from a development board.
A statistical check may catch gross output defects, but it cannot replace the API contract, backend review and protocol analysis. The most useful immediate test is often simple: make generation fail, then prove that the operation did not quietly proceed with a different class of randomness.