docs/entropy.md tells a RAND=drbg integrator to build the boot seed by layering several sources and compressing them:
Mix all of the following into the boot seed (concatenate and hash with sha256_of, or XOR into the reseed input).
That recipe does not link. sha256_of is not in PUBLIC (Makefile:227), and objcopy $(foreach s,$(PUBLIC),-G $(s)) (Makefile:262) makes every other symbol local in the packaged object.
Reproduction
$ make lib-check RAND=drbg
lib-check: 5 exported symbols, all public API
$ nm bin/chapulin.o | grep -E 'sha256_of|drbg_seed'
0000000000007e10 T _ch_drbg_seed
0000000000000b2c t _sha256_of <- local
Writing the page's own recipe and linking it against the object:
$ cc -I. -o seedtest seedtest.c bin/chapulin.o
Undefined symbols for architecture arm64:
"_sha256_of", referenced from:
_boot in seedtest.o
ld: symbol(s) not found for architecture arm64
The same file links cleanly with the sha256_of line removed, so that symbol is the only unresolvable one. (ch_assert_fail is supplied by the image as usual; the test defines it.)
Why it matters
Compression is not optional on this path. ch_drbg_seed takes exactly 32 bytes (drbg.h:26), and the same page forbids seeding from one source alone. So an integrator following the documentation has to compress several sources into 32 bytes, and the call the page names for it is unavailable.
Fix, two options
- Export it under the drbg arm only:
PUBLIC_RAND := ch_drbg_seed ch_sha256, renamed for the ch_ prefix every public call carries. lib-check already reads a different export list per arm, so this costs the default arm nothing and keeps the four-export claim for builds that do not use the DRBG. It does gate an export on need rather than on dependency, one step past x509_ca.h's precedent, so it deserves a decisions.md entry.
- Rewrite the recipe to use only exported calls.
Either way, add a link-only check to the lib-check RAND=drbg leg that compiles and links the documented recipe, so it cannot rot again. Nothing in the tree currently compiles what the documentation tells an integrator to write, which is why this went unnoticed.
Found while evaluating #25.
docs/entropy.mdtells aRAND=drbgintegrator to build the boot seed by layering several sources and compressing them:That recipe does not link.
sha256_ofis not inPUBLIC(Makefile:227), andobjcopy $(foreach s,$(PUBLIC),-G $(s))(Makefile:262) makes every other symbol local in the packaged object.Reproduction
Writing the page's own recipe and linking it against the object:
The same file links cleanly with the
sha256_ofline removed, so that symbol is the only unresolvable one. (ch_assert_failis supplied by the image as usual; the test defines it.)Why it matters
Compression is not optional on this path.
ch_drbg_seedtakes exactly 32 bytes (drbg.h:26), and the same page forbids seeding from one source alone. So an integrator following the documentation has to compress several sources into 32 bytes, and the call the page names for it is unavailable.Fix, two options
PUBLIC_RAND := ch_drbg_seed ch_sha256, renamed for thech_prefix every public call carries.lib-checkalready reads a different export list per arm, so this costs the default arm nothing and keeps the four-export claim for builds that do not use the DRBG. It does gate an export on need rather than on dependency, one step pastx509_ca.h's precedent, so it deserves a decisions.md entry.Either way, add a link-only check to the
lib-check RAND=drbgleg that compiles and links the documented recipe, so it cannot rot again. Nothing in the tree currently compiles what the documentation tells an integrator to write, which is why this went unnoticed.Found while evaluating #25.