# nettle 3.9.1 (poky recipes-support/nettle) on wasm32-hwjs glibc. # # nettle is the low-level crypto primitives library: symmetric ciphers, hashes, # MACs and AEADs in libnettle, and the public-key half -- RSA, DSA, ECDSA, # GOSTDSA, EdDSA, Curve25519 -- in libhogweed, which is the only part that links # gmp. The port ships nettle-bin, nettle-dev and nettle-staticdev; the main # `nettle` package is empty on this static-only arm and is deliberately not in # the image. # # THREE THINGS THIS SUITE ASSERTS, in increasing order of what they cost to get # right: # # 1. The five shipped CLIs run and produce PUBLISHED digests. nettle-hash is # driven against FIPS 180-4 / FIPS 202 / RFC 1321 vectors, nettle-pbkdf2 # against the published PBKDF2-HMAC-SHA256 vectors (NOT RFC 6070's, which # are SHA-1 -- this tool is SHA-256, measured, not assumed), sexp-conv # against the canonical S-expression encoding, and nettle-lfib-stream # against its own deterministic first bytes. # # 2. The assembly and fat (runtime-CPU-dispatch) paths really are off. A # build log is not something a target can be re-checked against; an ar # member table is. Both directions are asserted, and both member sets were # MEASURED rather than guessed -- a native x86_64 build of this identical # release carries fat-x86_64.o and a -2.o variant family (aes128-encrypt-2.o, # memxor-2.o, sha256-compress-n-2.o, ...), and the shipped wasm32 archive # carries neither, while still carrying all sixteen portable C cores. # Absence alone would also be satisfied by an archive that failed to build # its cores at all, which is why the C members are asserted in the same # breath. # # 3. The library RUNS, via data/nettle-probe -- cross-linked with wasmcc-glibc # against the very /usr/lib/libnettle.a and /usr/lib/libhogweed.a that ship. # Its 57 cases are published constants (FIPS 197, SP 800-38A, RFC 4231, # RFC 4493, RFC 8439, RFC 7748, RFC 8032, ...), and it scores 57/57 against # a native x86_64 build of the identical release, captured before this # suite was ever run on target. src/nettle_probe.c is its source. # # WHY THE PROBE MATTERS MOST HERE. ecdsa_sign and gostdsa_sign are the two # functions the coroutinize pass REFUSED on this arm before the port's bbappend # turned off nettle's dynamic alloca (hwjs-cc#15); the stock recipe FATALs at # link. The probe calls both, so if that workaround is ever dropped while the # issue is open, the probe cannot be produced at all -- this suite is the # regression guard for it. The shipped CLIs would not catch that: not one of # them touches libhogweed's signature schemes. . "$BST_LIB" require nettle-hash nettle/present lib=/usr/lib/libnettle.a hog=/usr/lib/libhogweed.a tmp=${TMPDIR:-/tmp} nl=' ' hasfile() { if [ -s "$2" ]; then bst_ok "$1"; else bst_notok "$1" "absent or empty: $2"; fi; } # --- what the port ships ----------------------------------------------------- hasfile nettle/archive-libnettle "$lib" hasfile nettle/archive-libhogweed "$hog" hasfile nettle/header /usr/include/nettle/nettle-meta.h hasfile nettle/pkgconfig-nettle /usr/lib/pkgconfig/nettle.pc hasfile nettle/pkgconfig-hogweed /usr/lib/pkgconfig/hogweed.pc hasfile nettle/bin-hash /usr/bin/nettle-hash hasfile nettle/bin-pbkdf2 /usr/bin/nettle-pbkdf2 hasfile nettle/bin-lfib-stream /usr/bin/nettle-lfib-stream hasfile nettle/bin-sexp-conv /usr/bin/sexp-conv hasfile nettle/bin-pkcs1-conv /usr/bin/pkcs1-conv check_out nettle/version "nettle 3.9.1" nettle-hash --version # --- nettle-hash against published digest vectors --------------------------- # The tool prints the digest in space-separated 8-byte groups with the algorithm # name appended -- e.g. "ba7816bf8f01cfea 414140de5dae2223 ... sha256" -- so the # needles below carry that grouping deliberately; a run that silently changed # the output shape would not quietly pass. hash_is() { _id=$1; _alg=$2; _want=$3 _out=$(printf 'abc' | nettle-hash -a "$_alg" 2>&1) case "$_out" in *"$_want"*) bst_ok "$_id" ;; *) bst_notok "$_id" "$(_bst_1line "$_out")" ;; esac } # FIPS 180-4 "abc" hash_is nettle/hash-sha256 sha256 \ "ba7816bf8f01cfea 414140de5dae2223 b00361a396177a9c b410ff61f20015ad" hash_is nettle/hash-sha1 sha1 \ "a9993e364706816a ba3e25717850c26c 9cd0d89d" hash_is nettle/hash-sha512 sha512 \ "ddaf35a193617aba cc417349ae204131 12e6fa4e89a97ea2 0a9eeee64b55d39a" # RFC 1321 hash_is nettle/hash-md5 md5 "900150983cd24fb0 d6963f7d28e17f72" # FIPS 202 hash_is nettle/hash-sha3-256 sha3_256 \ "3a985da74fe225b2 045c172d6bd390bd 855f086e3e9d525b 46bfe24511431532" # file mode names the file it hashed, which the stdin path cannot show f=$tmp/bst-nettle-abc.$$ printf 'abc' > "$f" check_out nettle/hash-file "b410ff61f20015ad" nettle-hash -a sha256 "$f" rm -f "$f" # --- nettle-pbkdf2 ----------------------------------------------------------- # MEASURED, not assumed: this tool is PBKDF2-HMAC-SHA256, so RFC 6070's SHA-1 # vectors do NOT apply to it. These are the published SHA-256 vectors for the # same parameter sets, and they are what a native build of this release prints. check_out nettle/pbkdf2-c4096-l20 "c5e478d59288c841 aa530db6845c4c8d 962893a0" \ sh -c 'printf password | nettle-pbkdf2 -i 4096 -l 20 salt' check_out nettle/pbkdf2-c1-l32 \ "120fb6cffcf8b32c 43e7225256c4f837 a86548c92ccc3548 0805987cb70be17b" \ sh -c 'printf password | nettle-pbkdf2 -i 1 -l 32 salt' # --- sexp-conv --------------------------------------------------------------- # The canonical encoding is fully determined by the S-expression spec: each atom # is :, so (a b c) has exactly one canonical form. check_out nettle/sexp-canonical "(1:a1:b1:c)" \ sh -c 'echo "(a b c)" | sexp-conv -s canonical' # --hash prints the bare fingerprint, no algorithm name. The expected value is # not a nettle self-comparison: it is the SHA-256 of the canonical encoding # above, which coreutils computes independently -- # printf '(1:a1:b1:c)' | sha256sum -> 5801d165...86e9 # so this case pins nettle's sexp fingerprint against a different implementation # of the same digest over a spec-determined byte string. check_out nettle/sexp-hash-sha256 \ "5801d165e9c68df5ba6581491a4a77804d33649c39aec4421cc0eebd986686e9" \ sh -c 'echo "(a b c)" | sexp-conv --hash=sha256' # --- nettle-lfib-stream ------------------------------------------------------ # Knuth's lagged-Fibonacci generator. THE SEED MUST BE GIVEN: with no argument # the tool seeds from the clock (measured -- three unseeded runs give three # different streams), so asserting fixed bytes there would be wrong by # construction and would flap. Seeded, it is exactly reproducible. # (It is not a CSPRNG and nettle does not claim it is.) check_out nettle/lfib-seeded-deterministic "ec c8 73 7f 38 f2 f9 e8" \ sh -c 'nettle-lfib-stream 4711 | head -c 8 | od -An -tx1' # --- the assembly / fat paths are off, and it is checkable here -------------- # Member names are read straight out of the archive rather than with ar(1), # which the image does not ship. arcobjs=$(grep -ao '[A-Za-z0-9_-]*\.o' "$lib" 2>/dev/null | sort -u) # (a) no fat dispatch module. A fat build emits exactly one of these. fat_present="" for o in fat-x86_64.o fat-arm.o fat-arm64.o fat-ppc.o fat-s390x.o; do case "$nl$arcobjs$nl" in *"$nl$o$nl"*) fat_present="$fat_present $o" ;; esac done if [ -z "$fat_present" ]; then bst_ok nettle/no-fat-member else bst_notok nettle/no-fat-member "fat dispatch module in a --disable-fat archive:$fat_present"; fi # (b) no -2.o accelerated variants. nettle names the fat/asm alternates of a # core with a -2 suffix; the native x86_64 build of this release carries # these, and this archive must carry none. asm_present="" for o in aes128-encrypt-2.o aes128-decrypt-2.o aes192-encrypt-2.o aes256-encrypt-2.o \ cbc-aes128-encrypt-2.o ghash-set-key-2.o ghash-update-2.o memxor-2.o \ sha1-compress-2.o sha256-compress-n-2.o; do case "$nl$arcobjs$nl" in *"$nl$o$nl"*) asm_present="$asm_present $o" ;; esac done if [ -z "$asm_present" ]; then bst_ok nettle/no-asm-variant-members else bst_notok nettle/no-asm-variant-members "assembly variants in a --disable-assembler archive:$asm_present"; fi # (c) ...and the portable C cores ARE there, so (a) and (b) cannot be satisfied # by an archive that simply failed to build them. c_missing="" for o in aes-encrypt-internal.o aes-decrypt-internal.o sha256-compress-n.o \ sha512-compress.o sha1-compress.o md5-compress.o sha3-permute.o \ chacha-core-internal.o salsa20-core-internal.o poly1305-internal.o \ ghash-set-key.o ghash-update.o memxor.o memxor3.o \ camellia-crypt-internal.o serpent-encrypt.o; do case "$nl$arcobjs$nl" in *"$nl$o$nl"*) ;; *) c_missing="$c_missing $o" ;; esac done if [ -z "$c_missing" ]; then bst_ok nettle/portable-c-cores else bst_notok nettle/portable-c-cores "portable C cores missing from the archive:$c_missing"; fi # (d) libhogweed carries the public-key cores -- the half that links gmp. hogobjs=$(grep -ao '[A-Za-z0-9_-]*\.o' "$hog" 2>/dev/null | sort -u) h_missing="" for o in rsa-sign.o rsa-verify.o ecdsa-sign.o ecdsa-verify.o eddsa-sign.o \ curve25519-mul.o gostdsa-sign.o ecc-mul-a.o bignum.o; do case "$nl$hogobjs$nl" in *"$nl$o$nl"*) ;; *) h_missing="$h_missing $o" ;; esac done if [ -z "$h_missing" ]; then bst_ok nettle/hogweed-pk-cores else bst_notok nettle/hogweed-pk-cores "public-key cores missing from libhogweed.a:$h_missing"; fi # --- the library itself, via the cross-linked probe ------------------------- # data/nettle-probe is cross-linked against THE VERY ARCHIVES THAT SHIP; its # source is src/nettle_probe.c. Each case is named here rather than harvested # from the probe's output, so a probe that prints NOTHING still produces 57 # `not ok` lines instead of silently contributing nothing to the count. probe=$tmp/bst-nettle-probe.$$ if cp "$BST_DATA/nettle-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 version-major version-minor version-is-3.9 \ sha256-empty sha256-abc sha1-abc sha224-abc sha384-abc sha512-abc \ md5-abc sha3-256-abc sha3-512-abc ripemd160-abc sm3-abc \ hmac-sha256-rfc4231-tc1 hmac-sha512-rfc4231-tc1 \ hmac-sha1-rfc2202-tc1 hmac-md5-rfc2202-tc1 \ aes128-ecb-fips197 aes128-ecb-roundtrip aes256-ecb-fips197 \ aes128-cbc-sp800-38a aes128-ctr-sp800-38a \ cmac-aes128-rfc4493-ex1 cmac-aes128-rfc4493-ex2 \ gcm-aes128-nist-tc2-ct gcm-aes128-nist-tc2-tag \ chacha20-rfc8439-keystream-blk1 chacha20poly1305-rfc8439-tag \ chacha20poly1305-roundtrip \ serpent128-nessie twofish128-ref camellia128-rfc3713 arcfour-ref \ salsa20-roundtrip \ pbkdf2-hmac-sha1-rfc6070-c4096 pbkdf2-hmac-sha256-rfc7914 \ base16-encode base16-decode base64-encode-rfc4648 base64-decode-rfc4648 \ ed25519-rfc8032-pubkey ed25519-rfc8032-sig ed25519-verify-good \ ed25519-verify-tampered-rejected \ x25519-rfc7748-alice-pub x25519-rfc7748-bob-pub x25519-rfc7748-shared \ x25519-shared-agrees \ ecdsa-secp256r1-verify ecdsa-secp256r1-wrong-digest-rejected \ gostdsa-gc256b-verify gostdsa-gc256b-wrong-digest-rejected \ rsa-keygen rsa-sign rsa-verify rsa-wrong-digest-rejected ; do case "$out" in *"P310 ok $c"*) bst_ok "nettle/probe-$c" ;; *"P310 FAIL $c :"*) bst_notok "nettle/probe-$c" \ "$(printf '%s\n' "$out" | sed -n "s/^P310 FAIL $c : //p" | head -1)" ;; *) bst_notok "nettle/probe-$c" "$why" ;; esac done # The probe's own tally and exit status. 57/57 is what the same source scores # against a native x86_64 build of nettle 3.9.1. case "$out" in *"P310-SUMMARY pass=57 fail=0"*) bst_ok nettle/probe-summary ;; *) bst_notok nettle/probe-summary "$(printf '%s\n' "$out" | sed -n 's/^P310-SUMMARY //p' | head -1)" ;; esac check_rc nettle/probe-exit0 0 "$probe" rm -f "$probe" else bst_notok nettle/probe-stage "cannot stage $BST_DATA/nettle-probe" fi