# libsodium -- the NaCl-derived modern crypto library, ported to the # wasm32-hwjs glibc image under BRINTOS-311. # # libsodium ships NO command-line tools at all. That is the single fact that # shapes this suite: for every other port on this Epic a shipped CLI could be # driven against a published vector, and here there is nothing to drive. The # main `libsodium` package is empty on this static-only arm (PKGSIZE 0 -- it # would have been the shared objects) and is deliberately not in the image, so # what ships is libsodium-dev (headers + .pc) and libsodium-staticdev (the # archive). The ONLY way to show the library runs rather than merely installs # is data/libsodium-probe, cross-linked against the very /usr/lib/libsodium.a # that ships. # # THREE THINGS THIS SUITE ASSERTS: # # 1. What the port ships -- the archive, the header tree, the pkg-config file. # # 2. The portable backend really is what executes. This one had to be # MEASURED rather than guessed, and the first guess was wrong: the wasm32 # archive DOES carry all nineteen accelerated members (libaesni_la-*, # libsse2_la-*, libssse3_la-*, libsse41_la-*, libavx2_la-*, libavx512f_la-*, # libarmcrypto_la-*), so "the accel objects are absent" would have been a # false assertion. What is true is that they are INERT: on this arm # libavx2_la-chacha20_dolbeau-avx2.o and libaesni_la-aegis128l_aesni.o # define NO SYMBOLS ("no symbols" from llvm-nm), while the same two objects # in a native x86_64 build of this identical release define # chacha20_encrypt_bytes / stream_ref / stream_ietf_ext_ref and the aegis # entry points. The intrinsics are preprocessed out; the members survive as # empty stubs. The target-side statement of that is the probe's eleven # cpu-no-* cases: every sodium_runtime_has_*() must report 0 here, and the # SAME probe on native reports 1 for ten of them -- so the detection is # live on both sides rather than a stub wired to return zero. # # 3. The library RUNS, via data/libsodium-probe: 80 cases against published # constants (FIPS 180-4, RFC 7693, RFC 4231, RFC 8439, RFC 7748, RFC 8032, # the SipHash-2-4 reference vector), scoring 70/80 against a native x86_64 # build of this identical release -- the ten "failures" there being exactly # the cpu-no-* cases that are true only on wasm32. # # WHY THE PROBE IS ALSO THE REGRESSION GUARD FOR THE PORT'S ONE WORKAROUND. # libsodium adds -fstack-protector to its own CFLAGS, and on this arm any object # compiled with it FATALs the first consumer link with # "phantom import: env.__stack_chk_fail" -- glibc defines the symbol, but the # call is emitted at final codegen from the bitcode ssp attribute, after symbol # resolution. The port's bbappend passes upstream's own --disable-ssp. If that # line is ever dropped while the platform issue is open, data/libsodium-probe # CANNOT BE BUILT AT ALL, and every probe case below goes red -- which is the # alarm. Nothing else in the image links libsodium, so no other test would # notice. . "$BST_LIB" lib=/usr/lib/libsodium.a inc=/usr/include/sodium.h pc=/usr/lib/pkgconfig/libsodium.pc tmp=${TMPDIR:-/tmp} hasfile() { if [ -s "$2" ]; then bst_ok "$1"; else bst_notok "$1" "absent or empty: $2"; fi; } # --- 1. what the port ships -------------------------------------------------- hasfile libsodium/archive "$lib" hasfile libsodium/header "$inc" hasfile libsodium/pkgconfig "$pc" hasfile libsodium/header-core /usr/include/sodium/core.h hasfile libsodium/header-randombytes /usr/include/sodium/randombytes.h hasfile libsodium/header-utils /usr/include/sodium/utils.h hasfile libsodium/header-version /usr/include/sodium/version.h # The empty main package must NOT have been installed: there is no shared object # on this arm, so a /usr/lib/libsodium.so of any kind means the packaging went # wrong. if [ -e /usr/lib/libsodium.so ] || [ -e /usr/lib/libsodium.so.26 ]; then bst_notok libsodium/static-only "a libsodium shared object is installed on a static-only arm" else bst_ok libsodium/static-only fi # --- 2. pkg-config contents -------------------------------------------------- check_out libsodium/pc-version "Version: 1.0.19" cat "$pc" check_out libsodium/pc-name "Name: libsodium" cat "$pc" check_out libsodium/pc-libs "-lsodium" cat "$pc" # --- 3. the archive's member table ------------------------------------------- # The image ships no `ar`, so member names are read straight out of the archive # with grep -ao, the same way the nettle suite does it. members=$(grep -ao 'lib[a-z0-9]*_la-[a-zA-Z0-9_.-]*\.o' "$lib" 2>/dev/null | sort -u) hasmember() { if printf '%s\n' "$members" | grep -q "^$2$"; then bst_ok "$1" else bst_notok "$1" "member absent from the shipped archive: $2"; fi } # The portable C cores must be present -- absence of the accelerated paths alone # would also be satisfied by an archive that simply failed to build anything. hasmember libsodium/core-blake2b-ref libsodium_la-blake2b-compress-ref.o hasmember libsodium/core-argon2-ref libsodium_la-argon2-fill-block-ref.o hasmember libsodium/core-poly1305 libsodium_la-poly1305_donna.o hasmember libsodium/core-ed25519 libsodium_la-ed25519_ref10.o hasmember libsodium/core-salsa libsodium_la-core_salsa_ref.o hasmember libsodium/core-scrypt-nosse libsodium_la-pwhash_scryptsalsa208sha256_nosse.o # The accelerated members ARE present on this arm and are empty stubs -- see the # header. Asserting their presence pins that measured fact, so a future release # that starts genuinely compiling them here is noticed rather than assumed away. hasmember libsodium/accel-stub-avx2 libavx2_la-chacha20_dolbeau-avx2.o hasmember libsodium/accel-stub-aesni libaesni_la-aegis128l_aesni.o # --- 4. the library itself, via the cross-linked probe ----------------------- # data/libsodium-probe is cross-linked against THE VERY ARCHIVE THAT SHIPS; its # source is src/libsodium_probe.c. Each case is named here rather than harvested # from the probe's output, so a probe that prints NOTHING still produces 80 # results instead of silently vanishing from the report. probe=$tmp/bst-libsodium-probe.$$ cases="init-first init-idempotent version-string version-major version-minor library-minimal cpu-no-sse2 cpu-no-sse3 cpu-no-ssse3 cpu-no-sse41 cpu-no-avx cpu-no-avx2 cpu-no-avx512f cpu-no-aesni cpu-no-neon cpu-no-pclmul cpu-no-rdrand sha256-fips180-abc sha512-fips180-abc hash-default-is-sha512 blake2b512-rfc7693-abc blake2b-keyed-differs blake2b-streaming-agrees hmacsha256-rfc4231-tc2 hmacsha512-rfc4231-tc2 auth-verify-accepts auth-verify-rejects-tampered aead-chacha20poly1305-ctlen aead-chacha20poly1305-rfc8439-ct aead-chacha20poly1305-rfc8439-tag aead-chacha20poly1305-decrypt aead-chacha20poly1305-aad-bound aead-chacha20poly1305-tamper-rejected chacha20-ietf-rfc8439-keystream secretbox-encrypt secretbox-roundtrip secretbox-tamper-rejected scalarmult-rc scalarmult-rfc7748-vec1 sign-rfc8032-test1-pk sign-rfc8032-test1-sig sign-verify-accepts sign-verify-rejects-tampered box-encrypt box-roundtrip box-wrong-key-rejected shorthash-siphash24-ref pwhash-argon2id-rc pwhash-deterministic pwhash-password-sensitive sodium-malloc sodium-malloc-readback sodium-mprotect-noaccess sodium-mprotect-readwrite sodium-malloc-survives-mprotect sodium-free sodium-allocarray randombytes-implementation randombytes-distinct randombytes-nonzero randombytes-uniform-bounded randombytes-deterministic-stable randombytes-deterministic-zeroseed randombytes-stir bin2hex hex2bin base64-encode base64-decode memcmp-equal memcmp-differ is-zero-true is-zero-false increment increment-wraps add compare-lt memzero stackzero pad unpad" if cp "$BST_DATA/libsodium-probe" "$probe" 2>/dev/null && chmod +x "$probe" 2>/dev/null; then out=$("$probe" 2>&1); prc=$? case $prc in 0) why="probe produced no result for this case" ;; *) why="probe produced no result for this case (rc=$prc)" ;; esac for c in $cases; do case "$out" in *"P311 ok $c"*) bst_ok "libsodium/probe-$c" ;; *"P311 FAIL $c :"*) bst_notok "libsodium/probe-$c" \ "$(printf '%s\n' "$out" | sed -n "s/^P311 FAIL $c : //p" | head -1)" ;; *) bst_notok "libsodium/probe-$c" "$why" ;; esac done # The probe's own tally and exit status. 80/80 is what this same source # scores natively once the ten x86-only cpu-no-* cases are excluded. case "$out" in *"P311-SUMMARY pass=80 fail=0"*) bst_ok libsodium/probe-summary ;; *) bst_notok libsodium/probe-summary \ "$(printf '%s\n' "$out" | sed -n 's/^P311-SUMMARY //p' | head -1)" ;; esac check_rc libsodium/probe-exit0 0 "$probe" rm -f "$probe" else bst_notok libsodium/probe-present "data/libsodium-probe is missing or not executable" for c in $cases; do bst_notok "libsodium/probe-$c" "probe payload absent" done bst_notok libsodium/probe-summary "probe payload absent" bst_notok libsodium/probe-exit0 "probe payload absent" fi