fix(crypto): seed the IV generator from OS entropy, not the wall clock - #142
Merged
Conversation
Deferred security item from the 2026-08 review: encryption IV *unpredictability* was weak. The Mersenne Twister behind __db_generate_iv was seeded from __os_gettime() hashed wall-clock SECONDS, so an attacker who knows roughly when the environment was created can narrow the IV stream. (AES-CBC mode and IV uniqueness were already correct; only unpredictability was at issue.) - New src/os/os_csprng.c: __os_csprng() fills a buffer from the OS CSPRNG -- getrandom(2) where available, else arc4random_buf(3), else /dev/urandom via the os layer. Returns an error rather than silently degrading. - configure.ac: probe getrandom, arc4random_buf, and sys/random.h; db_int.in includes <sys/random.h> when present. Registered in srcfiles.in, Makefile.in and dist/meson.build (POSIX only; Windows keeps its own path and the historical fallback). - mt19937db.c: seed from __os_csprng(); fall back to the hashed clock ONLY if the OS has no entropy source, so encryption still functions there. Also fixes a latent tooling breakage found while doing this: our SSI work put category-9 message ids (4573/4574) into src/common/db_err.c, which lives in message category 0 (range 1-500). dist/s_message_id therefore computed a next-id of 4575, exceeded category 0's max, and reported RANGE FULL -- blocking any new DB_STR in src/os, src/common, src/crypto, src/hmac or src/fileops. Reassigned those two to 0211/0212 (DB_SNAPSHOT_CONFLICT / DB_SNAPSHOT_UNSAFE strings are unchanged) and gave os_csprng 0213. s_message_id now runs clean. Verified: probes detected (HAVE_GETRANDOM, HAVE_SYS_RANDOM_H, HAVE_ARC4RANDOM_BUF); build clean; a direct check shows two __os_csprng draws differ and are non-zero; sec001, sec002 (encryption) and test001 btree/hash pass.
|
ABI diff produced no report (build skipped or no base tag). Advisory: libabigail/nm is the authoritative binary-ABI check; Coccinelle is complementary source-level early warning. See dist/cocci/README.md. |
Coccinelle convention checksNo new violations. ✅ Resolved since baseline (2) -- update dist/cocci/baseline.txt to lock these in. |
My first version of the /dev/urandom fallback used a raw `int fd` with __os_open/__os_read/__os_closehandle, but this OS layer takes an opaque DB_FH * (__os_open's last arg is DB_FH **, __os_read takes DB_FH * and size_t *nr). That broke 26 CI jobs (macOS, clang, Windows, nix, meson). Why my local check missed it: HAVE_GETRANDOM is defined on this host, so the fallback branch was preprocessed out and never compiled -- I validated only the configuration that skips the buggy code. Now compiled AND run in all three configurations: getrandom, arc4random_buf, and the urandom fallback (0 errors, 0 warnings each); clang and --disable-cryptography builds clean; two draws differ in both the default and the forced-fallback build.
Windows compiles mt19937db.c (which now calls __os_csprng) but had no implementation, so the DLL link failed with LNK2019: unresolved external symbol __os_csprng referenced in function __db_genrand. I had registered os_csprng.c only in the POSIX build registries; Windows keeps its sources in the VS project files, not dist/srcfiles.in. src/os_windows/os_csprng.c uses RtlGenRandom (SystemFunction036 via advapi32) rather than BCryptGenRandom: no provider handle, available since XP, and no new bcrypt.lib dependency. Registered in VS10/db.vcxproj and db_small.vcxproj. POSIX build re-verified clean; message ids stay in category 0's range (0213 POSIX / 0214 Windows) and s_message_id runs clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deferred security item from the 2026-08 review. Encryption IV unpredictability was weak: the Mersenne Twister behind
__db_generate_ivwas seeded from__os_gettime()hashed wall-clock seconds, so an attacker who knows roughly when the environment was created can narrow the IV stream. (AES-CBC mode and IV uniqueness were already correct — only unpredictability was at issue.)The fix
src/os/os_csprng.c—__os_csprng()fills a buffer from the OS CSPRNG:getrandom(2)where available, elsearc4random_buf(3), else/dev/urandomthrough the os layer. It returns an error rather than silently degrading.getrandom,arc4random_buf,sys/random.h;db_int.inincludes<sys/random.h>when present. Registered insrcfiles.in,dist/Makefile.in,dist/meson.build(POSIX only — Windows keeps its own path and the historical fallback).mt19937db.c: seed from__os_csprng(), falling back to the hashed clock only if the OS has no entropy source, so encryption still functions there.Also fixes a latent tooling breakage found while doing this
Our SSI work put category-9 message IDs (4573/4574) into
src/common/db_err.c, which is message category 0 (range 1–500).dist/s_message_idtherefore computed a next-ID of 4575, exceeded category 0's max, and reportedRANGE FULL— silently blocking any newDB_STRinsrc/os,src/common,src/crypto,src/hmacorsrc/fileops. Reassigned those two to0211/0212(theDB_SNAPSHOT_CONFLICT/DB_SNAPSHOT_UNSAFEstrings themselves are unchanged) and gaveos_csprng0213.s_message_idnow runs clean.This is the same root-cause class as #140: SSI touched a shared convention without auditing it.
Verified
Probes detected (
HAVE_GETRANDOM,HAVE_SYS_RANDOM_H,HAVE_ARC4RANDOM_BUF); build clean; a direct check confirms two__os_csprngdraws differ and are non-zero;sec001,sec002(encryption) andtest001btree/hash pass.