diff --git a/.github/actions/apt-update/action.yml b/.github/actions/apt-update/action.yml new file mode 100644 index 000000000..60ed94460 --- /dev/null +++ b/.github/actions/apt-update/action.yml @@ -0,0 +1,15 @@ +name: 'apt update' +description: 'Refresh apt, minus the runner vendor repos we never install from' + +runs: + using: composite + steps: + - shell: bash + run: | + set -euo pipefail + # the image ships azure-cli/msprod repos we install nothing from; when they 403 apt fails the whole update + msft=$(grep -rl packages.microsoft.com /etc/apt/sources.list.d/ 2>/dev/null || true) + if [ -n "$msft" ]; then + sudo rm -f $msft + fi + sudo apt-get update -qq diff --git a/.github/actions/setup-wolfssl/action.yml b/.github/actions/setup-wolfssl/action.yml new file mode 100644 index 000000000..8ba7137b0 --- /dev/null +++ b/.github/actions/setup-wolfssl/action.yml @@ -0,0 +1,126 @@ +name: 'Setup wolfSSL' +description: 'Build a wolfSSL profile, install it to /usr/local, and report its sha256' + +inputs: + ref: + description: 'wolfSSL git ref (branch, tag, or SHA)' + required: true + default: 'master' + flags: + description: 'configure flags for this profile' + required: true + cflags: + description: 'extra CFLAGS for this profile' + required: false + default: '' + +outputs: + sha256: + description: 'sha256 of the installed libwolfssl.so - the identity gate compares against this' + value: ${{ steps.identity.outputs.sha256 }} + resolved-ref: + description: 'the commit SHA the input ref resolved to' + value: ${{ steps.resolve.outputs.sha }} + +runs: + using: composite + steps: + # Resolve to a commit SHA so the cache key is stable across a run. Keying on + # a moving branch name lets two jobs in one nightly build different wolfSSLs. + - name: Resolve wolfSSL ref + id: resolve + shell: bash + run: | + ref='${{ inputs.ref }}' + if [[ "$ref" =~ ^[0-9a-f]{40}$ ]]; then + sha="$ref" + else + # An annotated tag resolves to the tag object, not the commit, so ask + # for the peeled ref first and fall back for branches. + sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git \ + "refs/tags/$ref^{}" | cut -f1) + [ -n "$sha" ] || sha=$(git ls-remote \ + https://github.com/wolfSSL/wolfssl.git "$ref" | head -n1 | cut -f1) + fi + [ -n "$sha" ] || { echo "could not resolve wolfSSL ref '$ref'"; exit 1; } + echo "sha=$sha" >> "$GITHUB_OUTPUT" + echo "resolved '$ref' -> $sha" + + - name: Hash profile config + id: cfg + shell: bash + run: | + printf '%s|%s' '${{ inputs.flags }}' '${{ inputs.cflags }}' \ + | sha256sum | cut -c1-16 | sed 's/^/hash=/' >> "$GITHUB_OUTPUT" + + # Key on the image, not runner.os: a binary built against a newer glibc must + # not be restored onto an older runner image. ImageOS is set by the hosted + # runner; fall back so a self-hosted or container runner still gets a key. + - name: Compute cache key + id: key + shell: bash + run: | + img="${ImageOS:-$(. /etc/os-release 2>/dev/null && echo "$ID$VERSION_ID" || echo unknown)}" + echo "key=wolfssl-${img}-${{ steps.resolve.outputs.sha }}-${{ steps.cfg.outputs.hash }}-v1" >> "$GITHUB_OUTPUT" + echo "cache key: wolfssl-${img}-${{ steps.resolve.outputs.sha }}-${{ steps.cfg.outputs.hash }}-v1" + + - name: Restore wolfSSL install + id: cache + uses: actions/cache@v5 + with: + path: ~/wolfssl-install + key: ${{ steps.key.outputs.key }} + + - name: Build wolfSSL + if: steps.cache.outputs.cache-hit != 'true' + shell: bash + run: | + set -euo pipefail + rm -rf /tmp/wolfssl && mkdir -p /tmp/wolfssl + cd /tmp/wolfssl + git init -q + git fetch -q --depth 1 https://github.com/wolfSSL/wolfssl.git ${{ steps.resolve.outputs.sha }} + git checkout -q FETCH_HEAD + ./autogen.sh + # We need the library, not wolfSSL's own examples and test suite. Those + # also fail to build under some profiles (the `tls` profile died on + # tests/unit.test), and skipping them cuts every build substantially. + ./configure --prefix="$HOME/wolfssl-install" \ + --disable-examples --disable-crypttests \ + ${{ inputs.flags }} \ + ${{ inputs.cflags && format('CFLAGS="{0}"', inputs.cflags) || '' }} + make -j"$(nproc)" + make install + + # Every README tells users to build against a wolfSSL at /usr/local, and 5 + # host-tier Makefiles have no -I/-L at all. Installing there means CI runs the + # exact command sequence the docs document, with no overrides. + - name: Install to /usr/local + shell: bash + run: | + set -euo pipefail + sudo cp -a "$HOME/wolfssl-install/." /usr/local/ + sudo ldconfig + + - name: Report cache outcome + shell: bash + run: | + if [ '${{ steps.cache.outputs.cache-hit }}' = 'true' ]; then + echo "wolfSSL restored from cache (no rebuild)" + else + echo "wolfSSL cache MISS -- built from source and saved for later jobs" + fi + + - name: Record wolfSSL identity + id: identity + shell: bash + run: | + set -euo pipefail + lib=$(ls /usr/local/lib/libwolfssl.so.*.*.* 2>/dev/null | head -n1 \ + || readlink -f /usr/local/lib/libwolfssl.so) + [ -f "$lib" ] || { echo "no libwolfssl.so installed under /usr/local/lib"; exit 1; } + sha=$(sha256sum "$lib" | cut -d' ' -f1) + echo "sha256=$sha" >> "$GITHUB_OUTPUT" + echo "installed $lib" + echo "sha256 $sha" + /usr/local/bin/wolfssl-config --version 2>/dev/null || true diff --git a/.github/examples-manifest.yml b/.github/examples-manifest.yml new file mode 100644 index 000000000..fca938511 --- /dev/null +++ b/.github/examples-manifest.yml @@ -0,0 +1,1829 @@ +# Source of truth for what CI builds and runs. +# +# Every directory holding buildable source must appear here, or +# `manifest.py check` fails. That is deliberate: a new example is a CI failure +# until someone decides what to do with it. +# +# tier: host (default) | emulated | cross -- which workflow owns it +# mode: run (default) | build-only | skip -- skip REQUIRES a reason +# profile: which wolfSSL build it needs (a property of the dir, never a matrix axis) +# build: make (default) | none | [literal, argv] +# +# Every entry gets its own CI job, so a red tile names the example that broke. +# +# Adding an example: add an entry. If it cannot run in CI, say so in `reason`. +# +# PIN EVERY EXTERNAL PROJECT. wolfSSL is the only thing CI follows a moving ref +# for -- that is the point. Anything else (picoTCP, mbedTLS, ibmswtpm2, newt, +# wolfTPM, an SDK) gets the version the example's README documents, or a tag if +# the README is silent. Tracking someone else's master means their drift lands +# as our red, on a PR that changed none of it. + +# Each profile is derived from the READMEs of the examples that use it -- NOT +# from --enable-all. --enable-all is not a superset: it omits mlkem, acert, +# ascon and trackmemory, so examples that need those fail to compile against it. +# Testing what the README documents is also the only honest thing for a repo +# whose whole job is showing people how to build. +# +# Where a README and the source disagree, the source wins (noted inline). +# A profile is built once per (profile, wolfSSL ref) and cached; every example +# using it then restores rather than rebuilds. +profiles: + # plain ./configure -- examples whose README asks for nothing special + default: + flags: "--enable-static --enable-shared" + + all: + # Only for the emulated/cross tiers, whose workflows either build wolfSSL + # in-tree (ESP32, Pico) or pass their own flags (tpm, sgx). Host examples + # must name the profile their README documents instead. + flags: "--enable-all --enable-static --enable-shared" + + crl: + # certmanager/README: certverify loads a CRL and fails rc=1 without it + flags: "--enable-crl --enable-ocsp --enable-static --enable-shared" + + debug: + # custom-io-callbacks/README: the file-io callback pair needs debug output + flags: "--enable-debug --enable-static --enable-shared" + + opensslextra: + # certfields/* and certstore. keyUsage/extendedKeyUsage READMEs say plain + # ./configure but their sources print "configure with --enable-opensslextra" + # and produce nothing without it. + flags: "--enable-opensslall --enable-opensslextra --enable-static --enable-shared" + + crypto: + # union of crypto/*: 3des, aes, aes-modes, camellia, ascon, keywrap, pkcs12 + flags: >- + --enable-pwdbased --enable-des3 --enable-camellia --enable-ascon + --enable-experimental --enable-aesgcm-stream --enable-aesccm --enable-aesctr + --enable-aescfb --enable-aesofb --enable-aeseax --enable-aessiv + --enable-aesxts --enable-aeskeywrap --enable-keygen --enable-certgen + --enable-certext --enable-pkcs12 --enable-static --enable-shared + # aes-cts and aes-ecb have no configure flag: without these defines both + # compile to a stub main() that prints "not compiled in" and returns 0. + # WC_RNG_SEED_CB likewise has no --enable of its own (only opensslextra and + # the FIPS paths set it), and aes/rdseed exits 1 with "requires __x86_64__ + # and WC_RNG_SEED_CB" without it. + cflags: "-DWOLFSSL_AES_CTS -DHAVE_AES_ECB -DWC_RNG_SEED_CB" + + certgen: + flags: >- + --enable-certgen --enable-certreq --enable-certext --enable-keygen + --enable-ecc --enable-ed25519 --enable-cryptocb --enable-static --enable-shared + cflags: "-DWOLFSSL_TEST_CERT -DHAVE_OID_DECODING -DHAVE_OID_ENCODING -DWOLFSSL_CUSTOM_OID -DOPENSSL_EXTRA_X509_SMALL" + + ecc: + flags: >- + --enable-ecc --enable-ecccustcurves --enable-trackmemory + --enable-static --enable-shared + # trackmemory is not in the README, but ecc-stack.c includes mem_track.h and + # fails to link with "undefined reference to InitMemoryTracker" without it. + cflags: "-DWOLFSSL_TEST_CERT -DWOLFSSL_DER_TO_PEM -DHAVE_ECC_KOBLITZ -DWOLFSSL_PUBLIC_MP" + + pk: + # union of pk/*: ecc, ed25519, ed448, curve25519/448, srp, hpke, rsa-pss, keygen + flags: >- + --enable-ecc --enable-ed25519 --enable-ed448 --enable-curve25519 + --enable-curve448 --enable-keygen --enable-rsapss --enable-srp --enable-hpke + --enable-aesgcm --enable-static --enable-shared + # WOLFSSL_RSA_KEY_CHECK has no configure option: pk/rsa-kg calls + # wc_CheckRsaKey, which rsa.c only defines under that macro. + cflags: "-DWOLFSSL_PUBLIC_MP -DUSE_CERT_BUFFERS_2048 -DWOLFSSL_ECDSA_DETERMINISTIC_K -DWOLFSSL_RSA_KEY_CHECK" + + pkcs7: + # --enable-indef is required by the streaming examples: without it + # envelopedData-ktri-stream prints "Must build wolfSSL using ./configure + # --enable-pkcs7 --enable-indef" and signedData-stream fails encode with -173. + flags: >- + --enable-pkcs7 --enable-indef --enable-pwdbased --enable-cryptocb --with-libz + --enable-static --enable-shared + cflags: "-DWOLFSSL_DER_TO_PEM" + + pkcs7smime: + # Split from pkcs7 because --enable-smime forces opensslall on, and the other + # eight targets do not need that surface. Without it smime and smime-verify + # print "wolfSSL was compiled with out HAVE_SMIME support" and return 0. + flags: >- + --enable-pkcs7 --enable-indef --enable-pwdbased --enable-cryptocb --with-libz + --enable-smime --enable-static --enable-shared + cflags: "-DWOLFSSL_DER_TO_PEM" + + tls: + # union of tls/ and tls-options/ READMEs. --enable-asynccrypt is deliberately + # absent: it needs the separate wolfAsyncCrypt repo patched in. + flags: >- + --enable-tls13 --enable-ech --enable-writedup --enable-pkcallbacks + --enable-postauth --enable-cryptocb --enable-opensslall --enable-session-ticket + --enable-earlydata --enable-static --enable-shared + cflags: "-DHAVE_SECRET_CALLBACK" + + dtls: + # earlydata requires session tickets or PSK: without session-ticket, + # configure dies with "cannot enable earlydata without enabling session + # tickets and/or PSK". + flags: >- + --enable-dtls --enable-dtls13 --enable-tls13 --enable-sessionexport + --enable-dtls-mtu --enable-earlydata --enable-session-ticket + --enable-dtlscid --enable-opensslextra --enable-ipv6 + --enable-static --enable-shared + # No configure flag for this one; dtls/README.md says to define it so + # server-dtls13-earlydata can call wolfSSL_dtls13_no_hrr_on_resume(). + cflags: "-DWOLFSSL_DTLS13_NO_HRR_ON_RESUME -DWOLFSSL_DTLS_RECORDS_CAN_SPAN_DATAGRAMS" + + psk: + flags: "--enable-psk --enable-opensslextra --enable-tls13 --enable-static --enable-shared" + cflags: "-DWOLFSSL_STATIC_PSK" + + pq: + # pq/ml_kem, pq/ml_dsa, pq/stateful_hash_sig. --enable-all omits mlkem + # entirely, which is what made pq-ml-kem fail on mlkem.h. + # extra-pqc-hybrids (default off) is what gates WOLFSSL_SECP521R1MLKEM1024 + # behind WOLFSSL_EXTRA_PQC_HYBRIDS in tls.c; pq/tls asks for that exact group, + # so without it the client dies on "failed to set the requested group". + flags: >- + --enable-mlkem --enable-dilithium --enable-lms --enable-xmss + --enable-extra-pqc-hybrids + --enable-experimental --enable-tls13 --enable-static --enable-shared + + acert: + flags: "--enable-acert --enable-opensslextra --enable-rsapss --enable-static --enable-shared" + + staticmemory: + # README says plain ./configure, but size-calculation.c has a hard + # `#error requires --enable-staticmemory`. + flags: "--enable-staticmemory --enable-static --enable-shared" + # DEBUG_MEMORY_PRINT makes every wolfSSL allocation print "Alloc: ... -> N", + # which is exactly what memory_bucket_optimizer parses. Its README reaches for + # testwolfcrypt, but that is just a convenient allocator -- any program linked + # against this build emits the same lines, so debug-callback-example next door + # is the log source and no crypttests build is needed. + cflags: "-DWOLFSSL_STATIC_MEMORY_DEBUG_CALLBACK -DWOLFSSL_DEBUG_MEMORY -DWOLFSSL_DEBUG_MEMORY_PRINT" + + eccencrypt: + flags: "--enable-eccencrypt --enable-tls13 --enable-static --enable-shared" + + httpsig: + flags: "--enable-ed25519 --enable-coding --enable-static --enable-shared" + + x9146: + flags: >- + --enable-experimental --enable-dual-alg-certs --enable-dilithium + --enable-debug --enable-static --enable-shared + + certvfy: + flags: "--enable-cryptonly --enable-singlethreaded --enable-static --enable-shared" + cflags: "-DWOLFSSL_SMALL_CERT_VERIFY" + + ocsp: + flags: >- + --enable-ocsp --enable-ocspstapling --enable-ocspstapling2 + --enable-ocsp-responder --enable-cert-setup-cb --enable-sessioncerts + --enable-tls13 --enable-static --enable-shared + + pkcs11: + flags: "--enable-pkcs11 --enable-cryptocb --enable-static --enable-shared" + + fastmath: + # Not irreconcilable with --enable-all: configure.ac lets fastmath win and + # sets SP_MATH_ALL=no, so it configures cleanly. Kept separate as a coverage + # choice -- folding it in would flip every other dir off the sp-math default + # that users actually ship. Drop this profile if pk/rsa gains an sp-math + # nonblock path. + flags: "--enable-all --enable-fastmath --enable-static --enable-shared" + cflags: "-DWC_RSA_NONBLOCK -DWC_RSA_NONBLOCK_TIME" + + cryptonly: + # Genuinely separate: removes the TLS API every other dir links against. + # This is signature/rsa_vfy_only's README line in full -- an abridged version + # fails configure with "please disable rsa if disabling asn", because + # --enable-rsavfy is what reconciles RSA with --disable-asn. + flags: >- + --disable-asn --disable-filesystem --enable-cryptonly + --enable-sp=smallrsa2048 --enable-sp-math + --disable-dh --disable-ecc --disable-sha224 --enable-rsavfy + --enable-static --enable-shared + cflags: "-DWOLFSSL_PUBLIC_MP" + +examples: + # ---------------------------------------------------------------- host: run + # cmake.yml, not here: add_subdirectory(wolfssl) needs a wolfSSL source tree + # beside it, and cloning one is impossible inside this harness's netns. + - id: cmake + path: cmake + tier: cross + profile: default + + - id: pkcs7 + path: pkcs7 + profile: pkcs7 + deps: [zlib1g-dev] + run: + # runall.sh drives the binaries in dependency order (envelopedData-ktri + # before envelopedDataDecode). It does not cover the targets driven + # explicitly below. + # openssl-verify.sh runs runall.sh and then validates every bundle it + # produced with openssl cms. runall.sh alone only checks exit codes, which + # is how signedData-stream shipped an empty eContent unnoticed. + - script: [./scripts/openssl-verify.sh] + timeout: 300 + # Every expect: below is also the --enable-pkcs7 gate: without it these + # print "Must build wolfSSL using ./configure --enable-pkcs7" and return 0, + # so exit code alone cannot tell a real pass from PKCS#7 never running. + - exec: [./signedData-p7b] + expect: "Successfully verified SignedData bundle." + # later and stricter than "PKCS7 Verify Success": the DER round-trip matched + - exec: [./pkcs7-verify] + expect: "DER output matches the original PEM" + - exec: [./envelopedData-ktri-stream, content.txt] + expect: "bytes for encrypted file found" + - exec: [./signedData-DetachedSignature] + expect: "Successfully verified SignedData bundle." + - exec: [./signedData-verifyFile, -b, signedData_detached_attrs.der, -c, content.txt] + expect: "Successfully verified SignedData bundle!" + + # Split out of pkcs7 above purely so the other 8 targets keep testing the + # released library. This one CANNOT pass on v5.9.2-stable: + # wc_PKCS7_EncodeContentStreamHelper() leaves ret at its BAD_FUNC_ARG + # initializer when the caller passes a precomputed hash, so the content is + # never written and the bundle verifies nowhere (ret = -140). + # wolfSSL 9b1aad457 fixed it after the tag, and no release contains it yet -- + # drop the pin and fold this back into pkcs7 once one does. + - id: pkcs7-signeddata-stream + path: pkcs7 + profile: pkcs7 + wolfssl_ref: master + deps: [zlib1g-dev] + run: + # last line of the real path; the not-compiled-in branch returns 0 without it + - exec: [./signedData-stream, content.txt] + expect: "bytes from file" + + # Both commands come from pkcs7/README.md "Creating an SMIME bundle and + # verifying it"; smime-verify consumes the bundle smime writes. + - id: pkcs7-smime + path: pkcs7 + profile: pkcs7smime + deps: [zlib1g-dev] + run: + - exec: [./smime, ../certs/client-key.der, ../certs/client-cert.der] + expect: "output to file ./smime-created.p7s" + - exec: [./smime-verify, smime-created.p7s, ../certs/client-cert.der, content.txt] + expect: "Verify Success" + + - id: certgen + path: certgen + profile: certgen + run: + - exec: [./certgen_example] + expect: "Tests passed" + - exec: [./certgen_ca_example] + expect: "Tests passed" + # the end marker: proves a whole PEM CSR was emitted, not a truncated one + - exec: [./csr_w_ed25519_example] + expect: "-----END CERTIFICATE REQUEST-----" + - exec: [./csr_example, ecc] + expect: "Saved PEM to \"ecc-csr.pem\"" + # csr_sign consumes ecc-csr.pem from csr_example + - exec: [./csr_sign, ecc-csr.pem, ca-ecc-cert.der, ca-ecc-key.der] + expect: "Tests passed" + - exec: [./csr_cryptocb, ecc] + expect: "Saved CSR PEM to \"ecc-csr.pem\"" + # custom_ext must be the LAST writer of newCert.der before the callback + # reads it -- certgen_example and csr_sign also write that filename. + - exec: [./custom_ext] + expect: "Tests passed" + - exec: [./custom_ext_callback, newCert.der] + expect: "Success" + + - id: certmanager + path: certmanager + profile: crl + run: + - exec: [./certverify] + - exec: [./certloadverifybuffer] + # certverify_ocsp is not run: it needs the wolfssl source tree as a sibling + # and a manually launched openssl responder on :22221. + + - id: certstore + path: certstore + profile: opensslextra + run: + - exec: [./certverify] + + - id: certvfy + path: certvfy + profile: certvfy + run: + - exec: [./certvfy] + - exec: [./certsigvfy] + - exec: [./sigvfycert] + + - id: certfields-all-fields + path: certfields/all-fields + profile: opensslextra + run: + # cert must be DER; keyType is RSA or ECC + - exec: [./app, ../../certs/client-cert.der, RSA] + + - id: certfields-keyusage + path: certfields/keyUsage + profile: opensslextra + run: + # the binary is named `run`, not `test` + - exec: [./run] + + - id: certfields-extendedkeyusage + path: certfields/extendedKeyUsage + profile: opensslextra + env: + # this Makefile bakes in -fsanitize=address; leak reports against a shared + # libwolfssl would fail the run without this + ASAN_OPTIONS: "detect_leaks=0" + run: + - exec: [./run] + + - id: certfields-extract-pubkey + path: certfields/extract-pubkey-from-certfile + profile: opensslextra + run: + - exec: [./app] + + - id: ecc + path: ecc + profile: ecc + run: + - exec: [./ecc-key-decode] + expect: "Success" + - exec: [./ecc-params] + expect: "Gy: 32" + # the last of 10 rounds; a failure in any earlier one now exits non-zero + - exec: [./ecc-sign] + expect: "Firmware Signature 9: Ret 0" + - exec: [./ecc-stack] + expect: "stack used =" + - exec: [./ecc-verify] + expect: "hash_firmware_verify: 0" + - exec: [./ecc-verify-minimal] + expect: "wc_ecc_verify_hash: ret=0, is_valid_sig=1" + # must follow ecc-key-export, which writes the .der it reads + - exec: [./ecc-key-export] + expect: "ECC Public Key Exported to ./ECC_SECP256K1_pub.pem" + # prints nothing on success, so exit code is genuinely its only signal + - exec: [./ecc-export-Qx-Qy, ECC_SECP256K1.der, qxqy.raw] + + - id: hash + path: hash + profile: crypto + # Known-answer tests: every digest below was cross-checked against shasum and + # openssl dgst, so these assert the algorithm is right, not just that it ran. + # input.txt is tracked -- if it changes on purpose, recompute these. + run: + - exec: [./sha256-hash, input.txt] + expect: "75294625788129796c09fcbf313ea16e2883356e322adc2f956b37dbdc10b6a7" + - exec: [./sha512-hash, input.txt] + expect: "ead56209da2dfb3562263aadc57d9382f0f7cb579ebb6dbf2f20bfd3cb68aaaad422f6ce6f1a88ec6c326edcf8456f650579b6e20eb39f3bb444bee8b65615ed" + - exec: [./sha3-256-hash, input.txt] + expect: "0704c6ca55e7e5c706b543f07da1daed8149c838549096df6a52dac5f95f2fe0" + - exec: [./hash-file, SHA256, input.txt] + expect: "75294625788129796c09fcbf313ea16e2883356e322adc2f956b37dbdc10b6a7" + # sha256 and sha3-256 of the literal "String to hash" + - exec: [./sha256-hash-string] + expect: "d4476d30fd94c746eb38d8a1b3931aa81d1e485be5a6362f47598017a91cb5d2" + - exec: [./sha256-hash-oneshot-string] + expect: "d4476d30fd94c746eb38d8a1b3931aa81d1e485be5a6362f47598017a91cb5d2" + - exec: [./sha3-256-hash-oneshot-string] + expect: "10d69e59ac10b1d81755733f323bdadca3e04e4b17df72f5b343d6da701a4225" + + - id: embedded + path: embedded + profile: default + run: + - exec: [./tls-client-server] + - exec: [./tls-threaded] + - exec: [./tls-sock-threaded] + - pair: + server: [./tls-sock-server] + client: [./tls-sock-client] + server_exit: killed + - pair: + server: [./tls-sock-server-ca] + client: [./tls-sock-client-ca] + server_exit: killed + # tls-server-size is deliberately not run: its buffer-IO recv callback returns + # WANT_READ forever with no client, so it spins at 100% CPU and never exits. + # It is a code-size demo, not a runnable example. + + - id: crypto-3des + path: crypto/3des + profile: crypto + setup: + - [sh, -c, "printf '3des ci input\\n' > in.txt"] + run: + # NoEcho() calls tcsetattr(fileno(stdin)), which returns ENOTTY on a pipe + # and makes main return -1060. `script -qec` gives it a real PTY. + # No expect:: this prints only on failure, so exit code is its only signal. + - exec: [sh, -c, "printf 'ciphertestpw\\n' | script -qec './3des-file-encrypt -e 168 -i in.txt -o out.enc' /dev/null"] + + - id: crypto-aes + path: crypto/aes + profile: crypto + run: + # known answer: hex of "single block msg" + - exec: [./aesgcm-minimal] + expect: "Decrypted: 73696e676c6520626c6f636b206d736700" + - exec: [./aesgcm-oneshot] + expect: "Decrypted: 090909090909090909090909090909090909090909090909090909090909090909" + # -t encrypts a random file, decrypts it and diffs the two + - exec: [./aesgcm-file-encrypt, -t, "256"] + expect: "Pass: The files are identical." + # aes/aescfb/aesctr-file-encrypt share crypto/3des's tcsetattr blocker and + # are deliberately absent from run:. + + - id: crypto-aes-modes + path: crypto/aes-modes + profile: crypto + setup: + - [sh, -c, "printf 'wolfssl-examples aes-modes CI input\\n' > in.txt"] + # Every one prints " not compiled in" and returns 0 when its feature is + # off, so exit code alone cannot tell a round-trip from a no-op. "Success!" + # is the last line before return and only the round-trip reaches it. + run: + - exec: [./aes-cbc, in.txt, out-cbc.bin] + expect: "Success!" + - exec: [./aes-cfb, in.txt, out-cfb.bin] + expect: "Success!" + - exec: [./aes-cfb1, in.txt, out-cfb1.bin] + expect: "Success!" + - exec: [./aes-cfb8, in.txt, out-cfb8.bin] + expect: "Success!" + - exec: [./aes-ofb, in.txt, out-ofb.bin] + expect: "Success!" + - exec: [./aes-ecb, in.txt, out-ecb.bin] + expect: "Success!" + - exec: [./aes-ctr, in.txt, out-ctr.bin] + expect: "Success!" + - exec: [./aes-direct, in.txt, out-direct.bin] + expect: "Success!" + - exec: [./aes-gcm, in.txt, out-gcm.bin] + expect: "Success!" + - exec: [./aes-gmac, in.txt, out-gmac.bin] + expect: "Success!" + - exec: [./aes-ccm, in.txt, out-ccm.bin] + expect: "Success!" + - exec: [./aes-keywrap, in.txt, out-keywrap.bin] + expect: "Success!" + - exec: [./aes-xts, in.txt, out-xts.bin] + expect: "Success!" + - exec: [./aes-siv, in.txt, out-siv.bin] + expect: "Success!" + - exec: [./aes-eax, in.txt, out-eax.bin] + expect: "Success!" + - exec: [./aes-cts, in.txt, out-cts.bin] + expect: "Success!" + + - id: crypto-aes-rdseed + path: crypto/aes/rdseed + profile: crypto + run: + # Deliberately unguarded. rdseed64() is bare inline asm with no CPUID probe, + # so a CPU without RDSEED SIGILLs rather than failing cleanly -- and a + # `grep /proc/cpuinfo || exit 0` guard would turn "never tested here" into a + # green tick, which is worse than a loud crash. Hosted runners are Xeon or + # EPYC and have had RDSEED since Broadwell/Zen. + - exec: [./aesgcm-rdseed] + # the last line it prints, and only reached once the GCM round-trip + # compared equal + expect: "Decrypted" + + - id: crypto-ascon + path: crypto/ascon + profile: crypto + setup: + - [sh, -c, "printf 'ascon ci input\\n' > in.txt"] + run: + # same tcsetattr prompt as crypto/3des; `script -qec` supplies a PTY. + # No expect:: prints only on failure, so exit code is its only signal. + - exec: [sh, -c, "printf 'ciphertestpw\\n' | script -qec './ascon-file-encrypt -e -i in.txt -o out.enc' /dev/null"] + + - id: crypto-camellia + path: crypto/camellia + profile: crypto + setup: + - [sh, -c, "printf 'camellia ci input\\n' > in.txt"] + run: + # same tcsetattr prompt as crypto/3des; `script -qec` supplies a PTY. + # No expect:: prints only on failure, so exit code is its only signal. + - exec: [sh, -c, "printf 'ciphertestpw\\n' | script -qec './camellia-encrypt -e 128 -i in.txt -o out.enc' /dev/null"] + + - id: crypto-keywrap + path: crypto/keywrap + profile: crypto + run: + # only printed once wc_AesGcmDecrypt's auth tag verified the unwrap + - exec: [./keywrap] + expect: "Decrypted Random Key: " + + - id: crypto-pkcs12 + path: crypto/pkcs12 + profile: crypto + run: + - exec: [./pkcs12-example] + expect: "return value of parsing pkcs12 = 0 SUCCESS" + - exec: [./pkcs12-create-example] + expect: "Printing PKCS12 DER file to output.p12" + + - id: signature + path: signature + profile: default + run: + - exec: [./signature, Makefile] + expect: "ECC Signature Verification: Pass (0)" + + - id: signature-ecc-sign-verify + path: signature/ecc-sign-verify + profile: default + run: + # the last curve it sweeps, so this only prints if every earlier one passed + - exec: [./ecc_sign_verify] + timeout: 120 + expect: "Successfully verified signature w/ ecc key size 521!" + + - id: signature-rsa-buffer + path: signature/rsa_buffer + profile: default + run: + # signature.h is committed, so verify works against it directly. Running + # ./sign would rewrite signature.h and require a rebuild of verify. + - exec: [./verify] + expect: "Verified" + + - id: signature-sigtest + path: signature/sigtest + profile: certgen + deps: [libssl-dev] + run: + - exec: [./wolfsigtest] + expect: "Signatures match!" + - exec: [./opensigtest] + expect: "CRYPTO: EXPECTED signature verify OK! 1" + # eccsiglentest is not run: 1000 loops across ~26 curves takes minutes. + + - id: staticmemory + path: staticmemory + profile: staticmemory + run: + # size-calculation.c has a hard #error without --enable-staticmemory, which + # the `all` profile supplies. + - exec: [./size-calculation] + - exec: [./debug-callback-example] + + - id: staticmemory-bucket-optimizer + path: staticmemory/memory-bucket-optimizer/optimizer + profile: staticmemory + setup: + # Generate the log from the sibling example rather than testwolfcrypt: the + # parser only wants "Alloc:"/"Free:" lines, which the profile's + # DEBUG_MEMORY_PRINT makes any wolfSSL program emit. + - [sh, -c, "make -C ../.. >/dev/null && ../../debug-callback-example > mem.log 2>&1"] + - [sh, -c, "grep -q 'Alloc:' mem.log"] + run: + # Summary only prints after the whole log parsed and buckets were computed. + - exec: [./memory_bucket_optimizer, mem.log] + expect: "Optimization Summary:" + + - id: staticmemory-bucket-tester + path: staticmemory/memory-bucket-optimizer/tester + profile: staticmemory + mode: build-only + reason: >- + needs a SECOND wolfSSL build. Its README configures -DWOLFSSL_NO_MALLOC on top + of the optimizer's flags, and without it the tester exits 255 with "ERROR: + WOLFSSL_NO_MALLOC is not defined" -- but its log source + (debug-callback-example) allocates, so one job cannot host both builds. Needs + its own no-malloc profile plus a committed or separately-generated log. + + - id: x509-acert + path: x509_acert + profile: acert + deps: [libssl-dev] + # `make` also builds openssl_acert, which needs openssl/x509_acert.h -- that + # is OpenSSL 3.4+, and ubuntu-24.04 ships 3.0. + build: [make, wolfssl_acert] + run: + # README says acerts/ -- the real dir is certs/ + - exec: [./wolfssl_acert, -f, certs/acert.pem, -k, certs/acert_pubkey.pem] + - exec: [./wolfssl_acert, -f, certs/acert_ietf.pem, -k, certs/acert_ietf_pubkey.pem] + # openssl_acert is not run: X509_ACERT is not in distro OpenSSL. + + - id: x9146 + path: X9.146 + profile: x9146 + deps: [openssl] + # ca-key.der / server-key.der are not committed, so the generators fopen() + # NULL on a fresh clone. The README documents this openssl step. + setup: + - [sh, -c, "openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:3072 -out ca-key.der -outform der"] + - [sh, -c, "openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:3072 -out server-key.der -outform der"] + run: + # root before server: the server generator reads ./ca-cert-pq.der that the + # root one writes. The rsa and ecdsa families collide on that filename, so + # only one family runs here. + - exec: [./gen_rsa_mldsa_dual_keysig_root_cert] + timeout: 120 + - exec: [./gen_rsa_mldsa_dual_keysig_server_cert] + timeout: 120 + + - id: tls-options + path: tls-options + profile: tls + run: + - exec: [./client-tls-cipher, -e] + - exec: [./server-tls-cipher, -e] + - pair: + server: [./server-tls-cipher] + client: [./client-tls-cipher, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + - pair: + server: [./server-tls-peerauth] + client: [./client-tls-peerauth, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + # The session/resume pair needs ../tls/server-tls13 built first and writes + # session.bin; client-tls-resume silently falls back to a fresh session when + # session.bin is absent, so a naive run would pass without testing resumption. + + - id: psk + path: psk + profile: psk + run: + # psk clients do NOT read stdin (the message is hardcoded), and no psk + # server honours a "shutdown" string -- that terminator exists only in + # tls/. Every server here accept-loops, so all pairs are server_exit: killed. + - pair: + server: [./server-tcp] + client: [./client-tcp, 127.0.0.1] + server_exit: killed + - pair: + server: [./server-psk] + client: [./client-psk, 127.0.0.1] + server_exit: killed + - pair: + server: [./server-psk-nonblocking] + client: [./client-psk-nonblocking, 127.0.0.1] + server_exit: killed + - pair: + server: [./server-psk-threaded] + client: [./client-psk, 127.0.0.1] + server_exit: killed + - pair: + server: [./server-psk-tls13-multi-id] + client: [./client-psk-tls13-multi-id, 127.0.0.1] + server_exit: killed + + - id: btle-ecies + path: btle/ecies + profile: eccencrypt + # Transport is a pair of FIFOs in /tmp, not sockets. Stale FIFOs from a + # previous run make ecc-server hang on open(), so clear them first. + setup: + - [rm, -f, /tmp/btleMiso, /tmp/btleMosi] + run: + - pair: + server: [./ecc-server] + client: [./ecc-client] + stdin: "exit\n" + server_exit: killed + port: none + + - id: btle-tls + path: btle/tls + profile: eccencrypt + setup: + - [rm, -f, /tmp/btleMiso, /tmp/btleMosi] + run: + - pair: + server: [./server-tls13-btle] + client: [./client-tls13-btle] + stdin: "exit\n" + server_exit: killed + port: none + + - id: http-message-signatures + path: http-message-signatures + profile: httpsig + run: + # test_vectors covers the RFC 9421 B.2.6 vector and is self-contained + - exec: [./test_vectors] + - exec: [./sign_request] + - pair: + server: [./http_server_verify] + client: [./http_client_signed] + port: 8080 + server_exit: killed + + - id: pq-ml-dsa + path: pq/ml_dsa + profile: pq + run: + # args are mandatory: a bare run prints usage and exits FAILURE + - exec: [./ml_dsa_test, -c, "2"] + expect: "info: verify message good" + - exec: [./ml_dsa_test, -c, "3"] + expect: "info: verify message good" + - exec: [./ml_dsa_test, -c, "5", -m, "wolfssl-examples CI"] + expect: "info: verify message good" + # -p only prints the FIPS 204 parameter tables + - exec: [./ml_dsa_test, -p] + expect: "ML-DSA-87" + + - id: pq-ml-kem + path: pq/ml_kem + profile: pq + run: + # asserts the KEM contract itself: both sides derived the same secret + - exec: [./ml_kem] + expect: "Shared secrets match" + + - id: pq-stateful-hash-sig + path: pq/stateful_hash_sig + profile: pq + run: + # Params pinned to the smallest viable set: LMS/XMSS keygen cost is + # exponential in levels*height, and height>=15 runs for minutes. + # a failed verify goto's past this print, so it means every round verified + - exec: [./lms_example, "1", "5", "1"] + timeout: 180 + expect: "finished" + - exec: [./xmss_example, XMSS-SHA2_10_256, "10"] + timeout: 180 + expect: "finished" + + - id: ocsp-nonblock + path: ocsp/ocsp_nonblock + profile: ocsp + mode: build-only + reason: "ocsp_nonblock_async connects to an external responder on :443" + + - id: ocsp-responder + path: ocsp/responder + profile: ocsp + run: + # ocsp-request-response builds a request, signs a response and verifies it + # in-process -- no responder, no network. Every error path gotos cleanup and + # skips this line, so it only prints when all seven steps succeeded. + - exec: [./ocsp-request-response] + expect: "=== Example complete ===" + # ocsp-responder-http serves OCSP over HTTP and needs a client driving it; that + # is the N-process recipe ocsp-stapling also waits on. + + - id: ocsp-stapling + path: ocsp/stapling + profile: ocsp + # Three processes, not two, which is why this waited on the procs: step. + # Certs are pre-generated and checked in (valid to 2027-09-14), so no cert + # step -- but they DO expire, and this is the example CI exists to catch. + run: + # `make responder` verbatim: openssl's own OCSP responder on :22221. + - procs: &stapling + background: + - argv: [openssl, ocsp, -index, responder-certs/index.txt, -port, "22221", + -rsigner, responder-certs/ocsp-responder-int1-cert.pem, + -rkey, responder-certs/ocsp-responder-int1-key.pem, + -CA, client-certs/intermediate1-ca-cert.pem] + port: 22221 + - argv: [./ocsp-server] + port: 11111 + client: [./ocsp-client, --tls12] + # exit 0 only means the client ran; this means it got a stapled response + # back and the handshake completed. + expect: "Client: TLS handshake success" + # ocsp-server accepts once and exits, so tls13 needs its own chain. + - procs: + <<: *stapling + client: [./ocsp-client, --tls13] + expect: "Client: TLS handshake success" + # A wolfSSL bug, not an example bug, reproduced locally: the RFC 8446 + # 4.4.2 check in tls.c searches only ssl->extensions, but + # wolfSSL_CTX_UseOCSPStapling leaves status_request on ctx->extensions, + # so the server's staple is killed with unsupported_extension (-429). + # wolfSSL's own TLSX_CheckUnsupportedExtension does that ctx fallback; + # this call site does not. Patching it locally makes this leg pass. + expect_fail: "wolfSSL drops a CTX-set status_request in the TLS1.3 Certificate msg (-429)" + + - id: custom-io-file-client + path: custom-io-callbacks/file-client + profile: debug + deps: [clang] + mode: build-only + reason: "client half of the file-server pair; custom-io-file-server runs both" + + - id: custom-io-file-server + path: custom-io-callbacks/file-server + profile: debug + deps: [clang] + setup: + # the pair talks over files in file-client/, and stale ones desync the handshake + - [sh, -c, "cd ../file-client && ./clean-io-files.sh 2>/dev/null || true"] + - [make, -C, ../file-client] + run: + # check.sh drives both halves; they live in different dirs and share io + # files by relative path, so neither runs standalone. + - script: [./check.sh] + timeout: 60 + + - id: dtls-mcast + path: dtls-mcast + profile: dtls + mode: build-only + reason: >- + 3 peers on 239.255.0.1:12345, and two blockers beyond the peer count. + (1) mcast-peer never exits -- it is a while(running) loop ended by SIGINT, + so there is no foreground driver for the procs: step; it needs run-all- + three-then-SIGTERM-and-assert-on-output, a shape the harness lacks. + (2) the harness netns only brings lo up, with no route for 224.0.0.0/4, + so the IP_ADD_MEMBERSHIP is likely to fail there -- unverified, needs a + Linux probe. + + - id: pq-pqc-proxy + path: pq/pqc_proxy + profile: pq + # Not the "4-process chain" this used to claim: it is TWO independent + # 3-process chains on disjoint ports (11111/11112 and 22221/22222), and the + # README says both can run at once. Six binaries, two directions. + run: + # Direction 1 -- quantum-safe front door: a modern client reaches a legacy + # TLS 1.2 origin through a PQ-terminating proxy. + - procs: + background: + - argv: [./legacy-server] + port: 11112 + - argv: [./pq-proxy] + port: 11111 + client: [./pq-client, 127.0.0.1] + stdin: "hello over pq\n" + # kex= is the negotiated key exchange: this asserts ML-KEM actually ran, + # not merely that some TLS handshake succeeded. + expect: "kex=" + # Direction 2 -- quantum-safe upgrade: a legacy client is upgraded to PQ + # by the proxy in front of a PQ origin. + - procs: + background: + - argv: [./pq-server] + port: 22222 + - argv: [./upgrade-proxy] + port: 22221 + client: [./legacy-client, 127.0.0.1] + stdin: "hello over legacy\n" + expect: "Connected to proxy:" + + # pk/* -- each subdir is its own Makefile and its own example + - id: pk-curve25519 + path: pk/curve25519 + profile: pk + run: + - exec: [./curve25519_test] + - id: pk-dh-pg + path: pk/dh-pg + profile: pk + run: + # -ffdhe uses predefined groups; a bare run GENERATES DH params and takes + # minutes. + - exec: [./dh-pg-ka, -ffdhe] + timeout: 180 + - id: pk-ecc + path: pk/ecc + profile: pk + run: + - exec: [./ecc_keys] + expect: "storing public key into ecc-public.x963 (65 bytes)" + # the key is random per run, so assert the exported sizes, not the bytes + - exec: [./ecc_pub] + expect: "Public Key Qy: 32" + # these print Success only after verify_res came back 1 + - exec: [./ecc_sign] + expect: "Success" + - exec: [./ecc_sign_deterministic] + expect: "Success" + - exec: [./ecc_verify] + expect: "Success" + - id: pk-ecdh-generate-secret + path: pk/ecdh_generate_secret + profile: pk + run: + # argv[1] is required: without it the example prompts on stdin via getchar. + - exec: [./ecdh_gen_secret, "1"] + - exec: [./ecdh_gen_secret, "2"] + - exec: [./ecdh_gen_secret, "3"] + - id: pk-ed25519 + path: pk/ed25519 + profile: pk + run: + - exec: [./ed25519_keys] + expect: "writing public key to ed25519-pubkey.der (32 bytes)" + - exec: [./ed25519_pub] + expect: "Public Key: 32" + - exec: [./ed25519_sign] + expect: "Success" + - exec: [./ed25519_verify] + expect: "Success" + - id: pk-ed25519-gen + path: pk/ed25519_gen + profile: pk + run: + # sign_and_verify uses the committed test_keys.h. gen_key_files is not run: + # it overwrites committed .der files and dirties the worktree. + - exec: [./sign_and_verify] + - id: pk-ed448 + path: pk/ed448 + profile: pk + run: + - exec: [./ed448_keys] + expect: "writing public key to ed448-pubkey.der (57 bytes)" + - exec: [./ed448_pub] + expect: "Public Key: 57" + - exec: [./ed448_sign] + expect: "Success" + - exec: [./ed448_verify] + expect: "Success" + - id: pk-enc-through-sign-rsa + path: pk/enc-through-sign-rsa + profile: pk + run: + - exec: [./rsa-private-encrypt-app] + # reads ./encryptedAesKey (hardcoded, no argv) written by the app above + - exec: [./rsa-public-decrypt-app] + - id: pk-hpke + path: pk/hpke + profile: pk + run: + - exec: [./hpke_test] + - id: pk-rsa-kg + path: pk/rsa-kg + profile: pk + run: + # -load-key uses the committed rsa-key.h; without it this generates RSA + # keys and can run for minutes. + - exec: [./rsa-kg-sv, -load-key] + - exec: [./rsa-kg, -bits, "2048"] + timeout: 180 + - id: pk-rsa-pss + path: pk/rsa-pss + profile: pk + run: + - exec: [./rsa-pss, -s, sign.bin] + # reads ./rsa-public.der + sign.bin written by -s + - exec: [./rsa-pss, -v, sign.bin] + - id: pk-srp + path: pk/srp + profile: pk + run: + # srp_store.h is committed, so this works without regenerating it + - exec: [./srp, wolfssl, password] + - exec: [./srp_gen, wolfssl, password] + - id: pk-test-cert-keypair + path: pk/test_cert_and_private_keypair + profile: pk + run: + # key first, then cert + - exec: [./test-cert-privkey-pair, ../../certs/client-key.pem, ../../certs/client-cert.pem] + + # ------------------------------------------------- host: own shard (heavy) + - id: tls + path: tls + profile: tls + run: + # memory-tls needs no sockets and no stdin: the safest target here. + - exec: [./memory-tls] + # `shutdown` is the literal terminator (strncmp(buff, "shutdown", 8)). + # Only these servers check for it; the rest accept-loop and must be killed. + - pair: + server: [./server-tls13] + client: [./client-tls13, 127.0.0.1] + stdin: "shutdown\n" + server_exit: clean + expect: "Server: I hear ya fa shizzle" + - pair: + server: [./server-tls-cryptocb] + client: [./client-tls-cryptocb, 127.0.0.1] + stdin: "shutdown\n" + server_exit: clean + - pair: + server: [./server-tls-posthsauth] + client: [./client-tls-posthsauth, 127.0.0.1] + stdin: "shutdown\n" + server_exit: clean + - pair: + server: [./server-tls-threaded] + client: [./client-tls, 127.0.0.1] + stdin: "shutdown\n" + server_exit: clean + expect: "Server: I hear ya fa shizzle" + - pair: + server: [./server-tls] + client: [./client-tls, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + expect: "Server: I hear ya fa shizzle" + - pair: + server: [./server-tls-ecdhe] + client: [./client-tls-ecdhe, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + expect: "Server: I hear ya fa shizzle" + - pair: + server: [./server-tls-nonblocking] + client: [./client-tls-nonblocking, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + - pair: + server: [./server-tls-callback] + client: [./client-tls-callback, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + # NOT RUN: see the note on the dtls13-earlydata pair. The server never + # sends a session ticket, so the client exits 1 on "Session ticket not + # received from server". + + - pair: + server: [./server-tls13-certauth-clienthello] + client: [./client-tls13-certauth-clienthello, 127.0.0.1] + stdin: "shutdown\n" + server_exit: clean + + - pair: + server: [./server-tls-pkcallback] + client: [./client-tls-pkcallback, 127.0.0.1] + stdin: "shutdown\n" + server_exit: clean + + - pair: + server: [./server-tls] + client: [./client-tls-cacb, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + + # server-tcp/client-tcp link no wolfSSL (tls/Makefile strips -lwolfssl); the + # server returns its write() byte count, so it cannot be server_exit: clean. + - pair: + server: [./server-tcp] + client: [./client-tcp, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + + - pair: + server: [./server-tls-verifycallback] + client: [./client-tls, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + expect: "Server: I hear ya fa shizzle" + - pair: + server: [./server-tls-writedup] + client: [./client-tls-writedup, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + - pair: + server: [./server-tls] + client: [./client-tls-bio, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + - pair: + server: [./server-tls] + client: [./client-tls-pkcs12, 127.0.0.1] + stdin: "shutdown\n" + server_exit: killed + # client-tls-resume calls fgets twice, so it needs two lines. + - pair: + server: [./server-tls] + client: [./client-tls-resume, 127.0.0.1] + stdin: "hello\nshutdown\n" + server_exit: killed + expect: "Successful resume." + - pair: + server: [./server-tls13] + client: [./client-tls13-resume, 127.0.0.1] + stdin: "hello\nshutdown\n" + server_exit: killed + # Deliberately not run: client-ech (external crypto.cloudflare.com:443), + # {client,server}-tls-uart (needs /dev/ttyUSB0), and the four *-perf + # benchmarks. All still build. + + - id: dtls + path: dtls + profile: dtls + deps: [libevent-dev] + run: + # No dtls server honours any in-band terminator -- "shutdown" does not + # exist in this dir. Every server loops until SIGINT, so all pairs are + # server_exit: killed. + # BIO_s_mem is a byte stream, so a DTLS record can end mid-read; without + # RECORDS_CAN_SPAN_DATAGRAMS (set in the profile) wolfSSL treats that as a + # truncated datagram and drops it, and nothing retransmits. + - exec: [./memory-bio-dtls] + # A complete DTLS server rather than a self-contained demo: bare exec just + # blocks in poll() until the step times out. It has no dedicated client. + # export writes dtls_{server,client}_session.bin; import reads them, so this + # order is load bearing. + - pair: + server: [./server-dtls-export] + proto: udp + client: [./client-dtls-export, 127.0.0.1] + stdin: "hello\n" + server_exit: clean + + - pair: + server: [./server-dtls-import] + proto: udp + client: [./client-dtls-import, 127.0.0.1] + stdin: "hello\nquit\n" + server_exit: killed + + # clients that pair with servers this dir already runs + - pair: + server: [./server-dtls] + proto: udp + client: [./client-dtls-cid, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + + - pair: + server: [./server-dtls13] + proto: udp + client: [./client-dtls13-cid, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + + - pair: + server: [./server-dtls] + proto: udp + client: [./client-dtls-resume, 127.0.0.1] + server_exit: killed + # proves the resumed session carried data back -- the whole point of + # the pair the close_notify fix was for + expect: "info: server response:" + + - pair: + server: [./server-dtls] + proto: udp + client: [./client-dtls-shared, 127.0.0.1] + server_exit: killed + + - pair: + server: [./server-dtls13-event] + proto: udp + client: [./client-dtls13, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + + - pair: + server: [./server-dtls-rw-threads] + proto: udp + client: [./client-dtls-rw-threads, 127.0.0.1] + server_exit: killed + + - pair: + server: [./server-dtls-threaded] + proto: udp + client: [./client-dtls-threaded, 127.0.0.1] + server_exit: killed + + - pair: + server: [./server-dtls-ipv6] + proto: udp + client: [./client-dtls-ipv6, "::1"] + server_exit: killed + + - pair: + server: [./server-dtls-demux] + proto: udp + client: [./client-dtls, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + - pair: + server: [./server-udp] + proto: udp + client: [./client-udp, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + - pair: + server: [./server-dtls] + proto: udp + client: [./client-dtls, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + - pair: + server: [./server-dtls13] + proto: udp + client: [./client-dtls13, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + - pair: + server: [./server-dtls-nonblocking] + proto: udp + client: [./client-dtls-nonblocking, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + - pair: + server: [./server-dtls-callback] + proto: udp + client: [./client-dtls-callback, 127.0.0.1] + stdin: "hello\n" + server_exit: killed + # NOT RUN: the earlydata servers never send a session ticket, so the + # clients exit 1 on "Session ticket not received from server". + # Measured, not guessed: wolfSSL_read_early_data() completes the handshake + # itself, so wolfSSL_is_init_finished() is already 1 and wolfSSL_accept() + # is skipped -- and SendTls13NewSessionTicket() only runs inside accept's + # state machine (tls13.c:15984). Calling wolfSSL_send_SessionTicket() + # explicitly, and peeking >0 bytes on the client, do not help either. + # Needs someone who knows the TLS 1.3 ticket state machine. + + + - id: pkcs11 + path: pkcs11 + profile: pkcs11 + deps: [softhsm2] + # softhsm2-init.sh does README steps 3-4 (config, token init) and reads back + # the slot id SoftHSM reassigns at random, then runs the 8 examples. + # The 3 TLS binaries need wolfSSL's own client as the peer, which is not in + # this repo, so 8 of 11 is the honest ceiling here. + run: + # 7 of the 8 pass. pkcs11_test is run separately rather than folded in + # here, so a regression in these 7 still turns the job red. + - script: [./softhsm2-init.sh, pkcs11_rsa, pkcs11_ecc, pkcs11_genecc, + pkcs11_aesgcm, pkcs11_aescbc, pkcs11_hmac, pkcs11_rand] + # softhsm2.sh only prints this once every example it ran returned 0. + expect: "All PKCS#11 examples passed" + timeout: 300 + - script: [./softhsm2-init.sh, pkcs11_test] + expect: "All PKCS#11 examples passed" + timeout: 300 + # Real, deterministic on master AND v5.9.2-stable, and reduced to the + # exact call: gen_ec_keys_label() then wc_ecc_verify_hash() against the + # PKCS#11-backed public key returns WC_HW_E (-248). Signing works, and + # the same generate/sign/verify with no label passes, so it is specific + # to looking the public key up by label. Not reproducible locally -- + # SoftHSM 2.7 (brew) reports PKCS#11 3.2 from C_GetFunctionList while + # exporting no C_GetInterface, which wolfSSL rejects before any test runs. + expect_fail: "wc_ecc_verify_hash on a label-generated PKCS#11 EC key returns WC_HW_E (-248)" + + # ------------------------------------------------- host: separate profiles + - id: pk-rsa + path: pk/rsa + profile: fastmath + run: + - exec: [./rsa-nb] + + - id: signature-rsa-vfy-only + path: signature/rsa_vfy_only + # Keep cryptonly. This used to say "try under the `all` profile and drop this + # one" -- but `all` is documented above as emulated/cross only, it supplies + # none of --disable-asn/--enable-cryptonly/--enable-rsavfy/-DWOLFSSL_PUBLIC_MP + # that verify.c's mp_read_unsigned_bin() needs, and --enable-all would defeat + # the point of a minimum-footprint demo anyway. + profile: cryptonly + run: + # No expect: verify.c prints nothing at all -- `return ret == 0 ? 0 : 1` is + # its entire result, so the exit code IS the assertion here. + - exec: [./verify] + + # -------------------------------------------------------------- emulated + # csharp.yml compiles the wrapper's .cs with mcs and plays the client against + # each server under mono; the .csproj targets .NET Framework v4.8 and pulls in + # wolfSSL's own wolfSSL_CSharp.csproj, so it is not buildable here. + - id: csharp-pq-client + path: CSharp/wolfSSL-TLS-pq-Client + tier: cross + profile: pq + + - id: csharp-pq-server + path: CSharp/wolfSSL-TLS-pq-Server + tier: cross + profile: pq + + - id: csharp-pq-server-threaded + path: CSharp/wolfSSL-TLS-pq-ServerThreaded + tier: cross + profile: pq + + - id: tpm + path: tpm + tier: emulated + profile: all + # emulated.yml runs it against wolfTPM's own fwTPM simulator on :2321 + + + - id: sgx-linux + path: SGX_Linux + tier: emulated + profile: all + # emulated.yml builds the enclave and runs ./App in SGX_MODE=SIM + + + - id: can-bus + path: can-bus + tier: emulated + profile: all + # emulated.yml runs server/client over vcan0 (root + linux-modules-extra) + + + - id: uefi-library + path: uefi-library + tier: cross + profile: all + mode: build-only + reason: >- + REAL, UNDIAGNOSED wolfCrypt BUG under UEFI. Booting works (OVMF, -cpu + qemu64, ESP as a real FAT image via mtools -- QEMU's vvfat "fat:rw:" + SIGABRTs on a runner) and the suite runs: AES, SHA, HMAC, CMAC, KDF and RNG + all pass, then "Running RSA ... wc_CheckRsaKey failed: -262" and "Test suite + FAILED: Aborted". RULED OUT: key size. The test used a 1024-bit asset while + RSA_MIN_SIZE defaults to 2048, which looked like the cause -- it is not; the + key is now wolfSSL's 2048-bit certs/client-key.der and -262 is unchanged. + -262 comes from _ifc_pairwise_consistency_test (rsa.c), which signs and + verifies "Everyone gets Friday off." and collapses ANY non-zero into + RSA_KEY_PAIR_E, so the real error is hidden. NEXT: instrument that call, and + look at this dir's user_settings.h, which sets both WC_RSA_BLINDING and + WC_NO_HARDEN (the latter cancels the former), plus RSA_LOW_MEM (no CRT) and + XMALLOC_USER. Needs someone who can run a UEFI build. Restore the boot step + from this file's history once fixed; it asserts "All tests passed!". + + # ----------------------------------------------------------------- cross + - id: esp32-dtls13-client + path: ESP32/DTLS13-wifi-station-client + tier: cross + profile: all + mode: build-only + - id: esp32-dtls13-server + path: ESP32/DTLS13-wifi-station-server + tier: cross + profile: all + mode: build-only + - id: esp32-tls13-enc28j60-client + path: ESP32/TLS13-ENC28J60-client + tier: cross + profile: all + mode: build-only + + - id: esp32-tls13-enc28j60-server + path: ESP32/TLS13-ENC28J60-server + tier: cross + profile: all + mode: build-only + + - id: esp32-tls13-wifi-client + path: ESP32/TLS13-wifi_station-client + tier: cross + profile: all + mode: build-only + - id: esp32-tls13-wifi-server + path: ESP32/TLS13-wifi_station-server + tier: cross + profile: all + mode: build-only + + - id: rpi-pico + path: RPi-Pico + tier: cross + profile: all + mode: build-only + - id: rpi-pico-benchmark + path: RPi-Pico/benchmark + tier: cross + profile: all + mode: build-only + - id: rpi-pico-testwolfcrypt + path: RPi-Pico/testwolfcrypt + tier: cross + profile: all + mode: build-only + - id: rpi-pico-tcp-client + path: RPi-Pico/tcp_client + tier: cross + profile: all + mode: build-only + - id: rpi-pico-tcp-server + path: RPi-Pico/tcp_server + tier: cross + profile: all + mode: build-only + - id: rpi-pico-tls-client + path: RPi-Pico/tls_client + tier: cross + profile: all + mode: build-only + - id: rpi-pico-tls-server + path: RPi-Pico/tls_server + tier: cross + profile: all + mode: build-only + - id: rpi-pico-wifi + path: RPi-Pico/wifi + tier: cross + profile: all + mode: build-only + + - id: rt1060 + path: RT1060 + tier: cross + profile: all + mode: build-only + - id: puf + path: puf + tier: cross + profile: all + mode: build-only + - id: uefi-static + path: uefi-static + tier: cross + profile: all + mode: build-only + - id: arduino-template + path: Arduino/sketches/template + tier: cross + profile: all + mode: build-only + - id: ebpf-syscall-write-trace + path: ebpf/syscall-write-trace + tier: cross + profile: all + mode: build-only + - id: ebpf-tls-uprobe-trace + path: ebpf/tls-uprobe-trace + tier: cross + profile: all + mode: build-only + - id: fullstack-https + path: fullstack/freertos-wolfip-wolfssl-https + tier: cross + profile: all + - id: android-wolfcryptjni + path: android/wolfcryptjni-ndk-gradle + tier: cross + profile: all + mode: build-only + reason: "gradle + NDK; assembleDebug is the honest ceiling (no instrumentation harness). No job wired yet" + - id: android-wolfcryptjni-app + path: android/wolfcryptjni-ndk-gradle/app + tier: cross + profile: all + mode: build-only + reason: "gradle + NDK; assembleDebug is the honest ceiling (no instrumentation harness). No job wired yet" + - id: android-wolfssljni + path: android/wolfssljni-ndk-gradle + tier: cross + profile: all + mode: build-only + reason: "gradle + NDK; assembleDebug is the honest ceiling (no instrumentation harness). No job wired yet" + - id: android-wolfssljni-app + path: android/wolfssljni-ndk-gradle/app + tier: cross + profile: all + mode: build-only + reason: "gradle + NDK; assembleDebug is the honest ceiling (no instrumentation harness). No job wired yet" + - id: android-wolfssljni-sample + path: android/wolfssljni-ndk-sample/jni + tier: cross + profile: all + mode: build-only + reason: "gradle + NDK; assembleDebug is the honest ceiling (no instrumentation harness). No job wired yet" + + # ------------------------------------------------------------------ skip + - id: btle-common + path: btle/common + mode: skip + reason: "shared helper (btle-sim.c) linked by btle/ecies and btle/tls; not an example" + + # arduino.yml does NOT cover these: it copies compile-all-examples.sh into + # $ARDUINO_ROOT/wolfssl/examples and runs it there, compiling the examples that + # ship inside the installed Arduino wolfSSL library, not this repo's sketches. + # Building them needs arduino-cli plus a core per board. + - id: arduino-client + path: Arduino/sketches/wolfssl_client + tier: cross + profile: all + mode: build-only + + - id: arduino-server + path: Arduino/sketches/wolfssl_server + tier: cross + profile: all + mode: build-only + + - id: arduino-client-dtls + path: Arduino/sketches/wolfssl_client_dtls + tier: cross + profile: all + mode: build-only + + - id: arduino-server-dtls + path: Arduino/sketches/wolfssl_server_dtls + tier: cross + profile: all + mode: build-only + + - id: arduino-AES-CTR + path: Arduino/sketches/wolfssl_AES_CTR + tier: cross + profile: all + mode: build-only + + - id: arduino-version + path: Arduino/sketches/wolfssl_version + tier: cross + profile: all + mode: build-only + + - id: esp32-hello-world + path: ESP32/ESP32-hello-world + tier: cross + mode: skip + reason: >- + Not worth wiring: hello_world.ino is 12 lines and does not include wolfSSL + at all, so compiling it would test arduino-cli rather than wolfSSL. It is + also an arduino-cli sketch rather than an ESP-IDF project (the esp32 job + builds idf.py projects), and its dir name does not match the .ino basename, + which arduino-cli requires -- so even Arduino/sketches/compile-all-examples.sh + could not pick it up as-is. Delete or fold into Arduino/sketches if anyone + wants it covered. + + - id: sgx-windows-benchmarks + path: SGX_Windows/Benchmarks + mode: skip + reason: >- + Tried on windows-latest and reverted: the Intel SGX SDK for Windows has no + download URL that can be verified from here. Intel serves it from + registrationcenter-download.intel.com behind a per-release GUID (a guessed + one returns AccessDenied), intel/linux-sgx's releases carry no Windows + assets, and there is no chocolatey package. Someone with a browser needs to + get the current installer link, or host it. Beyond that: README.md targets + Visual Studio 2013 with the Intel compiler so the project files likely need + retargeting, and wolfssl.lib must be built first from wolfSSL's own + IDE/WIN-SGX solution and copied in. sgx-linux already covers the same + wolfSSL code under SGX_MODE=SIM, so the payoff is small either way. + + - id: sgx-windows-enclave + path: SGX_Windows/Enclave + mode: skip + reason: >- + Tried on windows-latest and reverted: the Intel SGX SDK for Windows has no + download URL that can be verified from here. Intel serves it from + registrationcenter-download.intel.com behind a per-release GUID (a guessed + one returns AccessDenied), intel/linux-sgx's releases carry no Windows + assets, and there is no chocolatey package. Someone with a browser needs to + get the current installer link, or host it. Beyond that: README.md targets + Visual Studio 2013 with the Intel compiler so the project files likely need + retargeting, and wolfssl.lib must be built first from wolfSSL's own + IDE/WIN-SGX solution and copied in. sgx-linux already covers the same + wolfSSL code under SGX_MODE=SIM, so the payoff is small either way. + + - id: java-https-url + path: java/https-url + tier: cross + profile: default + mode: build-only + # java.yml builds wolfSSL with JNI, builds wolfssljni on top and javac's + # URLClient against wolfssl-jsse.jar -- so `build: none` here means the + # harness does not build it, not that nothing does. + build: none + reason: >- + URLClient fetches a real URL over the public internet (the README's own + invocation is -h https://www.google.com with example-keystores/external.jks), + so running it in CI would test GitHub's network, not wolfJSSE. Compiling it + against the jar is the honest ceiling. Same call as ocsp-nonblock. + + - id: kernel-bsdkm + path: kernel/bsdkm + tier: cross + profile: default + # bsdkm.yml runs it in a real FreeBSD 14.2 VM (vmactions/freebsd-vm), the + # version README.md says it was tested on. It also fetches src.txz, because + # the Makefile includes /usr/src/sys/conf/kmod.mk -- the live kernel source, + # not the bsd.kmod.mk in base. kldload then proves it in-kernel. + build: none + + - id: meta-wolfssl-linux-fips + path: meta-wolfssl-linux-fips + mode: skip + reason: "full Yocto bitbake: hours of build time and tens of GB" + + - id: stsafe + path: stsafe + mode: skip + reason: "needs a real STSAFE-A120 over /dev/i2c-N; platform layer is hard-wired to Linux I2C with no transport abstraction, so wolfSSL/simulators' STSAFEA120Sim cannot drive it without a new platform shim" + + - id: rtl8735b + path: rtl8735b + mode: skip + reason: "RealTek AmebaPro2 SDK + licensed ASDK 10.3.0 toolchain" + - id: rtl8735b-test + path: rtl8735b/test + mode: skip + reason: "RealTek AmebaPro2 SDK + licensed ASDK 10.3.0 toolchain" + - id: rtl8735b-tls + path: rtl8735b/tls + mode: skip + reason: "RealTek AmebaPro2 SDK + licensed ASDK 10.3.0 toolchain" + + - id: renesas-rh850 + path: Renesas/cs+/RH850/rsapss_sign_verify + mode: skip + reason: "Renesas CS+ IDE project; licensed Windows-only CC-RH compiler" + + - id: ccb-vaultic + path: ccb_vaultic + mode: skip + reason: "Wisekey VaultIC dev kit + Android NDK ($NDK_CC)" + + - id: caam-seco + path: caam/seco + mode: skip + reason: "NXP SECO HSM ($HSM_DIR) + aarch64-poky cross toolchain" + - id: caam-seco-cryptodev + path: caam/seco/cryptodev + mode: skip + reason: "NXP SECO HSM ($HSM_DIR) + aarch64-poky cross toolchain" + + - id: maxq10xx + path: maxq10xx + mode: skip + reason: "Analog Devices MAXQ10xx SDK and hardware" + + - id: crypto-magiccrypto + path: crypto/MagicCrypto + mode: skip + reason: "Aria vendor SDK (ships MagicCrypto.patch); not redistributable" + + - id: psa + path: psa + tier: cross + profile: default + # psa.yml owns this one: the example's own build_with_mbedtls_psa.sh pins an + # mbedTLS commit and runs ./configure --enable-psa itself, so it cannot be a + # profile here. That script is why the old "needs a PSA implementation" skip + # was too pessimistic -- the implementation builds from source in ~2 minutes. + build: none + + - id: pq-tls + path: pq/tls + profile: pq + # "needs liboqs" was stale: it predates wolfSSL's native ML-KEM/ML-DSA. + # Neither the sources nor the Makefile mention oqs -- they gate on + # WOLFSSL_HAVE_MLKEM and HAVE_DILITHIUM, which the pq profile already + # supplies, and the README asks for plain --enable-kyber --enable-dilithium. + # The mldsa87 certs it wants are checked in under certs/. + run: + - pair: + server: [./server-pq-tls13] + client: [./client-pq-tls13, 127.0.0.1] + stdin: "hello pq tls\n" + server_exit: term + # the server sends a fixed reply rather than echoing + # (server-pq-tls13.c:156), so this is the proof that a + # SECP521R1MLKEM1024 session carried data back. + expect: "Server: I hear ya fa shizzle" + - id: pq-tls-stm32 + path: pq/tls/stm32 + mode: skip + reason: "STM32 board project for the liboqs TLS example" + + - id: se050 + path: SE050/wolfssl + mode: skip + reason: >- + Got a long way and hit a real wall. Everything the old "NXP Plug&Trust + middleware (simw-top)" reason implied was unobtainable IS public: the sim + (wolfSSL/simulators SE050Sim, full I2C/T=1/APDU over TCP, no chip), the SDK + (github.com/NXP/plug-and-trust v04.07.01) and wolfSSL osp's + simw-top-v040701.patch. The wall is that the GitHub plug-and-trust repo is + a SUBSET of the simw-top NXP ships on its website: it has sss/, hostlib/ + and ecc_example/ but NO demos/ and no top-level CMakeLists.txt. This repo's + SE050/README.md says to copy these demos to simw-top/demos/wolfssl and add + an ADD_SUBDIRECTORY to demos/CMakeLists.txt -- neither exists in the public + tree, so `cp` fails outright. SE050Sim sidesteps this by shipping its own + CMakeLists for its own wolfcrypt-test rather than using demos/. Wiring + these six demos therefore means writing a CMakeLists that builds them + against the SDK's six static libs (libSSS_APIs, libex_common, libse05x, + liba7x_utils, libmwlog, libsmCom), which is authoring, not CI wiring. + - id: se050-benchmark + path: SE050/wolfssl/wolfcrypt_benchmark + mode: skip + reason: same as se050 -- the public plug-and-trust tree has no demos/ scaffolding to build these in + - id: se050-generate-csr + path: SE050/wolfssl/wolfcrypt_generate_csr + mode: skip + reason: same as se050 -- the public plug-and-trust tree has no demos/ scaffolding to build these in + - id: se050-key-cert-insert + path: SE050/wolfssl/wolfcrypt_key_cert_insert + mode: skip + reason: same as se050 -- the public plug-and-trust tree has no demos/ scaffolding to build these in + - id: se050-test + path: SE050/wolfssl/wolfcrypt_test + mode: skip + reason: same as se050 -- the public plug-and-trust tree has no demos/ scaffolding to build these in + - id: se050-client + path: SE050/wolfssl/wolfssl_client + mode: skip + reason: same as se050 -- the public plug-and-trust tree has no demos/ scaffolding to build these in + - id: se050-client-cert-key + path: SE050/wolfssl/wolfssl_client_cert_key + mode: skip + reason: same as se050 -- the public plug-and-trust tree has no demos/ scaffolding to build these in + + - id: toppers + path: TOPPERS/WolfSSLDemo + mode: skip + reason: "Renesas RX72N + TOPPERS/ASP3 RTOS; needs the Renesas software package" + - id: toppers-wolfdemo + path: TOPPERS/WolfSSLDemo/src/wolfDemo + mode: skip + reason: "Renesas RX72N + TOPPERS/ASP3 RTOS" + + - id: tirtos-tcpecho-client + path: tirtos_ccs_examples/tcpEcho_Client_TivaTM4C1294NCPDT + mode: skip + reason: "TI Code Composer Studio + XDCtools + TI-RTOS" + - id: tirtos-tcpecho-server + path: tirtos_ccs_examples/tcpEcho_Server_TivaTM4C1294NCPDT + mode: skip + reason: "TI Code Composer Studio + XDCtools + TI-RTOS" + - id: tirtos-tests + path: tirtos_ccs_examples/wolfssl_tests + mode: skip + reason: "TI Code Composer Studio + XDCtools + TI-RTOS" + - id: tirtos-benchmark + path: tirtos_ccs_examples/wolfssl_tirtos_benchmark + mode: skip + reason: "TI Code Composer Studio + XDCtools + TI-RTOS" + + - id: mynewt + path: mynewt + mode: skip + reason: >- + BLOCKED ON A REAL wolfSSL BUG, found by wiring this up. The mechanics all + work: newt installs, jenkins.sh (in this dir, unrun since 2018) builds the + native bsp sim, and WOLFSSL_REF now selects the branch. The wall is that + wolfSSL's Mynewt port does not compile: settings.h sets XMALLOC_OVERRIDE and + defines XFREE as a macro ("#define XFREE(p, heap, type) ((void)(heap), + (void)(type), os_free(p))"), but types.h still declares "extern void + XFREE(void *p, void* heap, int type);" -- the macro expands inside the + declaration and gcc stops with "expected ')' before '(' token". The guard on + that declaration needs to account for the Mynewt override. Fails on master + AND v5.9.2-stable, so it is long-standing, not a regression. Fix that + upstream and this is ready: mynewt.yml only has to install newt + expect and + run jenkins.sh. (Also fixed here on the way: client-tls-mn.c cast pointers + through int, which -Werror rejects on the 64-bit native BSP.) + + - id: picotcp + path: picotcp + profile: default + mode: build-only + # v1.7.0, not master: README.md:10 asks for "PicoTCP v.1.7 or later", and + # picoTCP is archived upstream so master has drifted from what this was + # written against. fetch: runs outside the netns; nothing is redirected, + # because hiding this build is what made an earlier attempt a mystery. + fetch: + - [sh, -c, "test -d ../../picotcp || git clone -q --depth 1 --branch v1.7.0 https://github.com/tass-belgium/picotcp ../../picotcp"] + # cd, NOT make -C: picotcp's Makefile:16 is PREFIX?=$(PWD)/build, and -C + # leaves PWD at the caller, so it built into wolfssl-examples/picotcp/build. + # deps before lib as well: lib cp's headers into $(PREFIX)/include but only + # deps mkdir's it (Makefile:367-380). + - [sh, -c, "cd ../../picotcp && make ARCH=shared TAP=1 deps && make ARCH=shared TAP=1 lib"] + - [sh, -c, "ls ../../picotcp/build/include/pico_stack.h"] + reason: >- + picotcp-server opens /dev/net/tun and brings up 10.0.0.1 itself, so running + it needs a tun device in the netns. Building against a real picoTCP is the + honest ceiling until that is probed. + - id: riot-os-posix-lwip + path: riot-os-posix-lwip + mode: skip + reason: >- + Got further than the old "needs a RIOT tree at $RIOTBASE" suggested, and + found two things that matter. (1) RIOT does NOT use the wolfSSL under test: + it vendors its own pinned wolfSSL package via pkg/pkg.mk, so a green here + would say nothing about master or stable -- the point of this CI. (2) That + pinned wolfSSL does not compile on a current toolchain anyway: + build/pkg/wolfssl/wolfcrypt/src/sp_int.c:13390 "implicit declaration of + _sp_exptmod_ex" under gcc-13 -Werror=implicit-function-declaration. + Wiring it needs RIOT's pkg pointed at the ref under test first (see + RIOT's PKG_URL/PKG_VERSION), which is real work upstream. Mechanics that + DO work and are worth reusing: clone RIOT to ../../RIOT (the Makefile's + default, BOARD ?= native) via fetch:, then `make pkg-prepare` in fetch: so + RIOT downloads its packages before the run enters the netns. + + - id: lwip + path: lwip + mode: skip + reason: "needs an lwIP source tree; no Makefile in this dir" + + - id: freertos + path: freertos + mode: skip + reason: "orphan source (tls_client_freertos_tcp.c): no Makefile and no README" + + - id: utasker + path: utasker + mode: skip + reason: "uTasker project task files; no standalone build" diff --git a/.github/scripts/ci_triage.py b/.github/scripts/ci_triage.py new file mode 100644 index 000000000..7c94f27a3 --- /dev/null +++ b/.github/scripts/ci_triage.py @@ -0,0 +1,731 @@ +#!/usr/bin/env python3 +"""Triage a nightly run: retry once, classify by retry outcome, file issues. + +Doctrine (from wolfProvider, and the reason this works at all): + + Cleared on retry = flake. Failed twice = real. A reproducing failure is REAL + even if low-impact -- that is what severity is for. "flake" means ONLY a + transient infra/network hiccup. + +Classification is by RETRY OUTCOME, never by guessing from the log. +""" + +import json +import os +import re +import sys +import time +import traceback +import urllib.error +import urllib.request +from collections import defaultdict +from concurrent.futures import ThreadPoolExecutor +from datetime import datetime, timezone + +import issue_store as store + +REPO = os.environ["GH_REPO"] +RUN_ID = os.environ["RUN_ID"] +TOKEN = os.environ["GITHUB_TOKEN"] +ANTHROPIC_KEY = os.environ.get("ANTHROPIC_API_KEY", "") +CLAUDE_MODEL = os.environ.get("CLAUDE_MODEL", "claude-opus-4-8") +AUTO_RETRY = os.environ.get("AUTO_RETRY", "false") == "true" +DRY_RUN = os.environ.get("DRY_RUN", "true") == "true" +RETRY_DEADLINE_S = int(os.environ.get("RETRY_DEADLINE_S", "3600")) + +API = "https://api.github.com" +POLL_INTERVAL_S = 30 +JOBS_PER_PAGE = 50 # the jobs endpoint 502s at per_page=100 on large runs +AI_MAX_CALLS = 15 +LOG_TAIL_CHARS = 4000 + + +def gh(path, method="GET", body=None, retry=True): + url = path if path.startswith("http") else f"{API}{path}" + data = json.dumps(body).encode() if body is not None else None + req = urllib.request.Request(url, method=method, data=data) + req.add_header("Authorization", f"Bearer {TOKEN}") + req.add_header("Accept", "application/vnd.github+json") + if data: + req.add_header("Content-Type", "application/json") + attempts = 3 if retry else 1 + for i in range(attempts): + try: + with urllib.request.urlopen(req, timeout=60) as r: + raw = r.read() + return json.loads(raw) if raw else {} + except urllib.error.HTTPError: + raise + except Exception: + if i == attempts - 1: + raise + time.sleep(2 ** i) + + +def all_jobs(run_id, attempt=None): + base = f"/repos/{REPO}/actions/runs/{run_id}" + base += f"/attempts/{attempt}/jobs" if attempt else "/jobs" + jobs, page = [], 1 + while True: + got = gh(f"{base}?per_page={JOBS_PER_PAGE}&page={page}").get("jobs", []) + jobs += got + if len(got) < JOBS_PER_PAGE: + return jobs + page += 1 + + +# --- retry: poll, do not trampoline ---------------------------------------- +# +# wolfProvider POSTs rerun-failed-jobs and returns, relying on the rerun +# re-firing workflow_run. Three paths then produce a GREEN triage run with zero +# output: the rerun never schedules; a 5xx on the POST raises out of main(); and +# the GITHUB_TOKEN loophole it leans on is undocumented behavior used as control +# flow. Polling dissolves all three. There is deliberately no path here that +# returns without the caller going on to report. + + +def rerun_and_wait(run_id): + before = int(gh(f"/repos/{REPO}/actions/runs/{run_id}").get("run_attempt", 1)) + try: + gh(f"/repos/{REPO}/actions/runs/{run_id}/rerun-failed-jobs", method="POST") + except urllib.error.HTTPError as e: + # 403 = run too old / Actions disabled / "No failed jobs" (every non-pass + # was `cancelled`, which this endpoint will not rerun). 409 = already running. + return before, f"retry could not be started (HTTP {e.code})" + except Exception as e: + return before, f"retry could not be started ({type(e).__name__})" + + end = time.monotonic() + RETRY_DEADLINE_S + seen = before + while time.monotonic() < end: + time.sleep(POLL_INTERVAL_S) + try: + run = gh(f"/repos/{REPO}/actions/runs/{run_id}") + except Exception: + continue + seen = int(run.get("run_attempt", before)) + # ORDER MATTERS: right after the POST the run still reads + # completed/attempt=1. Checking status first returns on the first poll + # and reports attempt 1 as though the retry had run. + if seen <= before: + continue + if run.get("status") == "completed": + return seen, "" + if seen <= before: + return before, "retry never started; reporting first-attempt results" + return seen, f"retry did not finish within {RETRY_DEADLINE_S // 60}m; partial results" + + +# --- results --------------------------------------------------------------- + + +class _NoRedirect(urllib.request.HTTPRedirectHandler): + def redirect_request(self, *a, **kw): + return None + + +_NOREDIR = urllib.request.build_opener(_NoRedirect) + + +def fetch_artifact(url): + """Download an artifact zip. + + The endpoint 302s to a pre-signed blob URL. urllib replays our Authorization + header onto it, the blob store then tries to authenticate with a GitHub token + and 401s -- so catch the redirect and fetch the Location with no auth. + Getting this wrong empties every result, which reads as "nothing failed". + """ + req = urllib.request.Request(url) + req.add_header("Authorization", f"Bearer {TOKEN}") + try: + with _NOREDIR.open(req, timeout=120) as r: + return r.read() + except urllib.error.HTTPError as e: + if e.code not in (301, 302, 303, 307, 308): + raise + loc = e.headers.get("Location") + if not loc: + raise + with urllib.request.urlopen(loc, timeout=120) as r: + return r.read() + + +def fetch_results(run_id, attempt): + """Per-dir results from the shard artifacts of one attempt.""" + # Paginate: one artifact per (example, ref) means a nightly with 3 refs and + # 62 entries produces ~186. Reading page 1 only silently drops the tail, and a + # dropped example is never triaged and never has its issue closed. + arts, page = [], 1 + while True: + got = gh( + f"/repos/{REPO}/actions/runs/{run_id}/artifacts" + f"?per_page={JOBS_PER_PAGE}&page={page}" + ).get("artifacts", []) + arts += got + if len(got) < JOBS_PER_PAGE: + break + page += 1 + want = f"-attempt{attempt}" + out = [] + wanted = read = 0 + for a in arts: + if not a["name"].endswith(want) or a.get("expired"): + continue + wanted += 1 + try: + import io + import zipfile + + blob = fetch_artifact(a["archive_download_url"]) + read += 1 + with zipfile.ZipFile(io.BytesIO(blob)) as z: + for name in z.namelist(): + if name.endswith(".json"): + out += json.loads(z.read(name)) + except Exception as e: + print(f"warn: could not read artifact {a['name']}: {e}", file=sys.stderr) + # One unreadable artifact is a warning; none of them readable means triage is + # blind, and reporting "0 failures" from that is the worst thing this can do. + if wanted and not read: + sys.exit( + f"could not read ANY of {wanted} result artifact(s) for attempt " + f"{attempt}. Refusing to report -- an empty read is not a pass." + ) + return out + + +def merged_results(run_id, attempt): + """Attempt 2 only reran the failed shards, so merge it OVER attempt 1.""" + # The ref MUST be in the key: nightly runs each example once per wolfSSL ref, + # so keying on (id, target) alone collapses master and stable into one row and + # a pass on one ref silently overwrites a failure on the other. + def key(r): + return (r["id"], r.get("ref", ""), r.get("target", "")) + + first = {key(r): r for r in fetch_results(run_id, 1)} + if attempt >= 2: + for r in fetch_results(run_id, attempt): + first[key(r)] = r + return list(first.values()) + + +def classify(run_id, attempt, retry_note): + """Fold per-target results into a per-dir observation.""" + a1 = defaultdict(list) + for r in fetch_results(run_id, 1): + a1[r["id"]].append(r["status"]) + final = defaultdict(list) + for r in merged_results(run_id, attempt): + final[r["id"]].append(r["status"]) + + # Which refs actually failed. The caller used to hardcode "master", which made + # the issue table and the AI prompt lie whenever a break was stable-only. + fail_refs = defaultdict(set) + for r in merged_results(run_id, attempt): + if r["status"] == "fail": + fail_refs[r["id"]].add(r.get("ref") or "unknown") + # A flake has no failing ref in the final attempt by definition, so without + # this its issue would name no ref at all. The ref that failed first is the + # whole point of the report. + a1_refs = defaultdict(set) + for r in fetch_results(run_id, 1): + if r["status"] == "fail": + a1_refs[r["id"]].add(r.get("ref") or "unknown") + + obs = {} + for eid in set(a1) | set(final): + failed_now = "fail" in final.get(eid, []) + failed_before = "fail" in a1.get(eid, []) + if failed_now: + obs[eid] = store.UNCONFIRMED if retry_note else store.REAL + elif failed_before and attempt >= 2: + obs[eid] = store.FLAKE_ONLY + fail_refs[eid] |= a1_refs.get(eid, set()) + else: + obs[eid] = store.PASS + # every host dir came from examples.yml, which nightly.yml calls as `host` + targets = {eid: "examples" for eid in obs} + + jobs_obs, jobs_refs, jobs_targets = classify_jobs(run_id, attempt, retry_note) + obs.update(jobs_obs) + fail_refs.update(jobs_refs) + targets.update(jobs_targets) + return obs, {k: sorted(v) for k, v in fail_refs.items()}, targets + + +# Jobs the nightly fans out to that emit no results-*.json. Without this they +# ran every night, went red, and told nobody -- 12 of the 13 targets. +# lowercased before matching: a `name:` override in nightly.yml renames every +# job under it, and a case mismatch would silently make "host" a 13th target +HOST_JOBS = {"host", "refs", "gate"} +REF_RE = re.compile(r"wolfSSL (\S+)|\((master|v[\d.]+-stable)\)") + + +def job_unit(name): + """`esp32 / Build / ESP32 (...) wolfSSL master` -> ('esp32', 'master'). + + The prefix is nightly.yml's job name, which is deliberately the target name + and therefore the ci: label. + """ + if " / " not in name: + return None, None + target, rest = name.split(" / ", 1) + if target.lower() in HOST_JOBS: + return None, None + m = REF_RE.search(rest) + return target, (m.group(1) or m.group(2)) if m else "unknown" + + +HOST_JOB_RE = re.compile(r"^host / (?:Run|Build) / (.+) \((.+)\)$", re.I) + + +def job_urls(run_id): + """(unit, ref) -> the URL of the job that ran it. + + Linking the run only makes a reader hunt through 250 jobs for the red one. + """ + out = {} + for j in all_jobs(run_id): + name, url = j.get("name", ""), j.get("html_url") + m = HOST_JOB_RE.match(name) + if m: + out[(m.group(1), m.group(2))] = url + continue + t, ref = job_unit(name) + if t: + out[(t, ref)] = url + return out + + +def classify_jobs(run_id, attempt, retry_note): + def by_unit(jobs): + out = defaultdict(list) + for j in jobs: + t, ref = job_unit(j.get("name", "")) + if t: + out[t].append((j.get("conclusion"), ref)) + return out + + a1 = by_unit(all_jobs(run_id, attempt=1)) + final = by_unit(all_jobs(run_id)) if attempt >= 2 else a1 + + obs, refs, targets = {}, defaultdict(set), {} + for t in set(a1) | set(final): + failed_now = any(c == "failure" for c, _ in final.get(t, [])) + failed_before = any(c == "failure" for c, _ in a1.get(t, [])) + if failed_now: + obs[t] = store.UNCONFIRMED if retry_note else store.REAL + refs[t] = {r for c, r in final[t] if c == "failure"} + elif failed_before and attempt >= 2: + obs[t] = store.FLAKE_ONLY + # nothing failed in the final attempt, so name the ref that failed first + refs[t] = {r for c, r in a1[t] if c == "failure"} + else: + obs[t] = store.PASS + targets[t] = t + return obs, refs, targets + + +# --- AI: advisory only ----------------------------------------------------- +# +# N per-dir calls, not one batched call. Batching gives ~120 output tokens per +# job and makes one truncation invalidate every dir's verdict. Per-dir isolation +# is structural rather than a plea in the prompt. + +SYSTEM = """\ +You triage failures in the wolfSSL/wolfssl-examples nightly CI. + +Context you must assume: +- Each example directory builds small C programs against a wolfSSL library built + from a given git ref (master, or a stable tag) and installed to /usr/local. +- The job below failed TWICE: an automatic retry did not clear it. Infra setup + failures are filtered out before you see this. +- You are judging ONE example directory from ONE log. You have no other context. + +Failure taxonomy for this repo, roughly by frequency: +- missing-build-option: the example needs a wolfSSL ./configure flag that was not + enabled ("WOLFSSL_KEY_GEN not defined", implicit declaration of a wc_* function). + The example is fine; the profile is wrong. Usually Medium. +- api-drift: a wolfSSL API changed and the example was not updated (wrong argument + count, removed symbol). The example must be fixed. High. +- link-error: "undefined reference to wc_*" - usually a build-option problem + wearing a link error's clothes. +- cert-expiry: the shared certs/ fixtures expired (ASN_AFTER_DATE_E, -155). Affects + the whole repo, not this dir. High, and blast is repo-wide. +- identity-gate: CI refused to run because a libwolfssl it did not build was + visible. An infrastructure fault, not an example bug. +- runtime-failure: builds clean, then asserts / segfaults / returns non-zero. +- toolchain: missing header or library, compiler version incompatibility. +- infra-flake: apt/git/download timeout, DNS failure, disk full. + +Verdict rules - not suggestions: +- "flake" ONLY if THIS log shows a transient network/registry/download hiccup. +- A build or test that reproducibly FAILS is "real" even if cosmetic or unrelated + to crypto. Severity is where you express that. Never use "flake" to mean + "unimportant". +- If the log is truncated or you cannot tell, say so in `symptom`, return "real" + with severity Medium. Do not guess. + +Set `upstream` true when the evidence says this is wolfSSL's regression rather than +the example's - typically api-drift that fails only against master while stable +refs pass. That routes a human to file against wolfSSL/wolfssl instead of here. + +Do not speculate about outages or other jobs. Judge only this log. Every free-text +field is one line, plain, no markdown. +""" + +SCHEMA = { + "type": "object", + "properties": { + "verdict": {"type": "string", "enum": ["real", "flake"]}, + "category": { + "type": "string", + "enum": [ + "missing-build-option", + "api-drift", + "link-error", + "cert-expiry", + "identity-gate", + "runtime-failure", + "toolchain", + "infra-flake", + "unknown", + ], + }, + "severity": {"type": "string", "enum": ["Critical", "High", "Medium", "Low"]}, + "symptom": {"type": "string"}, + "cause": {"type": "string"}, + "next": {"type": "string"}, + "blast": {"type": "string", "enum": ["this-dir", "repo-wide"]}, + "upstream": {"type": "boolean"}, + }, + "required": [ + "verdict", + "category", + "severity", + "symptom", + "cause", + "next", + "blast", + "upstream", + ], + "additionalProperties": False, +} + +TIER_SEV = {"build": "High", "run": "Medium", "setup": "Medium"} + + +def ai_one(client, fd): + if client is None: + return None + user = ( + f"example dir: {fd['id']}\n" + f"failing refs: {', '.join(fd['refs'])}\n" + f"consecutive nights failing: {fd['streak']}\n\n" + f"log tail (secrets scrubbed):\n{store.scrub(fd['log'])[-LOG_TAIL_CHARS:]}" + ) + try: + resp = client.messages.create( + model=CLAUDE_MODEL, + max_tokens=2000, + system=SYSTEM, + thinking={"type": "adaptive"}, + output_config={ + "effort": "low", + "format": {"type": "json_schema", "schema": SCHEMA}, + }, + messages=[{"role": "user", "content": user}], + ) + if resp.stop_reason in ("refusal", "max_tokens"): + return None + text = next((b.text for b in resp.content if b.type == "text"), "") + return json.loads(text) + except Exception as e: + print(f"warn: AI triage unavailable for {fd['id']}: {e}", file=sys.stderr) + return None + + +def ai_batch(failures): + if not ANTHROPIC_KEY or not failures: + return {} + if len(failures) > AI_MAX_CALLS: + print( + f"note: {len(failures)} failures exceeds the {AI_MAX_CALLS}-call cap; " + "this looks systemic, skipping AI triage", + file=sys.stderr, + ) + return {} + try: + import anthropic + + client = anthropic.Anthropic(api_key=ANTHROPIC_KEY) + except ImportError: + print("warn: anthropic SDK not installed; skipping AI triage", file=sys.stderr) + return {} + with ThreadPoolExecutor(max_workers=4) as pool: + verdicts = list(pool.map(lambda f: ai_one(client, f), failures)) + return {f["id"]: v for f, v in zip(failures, verdicts) if v} + + +# --- issues ---------------------------------------------------------------- + + +def open_issues(): + """REST list, not Search: strongly consistent and returns bodies.""" + out, page = [], 1 + while True: + got = gh( + f"/repos/{REPO}/issues?labels={store.LABEL}&state=all" + f"&per_page=100&page={page}" + ) + out += [i for i in got if "pull_request" not in i] + if len(got) < 100: + return out + page += 1 + + +NIGHTLY_TARGETS = ("examples", "esp32", "android", "rt1060", "uefi", "puf", + "rpi-pico", "ebpf", "fullstack", "java", "cmake", "csharp", + "emulated") + + +def ensure_labels(): + for t in NIGHTLY_TARGETS: + try: + gh(f"/repos/{REPO}/labels", method="POST", retry=False, + body={"name": store.target_label(t), "color": "1d76db", + "description": f"Nightly {t} target"}) + except urllib.error.HTTPError: + pass # 422 = already exists + for name, color, desc in [ + (store.LABEL, "b60205", "Filed by the nightly examples triage"), + (store.LABEL_MUTE, "ededed", "Triage will not touch this issue"), + (store.LABEL_UNCONFIRMED, "d4c5f9", "Retry did not run; not double-confirmed"), + ]: + try: + gh( + f"/repos/{REPO}/labels", + method="POST", + body={"name": name, "color": color, "description": desc}, + retry=False, + ) + except urllib.error.HTTPError: + pass # 422 = already exists + + +def previous_job_count(): + """Baseline for the circuit breaker: the last COMPLETED nightly's job count.""" + try: + runs = gh( + f"/repos/{REPO}/actions/workflows/nightly.yml/runs" + f"?status=completed&per_page=2" + ).get("workflow_runs", []) + for r in runs: + if str(r["id"]) != str(RUN_ID): + return len(all_jobs(r["id"])) + except Exception: + pass + return 0 + + +def run_url(): + return f"https://github.com/{REPO}/actions/runs/{RUN_ID}" + + +def apply(eid, observation, issue, ai, state, rows, close_allowed, target): + """Returns the issue number now tracking this dir, or None.""" + now = datetime.now(timezone.utc).strftime("%Y-%m-%d") + action, why = store.decide(observation, issue, close_allowed) + num = (issue or {}).get("number") + + if action == "noop": + print(f" {eid}: noop ({why})") + return num + if DRY_RUN: + print(f" {eid}: WOULD {action} ({why})") + return num + + body = store.render_body(eid, state, ai, rows, run_url(), now) + + if action == "open": + body_kw = { + "title": f"CI: `{eid}` failing in the nightly", + "body": body, + "labels": [store.LABEL, store.target_label(target)] + + ([store.LABEL_UNCONFIRMED] if observation == store.UNCONFIRMED else []), + # wolfHSM assigns its nightly issues to the bot; retried + # without it below if the account is not assignable here. + "assignees": ["wolfSSL-Bot"], + } + try: + created = gh(f"/repos/{REPO}/issues", method="POST", body=body_kw) + except urllib.error.HTTPError: + # not assignable in this repo; file it anyway rather than lose it + body_kw.pop("assignees", None) + created = gh(f"/repos/{REPO}/issues", method="POST", body=body_kw) + num = created["number"] + print(f" {eid}: opened #{num} ({why})") + elif action == "reopen": + gh( + f"/repos/{REPO}/issues/{issue['number']}", + method="PATCH", + body={"state": "open", "body": body}, + ) + gh( + f"/repos/{REPO}/issues/{issue['number']}/comments", + method="POST", + body={"body": f"Failing again in the nightly. [Run]({run_url()})"}, + ) + print(f" {eid}: reopened #{issue['number']} ({why})") + elif action == "update": + gh(f"/repos/{REPO}/issues/{issue['number']}", method="PATCH", body={"body": body}) + # A comment every night, so the thread IS the history. wolfHSM #412 does + # this with a bare "Still failing as of " x15; carry the verdict, + # the retry outcome and what changed instead, so a reader can skim the + # thread and see how the failure evolved. + reason = store.material_change(store.parse_state(issue.get("body", "")), state) + gh( + f"/repos/{REPO}/issues/{issue['number']}/comments", + method="POST", + body={"body": store.render_comment(state, ai, observation, reason, + run_url(), now)}, + ) + print(f" {eid}: updated #{issue['number']} + comment" + + (f" ({reason})" if reason else "")) + elif action == "close": + gh( + f"/repos/{REPO}/issues/{issue['number']}/comments", + method="POST", + body={"body": f"{why.capitalize()} — closing. [Run]({run_url()})"}, + ) + gh( + f"/repos/{REPO}/issues/{issue['number']}", + method="PATCH", + body={"state": "closed", "state_reason": "completed"}, + ) + print(f" {eid}: closed #{issue['number']} ({why})") + num = None + + return num + + +def report(attempt, retry_note): + results = merged_results(RUN_ID, attempt) + obs, fail_refs, targets = classify(RUN_ID, attempt, retry_note) + + logs = defaultdict(str) + for r in results: + if r["status"] == "fail" and r.get("log"): + logs[r["id"]] += r["log"] + + issues = {store.parse_fp(i.get("body", "")): i for i in open_issues()} + issues.pop(None, None) + + urls = job_urls(RUN_ID) + total = len(all_jobs(RUN_ID)) + prev = previous_job_count() + close_allowed = not (prev and total < 0.5 * prev) + if not close_allowed: + print( + f"CIRCUIT BREAKER: {total} jobs vs {prev} last nightly (<50%). " + "Refusing to close anything this run.", + file=sys.stderr, + ) + + failing = [e for e, o in obs.items() if o in (store.REAL, store.UNCONFIRMED)] + now = datetime.now(timezone.utc).strftime("%Y-%m-%d") + + ai_input = [] + for eid in failing: + old = store.parse_state(issues.get(eid, {}).get("body", "")) + ai_input.append( + { + "id": eid, + "refs": fail_refs.get(eid, []), + "streak": old.get("streak", 0) + 1, + "log": logs.get(eid, "(no log captured)"), + } + ) + verdicts = ai_batch(ai_input) + + if not DRY_RUN: + ensure_labels() + + print(f"\n{len(failing)} real failure(s), attempt {attempt}" + f"{' — ' + retry_note if retry_note else ''}\n") + + filed = {} + for eid, observation in sorted(obs.items()): + issue = issues.get(eid) + old = store.parse_state(issue.get("body", "")) if issue else {} + sig = ( + store.signature(logs[eid]) + if logs.get(eid) + else old.get("sig", "unknown") + ) + opens = old.get("opens", 0) + (1 if not issue or issue.get("state") == "closed" else 0) + sticky = old.get("sticky", False) or opens >= 3 + state = { + "opens": opens, + "first": old.get("first", now), + "last_fail": now, + "streak": old.get("streak", 0) + 1 if observation != store.PASS else 0, + "sig": sig, + "sticky": sticky, + # Written, not just read: without this a sticky issue re-reports + # "flapping" every night -- the exact spam material_change forbids. + "flaky_noted": old.get("flaky_noted", False) or sticky, + "failing": fail_refs.get(eid, []) if observation != store.PASS else [], + "log": logs.get(eid, "")[-LOG_TAIL_CHARS:], + } + # The real failing target + its error + a link to the job that ran it. + # This used to be a hardcoded "-" profile column and a bare ":x: fail", + # which told a reader nothing they could act on. + rows = [ + { + "test": r.get("target") or r.get("stage", "build"), + "ref": r.get("ref", "?"), + "detail": (r.get("detail") or "").strip(), + "url": urls.get((eid, r.get("ref"))), + } + for r in results + if r["id"] == eid and r["status"] == "fail" + ] + # cross targets emit no results rows, so fall back to the job itself + if not rows and observation != store.PASS: + rows = [ + {"test": eid, "ref": ref, "detail": "job failed", + "url": urls.get((eid, ref))} + for ref in fail_refs.get(eid, ["unknown"]) + ] + # collected, not read back from `issues`: a dir filed for the first time + # tonight is not in that map, and its card entry would have no link + filed[eid] = apply(eid, observation, issue, verdicts.get(eid), state, rows, + close_allowed, targets.get(eid, "examples")) + + +def main(): + run = gh(f"/repos/{REPO}/actions/runs/{RUN_ID}") + attempt = int(run.get("run_attempt", 1)) + retry_note = "" + + if AUTO_RETRY and attempt == 1: + nonpass = [ + j for j in all_jobs(RUN_ID) if j.get("conclusion") in ("failure", "cancelled") + ] + if nonpass: + print(f"{len(nonpass)} non-passing job(s); retrying once and waiting...") + attempt, retry_note = rerun_and_wait(RUN_ID) + if retry_note: + print(f"note: {retry_note}", file=sys.stderr) + + try: + report(attempt, retry_note) + except Exception: + # A broken reporter must not be a silent reporter. + print("TRIAGE CRASHED:\n" + traceback.format_exc(), file=sys.stderr) + raise + + +if __name__ == "__main__": + main() diff --git a/.github/scripts/issue_store.py b/.github/scripts/issue_store.py new file mode 100644 index 000000000..acfbef805 --- /dev/null +++ b/.github/scripts/issue_store.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python3 +"""Issue identity, body rendering, and the open/close state machine. + +Identity is an HTML marker matched in-process against the REST *list* endpoint, +never the Search API: `is:issue in:body` is eventually consistent, so a search +that misses files a duplicate. `GET /issues?labels=...&state=open` hits the +primary DB, is strongly consistent, and returns bodies. +""" + +import hashlib +import json +import re + +LABEL = "ci:nightly" +# ci: -- the nightly job that failed (examples, esp32, android, ...). +# Added only when that target fails, so a green night adds no labels. +def target_label(target): + return f"ci:{target}" + +LABEL_MUTE = "ci:mute" +LABEL_UNCONFIRMED = "ci:unconfirmed" + +FP_RE = re.compile(r"") +STATE_RE = re.compile(r"", re.S) + +# Secrets are scrubbed before anything reaches a PUBLIC issue tracker -- both +# log tails and every AI-authored field (a model can quote a secret back). +SCRUB = [ + (re.compile(r"gh[pousr]_[A-Za-z0-9]{20,}"), "***token***"), + (re.compile(r"(?i)bearer\s+[A-Za-z0-9._\-]+"), "Bearer ***"), + ( + re.compile( + r"(?i)(x-api-key|authorization|password|secret|token)(['\"\s:=]+)\S+" + ), + r"\1\2***", + ), + ( + re.compile(r"eyJ[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}\.[A-Za-z0-9_\-]{8,}"), + "***jwt***", + ), + (re.compile(r"sk-ant-[A-Za-z0-9_\-]{10,}"), "***anthropic-key***"), +] + + +def scrub(text): + if not text: + return text + for pat, repl in SCRUB: + text = pat.sub(repl, text) + return text + + +# --- failure signature ----------------------------------------------------- +# +# Deterministic, derived from the log -- never from the AI's prose, which wobbles +# run to run and would produce a "changed" comment every night. + +ERR_RE = re.compile( + r"^.*?(?:\berror\b|undefined reference|Assertion .* failed|" + r"Segmentation fault|No rule to make target|identity gate).*$", + re.M | re.I, +) +NORM = [ + # Drop the directory prefix entirely, not down to a leading "/": the same + # error under /home/runner/... and a relative path must hash identically, + # or every run reports a "signature changed" and the bot spams. + (re.compile(r"[\w./+-]*/"), ""), + (re.compile(r":\d+(:\d+)?\b"), ":N"), + (re.compile(r"0x[0-9a-fA-F]+"), "0xADDR"), + (re.compile(r"\b\d+\b"), "N"), +] + + +def signature(log): + """Stable hash of what broke. Normalising paths and line numbers means an + upstream whitespace shift does not notify, but a changed symbol does.""" + lines = ERR_RE.findall(log or "")[:3] + if not lines: + return "unknown" + text = "\n".join(lines).lower() + for pat, repl in NORM: + text = pat.sub(repl, text) + return hashlib.sha256(text.encode()).hexdigest()[:12] + + +# --- body ------------------------------------------------------------------ + + +def parse_fp(body): + m = FP_RE.search(body or "") + return m.group(1) if m else None + + +def parse_state(body): + m = STATE_RE.search(body or "") + if not m: + return {} + try: + return json.loads(m.group(1)) + except json.JSONDecodeError: + return {} + + +def render_body(eid, state, ai, failing_rows, run_url, now): + # The log never goes in the state marker. An HTML comment is invisible in + # rendered markdown but fully readable via the API and the raw view, so an + # unscrubbed log there is a silent leak into a PUBLIC tracker. + log = state.get("log", "") + marker = {k: v for k, v in state.items() if k != "log"} + lines = [ + f"", + f"", + "", + f"**`{eid}`** is failing in the nightly — " + f"{state.get('streak', 1)} night(s) running, since {state.get('first', now)}.", + "", + ] + + if ai: + lines += [ + f"### {ai.get('severity', '?')} · {ai.get('category', '?')} · " + f"affects {ai.get('blast', '?')}", + "", + f"- **Symptom** — {scrub(ai.get('symptom', ''))}", + f"- **Likely cause** — {scrub(ai.get('cause', ''))}", + f"- **Next** — {scrub(ai.get('next', ''))}", + "", + ] + + # "wolfSSL" not "wolfSSL ref": the column answers "which wolfSSL broke it", + # and master-vs-stable is the single most useful fact here -- a stable-only + # break is a released bug, a master-only one is upstream drift. + lines += [ + "### What failed", + "", + "| test | wolfSSL | error |", + "|---|---|---|", + ] + for row in failing_rows: + test = f"`{row['test']}`" + if row.get("url"): + test = f"[{test}]({row['url']})" + detail = (row.get("detail") or "").replace("|", "\\|")[:120] or "—" + lines.append(f"| {test} | `{row['ref']}` | {detail} |") + lines.append("") + + if ai and ai.get("upstream"): + lines += [ + "> Fails only against wolfSSL `master` and passes on stable — this " + "is more likely a wolfSSL regression than an example bug. Consider " + "filing against wolfSSL/wolfssl.", + "", + ] + + if state.get("log"): + lines += [ + "
log tail", + "", + "```", + scrub(state["log"]), + "```", + "", + "
", + "", + ] + + lines += [ + "---", + f"*Filed automatically by [ci-triage]({run_url}). Body updated {now} UTC.*", + f"*Add the `{LABEL_MUTE}` label to stop all updates. Closing as " + f"**not planned** prevents reopening.*", + ] + return "\n".join(lines) + + +# --- state machine --------------------------------------------------------- + +PASS = "pass" +REAL = "real" +FLAKE_ONLY = "flake_only" +ABSENT = "absent" +UNCONFIRMED = "unconfirmed" + + +def decide(observation, issue, close_allowed=True): + """Return (action, comment_reason). + + action: open | comment | update | close | reopen | noop + """ + labels = {l["name"] if isinstance(l, dict) else l for l in (issue or {}).get("labels", [])} + + if issue and LABEL_MUTE in labels: + return "noop", "muted" + if issue and issue.get("state_reason") == "not_planned": + return "noop", "wontfix" + + if observation == ABSENT: + # Absence of evidence is not recovery. Only an observed pass closes. + return "noop", "absent from this run" + + if observation == PASS: + if issue and issue.get("state") == "open": + if not close_allowed: + return "update", "circuit breaker: refusing to close" + if parse_state(issue.get("body", "")).get("sticky"): + return "update", "sticky (flaky): human closes" + return "close", "passing again" + return "noop", "passing" + + if observation == FLAKE_ONLY: + # A flake is a failure a retry hid, not a pass. It used to fall in with + # PASS above, so a dir that flaked every night closed its own issue every + # night and left no trace -- which is how the dtls resume flake stayed + # invisible until two runs were diffed by hand. Only a clean night closes. + if not issue: + return "open", "flaked and recovered on retry" + if issue.get("state") == "closed": + return "reopen", "flaked again" + return "update", "flaked and recovered on retry" + + # REAL or UNCONFIRMED + if not issue: + return "open", "first failure" + if issue.get("state") == "closed": + return "reopen", "failing again" + return "update", "still failing" + + +def render_comment(state, ai, observation, reason, run_url, now): + """One comment per night, so the thread carries the history. + + wolfHSM's nightly posts a bare "Still failing as of " -- 15 of them on + one issue, none of which say what happened. Carry the verdict and the retry + outcome, so the thread is readable rather than just long. + """ + n = state.get("streak", 1) + verdict = ("**Real** — retried once, failed again." if observation == REAL + else "**Unconfirmed** — the retry did not complete, so this is " + "not double-checked.") + lines = [ + f"**Night {n}** · [run]({run_url}) · {now}", + "", + verdict, + ] + if reason: + lines += ["", f"Changed since last night: **{reason}**."] + if ai: + lines += ["", f"`{ai.get('severity', '?')}` · {scrub(ai.get('symptom', ''))}"] + if ai.get("next"): + lines.append(f"_next:_ {scrub(ai.get('next', ''))}") + refs = state.get("failing") or [] + if refs: + lines += ["", f"Failing on: {', '.join(f'`{r}`' for r in refs)}"] + return "\n".join(lines) + + +def material_change(old_state, new_state): + """Comment only on a material change. Body edits are silent; comments notify, + and a comment every night on a long-standing break gets the bot muted.""" + if not old_state: + return "first failure" + if old_state.get("sig") != new_state.get("sig"): + return "failure signature changed" + new_refs = set(new_state.get("failing", [])) - set(old_state.get("failing", [])) + if new_refs: + return f"now also failing on {', '.join(sorted(new_refs))}" + if not old_state.get("flaky_noted") and new_state.get("sticky"): + return "flapping: 3rd open in 14 days" + return None diff --git a/.github/scripts/manifest.py b/.github/scripts/manifest.py new file mode 100644 index 000000000..a7843e326 --- /dev/null +++ b/.github/scripts/manifest.py @@ -0,0 +1,430 @@ +#!/usr/bin/env python3 +"""Read examples-manifest.yml: emit the CI matrix, or gate coverage.""" + +import argparse +import collections +import json +import re +import subprocess +import sys +from pathlib import Path + +REPO = Path(__file__).resolve().parents[2] +MANIFEST = REPO / ".github" / "examples-manifest.yml" + +# Dirs that are not examples and never will be. +NOT_EXAMPLES = {".git", ".github", "certs"} + +# A dir is "buildable source" -- and therefore must be accounted for -- if it +# holds any of these. Gating on Makefile alone missed SGX (own scripts), Android +# (gradle), ESP32 (idf/cmake) and the README-gcc-one-liner dirs, which is exactly +# the "someone added an example and forgot to wire it up" case the gate exists for. +BUILD_MARKERS = ("Makefile", "CMakeLists.txt", "build.gradle", "build.gradle.kts") + +# Project files are named after their project, so they match by suffix, not name. +# A .sln is a container for these, not a build unit itself. +BUILD_MARKER_SUFFIXES = (".csproj", ".vcxproj") + +# Not just .c: an example written in another language is still an example, and a +# gate that cannot see it cannot force a decision about it. .ino in particular +# looked covered -- arduino.yml compiles the examples inside the *installed* +# Arduino wolfSSL library, not this repo's Arduino/sketches/*. +SOURCE_SUFFIXES = (".c", ".ino", ".java", ".cpp", ".cs") + +# Dirs that carry a build marker but are not independently buildable units: +# IDE projects, generated tool config, and subproject components. +NOISE = ( + "/VisualGDB", # IDE projects mirroring a parent Makefile's targets + "/.config/", # generated CCS/XDC config under tirtos_ccs_examples + "/components/", # ESP-IDF components of a parent project + "/wolfssl_library/", # the Arduino template's bundled library, not a unit + "/src/com/", # java package tree of an android project declared above it +) + + +def is_noise(d): + s = f"/{d}/" + return any(n in s for n in NOISE) or d.endswith("/main") + + +def load(path=MANIFEST): + try: + import yaml + except ImportError: + sys.exit("PyYAML required: pip install pyyaml") + with open(path) as fh: + data = yaml.safe_load(fh) + validate(data) + return data + + +def validate(data): + profiles = data.get("profiles") or {} + seen = set() + for e in data.get("examples") or []: + for key in ("id", "path"): + if key not in e: + sys.exit(f"manifest: entry missing '{key}': {e}") + if e["id"] in seen: + sys.exit(f"manifest: duplicate id '{e['id']}'") + seen.add(e["id"]) + mode = e.get("mode", "run") + if mode not in ("run", "build-only", "skip"): + sys.exit(f"manifest: {e['id']}: bad mode '{mode}'") + if mode == "skip" and not e.get("reason"): + sys.exit(f"manifest: {e['id']}: mode 'skip' requires a 'reason'") + tier = e.get("tier", "host") + if tier not in ("host", "emulated", "cross"): + sys.exit(f"manifest: {e['id']}: bad tier '{tier}'") + # A host example that only builds is an untested example, so say why. + # Cross-tier entries are exempt: for a cross-compile target, building is + # the test. + if mode == "build-only" and tier == "host" and not e.get("reason"): + sys.exit( + f"manifest: {e['id']}: host 'build-only' requires a 'reason'.\n" + "Add a run: recipe, or state why it cannot run in CI." + ) + if mode != "skip": + if not e.get("profile"): + sys.exit(f"manifest: {e['id']}: needs a 'profile'") + if e["profile"] not in profiles: + sys.exit(f"manifest: {e['id']}: unknown profile '{e['profile']}'") + if not (REPO / e["path"]).is_dir(): + sys.exit(f"manifest: {e['id']}: path does not exist: {e['path']}") + + +def job_built_paths(): + """Paths some cross-tier workflow actually builds. + + Read from the workflows rather than declared in the manifest: a manifest + that states its own coverage would just agree with itself. + """ + import yaml + wf_dir = REPO / ".github/workflows" + # one workflow per target, so scan them all rather than a single file + paths = set() + jobs_seen = set() + for f in sorted(wf_dir.glob("*.yml")): + try: + wf = yaml.safe_load(f.read_text()) + except Exception: + continue + if not isinstance(wf, dict): + continue + for name, job in (wf.get("jobs") or {}).items(): + if not isinstance(job, dict): + continue + jobs_seen.add(name) + matrix = ((job.get("strategy") or {}).get("matrix") or {}) + for item in matrix.get("example") or []: + if isinstance(item, str): + paths.add(item) + for item in matrix.get("include") or []: + if isinstance(item, dict) and isinstance(item.get("example"), str): + paths.add(item["example"]) + + # arduino.yml runs compile-all-examples.sh over board_list.txt, so it covers + # every sketch dir rather than naming them in a matrix + if (REPO / ".github/workflows/arduino.yml").is_file(): + for d in (REPO / "Arduino/sketches").glob("*/"): + if d.is_dir(): + paths.add("Arduino/sketches/" + d.name) + # jobs that build one hardcoded dir rather than a matrix + # csharp: the client is the peer in every matrix leg rather than an axis + for job, path in (("puf", "puf"), ("rpi-pico", "RPi-Pico"), + ("fullstack", "fullstack/freertos-wolfip-wolfssl-https"), + ("java", "java/https-url"), ("rt1060", "RT1060"), + ("csharp", "CSharp/wolfSSL-TLS-pq-Client"), + ("psa", "psa"), + ("bsdkm", "kernel/bsdkm"), + ("cmake", "cmake")): + if job in jobs_seen: + paths.add(path) + # the pico job builds the whole cmake tree, so its subdirs come with it + pico = REPO / "RPi-Pico/CMakeLists.txt" + if pico.is_file() and "RPi-Pico" in paths: + for sub in re.findall(r"add_subdirectory\(([^)]+)\)", pico.read_text()): + paths.add("RPi-Pico/" + sub.strip().strip('"').strip("'")) + return paths + + +def emulated_jobs(): + emul = (REPO / ".github/workflows/emulated.yml").read_text() + body = emul.split("\njobs:", 1)[-1] + return set(re.findall(r"^ ([a-z0-9][a-z0-9-]*):$", body, re.M)) + + +def validate_has_job(data): + """A cross/emulated entry that is not skipped must be built by some job. + + Without this, `mode: build-only` on an entry no workflow touches reads as + covered while nothing compiles it. + """ + built = job_built_paths() + emul = emulated_jobs() + orphans = [] + for e in data.get("examples") or []: + tier = e.get("tier", "host") + if tier not in ("cross", "emulated") or e.get("mode", "run") == "skip": + continue + if tier == "emulated": + # emulated ids are the job names (sgx-linux -> sgx) + if not any(j == e["id"] or e["id"].startswith(j) for j in emul): + orphans.append(e["id"]) + continue + p = e["path"] + if not any(p == b or p.startswith(b + "/") for b in built): + orphans.append(e["id"]) + if orphans: + sys.exit( + "manifest: no job builds these, so 'build-only' is not true:\n " + + "\n ".join(orphans) + + "\n\nAdd a job, or set mode: skip with a reason." + ) + + +def buildable_dirs(): + """Topmost buildable units, relative to the repo root. + + A dir counts only if no ancestor already has a build marker -- otherwise + tls/VisualGDB-tls/* (28 IDE subdirs under tls/Makefile) and ESP32/*/main + (an ESP-IDF component of its parent project) would each demand an entry. + """ + tracked = subprocess.run( + ["git", "ls-files"], cwd=REPO, capture_output=True, text=True, check=True + ).stdout.splitlines() + + marker_dirs, source_dirs = set(), set() + for f in tracked: + p = Path(f) + if not p.parts or p.parts[0] in NOT_EXAMPLES: + continue + if p.name in BUILD_MARKERS or p.suffix in BUILD_MARKER_SUFFIXES: + marker_dirs.add(str(p.parent)) + elif p.suffix in SOURCE_SUFFIXES and len(p.parts) > 1: + source_dirs.add(str(p.parent)) + + def has_buildable_ancestor(d): + return any(str(a) in marker_dirs for a in Path(d).parents if str(a) != ".") + + # A dir with its own build marker is its own unit (signature/rsa_buffer has a + # Makefile independent of signature/'s). A dir with only .c is a unit just + # when nothing above it builds -- otherwise every ESP-IDF source subdir counts. + units = {d for d in marker_dirs} + units |= {d for d in source_dirs if not has_buildable_ancestor(d)} + return {d for d in units if not is_noise(d)} + + +def cmd_check(data): + validate_has_job(data) + declared = {e["path"] for e in data["examples"]} + actual = buildable_dirs() + + missing = sorted(actual - declared) + stale = sorted(d for d in declared - actual if not (REPO / d).is_dir()) + + if stale: + print("Manifest entries whose path no longer exists:", file=sys.stderr) + for d in stale: + print(f" {d}", file=sys.stderr) + + if missing: + print( + "\nThese dirs hold buildable source but are not in " + ".github/examples-manifest.yml.\nAdd an entry, or add one with " + "`mode: skip` and a `reason:`.\n", + file=sys.stderr, + ) + for d in missing: + print(f" {d}", file=sys.stderr) + + if missing or stale: + sys.exit(1) + print(f"coverage: ok ({len(declared)} entries cover {len(actual)} buildable dirs)") + + # The job count is one per entry per ref whatever the mode, so it never moves + # when an example is promoted. Print the tally, or a reviewer cannot see it. + modes = collections.Counter(e.get("mode", "run") for e in data["examples"]) + asserts = sum( + 1 + for e in data["examples"] + for s in (e.get("run") or []) + if isinstance(s, dict) and "expect" in s + ) + xfails = sum( + 1 + for e in data["examples"] + for s in (e.get("run") or []) + if isinstance(s, dict) and "expect_fail" in s + ) + print( + f"tested: {modes['run']} run, {modes['build-only']} build-only, " + f"{modes['skip']} skip -- {asserts} output assertions, {xfails} known-fail" + ) + + +def live_entries(data, tier): + return [ + e + for e in data["examples"] + if e.get("mode") != "skip" and e.get("tier", "host") == tier + ] + + +def entry_refs(entry, refs): + ref = entry.get("wolfssl_ref") + return [ref] if ref else refs + + +def cmd_matrix(data, refs, tier, shas=None): + """One matrix entry per (example, ref) -- each example is its own job. + + A profile is a property of a directory, never an axis: pk/rsa is only ever + 'fastmath'. Never cross profiles x examples. + + `shas` pins each ref to a commit resolved once upstream, so every job shares + one cache key instead of racing a moving branch. + """ + pinned = dict(zip(refs, shas)) if shas else {} + out = [] + for e in sorted(live_entries(data, tier), key=lambda x: x["id"]): + p = data["profiles"][e["profile"]] + # wolfssl_ref pins one example to a specific ref (e.g. refs/pull/N/head) + # while a fix is in flight upstream. setup-wolfssl still resolves it to a + # sha, so the cache key stays sha-based. + for ref in entry_refs(e, refs): + out.append( + { + "id": e["id"], + "path": e["path"], + "profile": e["profile"], + # in the job title, so a green tile says whether it ran or + # only compiled instead of implying more than it proves + "mode_label": "Build" if e.get("mode") == "build-only" else "Run", + "wolfssl_ref": ref, + # refs/pull/N/head has slashes; anything used in a filename or + # artifact name needs the slug, not the ref. + "ref_slug": ref.replace("/", "-"), + "wolfssl_sha": pinned.get(ref, ref), + "flags": " ".join(p.get("flags", "").split()), + "cflags": p.get("cflags", ""), + "deps": " ".join(e.get("deps") or []), + } + ) + if len(out) > 256: + sys.exit( + f"matrix would be {len(out)} jobs; GitHub caps a matrix at 256.\n" + "Reduce refs, or split this tier across workflows." + ) + print(json.dumps(out)) + + +def cmd_wolfssl_matrix(data, refs, tier, shas=None): + """The distinct (profile, ref) builds this tier needs. + + Built once each and cached, so the per-example jobs restore rather than + rebuild -- otherwise every example pays a full wolfSSL build. + """ + pinned = dict(zip(refs, shas)) if shas else {} + profiles = sorted({e["profile"] for e in live_entries(data, tier)}) + out = [ + { + "profile": name, + "wolfssl_ref": ref, + "wolfssl_sha": pinned.get(ref, ref), + "flags": " ".join(data["profiles"][name].get("flags", "").split()), + "cflags": data["profiles"][name].get("cflags", ""), + } + for name in profiles + for ref in refs + ] + # A pinned example needs its (profile, ref) seeded too, or its job pays a + # full wolfSSL build on every run. + for e in live_entries(data, tier): + ref = e.get("wolfssl_ref") + if ref and not any( + o["profile"] == e["profile"] and o["wolfssl_ref"] == ref for o in out + ): + out.append( + { + "profile": e["profile"], + "wolfssl_ref": ref, + "wolfssl_sha": pinned.get(ref, ref), + "flags": " ".join( + data["profiles"][e["profile"]].get("flags", "").split() + ), + "cflags": data["profiles"][e["profile"]].get("cflags", ""), + } + ) + print(json.dumps(out)) + + +def cmd_skips(data): + """Report every dir CI does not build, and why. Generated, never hand-kept.""" + skips = sorted( + (e for e in data["examples"] if e.get("mode") == "skip"), + key=lambda e: e["path"], + ) + bo = sorted( + (e for e in data["examples"] if e.get("mode") == "build-only"), + key=lambda e: e["path"], + ) + print(f"# Directories CI does not run\n") + print(f"Generated by `manifest.py skips` from `.github/examples-manifest.yml`.\n") + print(f"{len(skips)} not built at all; {len(bo)} built but not run.\n") + print("## Not built\n") + print("| directory | why |") + print("|---|---|") + for e in skips: + print(f"| `{e['path']}` | {e['reason']} |") + print("\n## Built, but not run\n") + print("| directory | why not run |") + print("|---|---|") + for e in bo: + print(f"| `{e['path']}` | {e.get('reason', 'no run recipe wired yet')} |") + + +def cmd_profiles(data): + """Emit the distinct profiles a matrix needs to build, with their flags.""" + used = {e["profile"] for e in data["examples"] if e.get("mode") != "skip"} + out = [ + { + "profile": name, + "flags": data["profiles"][name].get("flags", "").strip(), + "cflags": data["profiles"][name].get("cflags", ""), + } + for name in sorted(used) + ] + print(json.dumps(out)) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument( + "command", choices=["check", "matrix", "wolfssl-matrix", "profiles", "skips"] + ) + ap.add_argument("--refs", default="master", help="comma-separated wolfSSL refs") + ap.add_argument("--shas", default="", help="commit SHAs for --refs, same order") + ap.add_argument("--tier", default="host", choices=["host", "emulated", "cross"]) + args = ap.parse_args() + + refs = args.refs.split(",") + shas = args.shas.split(",") if args.shas else None + if shas and len(shas) != len(refs): + sys.exit(f"--shas has {len(shas)} entries but --refs has {len(refs)}") + + data = load() + if args.command == "check": + cmd_check(data) + elif args.command == "matrix": + cmd_matrix(data, refs, args.tier, shas) + elif args.command == "wolfssl-matrix": + cmd_wolfssl_matrix(data, refs, args.tier, shas) + elif args.command == "skips": + cmd_skips(data) + else: + cmd_profiles(data) + + +if __name__ == "__main__": + main() diff --git a/.github/scripts/run_example.py b/.github/scripts/run_example.py new file mode 100644 index 000000000..2cb84ebdb --- /dev/null +++ b/.github/scripts/run_example.py @@ -0,0 +1,741 @@ +#!/usr/bin/env python3 +"""Build and run one example directory from .github/examples-manifest.yml.""" + +import argparse +import json +import os +import shlex +import shutil +import signal +import subprocess +import sys +import time +from pathlib import Path + +REPO = Path(__file__).resolve().parents[2] +MANIFEST = REPO / ".github" / "examples-manifest.yml" +NETNS_SENTINEL = "WOLFEX_IN_NETNS" +LISTEN = "0A" + + +def load_manifest(): + sys.path.insert(0, str(Path(__file__).resolve().parent)) + import manifest as mf + + return mf, mf.load(MANIFEST) + + +# --- wolfSSL identity gate ------------------------------------------------- +# +# 5 host-tier Makefiles link -lwolfssl with no -I/-L and cannot be pointed at a +# prefix, so a path assertion is meaningless. Assert instead that exactly one +# libwolfssl is visible to the linker and that it is the one this job built. + + +def visible_libwolfssl(): + out = subprocess.run( + ["ldconfig", "-p"], capture_output=True, text=True + ).stdout + paths = set() + for line in out.splitlines(): + if "libwolfssl" in line and "=>" in line: + paths.add(os.path.realpath(line.split("=>")[-1].strip())) + for extra in ("/usr/local/lib", "/usr/lib", "/usr/lib64"): + d = Path(extra) + if d.is_dir(): + for p in d.glob("libwolfssl.so*"): + paths.add(os.path.realpath(p)) + return {p for p in paths if Path(p).exists()} + + +def sha256(path): + out = subprocess.run( + ["sha256sum", str(path)], capture_output=True, text=True, check=True + ).stdout + return out.split()[0] + + +def assert_identity(expect_sha): + found = visible_libwolfssl() + if not found: + sys.exit("identity gate: no libwolfssl visible to the linker at all") + shas = {p: sha256(p) for p in sorted(found)} + bad = {p: s for p, s in shas.items() if s != expect_sha} + if bad: + for p, s in bad.items(): + print(f" {p}\n sha256 {s}", file=sys.stderr) + print(f" expected sha256 {expect_sha}", file=sys.stderr) + sys.exit( + "identity gate: a libwolfssl that this job did not build is visible.\n" + "A green run here would have tested the wrong library." + ) + print(f"identity gate: ok ({len(shas)} lib(s), all sha256 {expect_sha[:12]})") + + +def assert_binary_links_ours(binary, expect_sha): + out = subprocess.run( + ["ldd", str(binary)], capture_output=True, text=True + ).stdout + for line in out.splitlines(): + if "libwolfssl" in line and "=>" in line: + resolved = os.path.realpath(line.split("=>")[1].split("(")[0].strip()) + if sha256(resolved) != expect_sha: + sys.exit(f"identity gate: {binary} links a foreign libwolfssl: {resolved}") + return "dynamic" + # Statically linked (or no wolfSSL): the job-level gate above already proved + # only our libwolfssl exists on this box, so it can only have come from ours. + return "static-or-none" + + +# --- network namespace ----------------------------------------------------- +# +# tls/server-tls.c has no SO_REUSEADDR and is the active closer, so port 11111 +# sits in TIME_WAIT ~60s. Serializing pairs is the WORST case (back-to-back +# binds). A private netns per run gives each pair its own port space. + + +USERNS = ["unshare", "--user", "--map-root-user", "--net"] +SUDONS = ["sudo", "-n", "-E", "unshare", "--net"] + + +def _works(argv): + return subprocess.run(argv + ["--", "true"], capture_output=True).returncode == 0 + + +def netns_prefix(): + """Pick a way to get a private netns with a usable loopback, or None. + + Probe the EXACT invocation we intend to run. `unshare --user --net true` + succeeds without a uid mapping and proves nothing: --map-root-user then + fails writing /proc/self/uid_map, which is the capability `ip link set lo up` + actually needs. + """ + if _works(USERNS): + return USERNS + # ubuntu 24.04 ships kernel.apparmor_restrict_unprivileged_userns=1 + subprocess.run( + ["sudo", "-n", "sysctl", "-w", "kernel.apparmor_restrict_unprivileged_userns=0"], + capture_output=True, + ) + if _works(USERNS): + return USERNS + # Root netns: no userns needed. Costs root-owned artifacts, which is fine on + # an ephemeral runner where the build already happened as the normal user. + if _works(SUDONS): + return SUDONS + return None + + +def describe_net(): + """One line of ground truth about the network we ended up in.""" + import socket + ns = os.readlink("/proc/self/ns/net") if os.path.exists("/proc/self/ns/net") else "?" + v6 = "no" + try: + sk = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + sk.bind(("::1", 0)) + sk.close() + v6 = "yes" + except OSError as e: + v6 = f"no ({e.errno})" + print(f"net: ns={ns} ipv6-loopback={v6}", flush=True) + + +def ensure_netns(): + """Re-exec self inside a private netns. Idempotent via sentinel.""" + if os.environ.get(NETNS_SENTINEL): + return + prefix = netns_prefix() + if prefix is None: + sys.exit( + "no way to obtain a private network namespace: unprivileged userns is\n" + "blocked (ubuntu 24.04 apparmor_restrict_unprivileged_userns), the\n" + "sysctl did not take, and passwordless sudo is unavailable.\n" + "Re-run with --no-netns to accept TIME_WAIT flakes on port 11111." + ) + print(f"netns via: {' '.join(prefix)}", flush=True) + env = dict(os.environ, **{NETNS_SENTINEL: "1"}) + argv = [sys.executable, os.path.abspath(__file__)] + sys.argv[1:] + # A fresh netns can come up with ipv6 disabled, which makes ::1 unreachable + # and dtls/client-dtls-ipv6 fail wolfSSL_connect with -308. Enable it and let + # the kernel assign ::1 to lo. Both are namespaced, so this is local to us. + inner = ( + "ip link set lo up && " + "sysctl -qw net.ipv6.conf.lo.disable_ipv6=0 2>/dev/null; " + "exec " + " ".join(shlex.quote(a) for a in argv) + ) + os.execvpe(prefix[0], prefix + ["--", "sh", "-c", inner], env) + + +# --- readiness ------------------------------------------------------------- +# +# Never probe with connect(): it burns the server's single accept(), so +# wolfSSL_accept fails and server-tls.c:161 does `goto exit` -- the server dies +# and every pair test fails. Poll /proc/net/tcp for a LISTEN socket instead. +# We are inside the server's netns (see ensure_netns), so this is its table. + + +def wait_listen(port, timeout=10.0, proto="tcp"): + # DTLS is UDP: a bound udp socket never enters TCP's LISTEN state and never + # appears in /proc/net/tcp at all, so a bound port is the only readiness + # signal available. + want = f"{port:04X}" + paths = ("/proc/net/tcp", "/proc/net/tcp6") + if proto == "udp": + paths = ("/proc/net/udp", "/proc/net/udp6") + deadline = time.monotonic() + timeout + while time.monotonic() < deadline: + for path in paths: + try: + with open(path) as fh: + next(fh, None) + for line in fh: + col = line.split() + if len(col) > 3: + if proto == "tcp" and col[3] != LISTEN: + continue + if col[1].rsplit(":", 1)[-1].upper() == want: + return True + except FileNotFoundError: + pass + time.sleep(0.05) + return False + + +def reap(proc): + if proc.poll() is None: + try: + os.killpg(proc.pid, signal.SIGKILL) + except (ProcessLookupError, PermissionError): + pass + try: + proc.wait(timeout=5) + except subprocess.TimeoutExpired: + pass + + +# --- runners --------------------------------------------------------------- + + +# --- output assertions ----------------------------------------------------- +# +# ~30 examples are wrapped in a feature #ifdef whose #else is a stub main() that +# prints "requires --enable-foo" and returns 0. Checking only the exit code marks +# those a pass, so a profile missing a flag silently tests nothing. + +STUB_MARKERS = ( + "requires --enable", + "please define", + "not compiled in", + "must build wolfssl using", + "must build wolfssl with", + "example requires", + "please configure wolfssl with", + "please build wolfssl with", + "pk not compiled in", +) + + +def stub_output(out): + """Return the marker a rc==0 run printed, if it never really ran.""" + for line in (out or "").splitlines(): + low = line.lower() + for m in STUB_MARKERS: + if m in low: + return line.strip() + return None + + +def check_output(out, step): + """(ok, detail) for a step that already exited 0.""" + marker = stub_output(out) + if marker: + return False, f"built a stub, not the example: {marker!r}" + want = step.get("expect") if isinstance(step, dict) else None + if want and want not in (out or ""): + return False, f"expected {want!r} in output" + return True, "" + + +def run_exec(spec, cwd, env, timeout): + argv = spec if isinstance(spec, list) else shlex.split(spec) + try: + p = subprocess.Popen( + argv, + cwd=cwd, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + start_new_session=True, + ) + except FileNotFoundError: + return False, f"binary not found: {argv[0]}", "" + try: + out, _ = p.communicate(timeout=timeout) + except subprocess.TimeoutExpired: + # Keep whatever it printed before it wedged: "timeout" with no output + # says nothing about how far it got. + reap(p) + out, _ = p.communicate() + return False, f"timeout after {timeout}s", (out or "")[-2000:] + if p.returncode != 0: + return False, f"rc={p.returncode}", (out or "")[-2000:] + return True, "", out or "" + + +def start_bg(argv, cwd, env): + """Start a background peer, line buffered so its output survives a kill. + + A pipe makes stdout fully buffered, and SIGKILL then throws the buffer away + -- which is why every failing pair used to show an empty server side. + """ + if shutil.which("stdbuf"): + argv = ["stdbuf", "-oL", "-eL"] + list(argv) + return subprocess.Popen( + argv, + cwd=cwd, + env=env, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + start_new_session=True, + ) + + +def await_ready(proc, port, proto, ready_delay, ready_timeout, what="server"): + """Wait for a background peer. Returns (ok, headline, detail).""" + if port in (None, "none", 0): + # No socket to poll: give it a moment to open its transport. btle talks + # over FIFOs in /tmp and custom-io over files, so waiting for a LISTEN + # that never comes would fail every time. + time.sleep(ready_delay) + return True, "", "" + if wait_listen(port, ready_timeout, proto): + return True, "", "" + diag = [f"{what} never bound {proto} :{port}"] + if proc.poll() is not None: + diag.append(f"{what} already exited rc={proc.returncode}") + try: + diag.append((proc.stdout.read() or "")[-600:]) + except Exception: + pass + else: + diag.append(f"{what} still running but not listening") + for f in ("/proc/net/tcp", "/proc/net/tcp6", "/proc/net/udp", "/proc/net/udp6"): + try: + hits = [ + l.split()[1:4] + for l in open(f).read().splitlines()[1:] + if l.split()[1].rsplit(":", 1)[-1].upper() == f"{port:04X}" + ] + if hits: + diag.append(f"{f}: {hits}") + except (FileNotFoundError, IndexError): + pass + return False, diag[0], "\n".join(diag[1:]) + + +def run_pair(spec, cwd, env): + port = spec.get("port", 11111) + proto = spec.get("proto", "tcp") + timeout = spec.get("timeout", 30) + server_exit = spec.get("server_exit", "clean") + + srv = start_bg(spec["server"], cwd, env) + try: + ok, head, detail = await_ready( + srv, port, proto, spec.get("ready_delay", 2), spec.get("ready_timeout", 10) + ) + if not ok: + return False, head, detail + + try: + cli = subprocess.run( + spec["client"], + cwd=cwd, + env=env, + input=spec.get("stdin", ""), + capture_output=True, + text=True, + timeout=timeout, + ) + except subprocess.TimeoutExpired: + return False, f"client timeout after {timeout}s", "" + if cli.returncode != 0: + # The reason is usually on the server's side; a client rc with no + # server output is close to undiagnosable. + reap(srv) + try: + srv_out = (srv.stdout.read() or "")[-1200:] + except Exception: + srv_out = "(server output unavailable)" + return False, f"client rc={cli.returncode}", ( + "--- client ---\n" + (cli.stdout + cli.stderr)[-1200:] + + "\n--- server ---\n" + srv_out + ) + + if server_exit == "clean": + try: + rc = srv.wait(timeout=10) + except subprocess.TimeoutExpired: + return False, "server did not exit after client completed", "" + if rc != 0: + # Client rc==0 is necessary but not sufficient: the client can + # finish its exchange while the server dies in cleanup. + return False, f"client ok but server rc={rc}", (srv.stdout.read() or "")[-2000:] + else: + os.killpg(srv.pid, signal.SIGTERM) + try: + srv.wait(timeout=5) + except subprocess.TimeoutExpired: + return False, "server ignored SIGTERM", "" + # the client's output, so expect: has something to match on + return True, "", (cli.stdout or "") + (cli.stderr or "") + finally: + reap(srv) + + +def run_procs(spec, cwd, env): + """N background peers, then one foreground driver. + + `pair:` is the 2-process case and stays as-is. This is for the chains that + genuinely need more: ocsp/stapling is responder + server + client, and + pq/pqc_proxy is origin + proxy + client. Writing a check.sh per directory + instead would duplicate this orchestration once per example. + + procs: + background: + - argv: [./legacy-server] + port: 11111 + - argv: [./pq-proxy] + port: 11112 + client: [./pq-client, 127.0.0.1] + """ + timeout = spec.get("timeout", 30) + procs = [] + try: + for bg in spec.get("background", []): + p = start_bg(bg["argv"], cwd, env) + procs.append(p) + ok, head, detail = await_ready( + p, bg.get("port"), bg.get("proto", "tcp"), + bg.get("ready_delay", 2), bg.get("ready_timeout", 10), + what=bg["argv"][0], + ) + if not ok: + return False, head, detail + + try: + cli = subprocess.run( + spec["client"], cwd=cwd, env=env, input=spec.get("stdin", ""), + capture_output=True, text=True, timeout=timeout, + ) + except subprocess.TimeoutExpired: + return False, f"client timeout after {timeout}s", bg_output(procs) + if cli.returncode != 0: + return False, f"client rc={cli.returncode}", ( + "--- client ---\n" + (cli.stdout + cli.stderr)[-1200:] + + bg_output(procs) + ) + # Return the driver's output, not "": otherwise `expect:` has nothing to + # match and every asserted step fails. run_exec already does this; run_pair + # does not, which is why no pair carries an expect: today. + return True, "", (cli.stdout or "") + (cli.stderr or "") + finally: + for p in procs: + reap(p) + + +def bg_output(procs): + """Whatever the background peers said. A client rc with no peer output is + close to undiagnosable, which is why every proc is reaped first.""" + out = [] + for p in procs: + reap(p) + try: + out.append(f"\n--- {p.args[-1] if p.args else 'peer'} ---\n" + + (p.stdout.read() or "")[-800:]) + except Exception: + out.append("\n--- peer output unavailable ---") + return "".join(out) + + +def run_script(spec, cwd, env, timeout): + argv = spec if isinstance(spec, list) else shlex.split(spec) + try: + p = subprocess.run( + argv, cwd=cwd, env=env, capture_output=True, text=True, timeout=timeout + ) + except subprocess.TimeoutExpired: + return False, f"timeout after {timeout}s", "" + if p.returncode != 0: + return False, f"rc={p.returncode}", (p.stdout + p.stderr)[-2000:] + # hand the output back on success too, or expect: has nothing to match on + return True, "", (p.stdout or "") + (p.stderr or "") + + +def build(entry, cwd): + system = entry.get("build", "make") + if system == "none": + return True, "", "" + # A list is a literal command, for dirs whose README documents a bare gcc + # line and ships no Makefile (e.g. pq/ml_kem). + if isinstance(system, list): + argv = system + elif system == "make": + argv = ["make", "-j", str(os.cpu_count() or 2)] + else: + return False, f"build system '{system}' not handled by this harness", "" + p = subprocess.run(argv, cwd=cwd, capture_output=True, text=True) + if p.returncode != 0: + return False, f"{argv[0]} rc={p.returncode}", (p.stdout + p.stderr)[-4000:] + return True, "", "" + + +BINARY_STUB_MARKERS = ( + "requires --enable", + "Must build wolfSSL using", + "Example requires", + "Please configure wolfSSL with", + "Please build wolfssl with", + "PK not compiled in", +) + + +def stub_binaries(cwd): + """Binaries that compiled a stub main(), without running anything. + + A stub is the #else of a feature #ifdef, so its "requires --enable-foo" + string is only present when the feature was NOT compiled in. Finding the + marker inside the binary therefore proves the stub was built -- which is how + build-only examples get checked at all, since they never execute. + """ + bad = [] + for f in sorted(Path(cwd).iterdir()): + if not f.is_file() or not os.access(f, os.X_OK) or f.suffix: + continue + try: + blob = f.read_bytes() + except OSError: + continue + # ELF on the runners; Mach-O too so this is verifiable on a dev mac + if not blob.startswith((b"\x7fELF", b"\xcf\xfa\xed\xfe", b"\xce\xfa\xed\xfe")): + continue + for m in BINARY_STUB_MARKERS: + if m.encode() in blob: + bad.append(f"{f.name}: {m!r}") + break + return bad + + +def do_fetch(entries): + """Run every fetch: step. Returns a process exit code.""" + rc = 0 + for e in entries: + for step in e.get("fetch") or []: + cwd = REPO / e["path"] + print(f"fetch {e['id']}: {' '.join(step)}", flush=True) + ok, detail, log = run_script(step, cwd, dict(os.environ), 600) + # print on success too: a fetch that "works" but produces nothing is + # exactly the case worth seeing + if log: + print(log, flush=True) + if not ok: + print(f"FAIL fetch {e['id']}: {detail}", flush=True) + rc = 1 + return rc + + +def run_entry(entry, expect_sha, results): + eid = entry["id"] + cwd = REPO / entry["path"] + env = dict(os.environ) + env.update({k: os.path.expandvars(v) for k, v in (entry.get("env") or {}).items()}) + + if entry.get("mode") == "skip": + results.append({"id": eid, "status": "skip", "detail": entry.get("reason", "")}) + return True + + # Before build, not after: setup is where an example's third-party tree gets + # fetched (RIOT, picoTCP), and the build needs it to already be there. + for step in entry.get("setup") or []: + ok, detail, log = run_script(step, cwd, env, 300) + if not ok: + results.append({"id": eid, "status": "fail", "stage": "setup", "detail": detail, "log": log}) + return False + + ok, detail, log = build(entry, cwd) + if not ok: + results.append({"id": eid, "status": "fail", "stage": "build", "detail": detail, "log": log}) + return False + + stubs = stub_binaries(cwd) + if stubs: + results.append({ + "id": eid, "status": "fail", "stage": "build", + "detail": "built a stub, not the example: " + "; ".join(stubs), + "log": "", + }) + return False + + if entry.get("mode") == "build-only": + results.append({"id": eid, "status": "pass", "stage": "build-only"}) + return True + + for target in entry.get("targets") or []: + binary = cwd / target + if binary.exists(): + assert_binary_links_ours(binary, expect_sha) + + all_ok = True + for step in entry.get("run") or []: + if "exec" in step: + label = " ".join(step["exec"]) + ok, detail, log = run_exec(step["exec"], cwd, env, step.get("timeout", 60)) + elif "pair" in step: + label = f"{step['pair']['server'][0]} + {step['pair']['client'][0]}" + ok, detail, log = run_pair(step["pair"], cwd, env) + elif "procs" in step: + bg = [b["argv"][0] for b in step["procs"].get("background", [])] + label = " + ".join(bg + [step["procs"]["client"][0]]) + ok, detail, log = run_procs(step["procs"], cwd, env) + elif "script" in step: + label = " ".join(step["script"]) + ok, detail, log = run_script(step["script"], cwd, env, step.get("timeout", 300)) + else: + continue + if ok: + ok, odetail = check_output(log, step) + if not ok: + detail, log = odetail, (log or "")[-2000:] + else: + log = "" + + xfail = step.get("expect_fail") + if xfail and not ok: + status, detail = "xfail", f"known: {xfail}" + ok = True + elif xfail and ok: + # Passing means the upstream fix landed; fail so the marker gets removed + # rather than silently masking a future regression. + status, detail = "fail", f"passed unexpectedly, drop expect_fail: {xfail}" + ok = False + else: + status = "pass" if ok else "fail" + + results.append( + { + "id": eid, + "target": label, + "status": status, + "stage": "run", + "detail": detail, + "log": log, + } + ) + all_ok = all_ok and ok + return all_ok + + +def write_summary(results): + path = os.environ.get("GITHUB_STEP_SUMMARY") + if not path: + return + lines = ["| example | target | result | detail |", "|---|---|---|---|"] + icon = {"pass": ":white_check_mark:", "fail": ":x:", "skip": ":fast_forward:", + "xfail": ":warning:"} + for r in results: + lines.append( + f"| `{r['id']}` | `{r.get('target', r.get('stage', ''))}` " + f"| {icon.get(r['status'], r['status'])} | {r.get('detail', '')} |" + ) + with open(path, "a") as fh: + fh.write("\n".join(lines) + "\n") + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--only", help="run a single example by id") + ap.add_argument("--tier", help="run every example in this tier") + ap.add_argument("--expect-sha", help="sha256 of the libwolfssl this job built") + ap.add_argument("--results", help="write per-example JSON results here") + ap.add_argument( + "--wolfssl-ref", + default="", + help="wolfSSL ref this job built against; stamped on every result row so " + "triage can tell master from stable instead of collapsing them", + ) + ap.add_argument("--no-netns", action="store_true") + ap.add_argument( + "--fetch", + action="store_true", + help="run only the fetch: steps, outside the netns, and exit. The run " + "itself is sandboxed with no route off loopback, so anything that has to " + "come off the internet (a third-party source tree) has to arrive first.", + ) + args = ap.parse_args() + + mf, data = load_manifest() + entries = [e for e in data["examples"] if e.get("mode") != "skip"] + if args.only: + entries = [e for e in entries if e["id"] == args.only] + if args.tier: + entries = [e for e in entries if e.get("tier", "host") == args.tier] + if not entries: + sys.exit(f"no examples matched (--only={args.only} --tier={args.tier})") + + # Deliberately before ensure_netns(): that call execs the whole process into a + # namespace with only loopback, so a fetch after it can never reach a remote. + if args.fetch: + sys.exit(do_fetch(entries)) + + if not args.no_netns: + ensure_netns() + describe_net() + + expect_sha = args.expect_sha + if expect_sha: + try: + assert_identity(expect_sha) + except BaseException as e: + # Exiting here with no results file makes triage read the job as + # never-ran rather than failed, so leave it a row first. + if args.results: + Path(args.results).write_text(json.dumps([{ + "id": args.only or "(all)", + "target": "identity-gate", + "status": "fail", + "detail": str(e), + "ref": args.wolfssl_ref, + }], indent=2)) + raise + + results = [] + ok = True + for entry in entries: + ok = run_entry(entry, expect_sha, results) and ok + + for r in results: + r["ref"] = args.wolfssl_ref + + write_summary(results) + if args.results: + Path(args.results).write_text(json.dumps(results, indent=2)) + + for r in results: + if r["status"] == "fail": + print(f"FAIL {r['id']} {r.get('target', '')}: {r.get('detail', '')}", file=sys.stderr) + if r.get("log"): + print(r["log"], file=sys.stderr) + print( + f"\n{sum(1 for r in results if r['status'] == 'pass')} passed, " + f"{sum(1 for r in results if r['status'] == 'fail')} failed, " + f"{sum(1 for r in results if r['status'] == 'skip')} skipped, " + f"{sum(1 for r in results if r['status'] == 'xfail')} known-fail" + ) + sys.exit(0 if ok else 1) + + +if __name__ == "__main__": + main() diff --git a/.github/workflows/_resolve-wolfssl.yml b/.github/workflows/_resolve-wolfssl.yml new file mode 100644 index 000000000..7d290a579 --- /dev/null +++ b/.github/workflows/_resolve-wolfssl.yml @@ -0,0 +1,92 @@ +name: Resolve wolfSSL refs + +# Resolve the wolfSSL refs at run time so a new release needs no edit here + +on: + workflow_call: + inputs: + stable_count: + description: 'how many most-recent v*-stable tags to include' + type: number + default: 1 + refs: + description: 'explicit comma-separated refs; skips resolution entirely' + type: string + default: '' + outputs: + refs: + description: 'comma-separated wolfSSL refs to test' + value: ${{ jobs.resolve.outputs.refs }} + shas: + description: 'commit SHAs for those refs, same order' + value: ${{ jobs.resolve.outputs.shas }} + refs_json: + description: 'same refs as a JSON array, for strategy.matrix' + value: ${{ jobs.resolve.outputs.refs_json }} + +jobs: + resolve: + runs-on: ubuntu-24.04 + timeout-minutes: 5 + outputs: + refs: ${{ steps.pick.outputs.refs }} + shas: ${{ steps.sha.outputs.shas }} + refs_json: ${{ steps.json.outputs.refs_json }} + steps: + - id: pick + run: | + set -euo pipefail + if [ -n '${{ inputs.refs }}' ]; then + refs='${{ inputs.refs }}' + else + # --refs drops the ^{} peel, so sort -V over tag names is enough + mapfile -t tags < <(git ls-remote --tags --refs \ + https://github.com/wolfSSL/wolfssl.git 'v*-stable' \ + | awk -F/ '{print $NF}' | sort -V | tail -n '${{ inputs.stable_count }}') + if [ "${#tags[@]}" -eq 0 ]; then + echo "could not resolve any v*-stable tag from wolfSSL/wolfssl" + exit 1 + fi + refs="master" + for t in "${tags[@]}"; do refs="$refs,$t"; done + fi + echo "refs=$refs" >> "$GITHUB_OUTPUT" + echo "testing against wolfSSL: $refs" + + # Pin each ref once: a push mid-run would give jobs different SHAs + - id: sha + run: | + set -euo pipefail + shas="" + IFS=',' read -ra list <<< '${{ steps.pick.outputs.refs }}' + for ref in "${list[@]}"; do + if [[ "$ref" =~ ^[0-9a-f]{40}$ ]]; then + sha="$ref" + else + # An annotated tag resolves to the tag object, not the commit, so + # ask for the peeled ref first and fall back for branches. + sha=$(git ls-remote https://github.com/wolfSSL/wolfssl.git \ + "refs/tags/$ref^{}" | cut -f1) + [ -n "$sha" ] || sha=$(git ls-remote \ + https://github.com/wolfSSL/wolfssl.git "$ref" \ + | head -n1 | cut -f1) + fi + [ -n "$sha" ] || { echo "could not resolve wolfSSL ref '$ref'"; exit 1; } + shas="${shas:+$shas,}$sha" + echo " $ref -> $sha" + done + echo "shas=$shas" >> "$GITHUB_OUTPUT" + { + echo "### wolfSSL under test" + paste -d'|' <(tr ',' '\n' <<< '${{ steps.pick.outputs.refs }}') \ + <(tr ',' '\n' <<< "$shas") \ + | awk -F'|' '{print "- `"$1"` @ `"substr($2,1,12)"`"}' + } >> "$GITHUB_STEP_SUMMARY" + + - id: json + run: | + set -euo pipefail + json=$(printf '%s' '${{ steps.pick.outputs.refs }}' \ + | tr ',' '\n' | jq -R . | jq -sc .) + echo "refs_json=$json" >> "$GITHUB_OUTPUT" + echo "matrix refs: $json" diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 000000000..105fb5f05 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,115 @@ +name: Android + +on: + push: + paths: + - 'android/**' + - '.github/workflows/android.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('android-call-{0}', inputs.caller_run_id) || format('android-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + android: + needs: resolve + name: Build / android (${{ matrix.example }}) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + example: + - android/wolfcryptjni-ndk-gradle + - android/wolfssljni-ndk-gradle + - android/wolfssljni-ndk-sample + steps: + - uses: actions/checkout@v5 + with: + submodules: recursive + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + + # README documents `git submodule update --remote`; point it at the ref under test + - name: Check out the wolfSSL ref under test + run: | + set -euo pipefail + cd '${{ matrix.example }}' + # a submodule's .git is a FILE (gitdir: ...), so -d silently skipped this + test -e wolfssl/.git || { echo "FAIL: wolfssl submodule not checked out"; exit 1; } + # Replace the tree: fetching into the shallow submodule races on .git/modules/*/shallow + rm -rf wolfssl + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl.git wolfssl + echo "wolfssl now at ${{ matrix.wolfssl_ref }}: $(git -C wolfssl rev-parse --short HEAD)" + + # The job title claims a ref; prove the tree matches it rather than + # trusting that the checkout above did anything. + - name: Assert wolfSSL is actually at the ref under test + run: | + set -euo pipefail + cd '${{ matrix.example }}/wolfssl' + want=$(git rev-parse HEAD) + got=$(git ls-remote https://github.com/wolfSSL/wolfssl.git \ + '${{ matrix.wolfssl_ref }}^{}' 2>/dev/null | cut -f1) + [ -n "$got" ] || got=$(git ls-remote https://github.com/wolfSSL/wolfssl.git \ + '${{ matrix.wolfssl_ref }}' | head -n1 | cut -f1) + [ "$want" = "$got" ] || { + echo "FAIL: building $want but ${{ matrix.wolfssl_ref }} is $got"; exit 1; } + echo "verified: wolfssl at ${{ matrix.wolfssl_ref }} ($want)" + + # android/README.md step 3: wolfSSL release tarballs ship wolfssl/options.h + # but a GitHub clone does not, and the jni sources include it. + - name: Create the stub options.h the README documents + run: | + set -euo pipefail + cd '${{ matrix.example }}' + if [ -f wolfssl/wolfssl/options.h.in ] && [ ! -f wolfssl/wolfssl/options.h ]; then + cp wolfssl/wolfssl/options.h.in wolfssl/wolfssl/options.h + echo "created wolfssl/wolfssl/options.h" + fi + + # These are Studio projects with no instrumentation harness, so a build is + # the honest ceiling. + - name: Build ${{ matrix.example }} + run: | + set -euo pipefail + cd '${{ matrix.example }}' + if [ -f gradlew ]; then + chmod +x gradlew + ./gradlew assembleDebug --no-daemon + else + # the older standalone-toolchain sample: Android.mk + ndk-build + "${ANDROID_NDK_HOME:-$ANDROID_NDK_ROOT}/ndk-build" + fi + + - name: Assert an apk or .so came out + run: | + set -euo pipefail + cd '${{ matrix.example }}' + find . \( -name '*.apk' -o -name '*.so' \) | head -n3 | grep -q . \ + || { echo "FAIL: no apk/.so produced"; exit 1; } + find . \( -name '*.apk' -o -name '*.so' \) | head -n3 diff --git a/.github/workflows/bsdkm.yml b/.github/workflows/bsdkm.yml new file mode 100644 index 000000000..f88cdd2c0 --- /dev/null +++ b/.github/workflows/bsdkm.yml @@ -0,0 +1,91 @@ +name: BSDKM + +on: + push: + paths: + - 'kernel/bsdkm/**' + - '.github/workflows/bsdkm.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('bsdkm-call-{0}', inputs.caller_run_id) || format('bsdkm-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + bsdkm: + needs: resolve + name: Run / kernel-bsdkm (kldload) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v5 + + # FreeBSD kernel code: BSD make, and kldload needs a real kernel. README.md + # says 14.2, but FreeBSD no longer serves it (only 14.3+), so run 14.3. + - name: Build the module and load it in a FreeBSD VM + uses: vmactions/freebsd-vm@v1 + with: + release: '14.3' + usesh: true + prepare: | + pkg install -y git autoconf automake libtool + run: | + set -e + # The Makefile ends with .include "/usr/src/sys/conf/kmod.mk" -- the + # LIVE kernel source, not the bsd.kmod.mk that ships in base, so the + # VM image's missing /usr/src has to be filled in first. + if [ ! -f /usr/src/sys/conf/kmod.mk ]; then + # keyed off the running kernel, so this cannot drift from the VM + rel=$(uname -r | sed 's/-p[0-9]*$//') + fetch -o /tmp/src.txz "https://download.freebsd.org/releases/amd64/${rel}/src.txz" + tar -C / -xf /tmp/src.txz + fi + test -f /usr/src/sys/conf/kmod.mk + + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl /tmp/wolfssl + cd /tmp/wolfssl + ./autogen.sh + ./configure --enable-freebsdkm --enable-cryptonly \ + --enable-crypttests --enable-all-crypto + make + test -f bsdkm/libwolfssl.ko + + # README: load wolfSSL's module first; it runs the wolfCrypt self-test + kldload bsdkm/libwolfssl.ko + dmesg | tail -20 + dmesg | grep -q 'wolfCrypt self-test passed' \ + || { echo "FAIL: wolfSSL kernel module did not report a passing self-test"; exit 1; } + + # Now this repo's example module against that wolfSSL tree. + cd "$GITHUB_WORKSPACE/kernel/bsdkm" + make WOLFSSL_DIR=/tmp/wolfssl/ + test -f bsd_example.ko + kldload ./bsd_example.ko + kldstat | grep -q bsd_example \ + || { echo "FAIL: bsd_example.ko did not stay loaded"; exit 1; } + dmesg | tail -10 + kldunload ./bsd_example.ko + echo "verified: wolfCrypt ran in a FreeBSD kernel module" diff --git a/.github/workflows/ci-triage.yml b/.github/workflows/ci-triage.yml new file mode 100644 index 000000000..0042745b4 --- /dev/null +++ b/.github/workflows/ci-triage.yml @@ -0,0 +1,62 @@ +name: CI Triage + +on: + workflow_run: + workflows: ["Nightly Examples"] + types: [completed] + workflow_dispatch: + inputs: + run_id: + description: 'nightly run ID to analyze' + required: true + type: string + auto_retry: + description: 'rerun failed jobs once before reporting' + type: boolean + default: false + dry_run: + description: 'print the report; do not touch issues' + type: boolean + default: true + +permissions: + actions: write # rerun-failed-jobs + contents: read + issues: write + +# Never cancel a pending report. Two triage runs racing would both list, both see +# nothing, and both open an issue -- there is no conditional-create primitive. +concurrency: + group: ci-triage-${{ github.repository }} + cancel-in-progress: false + +jobs: + triage: + runs-on: ubuntu-24.04 + timeout-minutes: 90 # must exceed RETRY_DEADLINE_S plus the AI budget + # run_attempt == 1 only: our own rerun-failed-jobs fires workflow_run again + if: > + github.event_name == 'workflow_dispatch' || + (github.event.workflow_run.head_repository.full_name == github.repository && + github.event.workflow_run.run_attempt == 1) + steps: + - uses: actions/checkout@v5 + with: + fetch-depth: 1 + + - name: Install deps + run: pip install --quiet anthropic + + - name: Triage, file issues, report + env: + GH_REPO: ${{ github.repository }} + RUN_ID: ${{ github.event_name == 'workflow_dispatch' && inputs.run_id || github.event.workflow_run.id }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + CLAUDE_MODEL: claude-opus-4-8 + AUTO_RETRY: ${{ github.event_name == 'workflow_run' && 'true' || inputs.auto_retry && 'true' || 'false' }} + # Defaults true on dispatch so a manual poke cannot file real issues + DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run && 'true' || 'false' }} + RETRY_DEADLINE_S: "3600" + run: python3 .github/scripts/ci_triage.py + working-directory: ${{ github.workspace }} diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 000000000..28d058b8f --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,74 @@ +name: CMake + +on: + push: + paths: + - 'cmake/**' + - '.github/workflows/cmake.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('cmake-call-{0}', inputs.caller_run_id) || format('cmake-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + cmake: + needs: resolve + name: Run / cmake (myApp) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 25 + steps: + - uses: actions/checkout@v5 + + # Own job, not a manifest entry: add_subdirectory(wolfssl) needs a source tree + - name: Fetch the wolfSSL ref under test + run: | + set -euo pipefail + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl cmake/wolfssl + git -C cmake/wolfssl log -1 --format='wolfssl at ${{ matrix.wolfssl_ref }}: %h %s' + + # README: cmake .. -DCMAKE_C_FLAGS=-I../include/ && make && ./hash example_string + - name: Build + run: | + set -euo pipefail + cd cmake + cmake -S . -B build -DCMAKE_C_FLAGS=-I../include/ + cmake --build build -j"$(nproc)" + test -x build/hash || { echo "FAIL: build/hash not produced"; exit 1; } + + - name: Run + run: | + set -euo pipefail + cd cmake + out=$(./build/hash example_string) + echo "$out" + # sha256("example_string"), so this asserts wolfCrypt's answer rather + # than just a zero exit + want=9BFB55A8406617FF3E6767EC5D27FC6B5682C3A79C415EF6E084BF7D050273E6 + case "$out" in + *"$want"*) echo "verified: hash matches sha256(example_string)" ;; + *) echo "FAIL: expected $want"; exit 1 ;; + esac diff --git a/.github/workflows/csharp.yml b/.github/workflows/csharp.yml new file mode 100644 index 000000000..52ed092ce --- /dev/null +++ b/.github/workflows/csharp.yml @@ -0,0 +1,146 @@ +name: CSharp + +on: + push: + paths: + - 'CSharp/**' + - '.github/workflows/csharp.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('csharp-call-{0}', inputs.caller_run_id) || format('csharp-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + csharp: + needs: resolve + name: Run / csharp (${{ matrix.example }}) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + # both server variants play the same client; full paths so the + # coverage gate can see which dirs this job builds + example: + - CSharp/wolfSSL-TLS-pq-Server + - CSharp/wolfSSL-TLS-pq-ServerThreaded + timeout-minutes: 25 + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install mono + run: sudo apt-get install -y --no-install-recommends mono-complete >/dev/null + + # The .csproj needs .NET v4.8 and wolfSSL's own csproj, so use mcs like wolfSSL's mono.yml + - name: Build wolfSSL with the C# wrapper's user_settings.h + run: | + set -euo pipefail + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl /tmp/wolfssl + cd /tmp/wolfssl + # wrapper/CSharp/user_settings.h already enables ML-KEM, ML-DSA and + # SHAKE, which is what the pq examples need + ./autogen.sh >/dev/null 2>&1 + ./configure --enable-usersettings --enable-static --enable-shared \ + CPPFLAGS=-I/tmp/wolfssl/wrapper/CSharp >/dev/null + make -j"$(nproc)" >/dev/null + sudo make install >/dev/null + sudo ldconfig + + # A green build proves nothing if the wrapper silently lost the PQ API the + # examples call, so assert the exact symbols rather than trusting configure. + - name: Verify the wrapper still exposes the PQ API + run: | + set -euo pipefail + W=/tmp/wolfssl/wrapper/CSharp/wolfSSL_CSharp + grep -q 'WOLFSSL_ML_KEM_1024' "$W/wolfSSL.cs" \ + || { echo "FAIL: NamedGroup.WOLFSSL_ML_KEM_1024 gone from the wrapper"; exit 1; } + grep -q 'public static int UseKeyShare' "$W/wolfSSL.cs" \ + || { echo "FAIL: UseKeyShare() gone from the wrapper"; exit 1; } + echo "verified: WOLFSSL_ML_KEM_1024 + UseKeyShare present" + + # wolfSSL's mono.yml only runs this against its PR head; this is the only place a RELEASE gets it + - name: Run wolfCrypt-Test through the wrapper + # One leg only: the suite is per-wolfSSL-ref, and the example axis would + # otherwise run the identical tests twice per ref for nothing. + if: matrix.example == 'CSharp/wolfSSL-TLS-pq-Server' + env: + LD_LIBRARY_PATH: /usr/local/lib + working-directory: /tmp/wolfssl/wrapper/CSharp + run: | + set -euo pipefail + cp /usr/local/lib/libwolfssl.so wolfssl.dll + cp /usr/local/lib/libwolfssl.so libwolfssl.so + mcs wolfCrypt-Test/wolfCrypt-Test.cs wolfSSL_CSharp/wolfCrypt.cs \ + wolfSSL_CSharp/wolfSSL.cs wolfSSL_CSharp/X509.cs -OUT:wolfcrypttest.exe + mono wolfcrypttest.exe | tee wct.log + # exit 0 is not enough: the suite prints per-test results and only says + # this once every one of them passed. + grep -q 'All tests completed successfully' wct.log \ + || { echo "FAIL: wolfCrypt-Test did not report all tests passing"; exit 1; } + + # wolfssl.setPath() is relative, so the exes must run from CSharp// + - name: Compile the pair with mcs + run: | + set -euo pipefail + W=/tmp/wolfssl/wrapper/CSharp/wolfSSL_CSharp + mcs "$W/wolfSSL.cs" "$W/X509.cs" \ + '${{ matrix.example }}'/*.cs \ + -OUT:'${{ matrix.example }}/server.exe' + mcs "$W/wolfCrypt.cs" "$W/wolfSSL.cs" "$W/X509.cs" \ + CSharp/wolfSSL-TLS-pq-Client/wolfSSL-TLS-Client.cs \ + -OUT:CSharp/wolfSSL-TLS-pq-Client/client.exe + for d in '${{ matrix.example }}' CSharp/wolfSSL-TLS-pq-Client; do + cp /usr/local/lib/libwolfssl.so "$d/wolfssl.dll" + cp /usr/local/lib/libwolfssl.so "$d/libwolfssl.so" + done + + - name: Run the ML-KEM-1024 / ML-DSA-87 handshake + env: + LD_LIBRARY_PATH: /usr/local/lib + run: | + set -euo pipefail + ( cd '${{ matrix.example }}' && timeout 30s mono server.exe ) \ + > server.log 2>&1 & + for _ in $(seq 1 100); do + ss -tln | grep -q ':11111 ' && break + sleep 0.1 + done + ss -tln | grep -q ':11111 ' \ + || { echo "FAIL: server never listened on 11111"; cat server.log; exit 1; } + + rc=0 + ( cd CSharp/wolfSSL-TLS-pq-Client && timeout 30s mono client.exe ) \ + > client.log 2>&1 || rc=$? + if [ "$rc" -ne 0 ]; then + echo "FAIL: client exited $rc"; echo "--- client:"; cat client.log + echo "--- server:"; cat server.log; exit 1 + fi + + # exit 0 alone does not prove a handshake, so assert on the negotiated + # session the way wolfSSL's own mono.yml does + grep -q 'SSL version is' client.log && grep -q 'SSL cipher suite is' client.log \ + || { echo "FAIL: no TLS session reported"; echo "--- client:"; cat client.log + echo "--- server:"; cat server.log; exit 1; } + echo "verified: PQ TLS 1.3 handshake" + grep -E 'SSL version is|SSL cipher suite is' client.log diff --git a/.github/workflows/ebpf.yml b/.github/workflows/ebpf.yml new file mode 100644 index 000000000..ea17d6267 --- /dev/null +++ b/.github/workflows/ebpf.yml @@ -0,0 +1,77 @@ +name: ebpf + +on: + push: + paths: + - 'ebpf/**' + - '.github/workflows/ebpf.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('ebpf-call-{0}', inputs.caller_run_id) || format('ebpf-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + ebpf: + needs: resolve + name: Build / ebpf (${{ matrix.example }}) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + example: + - ebpf/syscall-write-trace + - ebpf/tls-uprobe-trace + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + # exactly what ebpf/tls-uprobe-trace/README.md documents + - name: Install deps + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends \ + clang llvm libbpf-dev libelf-dev zlib1g-dev make >/dev/null + + # tls-uprobe-trace resolves wolfSSL_write in the installed libwolfssl.so + - uses: ./.github/actions/setup-wolfssl + with: + ref: ${{ matrix.wolfssl_ref }} + flags: "--enable-static --enable-shared" + + - name: Build ${{ matrix.example }} + run: | + set -euo pipefail + cd '${{ matrix.example }}' + make + + # a green make proves nothing if the BPF object was not produced + - name: Assert a BPF object came out + run: | + set -euo pipefail + cd '${{ matrix.example }}' + o=$(find . -name '*.bpf.o' -o -name '*_bpf.o' | head -n1) + [ -n "$o" ] || { echo "FAIL: no BPF object built"; exit 1; } + file "$o" + file "$o" | grep -qi 'eBPF\|BPF' || { echo "FAIL: not a BPF object"; exit 1; } + echo "verified: $o" diff --git a/.github/workflows/emulated.yml b/.github/workflows/emulated.yml new file mode 100644 index 000000000..b1b0d430c --- /dev/null +++ b/.github/workflows/emulated.yml @@ -0,0 +1,225 @@ +name: Emulated Examples + +# Examples that need hardware -- run against a simulator instead. No boards, +# no licences, all on a stock runner. + +on: + push: + branches: [ '**' ] + paths: + - 'tpm/**' + - 'SGX_Linux/**' + - 'can-bus/**' + - '.github/workflows/emulated.yml' + - '.github/examples-manifest.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('emulated-call-{0}', inputs.caller_run_id) || format('emulated-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + tpm: + needs: resolve + name: Run / tpm (${{ matrix.simulator }}) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + # Both TPMs: a disagreement between them is a real finding + simulator: [ibmswtpm2, fwtpm] + steps: + - uses: actions/checkout@v5 + - uses: ./.github/actions/apt-update + - run: | + sudo apt-get install -y --no-install-recommends autoconf automake libtool + pip install --quiet pyyaml + + - uses: ./.github/actions/setup-wolfssl + id: wolfssl + with: + ref: ${{ matrix.wolfssl_ref }} + flags: --enable-all --enable-wolftpm --enable-cryptocb --enable-static --enable-shared + # fwTPM's RSA_Encrypt/Decrypt return TPM_RC_SCHEME without it, and + # --enable-all does not imply it (only the FIPS and provider paths do) + cflags: -DWC_RSA_NO_PADDING + + # fwtpm builds wolfTPM's own simulator; swtpm gives both legs the socket transport + - name: Build wolfTPM + run: | + set -euo pipefail + git clone --depth 1 --branch v4.1.0 https://github.com/wolfSSL/wolfTPM /tmp/wolftpm + cd /tmp/wolftpm + ./autogen.sh + ./configure --enable-fwtpm --enable-swtpm + make -j"$(nproc)" + sudo make install + sudo ldconfig + + - name: Start ibmswtpm2 + if: matrix.simulator == 'ibmswtpm2' + run: | + set -euo pipefail + git clone --depth 1 --branch rev1682 https://github.com/kgoldman/ibmswtpm2 /tmp/ibmswtpm2 + make -C /tmp/ibmswtpm2/src -j"$(nproc)" + (cd /tmp/ibmswtpm2/src && ./tpm_server &) + + - name: Start fwtpm_server + if: matrix.simulator == 'fwtpm' + run: | + set -euo pipefail + # --clear wipes NV state so a rerun cannot inherit the last run's keys + (cd /tmp/wolftpm && ./src/fwtpm/fwtpm_server --clear &) + + # both simulators speak the swtpm command interface on TCP 2321, which is + # what makes them interchangeable under the same example + - name: Wait for the TPM on :2321 + run: | + for _ in $(seq 1 200); do + ss -tln | grep -q ':2321 ' && break + sleep 0.05 + done + ss -tln | grep ':2321 ' \ + || { echo "${{ matrix.simulator }} never listened on 2321"; exit 1; } + + - name: Build and run tpm example + run: | + python3 .github/scripts/run_example.py --only tpm --no-netns \ + --expect-sha '${{ steps.wolfssl.outputs.sha256 }}' \ + --results results-tpm-${{ matrix.simulator }}.json + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: results-tpm-${{ matrix.simulator }}-attempt${{ github.run_attempt }} + path: results-*.json + retention-days: 5 + if-no-files-found: ignore + + sgx: + needs: resolve + name: Run / SGX_Linux (SGX_MODE=SIM) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + timeout-minutes: 40 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + steps: + - uses: actions/checkout@v5 + + - name: Install Intel SGX SDK + run: | + set -euo pipefail + # Simulation mode needs only the SDK -- no PSW, no aesmd, no /dev/sgx_enclave. + url=https://download.01.org/intel-sgx/sgx-linux/2.29/distro/ubuntu24.04-server + wget -q "$url/sgx_linux_x64_sdk_2.29.100.1.bin" + chmod +x sgx_linux_x64_sdk_2.29.100.1.bin + # The installer is interactive. + echo yes | ./sgx_linux_x64_sdk_2.29.100.1.bin + + - name: Build wolfSSL for SGX + run: | + set -euo pipefail + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl /tmp/wolfssl + source sgxsdk/environment + # test.c includes , which the SGX build never generates + : > /tmp/wolfssl/wolfssl/options.h + # HAVE_WOLFSSL_TEST must match the App build below: the enclave + # references wolfcrypt_test, so the static lib has to contain it. + make -C /tmp/wolfssl/IDE/LINUX-SGX -f sgx_t_static.mk HAVE_WOLFSSL_TEST=1 + + - name: Build enclave and run in simulation + run: | + set -euo pipefail + source sgxsdk/environment + # SKIP_INTELCPU_CHECK: runners are often AMD and SIM mode uses no SGX instructions + make -C SGX_Linux \ + SGX_MODE=SIM SGX_PRERELEASE=0 SGX_DEBUG=0 \ + SGX_WOLFSSL_LIB=/tmp/wolfssl/IDE/LINUX-SGX/ \ + WOLFSSL_ROOT=/tmp/wolfssl \ + HAVE_WOLFSSL_TEST=1 + cd SGX_Linux && SKIP_INTELCPU_CHECK=TRUE ./App + + can-bus: + needs: resolve + name: Run / can-bus (vcan) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + timeout-minutes: 25 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + steps: + - uses: actions/checkout@v5 + - uses: ./.github/actions/apt-update + - run: | + sudo apt-get install -y --no-install-recommends autoconf automake libtool openssl + pip install --quiet pyyaml + + - name: Set up vcan0 + run: | + set -euo pipefail + # vcan ships in linux-modules-extra and must match the running kernel exactly + sudo apt-get install -y "linux-modules-extra-$(uname -r)" + sudo modprobe can + sudo modprobe can-raw + sudo modprobe vcan + sudo ip link add dev vcan0 type vcan + sudo ip link set vcan0 mtu 16 # 16 = classic CAN (72 for CAN FD) + sudo ip link set up vcan0 + ip -details link show vcan0 + + - uses: ./.github/actions/setup-wolfssl + id: wolfssl + with: + ref: ${{ matrix.wolfssl_ref }} + flags: --enable-all --enable-static --enable-shared + cflags: "-DWOLFSSL_ISOTP" + + - name: Generate certs and build + working-directory: can-bus + run: | + ./generate_ssl.sh + make + + - name: Run over vcan0 + working-directory: can-bus + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends can-utils + candump -L vcan0 >/tmp/candump.log 2>&1 & + dump=$! + ./server vcan0 >/tmp/can-server.log 2>&1 & + srv=$! + sleep 1 + # The client getline()s stdin, so /dev/null || true + sleep 1; kill "$dump" 2>/dev/null || true + echo "--- server output:" + cat /tmp/can-server.log || true + echo "--- frames on vcan0 ($(wc -l > "$GITHUB_ENV" + + - name: Build ${{ matrix.example }} + shell: bash + run: | + set -euo pipefail + . /opt/esp/idf/export.sh + cd '${{ matrix.example }}' + # -Wcpp: IDF builds -Werror and wolfSSL emits an advisory #warning + idf.py build -DCMAKE_C_FLAGS=-Wno-error=cpp + + # A green build proves nothing if idf.py fell back to the host compiler or + # skipped the wolfSSL component entirely. + - name: Assert it really cross-compiled + shell: bash + run: | + set -euo pipefail + cd '${{ matrix.example }}' + elf=$(find build -maxdepth 1 -name '*.elf' | head -n1) + [ -n "$elf" ] || { echo "no .elf produced"; exit 1; } + # readelf ships with the toolchain; the idf container has no `file`. + arch=$(readelf -h "$elf" | awk -F: '/Machine:/ {print $2}' | xargs) + echo "machine: $arch" + case "$arch" in + *Tensilica*|*Xtensa*|*RISC-V*) ;; + *X86-64*|*x86-64*) echo "FAIL: host binary -- the cross toolchain was not used"; exit 1 ;; + *) echo "FAIL: unexpected architecture: $arch"; exit 1 ;; + esac + # and wolfSSL must actually be linked in, not stubbed out + find build -name 'libwolfssl.a' -o -name '*wolfssl*.o' | head -n1 | grep -q . \ + || { echo "FAIL: no wolfSSL objects in the build tree"; exit 1; } + echo "cross-compile verified: Xtensa/RISC-V ELF with wolfSSL objects" diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml new file mode 100644 index 000000000..aad14d006 --- /dev/null +++ b/.github/workflows/examples.yml @@ -0,0 +1,178 @@ +name: Examples + +# Builds and runs the host-tier examples against a wolfSSL built per profile. +# +# Deliberately carries NO `github.repository_owner == 'wolfssl'` guard. That +# convention exists to stop *scheduled* runs on forks (see nightly.yml, which +# does guard). Applying it here would make every fork run 100% skips and remove +# any way to validate a CI change before it reaches master. + +# START OF COMMON SECTION +on: + push: + branches: [ '**' ] + paths-ignore: + - 'Arduino/**' + - '.github/workflows/arduino*.yml' + - '**.md' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [ '*' ] + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + wolfssl_refs: + description: 'comma-separated wolfSSL refs' + type: string + default: 'master' + +# A reusable workflow must not self-cancel: the group would collide with its caller +concurrency: + group: ${{ inputs.caller_run_id && format('{0}-call-{1}', github.workflow, inputs.caller_run_id) || format('{0}-{1}', github.workflow, github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} +# END OF COMMON SECTION + +permissions: + contents: read + +jobs: + # Fails when a dir holding buildable source has no manifest entry. This is what + # keeps "test every example" true a year from now rather than only on day one. + coverage: + name: Coverage gate + runs-on: ubuntu-24.04 + timeout-minutes: 5 + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + steps: + - uses: actions/checkout@v5 + - run: pip install --quiet pyyaml + - run: python3 .github/scripts/manifest.py check + + # PRs test master AND the latest stable tag. Testing only master would let a + # break against the released version reach users unnoticed until nightly. + refs: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + refs: ${{ inputs.wolfssl_refs || '' }} + stable_count: 1 + + matrix: + name: Resolve matrix + needs: [refs] + runs-on: ubuntu-24.04 + timeout-minutes: 5 + if: github.event_name != 'pull_request' || github.event.pull_request.draft == false + outputs: + examples: ${{ steps.gen.outputs.examples }} + wolfssl: ${{ steps.gen.outputs.wolfssl }} + steps: + - uses: actions/checkout@v5 + - run: pip install --quiet pyyaml + - id: gen + run: | + set -euo pipefail + refs='${{ needs.refs.outputs.refs }}' + shas='${{ needs.refs.outputs.shas }}' + m() { python3 .github/scripts/manifest.py "$1" --refs "$refs" --shas "$shas"; } + echo "examples=$(m matrix)" >> "$GITHUB_OUTPUT" + echo "wolfssl=$(m wolfssl-matrix)" >> "$GITHUB_OUTPUT" + n=$(m matrix | python3 -c 'import json,sys;print(len(json.load(sys.stdin)))') + w=$(m wolfssl-matrix | python3 -c 'import json,sys;print(len(json.load(sys.stdin)))') + echo "$n example jobs against $w wolfSSL build(s)" + echo "$n example jobs against $w cached wolfSSL build(s)" >> "$GITHUB_STEP_SUMMARY" + + # Build each wolfSSL profile ONCE and let the cache fan out to the per-example + # jobs. Without this, every example pays a full wolfSSL build. + build-wolfssl: + name: wolfSSL ${{ matrix.profile }} (${{ matrix.wolfssl_ref }}) + needs: [matrix] + runs-on: ubuntu-24.04 + timeout-minutes: 25 + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.matrix.outputs.wolfssl) }} + steps: + - uses: actions/checkout@v5 + - uses: ./.github/actions/apt-update + - name: Install build deps + run: sudo apt-get install -y --no-install-recommends autoconf automake libtool + - name: Setup wolfSSL (${{ matrix.profile }}) + uses: ./.github/actions/setup-wolfssl + with: + # the pinned commit, not the branch name: every job must build and + # cache the same wolfSSL + ref: ${{ matrix.wolfssl_sha }} + flags: ${{ matrix.flags }} + cflags: ${{ matrix.cflags }} + + # One job per example, so a red tile names the example that broke. + examples: + name: ${{ matrix.mode_label }} / ${{ matrix.id }} (${{ matrix.wolfssl_ref }}) + needs: [matrix, build-wolfssl] + # always(): plain needs would skip every example job if one profile failed + if: ${{ !cancelled() && needs.matrix.result == 'success' }} + runs-on: ubuntu-24.04 + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: ${{ fromJson(needs.matrix.outputs.examples) }} + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install deps + run: | + sudo apt-get install -y --no-install-recommends autoconf automake libtool ${{ matrix.deps }} + pip install --quiet pyyaml + + # Cache hit from build-wolfssl above: restores and installs, does not rebuild. + - name: Setup wolfSSL (${{ matrix.profile }}) + id: wolfssl + uses: ./.github/actions/setup-wolfssl + with: + # the pinned commit, not the branch name: every job must build and + # cache the same wolfSSL + ref: ${{ matrix.wolfssl_sha }} + flags: ${{ matrix.flags }} + cflags: ${{ matrix.cflags }} + + # Probe the exact netns invocation: --map-root-user is the part that fails + - name: Enable unprivileged user namespaces + run: | + if ! unshare --user --map-root-user --net -- true 2>/dev/null; then + echo "userns with uid mapping blocked; relaxing the apparmor restriction" + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true + fi + unshare --user --map-root-user --net -- true 2>/dev/null \ + && echo "userns ok" \ + || echo "userns still blocked; harness will fall back to sudo unshare --net" + + # Before the run: run_example.py execs itself into a netns with only + # loopback, so an example needing a third-party tree has to get it now. + - name: Fetch third-party sources for ${{ matrix.id }} + run: | + python3 .github/scripts/run_example.py --only '${{ matrix.id }}' --fetch + + - name: Build and run ${{ matrix.id }} + run: | + python3 .github/scripts/run_example.py \ + --only '${{ matrix.id }}' \ + --expect-sha '${{ steps.wolfssl.outputs.sha256 }}' \ + --wolfssl-ref '${{ matrix.wolfssl_ref }}' \ + --results "results-${{ matrix.id }}-${{ matrix.ref_slug }}.json" + + # run_attempt in the name: a rerun (attempt 2) must not collide with the + # attempt-1 artifact, and triage merges attempt 2 over attempt 1 per dir. + - name: Upload results + if: always() + uses: actions/upload-artifact@v4 + with: + name: results-${{ matrix.id }}-${{ matrix.ref_slug }}-attempt${{ github.run_attempt }} + path: results-*.json + retention-days: 5 + if-no-files-found: ignore diff --git a/.github/workflows/fullstack.yml b/.github/workflows/fullstack.yml new file mode 100644 index 000000000..0cbe8f2c9 --- /dev/null +++ b/.github/workflows/fullstack.yml @@ -0,0 +1,112 @@ +name: Fullstack + +on: + push: + paths: + - 'fullstack/**' + - '.github/workflows/fullstack.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('fullstack-call-{0}', inputs.caller_run_id) || format('fullstack-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + fullstack: + needs: resolve + name: Build / fullstack (freertos + wolfip + wolfssl) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v5 + + # setup.sh clones the deps as siblings; pre-place the ref so its guard skips its own clone + - name: Pre-place the wolfSSL ref under test + run: | + set -euo pipefail + cd "$GITHUB_WORKSPACE/.." + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl.git wolfssl + cd wolfssl + ./autogen.sh >/dev/null 2>&1 + ./configure --enable-tls13 --enable-static >/dev/null + make -j"$(nproc)" >/dev/null + sudo make install >/dev/null + sudo ldconfig + + - name: Run the example's own setup.sh + run: | + set -euo pipefail + cd fullstack/freertos-wolfip-wolfssl-https + chmod +x setup.sh + ./setup.sh + + - name: Build + run: | + set -euo pipefail + cd fullstack/freertos-wolfip-wolfssl-https + mkdir -p build && cd build + cmake .. + make + + - name: Assert the sim binary came out + run: | + set -euo pipefail + cd fullstack/freertos-wolfip-wolfssl-https + f=$(find . -name 'freertos_sim' -type f | head -n1) + [ -n "$f" ] || { echo "FAIL: freertos_sim not built"; exit 1; } + file "$f" + + # The sim talks wolfIP over a TAP link, so it is unreachable without this. + - name: Bring up the wtap0 interface + run: | + set -euo pipefail + cd fullstack/freertos-wolfip-wolfssl-https + chmod +x setup_network.sh test_https.sh + sudo ./setup_network.sh + ip addr show wtap0 + + # The whole point of the stack is that it serves HTTPS, which building + # proves nothing about. Run the author's own curl test against it. + - name: Serve HTTPS from the sim and fetch it + run: | + set -euo pipefail + d=fullstack/freertos-wolfip-wolfssl-https + # CERT_FILE only resolves from build/; stdbuf or the sim's printf never flushes + ( cd "$d/build" && sudo stdbuf -oL -eL ./freertos_sim ) > "$d/sim.log" 2>&1 & + for _ in $(seq 1 100); do + curl -sk --max-time 1 https://10.10.0.10:443/ >/dev/null 2>&1 && break + sleep 0.3 + done + echo "--- sim:"; cat "$d/sim.log" || true + ip link show wtap0 + rc=0 + ( cd "$d" && sudo ./test_https.sh ) > "$d/curl.log" 2>&1 || rc=$? + echo "--- test_https.sh:"; cat "$d/curl.log" + if [ "$rc" -ne 0 ]; then + exit 1 + fi + grep -q 'HTTPS test successful' "$d/curl.log" \ + || { echo "FAIL: no successful HTTPS fetch"; exit 1; } diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml new file mode 100644 index 000000000..0995e3834 --- /dev/null +++ b/.github/workflows/java.yml @@ -0,0 +1,76 @@ +name: Java + +on: + push: + paths: + - 'java/**' + - '.github/workflows/java.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('java-call-{0}', inputs.caller_run_id) || format('java-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + java: + needs: resolve + name: Build / java (https-url) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 25 + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + + # README: javac -cp /lib/wolfssl-jsse.jar URLClient.java + # so wolfSSL must be built with JNI support and wolfssljni built on top. + - uses: ./.github/actions/apt-update + - name: Build wolfSSL and wolfssljni + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends ant >/dev/null + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' https://github.com/wolfSSL/wolfssl /tmp/wolfssl + cd /tmp/wolfssl + ./autogen.sh >/dev/null 2>&1 + ./configure --enable-jni --enable-static --enable-shared >/dev/null + make -j"$(nproc)" >/dev/null + sudo make install >/dev/null + sudo ldconfig + git clone -q --depth 1 https://github.com/wolfSSL/wolfssljni /tmp/wolfssljni + cd /tmp/wolfssljni + ./java.sh + ant + test -f lib/wolfssl-jsse.jar || { echo "FAIL: wolfssl-jsse.jar not built"; exit 1; } + + - name: Compile URLClient + run: | + set -euo pipefail + cd java/https-url + javac -cp /tmp/wolfssljni/lib/wolfssl-jsse.jar URLClient.java + test -f URLClient.class || { echo "FAIL: no class produced"; exit 1; } + echo "verified: URLClient.class" diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml new file mode 100644 index 000000000..22f8c8ed8 --- /dev/null +++ b/.github/workflows/nightly.yml @@ -0,0 +1,134 @@ +name: Nightly Examples + +# One scheduled run, with wolfSSL refs as a MATRIX AXIS inside it. +# +# Not three cron entries: that would be three runs, and therefore three +# concurrent ci_triage.py processes doing read-modify-write on the same per-dir +# issue bodies. One run keeps triage single-writer. + +on: + schedule: + - cron: '0 6 * * *' + workflow_dispatch: + inputs: + wolfssl_refs: + description: 'comma-separated wolfSSL refs' + type: string + default: 'master' + +# cancel-in-progress false: true would cancel the attempt-2 rerun ci-triage triggers +concurrency: + group: nightly-examples + cancel-in-progress: false + +permissions: + contents: read + +jobs: + # Only the scheduled run is upstream-only; dispatch stays open for forks + gate: + runs-on: ubuntu-24.04 + timeout-minutes: 1 + if: github.event_name == 'workflow_dispatch' || github.repository_owner == 'wolfssl' + steps: + - run: echo "nightly authorised for ${{ github.repository }}" + + # master + the two most recent stable tags, resolved at run time. + refs: + needs: [gate] + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + refs: ${{ inputs.wolfssl_refs || '' }} + stable_count: 2 + + # Every target in ONE run: 13 crons meant 13 triage writers racing + host: + needs: [refs] + uses: ./.github/workflows/examples.yml + with: + wolfssl_refs: ${{ needs.refs.outputs.refs }} + caller_run_id: ${{ github.run_id }} + + esp32: + needs: [refs] + uses: ./.github/workflows/esp32.yml + with: + caller_run_id: ${{ github.run_id }} + + android: + needs: [refs] + uses: ./.github/workflows/android.yml + with: + caller_run_id: ${{ github.run_id }} + + rt1060: + needs: [refs] + uses: ./.github/workflows/rt1060.yml + with: + caller_run_id: ${{ github.run_id }} + + uefi: + needs: [refs] + uses: ./.github/workflows/uefi.yml + with: + caller_run_id: ${{ github.run_id }} + + puf: + needs: [refs] + uses: ./.github/workflows/puf.yml + with: + caller_run_id: ${{ github.run_id }} + + rpi-pico: + needs: [refs] + uses: ./.github/workflows/rpi-pico.yml + with: + caller_run_id: ${{ github.run_id }} + + ebpf: + needs: [refs] + uses: ./.github/workflows/ebpf.yml + with: + caller_run_id: ${{ github.run_id }} + + fullstack: + needs: [refs] + uses: ./.github/workflows/fullstack.yml + with: + caller_run_id: ${{ github.run_id }} + + psa: + needs: [refs] + uses: ./.github/workflows/psa.yml + with: + caller_run_id: ${{ github.run_id }} + + bsdkm: + needs: [refs] + uses: ./.github/workflows/bsdkm.yml + with: + caller_run_id: ${{ github.run_id }} + + java: + needs: [refs] + uses: ./.github/workflows/java.yml + with: + caller_run_id: ${{ github.run_id }} + + cmake: + needs: [refs] + uses: ./.github/workflows/cmake.yml + with: + caller_run_id: ${{ github.run_id }} + + csharp: + needs: [refs] + uses: ./.github/workflows/csharp.yml + with: + caller_run_id: ${{ github.run_id }} + + emulated: + needs: [refs] + uses: ./.github/workflows/emulated.yml + with: + caller_run_id: ${{ github.run_id }} diff --git a/.github/workflows/psa.yml b/.github/workflows/psa.yml new file mode 100644 index 000000000..f00de7521 --- /dev/null +++ b/.github/workflows/psa.yml @@ -0,0 +1,97 @@ +name: PSA + +on: + push: + paths: + - 'psa/**' + - '.github/workflows/psa.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('psa-call-{0}', inputs.caller_run_id) || format('psa-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + psa: + needs: resolve + name: Run / psa (tls13-ecc) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install build deps + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends cmake python3 >/dev/null + + # The example's own script pins mbedTLS and runs ./configure --enable-psa itself + - name: Build mbedTLS PSA and wolfSSL with the example's own script + run: | + set -euo pipefail + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl /tmp/wolfssl + cd /tmp/wolfssl + "$GITHUB_WORKSPACE/psa/build_with_mbedtls_psa.sh" + sudo make install >/dev/null + sudo ldconfig + + - name: Build the PSA client and server + env: + PSA_INCLUDE: /tmp/mbedtls/build/include + PSA_LIB_PATH: /tmp/mbedtls/build/library/libmbedcrypto.a + run: | + set -euo pipefail + cd psa + make + test -x ./server-tls13-ecc-psa && test -x ./client-tls13-ecc-psa + + # Building proves the PSA glue compiles; only a handshake proves wolfSSL + # actually drove ECDH/ECDSA/HKDF/AES-GCM through mbedTLS's PSA API. + - name: Run the TLS 1.3 PSA handshake + env: + LD_LIBRARY_PATH: /usr/local/lib + run: | + set -euo pipefail + cd psa + stdbuf -oL -eL ./server-tls13-ecc-psa > server.log 2>&1 & + for _ in $(seq 1 100); do + ss -tln | grep -q ':11111 ' && break + sleep 0.2 + done + ss -tln | grep -q ':11111 ' \ + || { echo "FAIL: server never listened on 11111"; cat server.log; exit 1; } + rc=0 + echo "hello psa" | stdbuf -oL -eL ./client-tls13-ecc-psa 127.0.0.1 > client.log 2>&1 || rc=$? + echo "--- client:"; cat client.log + echo "--- server:"; cat server.log + [ "$rc" -eq 0 ] || { echo "FAIL: client exited $rc"; exit 1; } + # The server sends a fixed reply, not an echo (server-tls13-ecc-psa.c:185) + grep -q 'Server: I hear ya fa shizzle' client.log \ + || { echo "FAIL: no reply back from the PSA server"; exit 1; } + grep -q 'Client: hello psa' server.log \ + || { echo "FAIL: server never received our message"; exit 1; } + echo "verified: TLS 1.3 handshake over mbedTLS PSA" diff --git a/.github/workflows/puf.yml b/.github/workflows/puf.yml new file mode 100644 index 000000000..7ebd8dd91 --- /dev/null +++ b/.github/workflows/puf.yml @@ -0,0 +1,72 @@ +name: PUF + +on: + push: + paths: + - 'puf/**' + - '.github/workflows/puf.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('puf-call-{0}', inputs.caller_run_id) || format('puf-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + puf: + needs: resolve + name: Build / puf (arm-none-eabi) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 20 + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install toolchain + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends \ + gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential + + # puf/Makefile:21 defaults WOLFSSL_ROOT to ../../wolfssl and compiles + # $(WOLFSSL_ROOT)/wolfcrypt/src/puf.c straight from source. + - name: Build puf + run: | + set -euo pipefail + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' https://github.com/wolfSSL/wolfssl /tmp/wolfssl + cd puf + make WOLFSSL_ROOT=/tmp/wolfssl + + - name: Assert it really cross-compiled + run: | + set -euo pipefail + cd puf + elf=$(find . -maxdepth 2 -name '*.elf' -o -maxdepth 2 -name '*.axf' | head -n1) + [ -n "$elf" ] || { echo "no elf produced"; exit 1; } + arch=$(readelf -h "$elf" | awk -F: '/Machine:/ {print $2}' | xargs) + echo "machine: $arch" + case "$arch" in + *ARM*) ;; + *) echo "FAIL: not an ARM binary: $arch"; exit 1 ;; + esac diff --git a/.github/workflows/rpi-pico.yml b/.github/workflows/rpi-pico.yml new file mode 100644 index 000000000..50b7fce35 --- /dev/null +++ b/.github/workflows/rpi-pico.yml @@ -0,0 +1,92 @@ +name: RPi-Pico + +on: + push: + paths: + - 'RPi-Pico/**' + - '.github/workflows/rpi-pico.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('rpi-pico-call-{0}', inputs.caller_run_id) || format('rpi-pico-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + # master only: v5.9.2-stable cannot compile its own Pico port (fixed after the tag) + refs: master + + rpi-pico: + needs: resolve + name: Build / RPi-Pico (arm-none-eabi) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 30 + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install toolchain and Pico SDK + run: | + set -euo pipefail + # libstdc++-arm-none-eabi-newlib supplies the C++ headers the Pico SDK + # needs (); gcc-arm-none-eabi alone is not enough. + sudo apt-get install -y --no-install-recommends \ + cmake gcc-arm-none-eabi libnewlib-arm-none-eabi \ + libstdc++-arm-none-eabi-newlib build-essential + git clone --depth 1 --recurse-submodules \ + https://github.com/raspberrypi/pico-sdk /tmp/pico-sdk + + - name: Build testwolfcrypt + env: + PICO_SDK_PATH: /tmp/pico-sdk + # WOLFSSL_ROOT must be in the env: CMakeLists.txt:48 overwrites the -D + WOLFSSL_ROOT: /tmp/wolfssl + run: | + set -euo pipefail + # --branch, or every leg silently clones the default branch and the + # "wolfSSL v5.9.2-stable" job builds master + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' \ + https://github.com/wolfSSL/wolfssl /tmp/wolfssl + git -C /tmp/wolfssl log -1 --format='wolfssl at ${{ matrix.wolfssl_ref }}: %h %s' + cd RPi-Pico + # No `|| cmake -B build .` fallback: retrying without the root would + # silently configure a build with no wolfSSL in it. + cmake -B build -DWOLFSSL_ROOT=/tmp/wolfssl . + cmake --build build -j"$(nproc)" + + - name: Assert it really cross-compiled + run: | + set -euo pipefail + cd RPi-Pico + elf=$(find build -name '*.elf' | head -n1) + [ -n "$elf" ] || { echo "no .elf produced"; exit 1; } + arch=$(file -b "$elf") + echo "$arch" + # wolfSSL must actually be linked in, not configured away + find build -name 'libwolfssl*' -o -name '*wolfssl*.obj' -o -name '*wolfssl*.o' \ + | head -n1 | grep -q . \ + || { echo "FAIL: no wolfSSL objects in the build tree"; exit 1; } + case "$arch" in + *ARM*) echo "cross-compile verified: ARM ELF with wolfSSL objects" ;; + *x86-64*) echo "FAIL: host binary -- arm-none-eabi was not used"; exit 1 ;; + *) echo "FAIL: unexpected architecture"; exit 1 ;; + esac diff --git a/.github/workflows/rt1060.yml b/.github/workflows/rt1060.yml new file mode 100644 index 000000000..c11bef8a2 --- /dev/null +++ b/.github/workflows/rt1060.yml @@ -0,0 +1,107 @@ +name: RT1060 + +on: + push: + paths: + - 'RT1060/**' + - '.github/workflows/rt1060.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('rt1060-call-{0}', inputs.caller_run_id) || format('rt1060-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + rt1060: + needs: resolve + name: Build / rt1060 (arm-none-eabi) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + timeout-minutes: 25 + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install toolchain + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends \ + gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential >/dev/null + + # NXP publishes the same SDK on GitHub; CMSIS is a separate repo + - name: Fetch the MCUXpresso SDK + run: | + set -euo pipefail + git clone -q --depth 1 https://github.com/nxp-mcuxpresso/mcux-sdk /tmp/sdk + git clone -q --depth 1 https://github.com/nxp-mcuxpresso/CMSIS_5 /tmp/cmsis + cp -r /tmp/cmsis/CMSIS /tmp/sdk/CMSIS + # The Builder zip nests debug_console/str under the device dir; the + # public repo keeps them top-level. Makefile expects the Builder shape. + mkdir -p /tmp/sdk/devices/MIMXRT1062/utilities + cp -r /tmp/sdk/utilities/debug_console /tmp/sdk/devices/MIMXRT1062/utilities/ + cp -r /tmp/sdk/utilities/str /tmp/sdk/devices/MIMXRT1062/utilities/ + # the zip also folds assert/ and misc_utilities/ straight into utilities/ + cp -n /tmp/sdk/utilities/assert/*.[ch] \ + /tmp/sdk/utilities/misc_utilities/*.[ch] \ + /tmp/sdk/devices/MIMXRT1062/utilities/ 2>/dev/null || true + # The zip flattens the drivers; the repo keeps them under drivers// + for d in common igpio lpuart trng dcp cache/armv7-m7 cache/xcache; do + [ -d "/tmp/sdk/drivers/$d" ] || continue + cp -n /tmp/sdk/drivers/$d/*.[ch] /tmp/sdk/devices/MIMXRT1062/drivers/ 2>/dev/null || true + done + echo "gpio driver taken from: $(grep -l PDDR /tmp/sdk/devices/MIMXRT1062/drivers/fsl_gpio.h >/dev/null 2>&1 && echo generic || echo igpio)" + for d in devices/MIMXRT1062/drivers devices/MIMXRT1062/utilities/debug_console \ + devices/MIMXRT1062/utilities/str components/serial_manager \ + components/uart CMSIS/Core/Include; do + test -d "/tmp/sdk/$d" || { echo "FAIL: SDK missing $d"; exit 1; } + done + for h in utilities/debug_console/fsl_debug_console.h drivers/fsl_common.h \ + utilities/fsl_assert.c utilities/fsl_sbrk.c utilities/str/fsl_str.c; do + test -f "/tmp/sdk/devices/MIMXRT1062/$h" \ + || { echo "FAIL: $h not where the Makefile looks"; exit 1; } + done + + # $(SDK) is a selector, not a path: it gates the CPU define, board objects and linker script + - name: Build + run: | + set -euo pipefail + git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' https://github.com/wolfSSL/wolfssl /tmp/wolfssl + cd RT1060 + ln -s /tmp/sdk ./SDK_2_13_1_MIMXRT1060-EVKB + make WOLFSSL=/tmp/wolfssl + + - name: Assert it really cross-compiled + run: | + set -euo pipefail + cd RT1060 + elf=$(find . -name '*.elf' | head -n1) + [ -n "$elf" ] || { echo "FAIL: no .elf produced"; exit 1; } + arch=$(readelf -h "$elf" | awk -F: '/Machine:/ {print $2}' | xargs) + echo "machine: $arch" + case "$arch" in + *ARM*) echo "cross-compile verified" ;; + *) echo "FAIL: not an ARM binary: $arch"; exit 1 ;; + esac + + # cross-build.yml already triggered on puf/** but had no job to run diff --git a/.github/workflows/uefi.yml b/.github/workflows/uefi.yml new file mode 100644 index 000000000..00d2c28ee --- /dev/null +++ b/.github/workflows/uefi.yml @@ -0,0 +1,77 @@ +name: UEFI + +on: + push: + paths: + - 'uefi-static/**' + - 'uefi-library/**' + - '.github/workflows/uefi.yml' + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer + workflow_call: + inputs: + caller_run_id: + description: 'run id of the calling workflow; keeps a called run in its own concurrency group' + type: string + default: '' + workflow_dispatch: + +# github.workflow is the CALLER's name in a called workflow, so hardcode ours +concurrency: + group: ${{ inputs.caller_run_id && format('uefi-call-{0}', inputs.caller_run_id) || format('uefi-{0}', github.ref) }} + cancel-in-progress: ${{ !inputs.caller_run_id }} + +permissions: + contents: read + +jobs: + resolve: + uses: ./.github/workflows/_resolve-wolfssl.yml + with: + stable_count: 1 + + uefi: + needs: resolve + name: Build / uefi (${{ matrix.example }}) wolfSSL ${{ matrix.wolfssl_ref }} + runs-on: ubuntu-24.04 + timeout-minutes: 25 + strategy: + fail-fast: false + matrix: + wolfssl_ref: ${{ fromJson(needs.resolve.outputs.refs_json) }} + include: + # uefi-static clones wolfSSL itself; `all` is wolfcrypt.efi + - example: uefi-static + target: all + # lib-nohw sets the target-specific CFLAGS; naming test.efi directly loses them + - example: uefi-library + target: lib-nohw + steps: + - uses: actions/checkout@v5 + + - uses: ./.github/actions/apt-update + - name: Install gnu-efi toolchain + run: | + set -euo pipefail + sudo apt-get install -y --no-install-recommends \ + gnu-efi build-essential >/dev/null + + # uefi-library defaults WOLFSSL_PATH to a sibling checkout + - name: Clone wolfSSL + run: git clone -q --depth 1 --branch '${{ matrix.wolfssl_ref }}' https://github.com/wolfSSL/wolfssl /tmp/wolfssl + + - name: Build ${{ matrix.example }} (${{ matrix.target }}) + run: | + set -euo pipefail + cd '${{ matrix.example }}' + make '${{ matrix.target }}' WOLFSSL_PATH=/tmp/wolfssl + + - name: Assert an EFI binary came out + run: | + set -euo pipefail + cd '${{ matrix.example }}' + f=$(find . -name '*.efi' | head -n1) + [ -n "$f" ] || { echo "FAIL: no .efi produced"; exit 1; } + file "$f" + echo "verified: $f" diff --git a/.gitignore b/.gitignore index 1a31a0765..95412cb4f 100644 --- a/.gitignore +++ b/.gitignore @@ -203,6 +203,9 @@ pkcs7/envelopedData-ktri-stream pkcs7/envelopedData-kekri pkcs7/envelopedData-pwri pkcs7/envelopedData-ori +pkcs7/envelopedDataDecode +pkcs7/smime +pkcs7/smime-verify pkcs7/signedData pkcs7/signedData-stream pkcs7/signedData-cryptodev @@ -246,7 +249,7 @@ pk/rsa-pss/sign.bin pk/rsa/rsa-nb pk/ecc/ecc_verify pk/ecc/ecc_sign -pk/ecc/ecc_sign_determinisitc +pk/ecc/ecc_sign_deterministic pk/ecc/ecc_pub pk/ecc/ecc_keys @@ -434,3 +437,11 @@ http-message-signatures/http_client_signed uefi-library/efifs puf/Build + +# python bytecode from .github/scripts +__pycache__/ +crypto/keywrap/keywrap +pq/ml_kem/ml_kem + +# openssl ocsp -index writes this beside the index when it is missing +ocsp/stapling/responder-certs/index.txt.attr diff --git a/CSharp/README.md b/CSharp/README.md index 829c4b7dd..7e26b1b89 100644 --- a/CSharp/README.md +++ b/CSharp/README.md @@ -10,29 +10,29 @@ wolfSSL Server and Client using PQC algorithms (ML-KEM / ML-DSA). ### Build Options -The following build options need to be added. - -#### for `wolfssl` Project +`wrapper/CSharp/user_settings.h` already enables these, so a wolfSSL built +against it needs nothing added: ``` HAVE_MLKEM -WOLFSSL_WC_MLKEM WOLFSSL_HAVE_MLKEM WOLFSSL_DTLS_CH_FRAG -HAVE_DILITHIUM -WOLFSSL_WC_DILITHIUM +WOLFSSL_HAVE_MLDSA WOLFSSL_SHAKE128 WOLFSSL_SHAKE256 ``` -#### for `wolfSSL_CSharp` Project +On Linux that is: -``` -HAVE_MLKEM -HAVE_MLDSA +```sh +cd wolfssl +./configure --enable-usersettings CPPFLAGS=-I$PWD/wrapper/CSharp +make && sudo make install ``` -If you want to execute `wolfCrypt-Test` Project as well, add these options to `wolfCrypt-Test` Project. +The Visual Studio `wolfssl` project needs the same defines added to it. +The `wolfSSL_CSharp` project needs none: the wrapper compiles the ML-KEM and +ML-DSA bindings unconditionally. ### wolfSSL-TLS-pq-Server diff --git a/ESP32/DTLS13-wifi-station-client/main/Kconfig.projbuild b/ESP32/DTLS13-wifi-station-client/main/Kconfig.projbuild new file mode 100644 index 000000000..94cdd31cb --- /dev/null +++ b/ESP32/DTLS13-wifi-station-client/main/Kconfig.projbuild @@ -0,0 +1,45 @@ +menu "Example Configuration" + + config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + config ESP_MAXIMUM_RETRY + int "Maximum retry" + default 5 + help + Set the Maximum retry to avoid station reconnecting to the AP + unlimited when the AP is really inexistent. + + choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD + prompt "WiFi Scan auth mode threshold" + default ESP_WIFI_AUTH_WPA2_PSK + help + The weakest authmode to accept in the scan mode. + + config ESP_WIFI_AUTH_OPEN + bool "OPEN" + config ESP_WIFI_AUTH_WEP + bool "WEP" + config ESP_WIFI_AUTH_WPA_PSK + bool "WPA PSK" + config ESP_WIFI_AUTH_WPA2_PSK + bool "WPA2 PSK" + config ESP_WIFI_AUTH_WPA_WPA2_PSK + bool "WPA/WPA2 PSK" + config ESP_WIFI_AUTH_WPA3_PSK + bool "WPA3 PSK" + config ESP_WIFI_AUTH_WPA2_WPA3_PSK + bool "WPA2/WPA3 PSK" + config ESP_WIFI_AUTH_WAPI_PSK + bool "WAPI PSK" + endchoice +endmenu diff --git a/ESP32/DTLS13-wifi-station-client/main/client-dtls13.c b/ESP32/DTLS13-wifi-station-client/main/client-dtls13.c index ec85629bf..49ee35c51 100644 --- a/ESP32/DTLS13-wifi-station-client/main/client-dtls13.c +++ b/ESP32/DTLS13-wifi-station-client/main/client-dtls13.c @@ -68,7 +68,7 @@ static const char* const TAG = "server-dtls13"; -WOLFSSL_CTX* ctx = NULL; +static WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; int listenfd = INVALID_SOCKET; /* Initialize our socket */ @@ -199,7 +199,7 @@ WOLFSSL_ESP_TASK dtls13_smp_client_task(void *pvParameters) ESP_LOGI(TAG, "Sending message"); - XSTRCPY(sendLine, "Hello World."); + XSTRLCPY(sendLine, "Hello World.", sizeof(sendLine)); /* Send sendLine to the server */ if (wolfSSL_write(ssl, sendLine, XSTRLEN(sendLine)) != diff --git a/ESP32/DTLS13-wifi-station-client/main/include/wifi_connect.h b/ESP32/DTLS13-wifi-station-client/main/include/wifi_connect.h index 8228e911d..623161fce 100644 --- a/ESP32/DTLS13-wifi-station-client/main/include/wifi_connect.h +++ b/ESP32/DTLS13-wifi-station-client/main/include/wifi_connect.h @@ -39,7 +39,7 @@ **/ /* when using a private config with plain text passwords, not my_private_config.h should be excluded from git updates */ -#define USE_MY_PRIVATE_CONFIG +/* #define USE_MY_PRIVATE_CONFIG */ #ifdef USE_MY_PRIVATE_CONFIG #if defined(WOLFSSL_CMAKE_SYSTEM_NAME_WINDOWS) diff --git a/ESP32/DTLS13-wifi-station-server/main/Kconfig.projbuild b/ESP32/DTLS13-wifi-station-server/main/Kconfig.projbuild new file mode 100644 index 000000000..94cdd31cb --- /dev/null +++ b/ESP32/DTLS13-wifi-station-server/main/Kconfig.projbuild @@ -0,0 +1,45 @@ +menu "Example Configuration" + + config ESP_WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + + config ESP_WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + config ESP_MAXIMUM_RETRY + int "Maximum retry" + default 5 + help + Set the Maximum retry to avoid station reconnecting to the AP + unlimited when the AP is really inexistent. + + choice ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD + prompt "WiFi Scan auth mode threshold" + default ESP_WIFI_AUTH_WPA2_PSK + help + The weakest authmode to accept in the scan mode. + + config ESP_WIFI_AUTH_OPEN + bool "OPEN" + config ESP_WIFI_AUTH_WEP + bool "WEP" + config ESP_WIFI_AUTH_WPA_PSK + bool "WPA PSK" + config ESP_WIFI_AUTH_WPA2_PSK + bool "WPA2 PSK" + config ESP_WIFI_AUTH_WPA_WPA2_PSK + bool "WPA/WPA2 PSK" + config ESP_WIFI_AUTH_WPA3_PSK + bool "WPA3 PSK" + config ESP_WIFI_AUTH_WPA2_WPA3_PSK + bool "WPA2/WPA3 PSK" + config ESP_WIFI_AUTH_WAPI_PSK + bool "WAPI PSK" + endchoice +endmenu diff --git a/ESP32/DTLS13-wifi-station-server/main/include/wifi_connect.h b/ESP32/DTLS13-wifi-station-server/main/include/wifi_connect.h index eb5bbe6d5..e0352ed6c 100644 --- a/ESP32/DTLS13-wifi-station-server/main/include/wifi_connect.h +++ b/ESP32/DTLS13-wifi-station-server/main/include/wifi_connect.h @@ -47,7 +47,7 @@ **/ /* when using a private config with plain text passwords, not my_private_config.h should be excluded from git updates */ -#define USE_MY_PRIVATE_CONFIG +/* #define USE_MY_PRIVATE_CONFIG */ #ifdef USE_MY_PRIVATE_CONFIG #if defined(WOLFSSL_CMAKE_SYSTEM_NAME_WINDOWS) diff --git a/ESP32/DTLS13-wifi-station-server/main/server-dtls13.c b/ESP32/DTLS13-wifi-station-server/main/server-dtls13.c index 699fdbabc..85d750e31 100644 --- a/ESP32/DTLS13-wifi-station-server/main/server-dtls13.c +++ b/ESP32/DTLS13-wifi-station-server/main/server-dtls13.c @@ -72,7 +72,7 @@ static const char* const TAG = "server-dtls13"; -WOLFSSL_CTX* ctx = NULL; +static WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; int listenfd = INVALID_SOCKET; /* Initialize our socket */ diff --git a/ESP32/TLS13-ENC28J60-client/main/CMakeLists.txt b/ESP32/TLS13-ENC28J60-client/main/CMakeLists.txt index ad8c0a309..b554d3362 100644 --- a/ESP32/TLS13-ENC28J60-client/main/CMakeLists.txt +++ b/ESP32/TLS13-ENC28J60-client/main/CMakeLists.txt @@ -4,8 +4,5 @@ set(srcs enc28j60_example_main.c idf_component_register( SRCS "${srcs}" - INCLUDE_DIRS "." - PRIV_INCLUDE_DIRS - /SysGCC/esp32/esp-idf/v4.4/components - /SysGCC/esp32/esp-idf/v4.4/components/wolfssl) + INCLUDE_DIRS ".") set_source_files_properties(enc28j60_example_main2.c PROPERTIES HEADER_FILE_ONLY TRUE) diff --git a/ESP32/TLS13-ENC28J60-client/main/enc28j60_example_main.c b/ESP32/TLS13-ENC28J60-client/main/enc28j60_example_main.c index 4015c4d36..eee049479 100644 --- a/ESP32/TLS13-ENC28J60-client/main/enc28j60_example_main.c +++ b/ESP32/TLS13-ENC28J60-client/main/enc28j60_example_main.c @@ -996,8 +996,6 @@ int init_ENC28J60() { enc28j60_config.int_gpio_num = CONFIG_EXAMPLE_ENC28J60_INT_GPIO; eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); - mac_config.smi_mdc_gpio_num = -1; // ENC28J60 doesn't have SMI interface - mac_config.smi_mdio_gpio_num = -1; esp_eth_mac_t *mac = esp_eth_mac_new_enc28j60(&enc28j60_config, &mac_config); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); diff --git a/ESP32/TLS13-ENC28J60-client/main/esp_eth_phy_enc28j60.c b/ESP32/TLS13-ENC28J60-client/main/esp_eth_phy_enc28j60.c index cbc9cceea..96c386090 100644 --- a/ESP32/TLS13-ENC28J60-client/main/esp_eth_phy_enc28j60.c +++ b/ESP32/TLS13-ENC28J60-client/main/esp_eth_phy_enc28j60.c @@ -16,7 +16,6 @@ #include #include "esp_log.h" #include "esp_eth.h" -#include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" @@ -34,6 +33,24 @@ static const char *TAG = "enc28j60"; /***************Vendor Specific Register***************/ +/** + * @brief PHCON1(PHY Control Register 1) + * + */ +typedef union { + struct { + uint32_t reserved_7_0 : 8; // Reserved + uint32_t pdpxmd : 1; // PHY Duplex Mode + uint32_t reserved_10_9: 2; // Reserved + uint32_t ppwrsv: 1; // PHY Power-Down + uint32_t reserved_13_12: 2; // Reserved + uint32_t ploopbk: 1; // PHY Loopback + uint32_t prst: 1; // PHY Software Reset + }; + uint32_t val; +} phcon1_reg_t; +#define ETH_PHY_PHCON1_REG_ADDR (0x00) + /** * @brief PHCON2(PHY Control Register 2) * @@ -57,6 +74,44 @@ typedef union { * @brief PHSTAT2(PHY Status Register 2) * */ +/* IDF 5.x removed eth_phy_regs_struct.h; this is the standard 802.3 BMCR */ +typedef union { + struct { + uint32_t reserved_5_0 : 6; // Reserved + uint32_t speed_select_msb : 1;// Speed select MSB + uint32_t collision_test : 1; // Collision test + uint32_t duplex_mode : 1; // Duplex mode + uint32_t restart_auto_nego : 1; // Restart auto negotiation + uint32_t isolate : 1; // Isolate + uint32_t power_down : 1; // Power down + uint32_t en_auto_nego : 1; // Enable auto negotiation + uint32_t speed_select : 1; // Speed select LSB + uint32_t loopback : 1; // Loopback + uint32_t reset : 1; // Reset + }; + uint32_t val; +} bmcr_reg_t; +#define ETH_PHY_BMCR_REG_ADDR (0x00) + +/* standard 802.3 PHY identifier registers, also from the removed header */ +typedef union { + struct { + uint32_t oui_msb : 16; // Organizationally Unique Identifier bits 3:18 + }; + uint32_t val; +} phyidr1_reg_t; +#define ETH_PHY_IDR1_REG_ADDR (0x02) + +typedef union { + struct { + uint32_t model_revision : 4; // Model revision number + uint32_t vendor_model : 6; // Vendor model number + uint32_t oui_lsb : 6; // Organizationally Unique Identifier bits 19:24 + }; + uint32_t val; +} phyidr2_reg_t; +#define ETH_PHY_IDR2_REG_ADDR (0x03) + typedef union { struct { uint32_t reserved_4_0 : 5; // Reserved @@ -171,7 +226,8 @@ static esp_err_t enc28j60_reset_hw(esp_eth_phy_t *phy) return ESP_OK; } -static esp_err_t enc28j60_negotiate(esp_eth_phy_t *phy) +static esp_err_t enc28j60_autonego_ctrl(esp_eth_phy_t *phy, eth_phy_autoneg_cmd_t cmd, + bool *autoneg_en_stat) { /** * ENC28J60 does not support automatic duplex negotiation. @@ -180,9 +236,70 @@ static esp_err_t enc28j60_negotiate(esp_eth_phy_t *phy) * To communicate in Full-Duplex mode, ENC28J60 and the remote node * must be manually configured for full-duplex operation. */ + switch (cmd) { + case ESP_ETH_PHY_AUTONEGO_RESTART: + /* Fallthrough */ + case ESP_ETH_PHY_AUTONEGO_EN: + return ESP_ERR_NOT_SUPPORTED; + case ESP_ETH_PHY_AUTONEGO_DIS: + /* Fallthrough */ + case ESP_ETH_PHY_AUTONEGO_G_STAT: + *autoneg_en_stat = false; + break; + default: + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} + +static esp_err_t enc28j60_set_link(esp_eth_phy_t *phy, eth_link_t link) +{ phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - /* Updata information about link, speed, duplex */ - PHY_CHECK(enc28j60_update_link_duplex_speed(enc28j60) == ESP_OK, "update link duplex speed failed", err); + esp_eth_mediator_t *eth = enc28j60->eth; + + if (enc28j60->link_status != link) { + enc28j60->link_status = link; + PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_LINK, (void *)link) == ESP_OK, + "change link failed", err); + } + return ESP_OK; +err: + return ESP_FAIL; +} + +static esp_err_t enc28j60_set_speed(esp_eth_phy_t *phy, eth_speed_t speed) +{ + /* ENC28J60 supports only 10Mbps */ + if (speed == ETH_SPEED_10M) { + return ESP_OK; + } + return ESP_ERR_NOT_SUPPORTED; +} + +static esp_err_t enc28j60_set_duplex(esp_eth_phy_t *phy, eth_duplex_t duplex) +{ + phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); + esp_eth_mediator_t *eth = enc28j60->eth; + phcon1_reg_t phcon1; + + /* the link is being reconfigured, so report it down until the driver restarts */ + enc28j60->link_status = ETH_LINK_DOWN; + + PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_PHCON1_REG_ADDR, &(phcon1.val)) == ESP_OK, + "read PHCON1 failed", err); + switch (duplex) { + case ETH_DUPLEX_HALF: + phcon1.pdpxmd = 0; + break; + case ETH_DUPLEX_FULL: + phcon1.pdpxmd = 1; + break; + default: + PHY_CHECK(false, "unknown duplex", err); + break; + } + PHY_CHECK(eth->phy_reg_write(eth, enc28j60->addr, ETH_PHY_PHCON1_REG_ADDR, phcon1.val) == ESP_OK, + "write PHCON1 failed", err); return ESP_OK; err: return ESP_FAIL; @@ -292,11 +409,14 @@ esp_eth_phy_t *esp_eth_phy_new_enc28j60(const eth_phy_config_t *config) enc28j60->parent.init = enc28j60_init; enc28j60->parent.deinit = enc28j60_deinit; enc28j60->parent.set_mediator = enc28j60_set_mediator; - enc28j60->parent.negotiate = enc28j60_negotiate; + enc28j60->parent.autonego_ctrl = enc28j60_autonego_ctrl; enc28j60->parent.get_link = enc28j60_get_link; + enc28j60->parent.set_link = enc28j60_set_link; enc28j60->parent.pwrctl = enc28j60_pwrctl; enc28j60->parent.get_addr = enc28j60_get_addr; enc28j60->parent.set_addr = enc28j60_set_addr; + enc28j60->parent.set_speed = enc28j60_set_speed; + enc28j60->parent.set_duplex = enc28j60_set_duplex; enc28j60->parent.del = enc28j60_del; return &(enc28j60->parent); err: diff --git a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/CMakeLists.txt b/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/CMakeLists.txt deleted file mode 100644 index 687c597bc..000000000 --- a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -idf_component_register(SRCS "esp_eth_mac_enc28j60.c" - "esp_eth_phy_enc28j60.c" - INCLUDE_DIRS ".") diff --git a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/component.mk b/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/component.mk deleted file mode 100644 index 9706df8e6..000000000 --- a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/component.mk +++ /dev/null @@ -1,6 +0,0 @@ -# -# "main" pseudo-component makefile. -# -# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) - -COMPONENT_ADD_INCLUDEDIRS := . diff --git a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/enc28j60.h b/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/enc28j60.h deleted file mode 100644 index 45a52330a..000000000 --- a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/enc28j60.h +++ /dev/null @@ -1,238 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief SPI Instruction Set - * - */ -#define ENC28J60_SPI_CMD_RCR (0x00) // Read Control Register -#define ENC28J60_SPI_CMD_RBM (0x01) // Read Buffer Memory -#define ENC28J60_SPI_CMD_WCR (0x02) // Write Control Register -#define ENC28J60_SPI_CMD_WBM (0x03) // Write Buffer Memory -#define ENC28J60_SPI_CMD_BFS (0x04) // Bit Field Set -#define ENC28J60_SPI_CMD_BFC (0x05) // Bit Field Clear -#define ENC28J60_SPI_CMD_SRC (0x07) // Soft Reset - -/** - * @brief Shared Registers in ENC28J60 (accessible on each bank) - * - */ -#define ENC28J60_EIE (0x1B) // Ethernet Interrupt Enable -#define ENC28J60_EIR (0x1C) // Ethernet Interrupt flags -#define ENC28J60_ESTAT (0x1D) // Ethernet Status -#define ENC28J60_ECON2 (0x1E) // Ethernet Control Register2 -#define ENC28J60_ECON1 (0x1F) // Ethernet Control Register1 - -/** - * @brief Per-bank Registers in ENC28J60 - * @note Address[15:12]: Register Type, 0 -> ETH, 1 -> MII/MAC - * Address[11:8] : Bank address - * Address[7:0] : Register Index - */ -// Bank 0 Registers -#define ENC28J60_ERDPTL (0x0000) // Read Pointer Low Byte ERDPT<7:0>) -#define ENC28J60_ERDPTH (0x0001) // Read Pointer High Byte (ERDPT<12:8>) -#define ENC28J60_EWRPTL (0x0002) // Write Pointer Low Byte (EWRPT<7:0>) -#define ENC28J60_EWRPTH (0x0003) // Write Pointer High Byte (EWRPT<12:8>) -#define ENC28J60_ETXSTL (0x0004) // TX Start Low Byte (ETXST<7:0>) -#define ENC28J60_ETXSTH (0x0005) // TX Start High Byte (ETXST<12:8>) -#define ENC28J60_ETXNDL (0x0006) // TX End Low Byte (ETXND<7:0>) -#define ENC28J60_ETXNDH (0x0007) // TX End High Byte (ETXND<12:8>) -#define ENC28J60_ERXSTL (0x0008) // RX Start Low Byte (ERXST<7:0>) -#define ENC28J60_ERXSTH (0x0009) // RX Start High Byte (ERXST<12:8>) -#define ENC28J60_ERXNDL (0x000A) // RX End Low Byte (ERXND<7:0>) -#define ENC28J60_ERXNDH (0x000B) // RX End High Byte (ERXND<12:8>) -#define ENC28J60_ERXRDPTL (0x000C) // RX RD Pointer Low Byte (ERXRDPT<7:0>) -#define ENC28J60_ERXRDPTH (0x000D) // RX RD Pointer High Byte (ERXRDPT<12:8>) -#define ENC28J60_ERXWRPTL (0x000E) // RX WR Pointer Low Byte (ERXWRPT<7:0>) -#define ENC28J60_ERXWRPTH (0x000F) // RX WR Pointer High Byte (ERXWRPT<12:8>) -#define ENC28J60_EDMASTL (0x0010) // DMA Start Low Byte (EDMAST<7:0>) -#define ENC28J60_EDMASTH (0x0011) // DMA Start High Byte (EDMAST<12:8>) -#define ENC28J60_EDMANDL (0x0012) // DMA End Low Byte (EDMAND<7:0>) -#define ENC28J60_EDMANDH (0x0013) // DMA End High Byte (EDMAND<12:8>) -#define ENC28J60_EDMADSTL (0x0014) // DMA Destination Low Byte (EDMADST<7:0>) -#define ENC28J60_EDMADSTH (0x0015) // DMA Destination High Byte (EDMADST<12:8>) -#define ENC28J60_EDMACSL (0x0016) // DMA Checksum Low Byte (EDMACS<7:0>) -#define ENC28J60_EDMACSH (0x0017) // DMA Checksum High Byte (EDMACS<15:8>) - -// Bank 1 Registers -#define ENC28J60_EHT0 (0x0100) // Hash Table Byte 0 (EHT<7:0>) -#define ENC28J60_EHT1 (0x0101) // Hash Table Byte 1 (EHT<15:8>) -#define ENC28J60_EHT2 (0x0102) // Hash Table Byte 2 (EHT<23:16>) -#define ENC28J60_EHT3 (0x0103) // Hash Table Byte 3 (EHT<31:24>) -#define ENC28J60_EHT4 (0x0104) // Hash Table Byte 4 (EHT<39:32>) -#define ENC28J60_EHT5 (0x0105) // Hash Table Byte 5 (EHT<47:40>) -#define ENC28J60_EHT6 (0x0106) // Hash Table Byte 6 (EHT<55:48>) -#define ENC28J60_EHT7 (0x0107) // Hash Table Byte 7 (EHT<63:56>) -#define ENC28J60_EPMM0 (0x0108) // Pattern Match Mask Byte 0 (EPMM<7:0>) -#define ENC28J60_EPMM1 (0x0109) // Pattern Match Mask Byte 1 (EPMM<15:8>) -#define ENC28J60_EPMM2 (0x010A) // Pattern Match Mask Byte 2 (EPMM<23:16>) -#define ENC28J60_EPMM3 (0x010B) // Pattern Match Mask Byte 3 (EPMM<31:24>) -#define ENC28J60_EPMM4 (0x010C) // Pattern Match Mask Byte 4 (EPMM<39:32>) -#define ENC28J60_EPMM5 (0x010D) // Pattern Match Mask Byte 5 (EPMM<47:40>) -#define ENC28J60_EPMM6 (0x010E) // Pattern Match Mask Byte 6 (EPMM<55:48>) -#define ENC28J60_EPMM7 (0x010F) // Pattern Match Mask Byte 7 (EPMM<63:56>) -#define ENC28J60_EPMCSL (0x0110) // Pattern Match Checksum Low Byte (EPMCS<7:0>) -#define ENC28J60_EPMCSH (0x0111) // Pattern Match Checksum High Byte (EPMCS<15:0>) -#define ENC28J60_EPMOL (0x0114) // Pattern Match Offset Low Byte (EPMO<7:0>) -#define ENC28J60_EPMOH (0x0115) // Pattern Match Offset High Byte (EPMO<12:8>) -#define ENC28J60_ERXFCON (0x0118) // Receive Fileter Control -#define ENC28J60_EPKTCNT (0x0119) // Ethernet Packet Count - -// Bank 2 Register -#define ENC28J60_MACON1 (0x1200) // MAC Control Register 1 -#define ENC28J60_MACON2 (0x1201) // MAC Control Register 2 -#define ENC28J60_MACON3 (0x1202) // MAC Control Register 3 -#define ENC28J60_MACON4 (0x1203) // MAC Control Register 4 -#define ENC28J60_MABBIPG (0x1204) // Back-to-Back Inter-Packet Gap (BBIPG<6:0>) -#define ENC28J60_MAIPGL (0x1206) // Non-Back-to-Back Inter-Packet Gap Low Byte (MAIPGL<6:0>) -#define ENC28J60_MAIPGH (0x1207) // Non-Back-to-Back Inter-Packet Gap High Byte (MAIPGH<6:0>) -#define ENC28J60_MACLCON1 (0x1208) // Retransmission Maximum (RETMAX<3:0>) -#define ENC28J60_MACLCON2 (0x1209) // Collision Window (COLWIN<5:0>) -#define ENC28J60_MAMXFLL (0x120A) // Maximum Frame Length Low Byte (MAMXFL<7:0>) -#define ENC28J60_MAMXFLH (0x120B) // Maximum Frame Length High Byte (MAMXFL<15:8>) -#define ENC28J60_MICMD (0x1212) // MII Command Register -#define ENC28J60_MIREGADR (0x1214) // MII Register Address (MIREGADR<4:0>) -#define ENC28J60_MIWRL (0x1216) // MII Write Data Low Byte (MIWR<7:0>) -#define ENC28J60_MIWRH (0x1217) // MII Write Data High Byte (MIWR<15:8>) -#define ENC28J60_MIRDL (0x1218) // MII Read Data Low Byte (MIRD<7:0>) -#define ENC28J60_MIRDH (0x1219) // MII Read Data High Byte(MIRD<15:8>) - -// Bank 3 Registers -#define ENC28J60_MAADR5 (0x1300) // MAC Address Byte 5 (MAADR<15:8>) -#define ENC28J60_MAADR6 (0x1301) // MAC Address Byte 6 (MAADR<7:0>) -#define ENC28J60_MAADR3 (0x1302) // MAC Address Byte 3 (MAADR<31:24>), OUI Byte 3 -#define ENC28J60_MAADR4 (0x1303) // MAC Address Byte 4 (MAADR<23:16>) -#define ENC28J60_MAADR1 (0x1304) // MAC Address Byte 1 (MAADR<47:40>), OUI Byte 1 -#define ENC28J60_MAADR2 (0x1305) // MAC Address Byte 2 (MAADR<39:32>), OUI Byte 2 -#define ENC28J60_EBSTSD (0x0306) // Built-in Self-Test Fill Seed (EBSTSD<7:0>) -#define ENC28J60_EBSTCON (0x0307) // Built-in Self-Test Control -#define ENC28J60_EBSTCSL (0x0308) // Built-in Self-Test Checksum Low Byte (EBSTCS<7:0>) -#define ENC28J60_EBSTCSH (0x0309) // Built-in Self-Test Checksum High Byte (EBSTCS<15:8>) -#define ENC28J60_MISTAT (0x130A) // MII Status Register -#define ENC28J60_EREVID (0x0312) // Ethernet Revision ID (EREVID<4:0>) -#define ENC28J60_ECOCON (0x0315) // Clock Output Control Register -#define ENC28J60_EFLOCON (0x0317) // Ethernet Flow Control -#define ENC28J60_EPAUSL (0x0318) // Pause Timer Value Low Byte (EPAUS<7:0>) -#define ENC28J60_EPAUSH (0x0319) // Pause Timer Value High Byte (EPAUS<15:8>) - -/** - * @brief status and flag of ENC28J60 specific registers - * - */ -// EIE bit definitions -#define EIE_INTIE (1<<7) // Global INT Interrupt Enable -#define EIE_PKTIE (1<<6) // Receive Packet Pending Interrupt Enable -#define EIE_DMAIE (1<<5) // DMA Interrupt Enable -#define EIE_LINKIE (1<<4) // Link Status Change Interrupt Enable -#define EIE_TXIE (1<<3) // Transmit Enable -#define EIE_TXERIE (1<<1) // Transmit Error Interrupt Enable -#define EIE_RXERIE (1<<0) // Receive Error Interrupt Enable - -// EIR bit definitions -#define EIR_PKTIF (1<<6) // Receive Packet Pending Interrupt Flag -#define EIR_DMAIF (1<<5) // DMA Interrupt Flag -#define EIR_LINKIF (1<<4) // Link Change Interrupt Flag -#define EIR_TXIF (1<<3) // Transmit Interrupt Flag -#define EIR_TXERIF (1<<1) // Transmit Error Interrupt Flag -#define EIR_RXERIF (1<<0) // Receive Error Interrupt Flag - -// ESTAT bit definitions -#define ESTAT_INT (1<<7) // INT Interrupt Flag -#define ESTAT_BUFER (1<<6) // Buffer Error Status -#define ESTAT_LATECOL (1<<4) // Late Collision Error -#define ESTAT_RXBUSY (1<<2) // Receive Busy -#define ESTAT_TXABRT (1<<1) // Transmit Abort Error -#define ESTAT_CLKRDY (1<<0) // Clock Ready - -// ECON2 bit definitions -#define ECON2_AUTOINC (1<<7) // Automatic Buffer Pointer Increment Enable -#define ECON2_PKTDEC (1<<6) // Packet Decrement -#define ECON2_PWRSV (1<<5) // Power Save Enable -#define ECON2_VRPS (1<<3) // Voltage Regulator Power Save Enable - -// ECON1 bit definitions -#define ECON1_TXRST (1<<7) // Transmit Logic Reset -#define ECON1_RXRST (1<<6) // Receive Logic Reset -#define ECON1_DMAST (1<<5) // DMA Start and Busy Status -#define ECON1_CSUMEN (1<<4) // DMA Checksum Enable -#define ECON1_TXRTS (1<<3) // Transmit Request to Send -#define ECON1_RXEN (1<<2) // Receive Enable -#define ECON1_BSEL1 (1<<1) // Bank Select1 -#define ECON1_BSEL0 (1<<0) // Bank Select0 - -// ERXFCON bit definitions -#define ERXFCON_UCEN (1<<7) // Unicast Filter Enable -#define ERXFCON_ANDOR (1<<6) // AND/OR Filter Select -#define ERXFCON_CRCEN (1<<5) // Post-Filter CRC Check Enable -#define ERXFCON_PMEN (1<<4) // Pattern Match Filter Enable -#define ERXFCON_MPEN (1<<3) // Magic Packet Filter Enable -#define ERXFCON_HTEN (1<<2) // Hash Table Filter Enable -#define ERXFCON_MCEN (1<<1) // Multicast Filter Enable -#define ERXFCON_BCEN (1<<0) // Broadcast Filter Enable - -// MACON1 bit definitions -#define MACON1_TXPAUS (1<<3) // Pause Control Frame Transmission Enable -#define MACON1_RXPAUS (1<<2) // Pause Control Frame Reception Enable -#define MACON1_PASSALL (1<<1) // Pass All Received Frames Enable -#define MACON1_MARXEN (1<<0) // MAC Receive Enable - -// MACON3 bit definitions -#define MACON3_PADCFG2 (1<<7) // Automatic Pad and CRC Configuration bit 2 -#define MACON3_PADCFG1 (1<<6) // Automatic Pad and CRC Configuration bit 1 -#define MACON3_PADCFG0 (1<<5) // Automatic Pad and CRC Configuration bit 0 -#define MACON3_TXCRCEN (1<<4) // Transmit CRC Enable -#define MACON3_PHDRLEN (1<<3) // Proprietary Header Enable -#define MACON3_HFRMLEN (1<<2) // Huge Frame Enable -#define MACON3_FRMLNEN (1<<1) // Frame Length Checking Enable -#define MACON3_FULDPX (1<<0) // MAC Full-Duplex Enable - -// MACON4 bit definitions -#define MACON4_DEFER (1<<6) // Defer Transmission Enable -#define MACON4_BPEN (1<<5) // No Backoff During Backpressure Enable -#define MACON4_NOBKFF (1<<4) // No Backoff Enable - -// MICMD bit definitions -#define MICMD_MIISCAN (1<<1) // MII Scan Enable -#define MICMD_MIIRD (1<<0) // MII Read Enable - -// EBSTCON bit definitions -#define EBSTCON_PSV2 (1<<7) // Pattern Shift Value 2 -#define EBSTCON_PSV1 (1<<6) // Pattern Shift Value 1 -#define EBSTCON_PSV0 (1<<5) // Pattern Shift Value 0 -#define EBSTCON_PSEL (1<<4) // Port Select -#define EBSTCON_TMSEL1 (1<<3) // Test Mode Select 1 -#define EBSTCON_TMSEL0 (1<<2) // Test Mode Select 0 -#define EBSTCON_TME (1<<1) // Test Mode Enable -#define EBSTCON_BISTST (1<<0) // Built-in Self-Test Start/Busy - -// MISTAT bit definitions -#define MISTAT_NVALID (1<<2) // MII Management Read Data Not Valid -#define MISTAT_SCAN (1<<1) // MII Management Scan Operation in Progress -#define MISTAT_BUSY (1<<0) // MII Management Busy - -// EFLOCON bit definitions -#define EFLOCON_FULDPXS (1<<2) // Full-Duplex Shadown -#define EFLOCON_FCEN1 (1<<1) // Flow Control Enable 1 -#define EFLOCON_FCEN0 (1<<0) // Flow Control Enable 0 - -#ifdef __cplusplus -} -#endif diff --git a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_enc28j60.h b/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_enc28j60.h deleted file mode 100644 index 666a93297..000000000 --- a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_enc28j60.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp_eth_phy.h" -#include "esp_eth_mac.h" -#include "driver/spi_master.h" - -#define CS_HOLD_TIME_MIN_NS 210 - -/** - * @brief ENC28J60 specific configuration - * - */ -typedef struct { - spi_device_handle_t spi_hdl; /*!< Handle of SPI device driver */ - int int_gpio_num; /*!< Interrupt GPIO number */ -} eth_enc28j60_config_t; - -/** - * @brief ENC28J60 Supported Revisions - * - */ -typedef enum { - ENC28J60_REV_B1 = 0b00000010, - ENC28J60_REV_B4 = 0b00000100, - ENC28J60_REV_B5 = 0b00000101, - ENC28J60_REV_B7 = 0b00000110 -} eth_enc28j60_rev_t; - -/** - * @brief Default ENC28J60 specific configuration - * - */ -#define ETH_ENC28J60_DEFAULT_CONFIG(spi_device) \ - { \ - .spi_hdl = spi_device, \ - .int_gpio_num = 4, \ - } - -/** - * @brief Compute amount of SPI bit-cycles the CS should stay active after the transmission - * to meet ENC28J60 CS Hold Time specification. - * - * @param clock_speed_mhz SPI Clock frequency in MHz (valid range is <1, 20>) - * @return uint8_t - */ -static inline uint8_t enc28j60_cal_spi_cs_hold_time(int clock_speed_mhz) -{ - if (clock_speed_mhz <= 0 || clock_speed_mhz > 20) { - return 0; - } - int temp = clock_speed_mhz * CS_HOLD_TIME_MIN_NS; - uint8_t cs_posttrans = temp / 1000; - if (temp % 1000) { - cs_posttrans += 1; - } - - return cs_posttrans; -} - -/** -* @brief Create ENC28J60 Ethernet MAC instance -* -* @param[in] enc28j60_config: ENC28J60 specific configuration -* @param[in] mac_config: Ethernet MAC configuration -* -* @return -* - instance: create MAC instance successfully -* - NULL: create MAC instance failed because some error occurred -*/ -esp_eth_mac_t *esp_eth_mac_new_enc28j60(const eth_enc28j60_config_t *enc28j60_config, const eth_mac_config_t *mac_config); - -/** -* @brief Create a PHY instance of ENC28J60 -* -* @param[in] config: configuration of PHY -* -* @return -* - instance: create PHY instance successfully -* - NULL: create PHY instance failed because some error occurred -*/ -esp_eth_phy_t *esp_eth_phy_new_enc28j60(const eth_phy_config_t *config); - -// todo: the below functions should be accessed through ioctl in the future -/** - * @brief Set ENC28J60 Duplex mode. It sets Duplex mode first to the PHY and then - * MAC is set based on what PHY indicates. - * - * @param phy ENC28J60 PHY Handle - * @param duplex Duplex mode - * - * @return esp_err_t - * - ESP_OK when PHY registers were correctly written. - */ -esp_err_t enc28j60_set_phy_duplex(esp_eth_phy_t *phy, eth_duplex_t duplex); - -/** - * @brief Get ENC28J60 silicon revision ID - * - * @param mac ENC28J60 MAC Handle - * @return eth_enc28j60_rev_t - * - returns silicon revision ID read during initialization - */ -eth_enc28j60_rev_t emac_enc28j60_get_chip_info(esp_eth_mac_t *mac); - -#ifdef __cplusplus -} -#endif diff --git a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_mac_enc28j60.c b/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_mac_enc28j60.c deleted file mode 100644 index 76dd46411..000000000 --- a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_mac_enc28j60.c +++ /dev/null @@ -1,1123 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include -#include -#include -#include "driver/gpio.h" -#include "esp_attr.h" -#include "esp_log.h" -#include "esp_eth.h" -#include "esp_system.h" -#include "esp_intr_alloc.h" -#include "esp_heap_caps.h" -#include "esp_rom_sys.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "hal/cpu_hal.h" -#include "esp_eth_enc28j60.h" -#include "enc28j60.h" -#include "sdkconfig.h" - -static const char *TAG = "enc28j60"; -#define MAC_CHECK(a, str, goto_tag, ret_value, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - ret = ret_value; \ - goto goto_tag; \ - } \ - } while (0) - -#define MAC_CHECK_NO_RET(a, str, goto_tag, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - goto goto_tag; \ - } \ - } while (0) - -#define ENC28J60_SPI_LOCK_TIMEOUT_MS (50) -#define ENC28J60_REG_TRANS_LOCK_TIMEOUT_MS (150) -#define ENC28J60_PHY_OPERATION_TIMEOUT_US (150) -#define ENC28J60_SYSTEM_RESET_ADDITION_TIME_US (1000) -#define ENC28J60_TX_READY_TIMEOUT_MS (2000) - -#define ENC28J60_BUFFER_SIZE (0x2000) // 8KB built-in buffer -/** - * ______ - * |__TX__| TX: 2 KB : [0x1800, 0x2000) - * | | - * | RX | RX: 6 KB : [0x0000, 0x1800) - * |______| - * - */ -#define ENC28J60_BUF_RX_START (0) -#define ENC28J60_BUF_RX_END (ENC28J60_BUF_TX_START - 1) -#define ENC28J60_BUF_TX_START ((ENC28J60_BUFFER_SIZE / 4) * 3) -#define ENC28J60_BUF_TX_END (ENC28J60_BUFFER_SIZE - 1) - -#define ENC28J60_RSV_SIZE (6) // Receive Status Vector Size -#define ENC28J60_TSV_SIZE (6) // Transmit Status Vector Size - -typedef struct { - uint8_t next_packet_low; - uint8_t next_packet_high; - uint8_t length_low; - uint8_t length_high; - uint8_t status_low; - uint8_t status_high; -} enc28j60_rx_header_t; - -typedef struct { - uint16_t byte_cnt; - - uint8_t collision_cnt:4; - uint8_t crc_err:1; - uint8_t len_check_err:1; - uint8_t len_out_range:1; - uint8_t tx_done:1; - - uint8_t multicast:1; - uint8_t broadcast:1; - uint8_t pkt_defer:1; - uint8_t excessive_defer:1; - uint8_t excessive_collision:1; - uint8_t late_collision:1; - uint8_t giant:1; - uint8_t underrun:1; - - uint16_t bytes_on_wire; - - uint8_t ctrl_frame:1; - uint8_t pause_ctrl_frame:1; - uint8_t backpressure_app:1; - uint8_t vlan_frame:1; -} enc28j60_tsv_t; - -typedef struct { - esp_eth_mac_t parent; - esp_eth_mediator_t *eth; - spi_device_handle_t spi_hdl; - SemaphoreHandle_t spi_lock; - SemaphoreHandle_t reg_trans_lock; - SemaphoreHandle_t tx_ready_sem; - TaskHandle_t rx_task_hdl; - uint32_t sw_reset_timeout_ms; - uint32_t next_packet_ptr; - uint32_t last_tsv_addr; - int int_gpio_num; - uint8_t addr[6]; - uint8_t last_bank; - bool packets_remain; - eth_enc28j60_rev_t revision; -} emac_enc28j60_t; - -static inline bool enc28j60_spi_lock(emac_enc28j60_t *emac) -{ - return xSemaphoreTake(emac->spi_lock, pdMS_TO_TICKS(ENC28J60_SPI_LOCK_TIMEOUT_MS)) == pdTRUE; -} - -static inline bool enc28j60_spi_unlock(emac_enc28j60_t *emac) -{ - return xSemaphoreGive(emac->spi_lock) == pdTRUE; -} - -static inline bool enc28j60_reg_trans_lock(emac_enc28j60_t *emac) -{ - return xSemaphoreTake(emac->reg_trans_lock, pdMS_TO_TICKS(ENC28J60_REG_TRANS_LOCK_TIMEOUT_MS)) == pdTRUE; -} - -static inline bool enc28j60_reg_trans_unlock(emac_enc28j60_t *emac) -{ - return xSemaphoreGive(emac->reg_trans_lock) == pdTRUE; -} - -/** - * @brief ERXRDPT need to be set always at odd addresses - */ -static inline uint32_t enc28j60_next_ptr_align_odd(uint32_t next_packet_ptr, uint32_t start, uint32_t end) -{ - uint32_t erxrdpt; - - if ((next_packet_ptr - 1 < start) || (next_packet_ptr - 1 > end)) { - erxrdpt = end; - } else { - erxrdpt = next_packet_ptr - 1; - } - - return erxrdpt; -} - -/** - * @brief Calculate wrap around when reading beyond the end of the RX buffer - */ -static inline uint32_t enc28j60_rx_packet_start(uint32_t start_addr, uint32_t off) -{ - if (start_addr + off > ENC28J60_BUF_RX_END) { - return (start_addr + off) - (ENC28J60_BUF_RX_END - ENC28J60_BUF_RX_START + 1); - } else { - return start_addr + off; - } -} - -/** - * @brief SPI operation wrapper for writing ENC28J60 internal register - */ -static esp_err_t enc28j60_do_register_write(emac_enc28j60_t *emac, uint8_t reg_addr, uint8_t value) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_WCR, // Write control register - .addr = reg_addr, - .length = 8, - .flags = SPI_TRANS_USE_TXDATA, - .tx_data = { - [0] = value - } - }; - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -} - -/** - * @brief SPI operation wrapper for reading ENC28J60 internal register - */ -static esp_err_t enc28j60_do_register_read(emac_enc28j60_t *emac, bool is_eth_reg, uint8_t reg_addr, uint8_t *value) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_RCR, // Read control register - .addr = reg_addr, - .length = is_eth_reg ? 8 : 16, // read operation is different for ETH register and non-ETH register - .flags = SPI_TRANS_USE_RXDATA - }; - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } else { - *value = is_eth_reg ? trans.rx_data[0] : trans.rx_data[1]; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -} - -/** - * @brief SPI operation wrapper for bitwise setting ENC28J60 internal register - * @note can only be used for ETH registers - */ -static esp_err_t enc28j60_do_bitwise_set(emac_enc28j60_t *emac, uint8_t reg_addr, uint8_t mask) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_BFS, // Bit field set - .addr = reg_addr, - .length = 8, - .flags = SPI_TRANS_USE_TXDATA, - .tx_data = { - [0] = mask - } - }; - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -} - -/** - * @brief SPI operation wrapper for bitwise clearing ENC28J60 internal register - * @note can only be used for ETH registers - */ -static esp_err_t enc28j60_do_bitwise_clr(emac_enc28j60_t *emac, uint8_t reg_addr, uint8_t mask) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_BFC, // Bit field clear - .addr = reg_addr, - .length = 8, - .flags = SPI_TRANS_USE_TXDATA, - .tx_data = { - [0] = mask - } - }; - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -} - -/** - * @brief SPI operation wrapper for writing ENC28J60 internal memory - */ -static esp_err_t enc28j60_do_memory_write(emac_enc28j60_t *emac, uint8_t *buffer, uint32_t len) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_WBM, // Write buffer memory - .addr = 0x1A, - .length = len * 8, - .tx_buffer = buffer - }; - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -} - -/** - * @brief SPI operation wrapper for reading ENC28J60 internal memory - */ -static esp_err_t enc28j60_do_memory_read(emac_enc28j60_t *emac, uint8_t *buffer, uint32_t len) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_RBM, // Read buffer memory - .addr = 0x1A, - .length = len * 8, - .rx_buffer = buffer - }; - - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -} - -/** - * @brief SPI operation wrapper for resetting ENC28J60 - */ -static esp_err_t enc28j60_do_reset(emac_enc28j60_t *emac) -{ - esp_err_t ret = ESP_OK; - spi_transaction_t trans = { - .cmd = ENC28J60_SPI_CMD_SRC, // Soft reset - .addr = 0x1F, - }; - if (enc28j60_spi_lock(emac)) { - if (spi_device_polling_transmit(emac->spi_hdl, &trans) != ESP_OK) { - ESP_LOGE(TAG, "%s(%d): spi transmit failed", __FUNCTION__, __LINE__); - ret = ESP_FAIL; - } - enc28j60_spi_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - - // After reset, wait at least 1ms for the device to be ready - esp_rom_delay_us(ENC28J60_SYSTEM_RESET_ADDITION_TIME_US); - - return ret; -} - -/** - * @brief Switch ENC28J60 register bank - */ -static esp_err_t enc28j60_switch_register_bank(emac_enc28j60_t *emac, uint8_t bank) -{ - esp_err_t ret = ESP_OK; - if (bank != emac->last_bank) { - MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_ECON1, 0x03) == ESP_OK, - "clear ECON1[1:0] failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_bitwise_set(emac, ENC28J60_ECON1, bank & 0x03) == ESP_OK, - "set ECON1[1:0] failed", out, ESP_FAIL); - emac->last_bank = bank; - } -out: - return ret; -} - -/** - * @brief Write ENC28J60 register - */ -static esp_err_t enc28j60_register_write(emac_enc28j60_t *emac, uint16_t reg_addr, uint8_t value) -{ - esp_err_t ret = ESP_OK; - if (enc28j60_reg_trans_lock(emac)) { - MAC_CHECK(enc28j60_switch_register_bank(emac, (reg_addr & 0xF00) >> 8) == ESP_OK, - "switch bank failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_register_write(emac, reg_addr & 0xFF, value) == ESP_OK, - "write register failed", out, ESP_FAIL); - enc28j60_reg_trans_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -out: - enc28j60_reg_trans_unlock(emac); - return ret; -} - -/** - * @brief Read ENC28J60 register - */ -static esp_err_t enc28j60_register_read(emac_enc28j60_t *emac, uint16_t reg_addr, uint8_t *value) -{ - esp_err_t ret = ESP_OK; - if (enc28j60_reg_trans_lock(emac)) { - MAC_CHECK(enc28j60_switch_register_bank(emac, (reg_addr & 0xF00) >> 8) == ESP_OK, - "switch bank failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_register_read(emac, !(reg_addr & 0xF000), reg_addr & 0xFF, value) == ESP_OK, - "read register failed", out, ESP_FAIL); - enc28j60_reg_trans_unlock(emac); - } else { - ret = ESP_ERR_TIMEOUT; - } - return ret; -out: - enc28j60_reg_trans_unlock(emac); - return ret; -} - -/** - * @brief Read ENC28J60 internal memroy - */ -static esp_err_t enc28j60_read_packet(emac_enc28j60_t *emac, uint32_t addr, uint8_t *packet, uint32_t len) -{ - esp_err_t ret = ESP_OK; - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERDPTL, addr & 0xFF) == ESP_OK, - "write ERDPTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERDPTH, (addr & 0xFF00) >> 8) == ESP_OK, - "write ERDPTH failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_memory_read(emac, packet, len) == ESP_OK, - "read memory failed", out, ESP_FAIL); -out: - return ret; -} - -/** - * @brief Write ENC28J60 internal PHY register - */ -static esp_err_t emac_enc28j60_write_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr, - uint32_t phy_reg, uint32_t reg_value) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - uint8_t mii_status; - - /* check if phy access is in progress */ - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MISTAT, &mii_status) == ESP_OK, - "read MISTAT failed", out, ESP_FAIL); - MAC_CHECK(!(mii_status & MISTAT_BUSY), "phy is busy", out, ESP_ERR_INVALID_STATE); - - /* tell the PHY address to write */ - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MIREGADR, phy_reg & 0xFF) == ESP_OK, - "write MIREGADR failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MIWRL, reg_value & 0xFF) == ESP_OK, - "write MIWRL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MIWRH, (reg_value & 0xFF00) >> 8) == ESP_OK, - "write MIWRH failed", out, ESP_FAIL); - - /* polling the busy flag */ - uint32_t to = 0; - do { - esp_rom_delay_us(15); - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MISTAT, &mii_status) == ESP_OK, - "read MISTAT failed", out, ESP_FAIL); - to += 15; - } while ((mii_status & MISTAT_BUSY) && to < ENC28J60_PHY_OPERATION_TIMEOUT_US); - MAC_CHECK(!(mii_status & MISTAT_BUSY), "phy is busy", out, ESP_ERR_TIMEOUT); -out: - return ret; -} - -/** - * @brief Read ENC28J60 internal PHY register - */ -static esp_err_t emac_enc28j60_read_phy_reg(esp_eth_mac_t *mac, uint32_t phy_addr, - uint32_t phy_reg, uint32_t *reg_value) -{ - esp_err_t ret = ESP_OK; - MAC_CHECK(reg_value, "can't set reg_value to null", out, ESP_ERR_INVALID_ARG); - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - uint8_t mii_status; - uint8_t mii_cmd; - - /* check if phy access is in progress */ - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MISTAT, &mii_status) == ESP_OK, - "read MISTAT failed", out, ESP_FAIL); - MAC_CHECK(!(mii_status & MISTAT_BUSY), "phy is busy", out, ESP_ERR_INVALID_STATE); - - /* tell the PHY address to read */ - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MIREGADR, phy_reg & 0xFF) == ESP_OK, - "write MIREGADR failed", out, ESP_FAIL); - mii_cmd = MICMD_MIIRD; - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MICMD, mii_cmd) == ESP_OK, - "write MICMD failed", out, ESP_FAIL); - - /* polling the busy flag */ - uint32_t to = 0; - do { - esp_rom_delay_us(15); - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MISTAT, &mii_status) == ESP_OK, - "read MISTAT failed", out, ESP_FAIL); - to += 15; - } while ((mii_status & MISTAT_BUSY) && to < ENC28J60_PHY_OPERATION_TIMEOUT_US); - MAC_CHECK(!(mii_status & MISTAT_BUSY), "phy is busy", out, ESP_ERR_TIMEOUT); - - mii_cmd &= (~MICMD_MIIRD); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MICMD, mii_cmd) == ESP_OK, - "write MICMD failed", out, ESP_FAIL); - - uint8_t value_l = 0; - uint8_t value_h = 0; - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MIRDL, &value_l) == ESP_OK, - "read MIRDL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MIRDH, &value_h) == ESP_OK, - "read MIRDH failed", out, ESP_FAIL); - *reg_value = (value_h << 8) | value_l; -out: - return ret; -} - -/** - * @brief Set mediator for Ethernet MAC - */ -static esp_err_t emac_enc28j60_set_mediator(esp_eth_mac_t *mac, esp_eth_mediator_t *eth) -{ - esp_err_t ret = ESP_OK; - MAC_CHECK(eth, "can't set mac's mediator to null", out, ESP_ERR_INVALID_ARG); - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - emac->eth = eth; -out: - return ret; -} - -/** - * @brief Verify chip revision ID - */ -static esp_err_t enc28j60_verify_id(emac_enc28j60_t *emac) -{ - esp_err_t ret = ESP_OK; - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_EREVID, (uint8_t *)&emac->revision) == ESP_OK, - "read EREVID failed", out, ESP_FAIL); - ESP_LOGI(TAG, "revision: %d", emac->revision); - MAC_CHECK(emac->revision >= ENC28J60_REV_B1 && emac->revision <= ENC28J60_REV_B7, "wrong chip ID", out, ESP_ERR_INVALID_VERSION); -out: - return ret; -} - -/** - * @brief Write mac address to internal registers - */ -static esp_err_t enc28j60_set_mac_addr(emac_enc28j60_t *emac) -{ - esp_err_t ret = ESP_OK; - - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAADR6, emac->addr[5]) == ESP_OK, - "write MAADR6 failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAADR5, emac->addr[4]) == ESP_OK, - "write MAADR5 failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAADR4, emac->addr[3]) == ESP_OK, - "write MAADR4 failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAADR3, emac->addr[2]) == ESP_OK, - "write MAADR3 failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAADR2, emac->addr[1]) == ESP_OK, - "write MAADR2 failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAADR1, emac->addr[0]) == ESP_OK, - "write MAADR1 failed", out, ESP_FAIL); -out: - return ret; -} - -/** - * @brief Clear multicast hash table - */ -static esp_err_t enc28j60_clear_multicast_table(emac_enc28j60_t *emac) -{ - esp_err_t ret = ESP_OK; - - for (int i = 0; i < 7; i++) { - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_EHT0 + i, 0x00) == ESP_OK, - "write ENC28J60_EHT%d failed", out, ESP_FAIL, i); - } -out: - return ret; -} - -/** - * @brief Default setup for ENC28J60 internal registers - */ -static esp_err_t enc28j60_setup_default(emac_enc28j60_t *emac) -{ - esp_err_t ret = ESP_OK; - - // set up receive buffer start + end - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXSTL, ENC28J60_BUF_RX_START & 0xFF) == ESP_OK, - "write ERXSTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXSTH, (ENC28J60_BUF_RX_START & 0xFF00) >> 8) == ESP_OK, - "write ERXSTH failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXNDL, ENC28J60_BUF_RX_END & 0xFF) == ESP_OK, - "write ERXNDL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXNDH, (ENC28J60_BUF_RX_END & 0xFF00) >> 8) == ESP_OK, - "write ERXNDH failed", out, ESP_FAIL); - uint32_t erxrdpt = enc28j60_next_ptr_align_odd(ENC28J60_BUF_RX_START, ENC28J60_BUF_RX_START, ENC28J60_BUF_RX_END); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXRDPTL, erxrdpt & 0xFF) == ESP_OK, - "write ERXRDPTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXRDPTH, (erxrdpt & 0xFF00) >> 8) == ESP_OK, - "write ERXRDPTH failed", out, ESP_FAIL); - - // set up transmit buffer start + end - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ETXSTL, ENC28J60_BUF_TX_START & 0xFF) == ESP_OK, - "write ETXSTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ETXSTH, (ENC28J60_BUF_TX_START & 0xFF00) >> 8) == ESP_OK, - "write ETXSTH failed", out, ESP_FAIL); - - // set up default filter mode: (unicast OR broadcast) AND crc valid - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN) == ESP_OK, - "write ERXFCON failed", out, ESP_FAIL); - - // enable MAC receive, enable pause control frame on Tx and Rx path - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MACON1, MACON1_MARXEN | MACON1_RXPAUS | MACON1_TXPAUS) == ESP_OK, - "write MACON1 failed", out, ESP_FAIL); - // enable automatic padding, append CRC, check frame length, half duplex by default (can update at runtime) - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN) == ESP_OK, "write MACON3 failed", out, ESP_FAIL); - // enable defer transmission (effective only in half duplex) - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MACON4, MACON4_DEFER) == ESP_OK, - "write MACON4 failed", out, ESP_FAIL); - // set inter-frame gap (back-to-back) - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MABBIPG, 0x12) == ESP_OK, - "write MABBIPG failed", out, ESP_FAIL); - // set inter-frame gap (non-back-to-back) - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAIPGL, 0x12) == ESP_OK, - "write MAIPGL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MAIPGH, 0x0C) == ESP_OK, - "write MAIPGH failed", out, ESP_FAIL); - -out: - return ret; -} - -/** - * @brief Start enc28j60: enable interrupt and start receive - */ -static esp_err_t emac_enc28j60_start(esp_eth_mac_t *mac) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - /* enable interrupt */ - MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, 0xFF) == ESP_OK, - "clear EIR failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_bitwise_set(emac, ENC28J60_EIE, EIE_PKTIE | EIE_INTIE | EIE_TXERIE) == ESP_OK, - "set EIE.[PKTIE|INTIE] failed", out, ESP_FAIL); - /* enable rx logic */ - MAC_CHECK(enc28j60_do_bitwise_set(emac, ENC28J60_ECON1, ECON1_RXEN) == ESP_OK, - "set ECON1.RXEN failed", out, ESP_FAIL); - - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERDPTL, 0x00) == ESP_OK, - "write ERDPTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERDPTH, 0x00) == ESP_OK, - "write ERDPTH failed", out, ESP_FAIL); -out: - return ret; -} - -/** - * @brief Stop enc28j60: disable interrupt and stop receiving packets - */ -static esp_err_t emac_enc28j60_stop(esp_eth_mac_t *mac) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - /* disable interrupt */ - MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIE, 0xFF) == ESP_OK, - "clear EIE failed", out, ESP_FAIL); - /* disable rx */ - MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_ECON1, ECON1_RXEN) == ESP_OK, - "clear ECON1.RXEN failed", out, ESP_FAIL); -out: - return ret; -} - -static esp_err_t emac_enc28j60_set_addr(esp_eth_mac_t *mac, uint8_t *addr) -{ - esp_err_t ret = ESP_OK; - MAC_CHECK(addr, "can't set mac addr to null", out, ESP_ERR_INVALID_ARG); - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - memcpy(emac->addr, addr, 6); - MAC_CHECK(enc28j60_set_mac_addr(emac) == ESP_OK, "set mac address failed", out, ESP_FAIL); -out: - return ret; -} - -static esp_err_t emac_enc28j60_get_addr(esp_eth_mac_t *mac, uint8_t *addr) -{ - esp_err_t ret = ESP_OK; - MAC_CHECK(addr, "can't set mac addr to null", out, ESP_ERR_INVALID_ARG); - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - memcpy(addr, emac->addr, 6); -out: - return ret; -} - -static inline esp_err_t emac_enc28j60_get_tsv(emac_enc28j60_t *emac, enc28j60_tsv_t *tsv) -{ - return enc28j60_read_packet(emac, emac->last_tsv_addr, (uint8_t *)tsv, ENC28J60_TSV_SIZE); -} - -static void enc28j60_isr_handler(void *arg) -{ - emac_enc28j60_t *emac = (emac_enc28j60_t *)arg; - BaseType_t high_task_wakeup = pdFALSE; - /* notify enc28j60 task */ - vTaskNotifyGiveFromISR(emac->rx_task_hdl, &high_task_wakeup); - if (high_task_wakeup != pdFALSE) { - portYIELD_FROM_ISR(); - } -} - -/** - * @brief Main ENC28J60 Task. Mainly used for Rx processing. However, it also handles other interrupts. - * - */ -static void emac_enc28j60_task(void *arg) -{ - emac_enc28j60_t *emac = (emac_enc28j60_t *)arg; - uint8_t status = 0; - uint8_t mask = 0; - uint8_t *buffer = NULL; - uint32_t length = 0; - - while (1) { -loop_start: - // block until some task notifies me or check the gpio by myself - if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) == 0 && // if no notification ... - gpio_get_level(emac->int_gpio_num) != 0) { // ...and no interrupt asserted - continue; // -> just continue to check again - } - // the host controller should clear the global enable bit for the interrupt pin before servicing the interrupt - MAC_CHECK_NO_RET(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, EIE_INTIE) == ESP_OK, - "clear EIE_INTIE failed", loop_start); - // read interrupt status - MAC_CHECK_NO_RET(enc28j60_do_register_read(emac, true, ENC28J60_EIR, &status) == ESP_OK, - "read EIR failed", loop_end); - MAC_CHECK_NO_RET(enc28j60_do_register_read(emac, true, ENC28J60_EIE, &mask) == ESP_OK, - "read EIE failed", loop_end); - status &= mask; - - // When source of interrupt is unknown, try to check if there is packet waiting (Errata #6 workaround) - if (status == 0) { - uint8_t pk_counter; - MAC_CHECK_NO_RET(enc28j60_register_read(emac, ENC28J60_EPKTCNT, &pk_counter) == ESP_OK, - "read EPKTCNT failed", loop_end); - if (pk_counter > 0) { - status = EIR_PKTIF; - } else { - goto loop_end; - } - } - - // packet received - if (status & EIR_PKTIF) { - do { - length = ETH_MAX_PACKET_SIZE; - buffer = heap_caps_malloc(length, MALLOC_CAP_DMA); - if (!buffer) { - ESP_LOGE(TAG, "no mem for receive buffer"); - } else if (emac->parent.receive(&emac->parent, buffer, &length) == ESP_OK) { - /* pass the buffer to stack (e.g. TCP/IP layer) */ - if (length) { - emac->eth->stack_input(emac->eth, buffer, length); - } else { - free(buffer); - } - } else { - free(buffer); - } - } while (emac->packets_remain); - } - - // transmit error - if (status & EIR_TXERIF) { - // Errata #12/#13 workaround - reset Tx state machine - MAC_CHECK_NO_RET(enc28j60_do_bitwise_set(emac, ENC28J60_ECON1, ECON1_TXRST) == ESP_OK, - "set TXRST failed", loop_end); - MAC_CHECK_NO_RET(enc28j60_do_bitwise_clr(emac, ENC28J60_ECON1, ECON1_TXRST) == ESP_OK, - "clear TXRST failed", loop_end); - - // Clear Tx Error Interrupt Flag - MAC_CHECK_NO_RET(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, EIR_TXERIF) == ESP_OK, - "clear TXERIF failed", loop_end); - - // Errata #13 workaround (applicable only to B5 and B7 revisions) - if (emac->revision == ENC28J60_REV_B5 || emac->revision == ENC28J60_REV_B7) { - __attribute__((aligned(4))) enc28j60_tsv_t tx_status; // SPI driver needs the rx buffer 4 byte align - MAC_CHECK_NO_RET(emac_enc28j60_get_tsv(emac, &tx_status) == ESP_OK, - "get Tx Status Vector failed", loop_end); - // Try to retransmit when late collision is indicated - if (tx_status.late_collision) { - // Clear Tx Interrupt status Flag (it was set along with the error) - MAC_CHECK_NO_RET(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, EIR_TXIF) == ESP_OK, - "clear TXIF failed", loop_end); - // Enable global interrupt flag and try to retransmit - MAC_CHECK_NO_RET(enc28j60_do_bitwise_set(emac, ENC28J60_EIE, EIE_INTIE) == ESP_OK, - "set INTIE failed", loop_end); - MAC_CHECK_NO_RET(enc28j60_do_bitwise_set(emac, ENC28J60_ECON1, ECON1_TXRTS) == ESP_OK, - "set TXRTS failed", loop_end); - continue; // no need to handle Tx ready interrupt nor to enable global interrupt at this point - } - } - } - - // transmit ready - if (status & EIR_TXIF) { - MAC_CHECK_NO_RET(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, EIR_TXIF) == ESP_OK, - "clear TXIF failed", loop_end); - MAC_CHECK_NO_RET(enc28j60_do_bitwise_clr(emac, ENC28J60_EIE, EIE_TXIE) == ESP_OK, - "clear TXIE failed", loop_end); - - xSemaphoreGive(emac->tx_ready_sem); - } -loop_end: - // restore global enable interrupt bit - MAC_CHECK_NO_RET(enc28j60_do_bitwise_set(emac, ENC28J60_EIE, EIE_INTIE) == ESP_OK, - "clear INTIE failed", loop_start); - // Note: Interrupt flag PKTIF is cleared when PKTDEC is set (in receive function) - } - vTaskDelete(NULL); -} - -static esp_err_t emac_enc28j60_set_link(esp_eth_mac_t *mac, eth_link_t link) -{ - esp_err_t ret = ESP_OK; - switch (link) { - case ETH_LINK_UP: - MAC_CHECK(mac->start(mac) == ESP_OK, "enc28j60 start failed", out, ESP_FAIL); - break; - case ETH_LINK_DOWN: - MAC_CHECK(mac->stop(mac) == ESP_OK, "enc28j60 stop failed", out, ESP_FAIL); - break; - default: - MAC_CHECK(false, "unknown link status", out, ESP_ERR_INVALID_ARG); - break; - } -out: - return ret; -} - -static esp_err_t emac_enc28j60_set_speed(esp_eth_mac_t *mac, eth_speed_t speed) -{ - esp_err_t ret = ESP_OK; - switch (speed) { - case ETH_SPEED_10M: - ESP_LOGI(TAG, "working in 10Mbps"); - break; - default: - MAC_CHECK(false, "100Mbps unsupported", out, ESP_ERR_NOT_SUPPORTED); - break; - } -out: - return ret; -} - -static esp_err_t emac_enc28j60_set_duplex(esp_eth_mac_t *mac, eth_duplex_t duplex) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - uint8_t mac3 = 0; - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_MACON3, &mac3) == ESP_OK, - "read MACON3 failed", out, ESP_FAIL); - switch (duplex) { - case ETH_DUPLEX_HALF: - mac3 &= ~MACON3_FULDPX; - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MABBIPG, 0x12) == ESP_OK, - "write MABBIPG failed", out, ESP_FAIL); - ESP_LOGI(TAG, "working in half duplex"); - break; - case ETH_DUPLEX_FULL: - mac3 |= MACON3_FULDPX; - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MABBIPG, 0x15) == ESP_OK, - "write MABBIPG failed", out, ESP_FAIL); - ESP_LOGI(TAG, "working in full duplex"); - break; - default: - MAC_CHECK(false, "unknown duplex", out, ESP_ERR_INVALID_ARG); - break; - } - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_MACON3, mac3) == ESP_OK, - "write MACON3 failed", out, ESP_FAIL); -out: - return ret; -} - -static esp_err_t emac_enc28j60_set_promiscuous(esp_eth_mac_t *mac, bool enable) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - if (enable) { - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXFCON, 0x00) == ESP_OK, - "write ERXFCON failed", out, ESP_FAIL); - } -out: - return ret; -} - -static esp_err_t emac_enc28j60_transmit(esp_eth_mac_t *mac, uint8_t *buf, uint32_t length) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - uint8_t econ1 = 0; - - /* ENC28J60 may be a bottle neck in Eth communication. Hence we need to check if it is ready. */ - if (xSemaphoreTake(emac->tx_ready_sem, pdMS_TO_TICKS(ENC28J60_TX_READY_TIMEOUT_MS)) == pdFALSE) { - ESP_LOGW(TAG, "tx_ready_sem expired"); - } - MAC_CHECK(enc28j60_do_register_read(emac, true, ENC28J60_ECON1, &econ1) == ESP_OK, - "read ECON1 failed", out, ESP_FAIL); - MAC_CHECK(!(econ1 & ECON1_TXRTS), "last transmit still in progress", out, ESP_ERR_INVALID_STATE); - - /* Set the write pointer to start of transmit buffer area */ - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_EWRPTL, ENC28J60_BUF_TX_START & 0xFF) == ESP_OK, - "write EWRPTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_EWRPTH, (ENC28J60_BUF_TX_START & 0xFF00) >> 8) == ESP_OK, - "write EWRPTH failed", out, ESP_FAIL); - - /* Set the end pointer to correspond to the packet size given */ - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ETXNDL, (ENC28J60_BUF_TX_START + length) & 0xFF) == ESP_OK, - "write ETXNDL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ETXNDH, ((ENC28J60_BUF_TX_START + length) & 0xFF00) >> 8) == ESP_OK, - "write ETXNDH failed", out, ESP_FAIL); - - /* copy data to tx memory */ - uint8_t per_pkt_control = 0; // MACON3 will be used to determine how the packet will be transmitted - MAC_CHECK(enc28j60_do_memory_write(emac, &per_pkt_control, 1) == ESP_OK, - "write packet control byte failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_memory_write(emac, buf, length) == ESP_OK, - "buffer memory write failed", out, ESP_FAIL); - emac->last_tsv_addr = ENC28J60_BUF_TX_START + length + 1; - - /* enable Tx Interrupt to indicate next Tx ready state */ - MAC_CHECK(enc28j60_do_bitwise_clr(emac, ENC28J60_EIR, EIR_TXIF) == ESP_OK, - "set EIR_TXIF failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_do_bitwise_set(emac, ENC28J60_EIE, EIE_TXIE) == ESP_OK, - "set EIE_TXIE failed", out, ESP_FAIL); - - /* issue tx polling command */ - MAC_CHECK(enc28j60_do_bitwise_set(emac, ENC28J60_ECON1, ECON1_TXRTS) == ESP_OK, - "set ECON1.TXRTS failed", out, ESP_FAIL); -out: - return ret; -} - -static esp_err_t emac_enc28j60_receive(esp_eth_mac_t *mac, uint8_t *buf, uint32_t *length) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - uint8_t pk_counter = 0; - uint16_t rx_len = 0; - uint32_t next_packet_addr = 0; - __attribute__((aligned(4))) enc28j60_rx_header_t header; // SPI driver needs the rx buffer 4 byte align - - // read packet header - MAC_CHECK(enc28j60_read_packet(emac, emac->next_packet_ptr, (uint8_t *)&header, sizeof(header)) == ESP_OK, - "read header failed", out, ESP_FAIL); - - // get packets' length, address - rx_len = header.length_low + (header.length_high << 8); - next_packet_addr = header.next_packet_low + (header.next_packet_high << 8); - - // read packet content - MAC_CHECK(enc28j60_read_packet(emac, enc28j60_rx_packet_start(emac->next_packet_ptr, ENC28J60_RSV_SIZE), buf, rx_len) == ESP_OK, - "read packet content failed", out, ESP_FAIL); - - // free receive buffer space - uint32_t erxrdpt = enc28j60_next_ptr_align_odd(next_packet_addr, ENC28J60_BUF_RX_START, ENC28J60_BUF_RX_END); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXRDPTL, (erxrdpt & 0xFF)) == ESP_OK, - "write ERXRDPTL failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_write(emac, ENC28J60_ERXRDPTH, (erxrdpt & 0xFF00) >> 8) == ESP_OK, - "write ERXRDPTH failed", out, ESP_FAIL); - emac->next_packet_ptr = next_packet_addr; - - MAC_CHECK(enc28j60_do_bitwise_set(emac, ENC28J60_ECON2, ECON2_PKTDEC) == ESP_OK, - "set ECON2.PKTDEC failed", out, ESP_FAIL); - MAC_CHECK(enc28j60_register_read(emac, ENC28J60_EPKTCNT, &pk_counter) == ESP_OK, - "read EPKTCNT failed", out, ESP_FAIL); - - *length = rx_len - 4; // substract the CRC length - emac->packets_remain = pk_counter > 0; -out: - return ret; -} - -/** - * @brief Get chip info - */ -eth_enc28j60_rev_t emac_enc28j60_get_chip_info(esp_eth_mac_t *mac) -{ - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - return emac->revision; -} - -static esp_err_t emac_enc28j60_init(esp_eth_mac_t *mac) -{ - esp_err_t ret = ESP_OK; - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - esp_eth_mediator_t *eth = emac->eth; - - /* init gpio used for reporting enc28j60 interrupt */ - gpio_reset_pin(emac->int_gpio_num); - gpio_set_direction(emac->int_gpio_num, GPIO_MODE_INPUT); - gpio_set_pull_mode(emac->int_gpio_num, GPIO_PULLUP_ONLY); - gpio_set_intr_type(emac->int_gpio_num, GPIO_INTR_NEGEDGE); - gpio_intr_enable(emac->int_gpio_num); - gpio_isr_handler_add(emac->int_gpio_num, enc28j60_isr_handler, emac); - MAC_CHECK(eth->on_state_changed(eth, ETH_STATE_LLINIT, NULL) == ESP_OK, - "lowlevel init failed", out, ESP_FAIL); - - /* reset enc28j60 */ - MAC_CHECK(enc28j60_do_reset(emac) == ESP_OK, "reset enc28j60 failed", out, ESP_FAIL); - /* verify chip id */ - MAC_CHECK(enc28j60_verify_id(emac) == ESP_OK, "vefiry chip ID failed", out, ESP_FAIL); - /* default setup of internal registers */ - MAC_CHECK(enc28j60_setup_default(emac) == ESP_OK, "enc28j60 default setup failed", out, ESP_FAIL); - /* clear multicast hash table */ - MAC_CHECK(enc28j60_clear_multicast_table(emac) == ESP_OK, "clear multicast table failed", out, ESP_FAIL); - - return ESP_OK; -out: - gpio_isr_handler_remove(emac->int_gpio_num); - gpio_reset_pin(emac->int_gpio_num); - eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); - return ret; -} - -static esp_err_t emac_enc28j60_deinit(esp_eth_mac_t *mac) -{ - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - esp_eth_mediator_t *eth = emac->eth; - mac->stop(mac); - gpio_isr_handler_remove(emac->int_gpio_num); - gpio_reset_pin(emac->int_gpio_num); - eth->on_state_changed(eth, ETH_STATE_DEINIT, NULL); - return ESP_OK; -} - -static esp_err_t emac_enc28j60_del(esp_eth_mac_t *mac) -{ - emac_enc28j60_t *emac = __containerof(mac, emac_enc28j60_t, parent); - vTaskDelete(emac->rx_task_hdl); - vSemaphoreDelete(emac->spi_lock); - vSemaphoreDelete(emac->reg_trans_lock); - vSemaphoreDelete(emac->tx_ready_sem); - free(emac); - return ESP_OK; -} - -esp_eth_mac_t *esp_eth_mac_new_enc28j60(const eth_enc28j60_config_t *enc28j60_config, const eth_mac_config_t *mac_config) -{ - esp_eth_mac_t *ret = NULL; - emac_enc28j60_t *emac = NULL; - MAC_CHECK(enc28j60_config, "can't set enc28j60 specific config to null", err, NULL); - MAC_CHECK(mac_config, "can't set mac config to null", err, NULL); - emac = calloc(1, sizeof(emac_enc28j60_t)); - MAC_CHECK(emac, "calloc emac failed", err, NULL); - /* enc28j60 driver is interrupt driven */ - MAC_CHECK(enc28j60_config->int_gpio_num >= 0, "error interrupt gpio number", err, NULL); - emac->last_bank = 0xFF; - emac->next_packet_ptr = ENC28J60_BUF_RX_START; - /* bind methods and attributes */ - emac->sw_reset_timeout_ms = mac_config->sw_reset_timeout_ms; - emac->int_gpio_num = enc28j60_config->int_gpio_num; - emac->spi_hdl = enc28j60_config->spi_hdl; - emac->parent.set_mediator = emac_enc28j60_set_mediator; - emac->parent.init = emac_enc28j60_init; - emac->parent.deinit = emac_enc28j60_deinit; - emac->parent.start = emac_enc28j60_start; - emac->parent.stop = emac_enc28j60_stop; - emac->parent.del = emac_enc28j60_del; - emac->parent.write_phy_reg = emac_enc28j60_write_phy_reg; - emac->parent.read_phy_reg = emac_enc28j60_read_phy_reg; - emac->parent.set_addr = emac_enc28j60_set_addr; - emac->parent.get_addr = emac_enc28j60_get_addr; - emac->parent.set_speed = emac_enc28j60_set_speed; - emac->parent.set_duplex = emac_enc28j60_set_duplex; - emac->parent.set_link = emac_enc28j60_set_link; - emac->parent.set_promiscuous = emac_enc28j60_set_promiscuous; - emac->parent.transmit = emac_enc28j60_transmit; - emac->parent.receive = emac_enc28j60_receive; - /* create mutex */ - emac->spi_lock = xSemaphoreCreateMutex(); - MAC_CHECK(emac->spi_lock, "create spi lock failed", err, NULL); - emac->reg_trans_lock = xSemaphoreCreateMutex(); - MAC_CHECK(emac->reg_trans_lock, "create register transaction lock failed", err, NULL); - emac->tx_ready_sem = xSemaphoreCreateBinary(); - MAC_CHECK(emac->tx_ready_sem, "create pkt transmit ready semaphore failed", err, NULL); - xSemaphoreGive(emac->tx_ready_sem); // ensures the first transmit is performed without waiting - /* create enc28j60 task */ - BaseType_t core_num = tskNO_AFFINITY; - if (mac_config->flags & ETH_MAC_FLAG_PIN_TO_CORE) { - core_num = cpu_hal_get_core_id(); - } - BaseType_t xReturned = xTaskCreatePinnedToCore(emac_enc28j60_task, "enc28j60_tsk", mac_config->rx_task_stack_size, emac, - mac_config->rx_task_prio, &emac->rx_task_hdl, core_num); - MAC_CHECK(xReturned == pdPASS, "create enc28j60 task failed", err, NULL); - - return &(emac->parent); -err: - if (emac) { - if (emac->rx_task_hdl) { - vTaskDelete(emac->rx_task_hdl); - } - if (emac->spi_lock) { - vSemaphoreDelete(emac->spi_lock); - } - if (emac->reg_trans_lock) { - vSemaphoreDelete(emac->reg_trans_lock); - } - if (emac->tx_ready_sem) { - vSemaphoreDelete(emac->tx_ready_sem); - } - free(emac); - } - return ret; -} diff --git a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_phy_enc28j60.c b/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_phy_enc28j60.c deleted file mode 100644 index ee2e80f65..000000000 --- a/ESP32/TLS13-ENC28J60-server/components/eth_enc28j60/esp_eth_phy_enc28j60.c +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include -#include -#include -#include "esp_log.h" -#include "esp_eth.h" -#include "eth_phy_regs_struct.h" -#include "esp_eth_enc28j60.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "driver/gpio.h" - -static const char *TAG = "enc28j60"; -#define PHY_CHECK(a, str, goto_tag, ...) \ - do \ - { \ - if (!(a)) \ - { \ - ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ - goto goto_tag; \ - } \ - } while (0) - -/***************Vendor Specific Register***************/ - -/** - * @brief PHCON2(PHY Control Register 2) - * - */ -typedef union { - struct { - uint32_t reserved_7_0 : 8; // Reserved - uint32_t pdpxmd : 1; // PHY Duplex Mode bit - uint32_t reserved_10_9: 2; // Reserved - uint32_t ppwrsv: 1; // PHY Power-Down bit - uint32_t reserved_13_12: 2; // Reserved - uint32_t ploopbk: 1; // PHY Loopback bit - uint32_t prst: 1; // PHY Software Reset bit - }; - uint32_t val; -} phcon1_reg_t; -#define ETH_PHY_PHCON1_REG_ADDR (0x00) - -/** - * @brief PHCON2(PHY Control Register 2) - * - */ -typedef union { - struct { - uint32_t reserved_7_0 : 8; // Reserved - uint32_t hdldis : 1; // Half-Duplex Loopback Disable - uint32_t reserved_9: 1; // Reserved - uint32_t jabber: 1; // Disable Jabber Correction - uint32_t reserved_12_11: 2; // Reserved - uint32_t txdis: 1; // Disable Twist-Pair Transmitter - uint32_t frclnk: 1; // Force Linkup - uint32_t reserved_15: 1; //Reserved - }; - uint32_t val; -} phcon2_reg_t; -#define ETH_PHY_PHCON2_REG_ADDR (0x10) - -/** - * @brief PHSTAT2(PHY Status Register 2) - * - */ -typedef union { - struct { - uint32_t reserved_4_0 : 5; // Reserved - uint32_t plrity : 1; // Polarity Status - uint32_t reserved_8_6 : 3; // Reserved - uint32_t dpxstat : 1; // PHY Duplex Status - uint32_t lstat : 1; // PHY Link Status (non-latching) - uint32_t colstat : 1; // PHY Collision Status - uint32_t rxstat : 1; // PHY Receive Status - uint32_t txstat : 1; // PHY Transmit Status - uint32_t reserved_15_14 : 2; // Reserved - }; - uint32_t val; -} phstat2_reg_t; -#define ETH_PHY_PHSTAT2_REG_ADDR (0x11) - -typedef struct { - esp_eth_phy_t parent; - esp_eth_mediator_t *eth; - uint32_t addr; - uint32_t reset_timeout_ms; - eth_link_t link_status; - int reset_gpio_num; -} phy_enc28j60_t; - -static esp_err_t enc28j60_update_link_duplex_speed(phy_enc28j60_t *enc28j60) -{ - esp_eth_mediator_t *eth = enc28j60->eth; - eth_speed_t speed = ETH_SPEED_10M; // enc28j60 speed is fixed to 10Mbps - eth_duplex_t duplex = ETH_DUPLEX_HALF; - phstat2_reg_t phstat; - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_PHSTAT2_REG_ADDR, &(phstat.val)) == ESP_OK, - "read PHSTAT2 failed", err); - eth_link_t link = phstat.lstat ? ETH_LINK_UP : ETH_LINK_DOWN; - /* check if link status changed */ - if (enc28j60->link_status != link) { - /* when link up, read result */ - if (link == ETH_LINK_UP) { - if (phstat.dpxstat) { - duplex = ETH_DUPLEX_FULL; - } else { - duplex = ETH_DUPLEX_HALF; - } - PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_SPEED, (void *)speed) == ESP_OK, - "change speed failed", err); - PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_DUPLEX, (void *)duplex) == ESP_OK, - "change duplex failed", err); - } - PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_LINK, (void *)link) == ESP_OK, - "change link failed", err); - enc28j60->link_status = link; - } - return ESP_OK; -err: - return ESP_FAIL; -} - -static esp_err_t enc28j60_set_mediator(esp_eth_phy_t *phy, esp_eth_mediator_t *eth) -{ - PHY_CHECK(eth, "can't set mediator for enc28j60 to null", err); - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - enc28j60->eth = eth; - return ESP_OK; -err: - return ESP_ERR_INVALID_ARG; -} - -static esp_err_t enc28j60_get_link(esp_eth_phy_t *phy) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - /* Updata information about link, speed, duplex */ - PHY_CHECK(enc28j60_update_link_duplex_speed(enc28j60) == ESP_OK, "update link duplex speed failed", err); - return ESP_OK; -err: - return ESP_FAIL; -} - -static esp_err_t enc28j60_reset(esp_eth_phy_t *phy) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - enc28j60->link_status = ETH_LINK_DOWN; - esp_eth_mediator_t *eth = enc28j60->eth; - bmcr_reg_t bmcr = {.reset = 1}; - PHY_CHECK(eth->phy_reg_write(eth, enc28j60->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, - "write BMCR failed", err); - /* Wait for reset complete */ - uint32_t to = 0; - for (to = 0; to < enc28j60->reset_timeout_ms / 10; to++) { - vTaskDelay(pdMS_TO_TICKS(10)); - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, - "read BMCR failed", err); - if (!bmcr.reset) { - break; - } - } - PHY_CHECK(to < enc28j60->reset_timeout_ms / 10, "PHY reset timeout", err); - return ESP_OK; -err: - return ESP_FAIL; -} - -static esp_err_t enc28j60_reset_hw(esp_eth_phy_t *phy) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - // set reset_gpio_num minus zero can skip hardware reset phy chip - if (enc28j60->reset_gpio_num >= 0) { - gpio_reset_pin(enc28j60->reset_gpio_num); - gpio_set_direction(enc28j60->reset_gpio_num, GPIO_MODE_OUTPUT); - gpio_set_level(enc28j60->reset_gpio_num, 0); - gpio_set_level(enc28j60->reset_gpio_num, 1); - } - return ESP_OK; -} - -static esp_err_t enc28j60_negotiate(esp_eth_phy_t *phy) -{ - /** - * ENC28J60 does not support automatic duplex negotiation. - * If it is connected to an automatic duplex negotiation enabled network switch, - * ENC28J60 will be detected as a half-duplex device. - * To communicate in Full-Duplex mode, ENC28J60 and the remote node - * must be manually configured for full-duplex operation. - */ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - /* Updata information about link, speed, duplex */ - PHY_CHECK(enc28j60_update_link_duplex_speed(enc28j60) == ESP_OK, "update link duplex speed failed", err); - return ESP_OK; -err: - return ESP_FAIL; -} - -esp_err_t enc28j60_set_phy_duplex(esp_eth_phy_t *phy, eth_duplex_t duplex) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - esp_eth_mediator_t *eth = enc28j60->eth; - phcon1_reg_t phcon1; - - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, 0, &phcon1.val) == ESP_OK, - "read PHCON1 failed", err); - switch (duplex) { - case ETH_DUPLEX_HALF: - phcon1.pdpxmd = 0; - break; - case ETH_DUPLEX_FULL: - phcon1.pdpxmd = 1; - break; - default: - PHY_CHECK(false, "unknown duplex", err); - break; - } - - PHY_CHECK(eth->phy_reg_write(eth, enc28j60->addr, 0, phcon1.val) == ESP_OK, - "write PHCON1 failed", err); - - PHY_CHECK(enc28j60_update_link_duplex_speed(enc28j60) == ESP_OK, "update link duplex speed failed", err); - return ESP_OK; -err: - return ESP_FAIL; -} - -static esp_err_t enc28j60_pwrctl(esp_eth_phy_t *phy, bool enable) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - esp_eth_mediator_t *eth = enc28j60->eth; - bmcr_reg_t bmcr; - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, - "read BMCR failed", err); - if (!enable) { - /* Enable IEEE Power Down Mode */ - bmcr.power_down = 1; - } else { - /* Disable IEEE Power Down Mode */ - bmcr.power_down = 0; - } - PHY_CHECK(eth->phy_reg_write(eth, enc28j60->addr, ETH_PHY_BMCR_REG_ADDR, bmcr.val) == ESP_OK, - "write BMCR failed", err); - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_BMCR_REG_ADDR, &(bmcr.val)) == ESP_OK, - "read BMCR failed", err); - if (!enable) { - PHY_CHECK(bmcr.power_down == 1, "power down failed", err); - } else { - PHY_CHECK(bmcr.power_down == 0, "power up failed", err); - } - return ESP_OK; -err: - return ESP_FAIL; -} - -static esp_err_t enc28j60_set_addr(esp_eth_phy_t *phy, uint32_t addr) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - enc28j60->addr = addr; - return ESP_OK; -} - -static esp_err_t enc28j60_get_addr(esp_eth_phy_t *phy, uint32_t *addr) -{ - PHY_CHECK(addr, "addr can't be null", err); - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - *addr = enc28j60->addr; - return ESP_OK; -err: - return ESP_ERR_INVALID_ARG; -} - -static esp_err_t enc28j60_del(esp_eth_phy_t *phy) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - free(enc28j60); - return ESP_OK; -} - -static esp_err_t enc28j60_init(esp_eth_phy_t *phy) -{ - phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - esp_eth_mediator_t *eth = enc28j60->eth; - /* Power on Ethernet PHY */ - PHY_CHECK(enc28j60_pwrctl(phy, true) == ESP_OK, "power control failed", err); - /* Reset Ethernet PHY */ - PHY_CHECK(enc28j60_reset(phy) == ESP_OK, "reset failed", err); - /* Check PHY ID */ - phyidr1_reg_t id1; - phyidr2_reg_t id2; - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_IDR1_REG_ADDR, &(id1.val)) == ESP_OK, - "read ID1 failed", err); - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_IDR2_REG_ADDR, &(id2.val)) == ESP_OK, - "read ID2 failed", err); - PHY_CHECK(id1.oui_msb == 0x0083 && id2.oui_lsb == 0x05 && id2.vendor_model == 0x00, - "wrong chip ID", err); - /* Disable half duplex loopback */ - phcon2_reg_t phcon2; - PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_PHCON2_REG_ADDR, &(phcon2.val)) == ESP_OK, - "read PHCON2 failed", err); - phcon2.hdldis = 1; - PHY_CHECK(eth->phy_reg_write(eth, enc28j60->addr, ETH_PHY_PHCON2_REG_ADDR, phcon2.val) == ESP_OK, - "write PHCON2 failed", err); - return ESP_OK; -err: - return ESP_FAIL; -} - -static esp_err_t enc28j60_deinit(esp_eth_phy_t *phy) -{ - /* Power off Ethernet PHY */ - PHY_CHECK(enc28j60_pwrctl(phy, false) == ESP_OK, "power off Ethernet PHY failed", err); - return ESP_OK; -err: - return ESP_FAIL; -} - -esp_eth_phy_t *esp_eth_phy_new_enc28j60(const eth_phy_config_t *config) -{ - PHY_CHECK(config, "can't set phy config to null", err); - phy_enc28j60_t *enc28j60 = calloc(1, sizeof(phy_enc28j60_t)); - PHY_CHECK(enc28j60, "calloc enc28j60 failed", err); - enc28j60->addr = config->phy_addr; // although PHY addr is meaningless to ENC28J60 - enc28j60->reset_timeout_ms = config->reset_timeout_ms; - enc28j60->reset_gpio_num = config->reset_gpio_num; - enc28j60->link_status = ETH_LINK_DOWN; - enc28j60->parent.reset = enc28j60_reset; - enc28j60->parent.reset_hw = enc28j60_reset_hw; - enc28j60->parent.init = enc28j60_init; - enc28j60->parent.deinit = enc28j60_deinit; - enc28j60->parent.set_mediator = enc28j60_set_mediator; - enc28j60->parent.negotiate = enc28j60_negotiate; - enc28j60->parent.get_link = enc28j60_get_link; - enc28j60->parent.pwrctl = enc28j60_pwrctl; - enc28j60->parent.get_addr = enc28j60_get_addr; - enc28j60->parent.set_addr = enc28j60_set_addr; - enc28j60->parent.del = enc28j60_del; - return &(enc28j60->parent); -err: - return NULL; -} diff --git a/ESP32/TLS13-ENC28J60-server/main/enc28j60_example_main.c b/ESP32/TLS13-ENC28J60-server/main/enc28j60_example_main.c index 5adf8d711..1677de068 100644 --- a/ESP32/TLS13-ENC28J60-server/main/enc28j60_example_main.c +++ b/ESP32/TLS13-ENC28J60-server/main/enc28j60_example_main.c @@ -1016,8 +1016,6 @@ int init_ENC28J60() { enc28j60_config.int_gpio_num = CONFIG_EXAMPLE_ENC28J60_INT_GPIO; eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); - mac_config.smi_mdc_gpio_num = -1; // ENC28J60 doesn't have SMI interface - mac_config.smi_mdio_gpio_num = -1; esp_eth_mac_t *mac = esp_eth_mac_new_enc28j60(&enc28j60_config, &mac_config); eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); diff --git a/ESP32/TLS13-ENC28J60-server/main/esp_eth_phy_enc28j60.c b/ESP32/TLS13-ENC28J60-server/main/esp_eth_phy_enc28j60.c index cbc9cceea..96c386090 100644 --- a/ESP32/TLS13-ENC28J60-server/main/esp_eth_phy_enc28j60.c +++ b/ESP32/TLS13-ENC28J60-server/main/esp_eth_phy_enc28j60.c @@ -16,7 +16,6 @@ #include #include "esp_log.h" #include "esp_eth.h" -#include "eth_phy_regs_struct.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" @@ -34,6 +33,24 @@ static const char *TAG = "enc28j60"; /***************Vendor Specific Register***************/ +/** + * @brief PHCON1(PHY Control Register 1) + * + */ +typedef union { + struct { + uint32_t reserved_7_0 : 8; // Reserved + uint32_t pdpxmd : 1; // PHY Duplex Mode + uint32_t reserved_10_9: 2; // Reserved + uint32_t ppwrsv: 1; // PHY Power-Down + uint32_t reserved_13_12: 2; // Reserved + uint32_t ploopbk: 1; // PHY Loopback + uint32_t prst: 1; // PHY Software Reset + }; + uint32_t val; +} phcon1_reg_t; +#define ETH_PHY_PHCON1_REG_ADDR (0x00) + /** * @brief PHCON2(PHY Control Register 2) * @@ -57,6 +74,44 @@ typedef union { * @brief PHSTAT2(PHY Status Register 2) * */ +/* IDF 5.x removed eth_phy_regs_struct.h; this is the standard 802.3 BMCR */ +typedef union { + struct { + uint32_t reserved_5_0 : 6; // Reserved + uint32_t speed_select_msb : 1;// Speed select MSB + uint32_t collision_test : 1; // Collision test + uint32_t duplex_mode : 1; // Duplex mode + uint32_t restart_auto_nego : 1; // Restart auto negotiation + uint32_t isolate : 1; // Isolate + uint32_t power_down : 1; // Power down + uint32_t en_auto_nego : 1; // Enable auto negotiation + uint32_t speed_select : 1; // Speed select LSB + uint32_t loopback : 1; // Loopback + uint32_t reset : 1; // Reset + }; + uint32_t val; +} bmcr_reg_t; +#define ETH_PHY_BMCR_REG_ADDR (0x00) + +/* standard 802.3 PHY identifier registers, also from the removed header */ +typedef union { + struct { + uint32_t oui_msb : 16; // Organizationally Unique Identifier bits 3:18 + }; + uint32_t val; +} phyidr1_reg_t; +#define ETH_PHY_IDR1_REG_ADDR (0x02) + +typedef union { + struct { + uint32_t model_revision : 4; // Model revision number + uint32_t vendor_model : 6; // Vendor model number + uint32_t oui_lsb : 6; // Organizationally Unique Identifier bits 19:24 + }; + uint32_t val; +} phyidr2_reg_t; +#define ETH_PHY_IDR2_REG_ADDR (0x03) + typedef union { struct { uint32_t reserved_4_0 : 5; // Reserved @@ -171,7 +226,8 @@ static esp_err_t enc28j60_reset_hw(esp_eth_phy_t *phy) return ESP_OK; } -static esp_err_t enc28j60_negotiate(esp_eth_phy_t *phy) +static esp_err_t enc28j60_autonego_ctrl(esp_eth_phy_t *phy, eth_phy_autoneg_cmd_t cmd, + bool *autoneg_en_stat) { /** * ENC28J60 does not support automatic duplex negotiation. @@ -180,9 +236,70 @@ static esp_err_t enc28j60_negotiate(esp_eth_phy_t *phy) * To communicate in Full-Duplex mode, ENC28J60 and the remote node * must be manually configured for full-duplex operation. */ + switch (cmd) { + case ESP_ETH_PHY_AUTONEGO_RESTART: + /* Fallthrough */ + case ESP_ETH_PHY_AUTONEGO_EN: + return ESP_ERR_NOT_SUPPORTED; + case ESP_ETH_PHY_AUTONEGO_DIS: + /* Fallthrough */ + case ESP_ETH_PHY_AUTONEGO_G_STAT: + *autoneg_en_stat = false; + break; + default: + return ESP_ERR_INVALID_ARG; + } + return ESP_OK; +} + +static esp_err_t enc28j60_set_link(esp_eth_phy_t *phy, eth_link_t link) +{ phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); - /* Updata information about link, speed, duplex */ - PHY_CHECK(enc28j60_update_link_duplex_speed(enc28j60) == ESP_OK, "update link duplex speed failed", err); + esp_eth_mediator_t *eth = enc28j60->eth; + + if (enc28j60->link_status != link) { + enc28j60->link_status = link; + PHY_CHECK(eth->on_state_changed(eth, ETH_STATE_LINK, (void *)link) == ESP_OK, + "change link failed", err); + } + return ESP_OK; +err: + return ESP_FAIL; +} + +static esp_err_t enc28j60_set_speed(esp_eth_phy_t *phy, eth_speed_t speed) +{ + /* ENC28J60 supports only 10Mbps */ + if (speed == ETH_SPEED_10M) { + return ESP_OK; + } + return ESP_ERR_NOT_SUPPORTED; +} + +static esp_err_t enc28j60_set_duplex(esp_eth_phy_t *phy, eth_duplex_t duplex) +{ + phy_enc28j60_t *enc28j60 = __containerof(phy, phy_enc28j60_t, parent); + esp_eth_mediator_t *eth = enc28j60->eth; + phcon1_reg_t phcon1; + + /* the link is being reconfigured, so report it down until the driver restarts */ + enc28j60->link_status = ETH_LINK_DOWN; + + PHY_CHECK(eth->phy_reg_read(eth, enc28j60->addr, ETH_PHY_PHCON1_REG_ADDR, &(phcon1.val)) == ESP_OK, + "read PHCON1 failed", err); + switch (duplex) { + case ETH_DUPLEX_HALF: + phcon1.pdpxmd = 0; + break; + case ETH_DUPLEX_FULL: + phcon1.pdpxmd = 1; + break; + default: + PHY_CHECK(false, "unknown duplex", err); + break; + } + PHY_CHECK(eth->phy_reg_write(eth, enc28j60->addr, ETH_PHY_PHCON1_REG_ADDR, phcon1.val) == ESP_OK, + "write PHCON1 failed", err); return ESP_OK; err: return ESP_FAIL; @@ -292,11 +409,14 @@ esp_eth_phy_t *esp_eth_phy_new_enc28j60(const eth_phy_config_t *config) enc28j60->parent.init = enc28j60_init; enc28j60->parent.deinit = enc28j60_deinit; enc28j60->parent.set_mediator = enc28j60_set_mediator; - enc28j60->parent.negotiate = enc28j60_negotiate; + enc28j60->parent.autonego_ctrl = enc28j60_autonego_ctrl; enc28j60->parent.get_link = enc28j60_get_link; + enc28j60->parent.set_link = enc28j60_set_link; enc28j60->parent.pwrctl = enc28j60_pwrctl; enc28j60->parent.get_addr = enc28j60_get_addr; enc28j60->parent.set_addr = enc28j60_set_addr; + enc28j60->parent.set_speed = enc28j60_set_speed; + enc28j60->parent.set_duplex = enc28j60_set_duplex; enc28j60->parent.del = enc28j60_del; return &(enc28j60->parent); err: diff --git a/ESP32/TLS13-wifi_station-client/main/station_example_main.c b/ESP32/TLS13-wifi_station-client/main/station_example_main.c index 20e1465bc..b2b7a29b2 100644 --- a/ESP32/TLS13-wifi_station-client/main/station_example_main.c +++ b/ESP32/TLS13-wifi_station-client/main/station_example_main.c @@ -50,7 +50,7 @@ **/ /* when using a private config with plain text passwords, not my_private_config.h should be excluded from git updates */ -#define USE_MY_PRIVATE_CONFIG +/* #define USE_MY_PRIVATE_CONFIG */ #ifdef USE_MY_PRIVATE_CONFIG #include "/workspace/my_private_config.h" diff --git a/ESP32/TLS13-wifi_station-server/main/station_example_main.c b/ESP32/TLS13-wifi_station-server/main/station_example_main.c index 9991f558f..0226aff20 100644 --- a/ESP32/TLS13-wifi_station-server/main/station_example_main.c +++ b/ESP32/TLS13-wifi_station-server/main/station_example_main.c @@ -55,7 +55,7 @@ ** define USE_MY_PRIVATE_CONFIG. ** note my_private_config.h should be excluded from git updates */ -#define USE_MY_PRIVATE_CONFIG +/* #define USE_MY_PRIVATE_CONFIG */ #ifdef USE_MY_PRIVATE_CONFIG #include "/mnt/c/workspace/my_private_config.h" diff --git a/RT1060/Makefile b/RT1060/Makefile index ac59b22fd..4f8067fde 100644 --- a/RT1060/Makefile +++ b/RT1060/Makefile @@ -2,6 +2,11 @@ SDK?=./SDK_2_13_1_MIMXRT1060-EVKB WOLFSSL?=../../wolfssl +# make defaults CC to the host cc, which cannot take the cortex-m7 flags below +CROSS_COMPILE?=arm-none-eabi- +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy + # Common settings and files ASMFLAGS=-D__STARTUP_CLEAR_BSS -D__STARTUP_INITIALIZE_NONCACHEDATA -mcpu=cortex-m7 -Wall -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fno-common -ffunction-sections -fdata-sections -ffreestanding -fno-builtin -mapcs -std=gnu99 CFLAGS+=-I$(SDK)/devices/MIMXRT1062/utilities/debug_console/ @@ -34,6 +39,7 @@ OBJS= \ $(WOLFSSL)/wolfcrypt/src/ge_low_mem.o \ $(WOLFSSL)/wolfcrypt/src/hash.o \ $(WOLFSSL)/wolfcrypt/src/pwdbased.o \ + $(WOLFSSL)/wolfcrypt/src/pkcs12.o \ $(WOLFSSL)/wolfcrypt/src/wolfmath.o \ $(WOLFSSL)/wolfcrypt/src/fe_low_mem.o @@ -101,10 +107,10 @@ BENCH_OBJS:=$(WOLFSSL)/wolfcrypt/benchmark/benchmark.o main-bench.o all: wolfcrypt-test.bin wolfcrypt-benchmark.bin wolfcrypt-test.bin: wolfcrypt-test.elf - arm-none-eabi-objcopy -O binary $^ $@ + $(OBJCOPY) -O binary $^ $@ wolfcrypt-benchmark.bin: wolfcrypt-benchmark.elf - arm-none-eabi-objcopy -O binary $^ $@ + $(OBJCOPY) -O binary $^ $@ wolfcrypt-test.elf: $(OBJS) $(TEST_OBJS) $(CC) -o $@ $^ $(LDFLAGS) diff --git a/RT1060/README.md b/RT1060/README.md index 280b2af8d..da25057fb 100644 --- a/RT1060/README.md +++ b/RT1060/README.md @@ -52,14 +52,14 @@ Build wolfSSL - For **MIMXRT1060-EVKB**: ``` -$ SDK=SDK_2_13_1_MIMXRT1060-EVKB make +$ SDK=./SDK_2_13_1_MIMXRT1060-EVKB make ``` - For **EVK-MIMXRT106**: ``` -$ SDK=SDK_2_8_2_EVK-MIMXRT1060 make +$ SDK=./SDK_2_8_2_EVK-MIMXRT1060 make ``` The resulting binary files will be in `wolfssl-examples/RT1060`: diff --git a/RT1060/common.c b/RT1060/common.c index e1615ed4c..7c2b0d4a7 100644 --- a/RT1060/common.c +++ b/RT1060/common.c @@ -23,6 +23,14 @@ void SysTick_Handler(void) g_systickCounter++; } +/* benchmark.c's generic branch calls clock_gettime, which this board has no + * implementation for; WOLFSSL_USER_CURRTIME routes it here instead. */ +double current_time(int reset) +{ + (void)reset; + return (double)g_systickCounter / 1000.0; +} + int32_t cust_rand_generate_block(uint8_t *rndb, uint32_t sz) { status_t status; diff --git a/RT1060/user_settings.h b/RT1060/user_settings.h index 32aebe858..d24df804b 100644 --- a/RT1060/user_settings.h +++ b/RT1060/user_settings.h @@ -34,6 +34,7 @@ #define WOLFCRYPT_ONLY #define SIZEOF_LONG_LONG 8 #define BENCH_EMBEDDED +#define WOLFSSL_USER_CURRTIME #define NO_WOLFSSL_MEMORY int32_t cust_rand_generate_block(uint8_t *rndb, uint32_t sz); diff --git a/SGX_Linux/sgx_t.mk b/SGX_Linux/sgx_t.mk index 1334127c3..a0a825747 100644 --- a/SGX_Linux/sgx_t.mk +++ b/SGX_Linux/sgx_t.mk @@ -86,7 +86,7 @@ Wolfssl_Enclave_C_Flags := $(Flags_Just_For_C) $(Common_C_Cpp_Flags) $(Wolfssl_C Wolfssl_Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \ -L$(SGX_WOLFSSL_LIB) -lwolfssl.sgx.static.lib \ -Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \ - -Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ + -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \ -Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \ -Wl,-pie,-eenclave_entry -Wl,--export-dynamic \ -Wl,--defsym,__ImageBase=0 \ diff --git a/X9.146/Makefile b/X9.146/Makefile index b916de0d6..dc957f543 100644 --- a/X9.146/Makefile +++ b/X9.146/Makefile @@ -1,4 +1,4 @@ -CC=gcc +# X9.146 Examples Makefile #if you installed wolfssl to an alternate location use CFLAGS and LIBS to #control your build: diff --git a/android/wolfcryptjni-ndk-gradle/app/build.gradle b/android/wolfcryptjni-ndk-gradle/app/build.gradle index ce1e09205..2b51fa95c 100644 --- a/android/wolfcryptjni-ndk-gradle/app/build.gradle +++ b/android/wolfcryptjni-ndk-gradle/app/build.gradle @@ -1,11 +1,11 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 28 + compileSdkVersion 32 defaultConfig { applicationId "com.wolfssl.wolfcrypt_ndk_gradle" minSdkVersion 23 - targetSdkVersion 28 + targetSdkVersion 32 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/android/wolfcryptjni-ndk-gradle/app/src/main/AndroidManifest.xml b/android/wolfcryptjni-ndk-gradle/app/src/main/AndroidManifest.xml index ba4451649..e86c175b3 100644 --- a/android/wolfcryptjni-ndk-gradle/app/src/main/AndroidManifest.xml +++ b/android/wolfcryptjni-ndk-gradle/app/src/main/AndroidManifest.xml @@ -12,7 +12,8 @@ android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning"> - + diff --git a/android/wolfssljni-ndk-gradle/app/CMakeLists.txt b/android/wolfssljni-ndk-gradle/app/CMakeLists.txt index ad687e3ac..a46084ef5 100644 --- a/android/wolfssljni-ndk-gradle/app/CMakeLists.txt +++ b/android/wolfssljni-ndk-gradle/app/CMakeLists.txt @@ -49,6 +49,9 @@ if ("${WOLFSSL_PKG_TYPE}" MATCHES "normal") -DHAVE_CRL -DHAVE_OCSP -DHAVE_CRL_MONITOR -DPERSIST_SESSION_CACHE -DPERSIST_CERT_CACHE -DATOMIC_USER -DHAVE_PK_CALLBACKS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN + # wolfssljni's WolfSSLCertRequest JNI calls wolfSSL_X509_REQ_*, which + # x509.c gates on CERT_GEN *and* CERT_REQ together + -DWOLFSSL_CERT_REQ -DHAVE_SNI -DHAVE_ALPN -DNO_RC4 -DHAVE_ENCRYPT_THEN_MAC -DNO_MD4 -DWOLFSSL_ENCRYPTED_KEYS -DHAVE_DH_DEFAULT_PARAMS -DNO_ERROR_QUEUE -DWOLFSSL_EITHER_SIDE -DWC_RSA_NO_PADDING diff --git a/android/wolfssljni-ndk-sample/jni/Android.mk b/android/wolfssljni-ndk-sample/jni/Android.mk index 962cee880..e177601c5 100644 --- a/android/wolfssljni-ndk-sample/jni/Android.mk +++ b/android/wolfssljni-ndk-sample/jni/Android.mk @@ -14,16 +14,17 @@ LOCAL_CFLAGS := -DOPENSSL_EXTRA -DWOLFSSL_DTLS -D_POSIX_THREADS -DNDEBUG \ -DECC_SHAMIR -DNO_MD4 -DNO_HC128 -DNO_RABBIT \ -DHAVE_OCSP -DHAVE_CRL -DWOLFSSL_JNI -DHAVE_DH \ -DUSE_FAST_MATH -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT \ - -DWC_RSA_BLINDING -DTFM_NO_ASM \ + -DWC_RSA_BLINDING -DTFM_NO_ASM -DHAVE_GETADDRINFO -DHAVE_NETDB_H \ -Wall LOCAL_SRC_FILES := src/crl.c \ src/internal.c \ - src/io.c \ + src/wolfio.c \ src/keys.c \ src/ocsp.c \ src/sniffer.c \ src/ssl.c \ src/tls.c \ + src/dtls.c \ wolfcrypt/src/aes.c \ wolfcrypt/src/arc4.c \ wolfcrypt/src/asm.c \ @@ -49,6 +50,7 @@ LOCAL_SRC_FILES := src/crl.c \ wolfcrypt/src/ge_operations.c \ wolfcrypt/src/hash.c \ wolfcrypt/src/hmac.c \ + wolfcrypt/src/kdf.c \ wolfcrypt/src/integer.c \ wolfcrypt/src/logging.c \ wolfcrypt/src/md2.c \ @@ -92,7 +94,7 @@ LOCAL_CFLAGS := -DOPENSSL_EXTRA -DWOLFSSL_DTLS -D_POSIX_THREADS -DNDEBUG \ -DECC_SHAMIR -DNO_MD4 -DNO_HC128 -DNO_RABBIT \ -DHAVE_OCSP -DHAVE_CRL -DWOLFSSL_JNI -DHAVE_DH \ -DUSE_FAST_MATH -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT \ - -DWC_RSA_BLINDING -DTFM_NO_ASM \ + -DWC_RSA_BLINDING -DTFM_NO_ASM -DHAVE_GETADDRINFO -DHAVE_NETDB_H \ -Wall LOCAL_SHARED_LIBRARIES := libwolfssl include $(BUILD_SHARED_LIBRARY) @@ -109,7 +111,7 @@ LOCAL_CFLAGS := -DOPENSSL_EXTRA -DWOLFSSL_DTLS -D_POSIX_THREADS -DNDEBUG \ -DECC_SHAMIR -DNO_MD4 -DNO_HC128 -DNO_RABBIT \ -DHAVE_OCSP -DHAVE_CRL -DWOLFSSL_JNI -DHAVE_DH \ -DUSE_FAST_MATH -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT \ - -DWC_RSA_BLINDING -DTFM_NO_ASM \ + -DWC_RSA_BLINDING -DTFM_NO_ASM -DHAVE_GETADDRINFO -DHAVE_NETDB_H \ -Wall LOCAL_SHARED_LIBRARIES := libwolfssl diff --git a/btle/common/btle-sim.c b/btle/common/btle-sim.c index 65e4c8b1a..6ec5a10b1 100644 --- a/btle/common/btle-sim.c +++ b/btle/common/btle-sim.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include "btle-sim.h" @@ -134,6 +135,10 @@ int btle_open(void** dev, int role) { int fdmiso, fdmosi; + /* Both peers shut the TLS session down, so whichever writes its close_notify + * after the other has gone would take a fatal SIGPIPE on the fifo. */ + signal(SIGPIPE, SIG_IGN); + mkfifo(kBtleMisoFifo, 0666); mkfifo(kBtleMosiFifo, 0666); diff --git a/can-bus/Makefile b/can-bus/Makefile index 75ca812dd..0f10b2210 100644 --- a/can-bus/Makefile +++ b/can-bus/Makefile @@ -1,6 +1,7 @@ CC=gcc -LIBS=-lwolfssl -CFLAGS=-g -Wno-cpp -Wall -Wextra -Wpedantic -Wdeclaration-after-statement +WOLFSSL_INSTALL_DIR=/usr/local +LIBS=-L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl +CFLAGS=-g -Wno-cpp -Wall -Wextra -Wpedantic -Wdeclaration-after-statement -I$(WOLFSSL_INSTALL_DIR)/include COMMON_OBJS=common.o CLIENT_OBJS=client.o diff --git a/can-bus/client.c b/can-bus/client.c index 46a218944..62f141345 100644 --- a/can-bus/client.c +++ b/can-bus/client.c @@ -51,11 +51,14 @@ int main(int argc, char *argv[]) size_t len = 0; ssize_t line_size = 0; line_size = getline(&line, &len, stdin); - if (line_size > 0) { - printf("Sending: %s\n", line); - wolfSSL_send(ssl, line, line_size, 0); - printf("Message sent\n"); + if (line_size <= 0) { + /* EOF: nothing left to send, and spinning here burns the CPU */ + free(line); + break; } + printf("Sending: %s\n", line); + wolfSSL_send(ssl, line, line_size, 0); + printf("Message sent\n"); free(line); } diff --git a/can-bus/generate_ssl.sh b/can-bus/generate_ssl.sh index cc6b49d59..1928ece67 100755 --- a/can-bus/generate_ssl.sh +++ b/can-bus/generate_ssl.sh @@ -1,11 +1,17 @@ #!/bin/sh +# X.509 caps CN at 64 characters, and cloud hosts routinely have longer FQDNs +CN=`hostname -f` +if [ ${#CN} -gt 64 ]; then + CN=`hostname` +fi + # Generate self signed root CA cert -openssl req -nodes -x509 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/C=GB/ST=London/L=Lon1/O=wolfSSL/OU=root/CN=`hostname -f`/emailAddress=info@wolfssl.com" +openssl req -nodes -x509 -newkey rsa:2048 -keyout ca.key -out ca.crt -subj "/C=GB/ST=London/L=Lon1/O=wolfSSL/OU=root/CN=$CN/emailAddress=info@wolfssl.com" # Generate server cert to be signed -openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=GB/ST=London/L=Lon1/O=wolfSSL/OU=server/CN=`hostname -f`/emailAddress=info@wolfssl.com" +openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj "/C=GB/ST=London/L=Lon1/O=wolfSSL/OU=server/CN=$CN/emailAddress=info@wolfssl.com" # Sign the server cert openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt @@ -15,7 +21,7 @@ cat server.key server.crt > server.pem # Generate client cert to be signed -openssl req -nodes -newkey rsa:2048 -keyout client.key -out client.csr -subj "/C=GB/ST=London/L=Lon1/O=wolfSSL/OU=client/CN=`hostname -f`/emailAddress=info@wolfssl.com" +openssl req -nodes -newkey rsa:2048 -keyout client.key -out client.csr -subj "/C=GB/ST=London/L=Lon1/O=wolfSSL/OU=client/CN=$CN/emailAddress=info@wolfssl.com" # Sign the client cert openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAserial ca.srl -out client.crt diff --git a/certgen/Makefile b/certgen/Makefile index 1693f19d1..77e6f2bc7 100644 --- a/certgen/Makefile +++ b/certgen/Makefile @@ -1,4 +1,4 @@ -CC=gcc +# CertGen Examples Makefile #if you installed wolfssl to an alternate location use CFLAGS and LIBS to #control your build: diff --git a/certgen/csr_w_ed25519_example.c b/certgen/csr_w_ed25519_example.c index 3b912873d..3b4c13e6a 100644 --- a/certgen/csr_w_ed25519_example.c +++ b/certgen/csr_w_ed25519_example.c @@ -121,6 +121,10 @@ int main(void) } printf("%s", pem); + /* wc_DerToPem returns a length, so only a negative value is an error */ + if (ret > 0) + ret = 0; + exit: wc_ForceZero(der, sizeof(der)); wc_ForceZero(pem, sizeof(pem)); diff --git a/certmanager/README.md b/certmanager/README.md index aeab0d22f..77274f240 100644 --- a/certmanager/README.md +++ b/certmanager/README.md @@ -86,7 +86,7 @@ openssl ocsp -port 22221 -ndays 365 \ From the `wolfssl-examples/certmanager` directory: ```bash -./certverify_crl_ocsp +./certverify_ocsp ``` ### Expected Output diff --git a/certmanager/certloadverifybuffer.c b/certmanager/certloadverifybuffer.c index 8821fadb1..3409b922c 100644 --- a/certmanager/certloadverifybuffer.c +++ b/certmanager/certloadverifybuffer.c @@ -35,11 +35,11 @@ /* root ca (certs/ca-ecc-cert.pem) */ static const byte authCert[] = "\ -----BEGIN CERTIFICATE-----\n\ -MIICljCCAjugAwIBAgIUZWdCTAbn5MNoAamUqQfm/r0s1j0wCgYIKoZIzj0EAwIw\n\ +MIIClTCCAjugAwIBAgIUMLkwUPgaDf+taNFt6KNrWCMzeoQwCgYIKoZIzj0EAwIw\n\ gZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT\n\ ZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEY\n\ MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv\n\ -bGZzc2wuY29tMB4XDTIyMTIxNjIxMTc0OVoXDTI1MDkxMTIxMTc0OVowgZcxCzAJ\n\ +bGZzc2wuY29tMB4XDTI0MTIxODIxMjUyOVoXDTI3MDkxNDIxMjUyOVowgZcxCzAJ\n\ BgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxl\n\ MRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEYMBYGA1UE\n\ AwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wu\n\ @@ -47,39 +47,39 @@ Y29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAtPZbtYBjkXIuZAx5cBM456t\n\ KTiYuhDW6QkqgKkuFyq5ir8zg0bjlQvkd0C1O0NFMw9hU3w3RMHL/IDK6EPqp6Nj\n\ MGEwHQYDVR0OBBYEFFaOmsPwQt4YuUVVbvmTz+rD86UhMB8GA1UdIwQYMBaAFFaO\n\ msPwQt4YuUVVbvmTz+rD86UhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD\n\ -AgGGMAoGCCqGSM49BAMCA0kAMEYCIQCwEhYDJnnUa5TZfsrhLSRk7xFu8hKB5M4d\n\ -d33KXEdQYgIhAIC/Rjxd2OWrR86iGb0h3oVvq8mPAfOrG7nhU9Ykd6ZN\n\ +AgGGMAoGCCqGSM49BAMCA0gAMEUCIQCIzH8A9alOwGluNjkkj4NFTfrQORS4yH+V\n\ +UfLFmMC34gIgKpNhsAbe69r9r2s5v4gX8boqfVmo3ucKEYNPkneNkjs=\n\ -----END CERTIFICATE-----\n"; /* chain cert, signed by authCert (above) (certs/server-ecc.pem) */ static const byte testCert1[] = "\ -----BEGIN CERTIFICATE-----\n\ -MIICoTCCAkegAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR\n\ +MIICojCCAkigAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR\n\ BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv\n\ bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz\n\ -bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjIxMjE2\n\ -MjExNzQ5WhcNMjUwOTExMjExNzQ5WjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgM\n\ -Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB0VsaXB0aWMx\n\ -DDAKBgNVBAsMA0VDQzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZI\n\ -hvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\n\ -QgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U6iv6yyAJOSwW6GEC6a9N0wKTmjFbl5Ih\n\ -f/DPGNqREQI0huggWDMLgDSJ2KOBiTCBhjAdBgNVHQ4EFgQUXV0m76x+NvmbdhUr\n\ -SiUCI++yiTAwHwYDVR0jBBgwFoAUVo6aw/BC3hi5RVVu+ZPP6sPzpSEwDAYDVR0T\n\ -AQH/BAIwADAOBgNVHQ8BAf8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEQYJ\n\ -YIZIAYb4QgEBBAQDAgZAMAoGCCqGSM49BAMCA0gAMEUCIQDPOheX1L58UOG+G1OV\n\ -e6O4xnPENOBzWts+yzq2qPHNvwIgK+b5ZbKrD7srNlzMLhmpWRxvb86beuZbZTEz\n\ -gAXLfJY=\n\ +bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQxMjE4\n\ +MjEyNTMwWhcNMjcwOTE0MjEyNTMwWjCBkDELMAkGA1UEBhMCVVMxEzARBgNVBAgM\n\ +Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxETAPBgNVBAoMCEVsbGlwdGlj\n\ +MQwwCgYDVQQLDANFQ0MxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEfMB0GCSqG\n\ +SIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEH\n\ +A0IABLszrEwnUErGSqUEwzzenzbbci3OlOor+ssgCTksFuhhAumvTdMCk5oxW5eS\n\ +IX/wzxjakRECNIboIFgzC4A0idijgYkwgYYwHQYDVR0OBBYEFF1dJu+sfjb5m3YV\n\ +K0olAiPvsokwMB8GA1UdIwQYMBaAFFaOmsPwQt4YuUVVbvmTz+rD86UhMAwGA1Ud\n\ +EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgOoMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBEG\n\ +CWCGSAGG+EIBAQQEAwIGQDAKBggqhkjOPQQDAgNIADBFAiEAi4Kl0vbKhLqtLd42\n\ +6SpN7ksgRrqrTtAQbuswtn7Yr4wCIAZ0QGqpMVT+IJ3GbSvfHapj2vyXUIeSae5j\n\ +V7bs4un6\n\ -----END CERTIFICATE-----\n"; /* This is a self-signed test cert so load in both as CA and entity cert (certs/client-ecc-cert.pem) */ static const byte testCert2[] = "\n\ -----BEGIN CERTIFICATE-----\n\ -MIIDXjCCAwSgAwIBAgIUWeZaIeDEP2cGmyFDPnbK8D9oW1MwCgYIKoZIzj0EAwIw\n\ +MIIDXjCCAwSgAwIBAgIUdZnbOO0yscLRLF5vb51HF1jd7iYwCgYIKoZIzj0EAwIw\n\ gY0xCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZPcmVnb24xDjAMBgNVBAcMBVNhbGVt\n\ MRMwEQYDVQQKDApDbGllbnQgRUNDMQ0wCwYDVQQLDARGYXN0MRgwFgYDVQQDDA93\n\ d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20w\n\ -HhcNMjIxMjE2MjExNzQ5WhcNMjUwOTExMjExNzQ5WjCBjTELMAkGA1UEBhMCVVMx\n\ +HhcNMjQxMjE4MjEyNTMwWhcNMjcwOTE0MjEyNTMwWjCBjTELMAkGA1UEBhMCVVMx\n\ DzANBgNVBAgMBk9yZWdvbjEOMAwGA1UEBwwFU2FsZW0xEzARBgNVBAoMCkNsaWVu\n\ dCBFQ0MxDTALBgNVBAsMBEZhc3QxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEf\n\ MB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBZMBMGByqGSM49AgEGCCqG\n\ @@ -89,11 +89,11 @@ WWuVYT9RV7YETYlBiERcq/Iwgc0GA1UdIwSBxTCBwoAU69RLWWuVYT9RV7YETYlB\n\ iERcq/KhgZOkgZAwgY0xCzAJBgNVBAYTAlVTMQ8wDQYDVQQIDAZPcmVnb24xDjAM\n\ BgNVBAcMBVNhbGVtMRMwEQYDVQQKDApDbGllbnQgRUNDMQ0wCwYDVQQLDARGYXN0\n\ MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9A\n\ -d29sZnNzbC5jb22CFFnmWiHgxD9nBpshQz52yvA/aFtTMAwGA1UdEwQFMAMBAf8w\n\ +d29sZnNzbC5jb22CFHWZ2zjtMrHC0Sxeb2+dRxdY3e4mMAwGA1UdEwQFMAMBAf8w\n\ HAYDVR0RBBUwE4ILZXhhbXBsZS5jb22HBH8AAAEwHQYDVR0lBBYwFAYIKwYBBQUH\n\ -AwEGCCsGAQUFBwMCMAoGCCqGSM49BAMCA0gAMEUCIHD4Dm6RyQl3JYy6mW1ULahS\n\ -hxdRJIsTkol9ybq0Qy5IAiEAq0ETOtXraGY2Vnx1XTfj9id/VNVCgCnb5ZsWitPC\n\ -rdY=\n\ +AwEGCCsGAQUFBwMCMAoGCCqGSM49BAMCA0gAMEUCIANpMUVvAYhrY8Yc6znkmqji\n\ +4DSsrOah1v7OhZgesA2pAiEAo92EXQgoS4tY+w0z2wLqyAzaNAtOg6IQZ5kZHJOR\n\ +yMc=\n\ -----END CERTIFICATE-----\n"; int main(void) diff --git a/certmanager/certverify.c b/certmanager/certverify.c index d4fe9fa2a..1f3f14746 100644 --- a/certmanager/certverify.c +++ b/certmanager/certverify.c @@ -104,6 +104,8 @@ int main(void) printf("CRL Verification Successful!\n"); #endif + ret = 0; + exit: wolfSSL_CertManagerFree(cm); wolfSSL_Cleanup(); diff --git a/certs/client-ecc-cert.der b/certs/client-ecc-cert.der index 571745cd5..cb9da779b 100644 Binary files a/certs/client-ecc-cert.der and b/certs/client-ecc-cert.der differ diff --git a/certs/crl/crl.pem b/certs/crl/crl.pem index 9da22d86e..8be68b27c 100644 --- a/certs/crl/crl.pem +++ b/certs/crl/crl.pem @@ -1,41 +1,13 @@ -Certificate Revocation List (CRL): - Version 2 (0x1) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Montana, L = Bozeman, O = Sawtooth, OU = Consulting, CN = www.wolfssl.com, emailAddress = info@wolfssl.com - Last Update: Dec 16 21:17:50 2022 GMT - Next Update: Sep 11 21:17:50 2025 GMT - CRL extensions: - X509v3 CRL Number: - 2 -Revoked Certificates: - Serial Number: 02 - Revocation Date: Dec 16 21:17:50 2022 GMT - Signature Algorithm: sha256WithRSAEncryption - 39:44:ff:39:f4:04:45:79:7e:73:e2:42:48:db:85:66:fd:99: - 76:94:7c:b5:79:5d:15:71:36:a9:87:f0:73:05:50:08:6b:1c: - 6e:de:96:45:31:c3:c0:ba:ba:f5:08:1d:05:4a:52:39:e9:03: - ef:59:c8:1d:4a:f2:86:05:99:7b:4b:74:f6:d3:75:8d:b2:57: - ba:ac:a7:11:14:d6:6c:71:c4:4c:1c:68:bc:49:78:f0:c9:52: - 8a:e7:8b:54:e6:20:58:20:60:66:f5:14:d8:cb:ff:e0:a0:45: - bc:b4:81:ad:1d:bc:cf:f8:8e:a8:87:24:55:99:d9:ce:47:f7: - 5b:4a:33:6d:db:bf:93:64:1a:a6:46:5f:27:dc:d8:d4:f9:c2: - 42:2a:7e:b2:7c:dd:98:77:f5:88:7d:15:25:08:bc:e0:d0:8d: - f4:c3:c3:04:41:a4:d1:b1:39:4a:6b:2c:b5:2e:9a:65:43:0d: - 0e:73:f4:06:e1:b3:49:34:94:b0:b7:ff:c0:27:c1:b5:ea:06: - f7:71:71:97:bb:bc:c7:1a:9f:eb:f6:3d:a5:7b:55:a7:bf:dd: - d7:ee:97:b8:9d:dc:cd:e3:06:db:9a:2c:60:bf:70:84:fa:6b: - 8d:70:7d:de:e8:b7:ab:b0:38:68:6c:c0:b1:e1:ba:45:e0:d7: - 12:3d:71:5b -----BEGIN X509 CRL----- -MIICBDCB7QIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMxEDAOBgNV +MIICBTCB7gIBATANBgkqhkiG9w0BAQsFADCBlDELMAkGA1UEBhMCVVMxEDAOBgNV BAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xETAPBgNVBAoMCFNhd3Rvb3Ro MRMwEQYDVQQLDApDb25zdWx0aW5nMRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20x -HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTIyMTIxNjIxMTc1MFoX -DTI1MDkxMTIxMTc1MFowFDASAgECFw0yMjEyMTYyMTE3NTBaoA4wDDAKBgNVHRQE -AwIBAjANBgkqhkiG9w0BAQsFAAOCAQEAOUT/OfQERXl+c+JCSNuFZv2ZdpR8tXld -FXE2qYfwcwVQCGscbt6WRTHDwLq69QgdBUpSOekD71nIHUryhgWZe0t09tN1jbJX -uqynERTWbHHETBxovEl48MlSiueLVOYgWCBgZvUU2Mv/4KBFvLSBrR28z/iOqIck -VZnZzkf3W0ozbdu/k2QapkZfJ9zY1PnCQip+snzdmHf1iH0VJQi84NCN9MPDBEGk -0bE5SmsstS6aZUMNDnP0BuGzSTSUsLf/wCfBteoG93Fxl7u8xxqf6/Y9pXtVp7/d -1+6XuJ3czeMG25osYL9whPprjXB93ui3q7A4aGzAseG6ReDXEj1xWw== +HzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTI2MDcxNDIxMjM1OVoX +DTM2MDcxMTIxMjM1OVowFDASAgECFw0yMjEyMTYyMTE3NTBaoA8wDTALBgNVHRQE +BAICEAAwDQYJKoZIhvcNAQELBQADggEBAGK74c5pj/yr1pFRKH7JCm1kwDqnL/e8 +GzEzKxomv6nN/yGK049/SmEAFEAy8GxgOA0AHfahJKeDORa7xqn61+K/lULZ3T5V +75puvN4ANZH3RtWhumm/Kl/MMpKlQMak3AkPQhw7cK/yfi7kkrZyUC7cUpXLASkS +I8LqDJRD+IDAhBTj5jqaetDF8tGRvRniDzy40PXT2fYELolS6aty2vc/oDQDU51e +w7bz7MduIovU7zIdeYwW+/ktU35SHnTmz0pdOISu1rxHkKtIl5YSzsAn1IeO9cDo +9tKEhmIk/SlZTcsg+QY2lQBFAhR80fV1Hwoub+c2HiGxhMdyAEbri6M= -----END X509 CRL----- diff --git a/certs/crl/regenerate-crl.sh b/certs/crl/regenerate-crl.sh new file mode 100755 index 000000000..45ad0819d --- /dev/null +++ b/certs/crl/regenerate-crl.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# Regenerate crl.pem, which certmanager/certverify loads. +# +# The previous one expired 2025-09-11 and silently broke every CRL example until +# CI started checking exit codes. Re-run this when nextUpdate gets close: +# openssl crl -in crl.pem -noout -nextupdate + +set -e +cd "$(dirname "$0")/../.." + +WORK=$(mktemp -d) +trap 'rm -rf "$WORK"' EXIT + +# certs/server-revoked-cert.pem is serial 02; keep its original revocation date +# so the CRL keeps saying the same thing. +EXPIRY=$(openssl x509 -in certs/server-revoked-cert.pem -noout -enddate | cut -d= -f2) +EXPIRY_Z=$(python3 -c " +import datetime +print(datetime.datetime.strptime('''$EXPIRY''', '%b %d %H:%M:%S %Y %Z').strftime('%y%m%d%H%M%S') + 'Z')") +SUBJECT=$(openssl x509 -in certs/server-revoked-cert.pem -noout -subject -nameopt compat | sed 's/^subject=//') + +printf 'R\t%s\t221216211750Z\t02\tunknown\t%s\n' "$EXPIRY_Z" "$SUBJECT" > "$WORK/index.txt" +# RFC 5280 wants a monotonically increasing CRL number: seed from the CRL being +# replaced so the new one supersedes it instead of colliding. +# openssl prints crlNumber=0x1000 on new versions and crlNumber=1000 on old ones +CURNUM=$(openssl crl -in certs/crl/crl.pem -noout -crlnumber 2>/dev/null | cut -d= -f2) +CURNUM=${CURNUM#0x} +printf '%X\n' "$(( 0x${CURNUM:-0FFF} + 1 ))" > "$WORK/crlnumber" + +cat > "$WORK/ca.cnf" </dev/null && [ "$i" -lt 30 ]; do + sleep 1 + i=$((i + 1)) +done + +if kill -0 "${SERVER_PID}" 2>/dev/null; then + echo "server still running after ${i}s; killing it" + kill "${SERVER_PID}" 2>/dev/null + SERVER_RESULT=1 +else + wait "${SERVER_PID}" + SERVER_RESULT=$? +fi -echo "RESULT1 = ${RESULT1}" -echo "" -echo "RESULT2 = ${RESULT2}" -echo "" -kill ${PID1} -kill ${PID2} +echo "server exited ${SERVER_RESULT}" +echo "client exited ${CLIENT_RESULT}" +[ ${CLIENT_RESULT} -eq 0 ] && [ ${SERVER_RESULT} -eq 0 ] diff --git a/custom-io-callbacks/file-server/file-server.c b/custom-io-callbacks/file-server/file-server.c index d9f8f8d91..03e99d269 100644 --- a/custom-io-callbacks/file-server/file-server.c +++ b/custom-io-callbacks/file-server/file-server.c @@ -162,6 +162,7 @@ int main(int argc, char** argv) char sMsg[] = "I hear you fashizzle\r\n"; char reply[MAXSZ]; int ret, msgSz; + int rc = -1; WOLFSSL* sslServ; WOLFSSL_CTX* ctxServ = NULL; @@ -185,7 +186,7 @@ int main(int argc, char** argv) // sslServ = Server(&ctxServ, "ECDHE-RSA-AES128-SHA", 1); sslServ = Server(&ctxServ, "let-wolfssl-choose", 0); - if (sslServ == NULL) { printf("sslServ NULL\n"); return 0;} + if (sslServ == NULL) { printf("sslServ NULL\n"); goto cleanup; } ret = SSL_FAILURE; printf("Starting server\n"); while (ret != SSL_SUCCESS) { @@ -216,7 +217,7 @@ int main(int argc, char** argv) if (error != SSL_ERROR_WANT_READ && error != SSL_ERROR_WANT_WRITE) { printf("server read failed\n"); - break; + goto cleanup; } } else { @@ -241,6 +242,7 @@ int main(int argc, char** argv) } } else if (ret == msgSz) { printf("Server send successful\n"); + rc = 0; break; } else { printf("Unkown error occurred, shutting down\n"); @@ -272,5 +274,5 @@ int main(int argc, char** argv) if (f != NULL) fclose(f); } - return -1; + return rc; } diff --git a/dtls/client-dtls-rw-threads.c b/dtls/client-dtls-rw-threads.c index 691285ac6..93df40a9e 100644 --- a/dtls/client-dtls-rw-threads.c +++ b/dtls/client-dtls-rw-threads.c @@ -158,7 +158,7 @@ int main (int argc, char** argv) struct sockaddr_in servAddr; WOLFSSL* ssl = 0; WOLFSSL_CTX* ctx = 0; - char cert_array[] = "certs/ca-cert.pem"; + char cert_array[] = "../certs/ca-cert.pem"; char* certs = cert_array; threadArgs args; pthread_t threadidReader; diff --git a/dtls/memory-bio-dtls.c b/dtls/memory-bio-dtls.c index 62f8a5b8a..4fdb815da 100644 --- a/dtls/memory-bio-dtls.c +++ b/dtls/memory-bio-dtls.c @@ -119,8 +119,7 @@ static void* client_thread(void* args) } while (ret <= 0 && ((err == WOLFSSL_ERROR_WANT_READ) || (err == WOLFSSL_ERROR_WANT_WRITE))); - /* clean up, wolfSSL_free would also free the WOLFSSL_BIO's so set as NULL - * since they are also being used with srv_ssl and will be free'd there. */ + /* drops this thread's BIO references; srv_ssl still holds its own */ wolfSSL_set_bio(cli_ssl, NULL, NULL); wolfSSL_free(cli_ssl); wolfSSL_CTX_free(cli_ctx); @@ -147,6 +146,10 @@ int main() io.rbio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); io.wbio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); + /* cli_ssl and srv_ssl both use these, so take the second reference here or + * whichever side cleans up first frees them under the other. */ + wolfSSL_BIO_up_ref(io.rbio); + wolfSSL_BIO_up_ref(io.wbio); sem_init(&io.bioSem, 0, 1); /* set up server */ diff --git a/dtls/server-dtls-nonblocking.c b/dtls/server-dtls-nonblocking.c index 2a2f02a9d..5f73047bb 100644 --- a/dtls/server-dtls-nonblocking.c +++ b/dtls/server-dtls-nonblocking.c @@ -142,6 +142,7 @@ int main(int argc, char** argv) clilen = sizeof(cliAddr); timeout.tv_sec = (currTimeout > 0) ? currTimeout : 0; + timeout.tv_usec = 0; /* Create a UDP/IP socket */ if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { @@ -266,6 +267,9 @@ int main(int argc, char** argv) printf("... server would write block\n"); currTimeout = wolfSSL_dtls_get_current_timeout(ssl); + /* select() consumes the timeout, so re-arm it every pass */ + timeout.tv_sec = (currTimeout > 0) ? currTimeout : 0; + timeout.tv_usec = 0; FD_ZERO(&recvfds); FD_SET(listenfd, &recvfds); diff --git a/dtls/server-dtls-rw-threads.c b/dtls/server-dtls-rw-threads.c index 0c6d120b4..ebd2188c6 100644 --- a/dtls/server-dtls-rw-threads.c +++ b/dtls/server-dtls-rw-threads.c @@ -221,9 +221,9 @@ void* Writer(void* openSock) int main(int argc, char** argv) { /* Loc short for "location" */ - char caCertLoc[] = "certs/ca-cert.pem"; - char servCertLoc[] = "certs/server-cert.pem"; - char servKeyLoc[] = "certs/server-key.pem"; + char caCertLoc[] = "../certs/ca-cert.pem"; + char servCertLoc[] = "../certs/server-cert.pem"; + char servKeyLoc[] = "../certs/server-key.pem"; WOLFSSL_CTX* ctx; /* Variables for awaiting datagram */ int on = 1; diff --git a/dtls/server-dtls.c b/dtls/server-dtls.c index d7275cef8..18677d69a 100644 --- a/dtls/server-dtls.c +++ b/dtls/server-dtls.c @@ -187,6 +187,14 @@ int main(int argc, char** argv) buff[recvLen] = 0; printf("I heard this: \"%s\"\n", buff); } + else if (recvLen == 0) { + /* close_notify: rebind now. Falling through to write instead + * only escapes once a send fails on an ICMP round trip, and + * until then this socket is still connect()ed to the old peer, + * so a client resuming from a new port is never heard. */ + printf("Client sent close notify\n"); + break; + } else if (recvLen < 0) { int readErr = wolfSSL_get_error(ssl, 0); if(readErr != SSL_ERROR_WANT_READ) { diff --git a/ebpf/syscall-write-trace/write_tracer.c b/ebpf/syscall-write-trace/write_tracer.c index c4ac4ac94..55148c594 100755 --- a/ebpf/syscall-write-trace/write_tracer.c +++ b/ebpf/syscall-write-trace/write_tracer.c @@ -167,12 +167,8 @@ int main(int argc, char **argv) goto cleanup_link; } - struct perf_buffer_opts pb_opts = { - .sample_cb = handle_event, - .lost_cb = handle_lost_events, - }; - - pb = perf_buffer__new(map_fd, 8, &pb_opts); + /* libbpf 1.0 moved the callbacks out of perf_buffer_opts into arguments */ + pb = perf_buffer__new(map_fd, 8, handle_event, handle_lost_events, NULL, NULL); if (libbpf_get_error(pb)) { fprintf(stderr, "Failed to create perf buffer\n"); err = 1; diff --git a/ebpf/tls-uprobe-trace/Makefile b/ebpf/tls-uprobe-trace/Makefile index 3da5a294f..eae9c9e40 100644 --- a/ebpf/tls-uprobe-trace/Makefile +++ b/ebpf/tls-uprobe-trace/Makefile @@ -1,6 +1,8 @@ CC = gcc CLANG = clang -CFLAGS = -O2 -g -Wall +WOLFSSL_INSTALL_DIR = /usr/local +CFLAGS = -O2 -g -Wall -I$(WOLFSSL_INSTALL_DIR)/include +WOLFSSL_LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl # Auto-detect host arch, convert to BPF target name UNAME_M := $(shell uname -m) @@ -25,10 +27,10 @@ all: $(TARGETS) # ===== TLS Programs ===== client-tls: client-tls.c - $(CC) $(CFLAGS) $< -o $@ -lwolfssl + $(CC) $(CFLAGS) $< -o $@ $(WOLFSSL_LIBS) server-tls: server-tls.c - $(CC) $(CFLAGS) $< -o $@ -lwolfssl + $(CC) $(CFLAGS) $< -o $@ $(WOLFSSL_LIBS) # ===== eBPF Program ===== wolfssl_uprobe.bpf.o: wolfssl_uprobe.bpf.c diff --git a/ebpf/tls-uprobe-trace/wolfssl_uprobe.c b/ebpf/tls-uprobe-trace/wolfssl_uprobe.c index 45f91c7ef..70f56ebe8 100755 --- a/ebpf/tls-uprobe-trace/wolfssl_uprobe.c +++ b/ebpf/tls-uprobe-trace/wolfssl_uprobe.c @@ -318,12 +318,8 @@ int main(int argc, char **argv) goto cleanup_read_exit; } - struct perf_buffer_opts pb_opts = { - .sample_cb = handle_event, - .lost_cb = handle_lost_events, - }; - - pb = perf_buffer__new(map_fd, 8, &pb_opts); + /* libbpf 1.0 moved the callbacks out of perf_buffer_opts into arguments */ + pb = perf_buffer__new(map_fd, 8, handle_event, handle_lost_events, NULL, NULL); if (libbpf_get_error(pb)) { fprintf(stderr, "Failed to create perf buffer\n"); err = 1; diff --git a/ecc/ecc-params.c b/ecc/ecc-params.c index f90fd45a3..72dea5b0c 100644 --- a/ecc/ecc-params.c +++ b/ecc/ecc-params.c @@ -118,6 +118,7 @@ int main(void) #if defined(HAVE_ECC) && defined(WOLFSSL_PUBLIC_MP) const char* curve_str = "SECP256R1"; int curve_id = ECC_SECP256R1; + int rc = 0; unsigned char param[MAX_ECC_BYTES]; wolfSSL_Debugging_ON(); @@ -126,27 +127,51 @@ int main(void) ret = load_curve_param(curve_id, ECC_CURVE_FIELD_PRIME, param, sizeof(param)); printf("Prime: %d\n", ret); - WOLFSSL_BUFFER(param, ret); + if (ret < 0) + rc = ret; + else + WOLFSSL_BUFFER(param, ret); ret = load_curve_param(curve_id, ECC_CURVE_FIELD_AF, param, sizeof(param)); printf("Af: %d\n", ret); - WOLFSSL_BUFFER(param, ret); + if (ret < 0) + rc = ret; + else + WOLFSSL_BUFFER(param, ret); ret = load_curve_param(curve_id, ECC_CURVE_FIELD_BF, param, sizeof(param)); printf("Bf: %d\n", ret); - WOLFSSL_BUFFER(param, ret); + if (ret < 0) + rc = ret; + else + WOLFSSL_BUFFER(param, ret); ret = load_curve_param(curve_id, ECC_CURVE_FIELD_ORDER, param, sizeof(param)); printf("Order: %d\n", ret); - WOLFSSL_BUFFER(param, ret); + if (ret < 0) + rc = ret; + else + WOLFSSL_BUFFER(param, ret); ret = load_curve_param(curve_id, ECC_CURVE_FIELD_GX, param, sizeof(param)); printf("Gx: %d\n", ret); - WOLFSSL_BUFFER(param, ret); + if (ret < 0) + rc = ret; + else + WOLFSSL_BUFFER(param, ret); ret = load_curve_param(curve_id, ECC_CURVE_FIELD_GY, param, sizeof(param)); printf("Gy: %d\n", ret); - WOLFSSL_BUFFER(param, ret); + if (ret < 0) + rc = ret; + else + WOLFSSL_BUFFER(param, ret); + + /* load_curve_param returns a length, so only a negative value is an error. + * rc latches a failure across all six calls; ret alone holds only the last. + * Return 1, not rc: an exit status is truncated mod 256, and -132 would + * surface as 124 -- the shell's timeout code. */ + ret = (rc < 0) ? 1 : 0; #else printf("Must build wolfSSL with ./configure CFLAGS=\"-DWOLFSSL_PUBLIC_MP\"\n"); #endif diff --git a/ecc/ecc-sign.c b/ecc/ecc-sign.c index c5668fb16..ac2173e8a 100644 --- a/ecc/ecc-sign.c +++ b/ecc/ecc-sign.c @@ -26,6 +26,7 @@ #include #include #include +#include #define MAX_FIRMWARE_LEN (1024 * 1024) static const int gFwLen = MAX_FIRMWARE_LEN; @@ -146,6 +147,9 @@ static int SignFirmware(byte* hashBuf, word32 hashLen, byte* sigBuf, word32* sig ret = wc_ecc_verify_hash(sigBuf, *sigLen, hashBuf, hashLen, &is_valid_sig, &gMyKey); printf("Verify ret %d, is_valid_sig %d\n", ret, is_valid_sig); + /* a bad signature also returns 0 here: the result is in is_valid_sig */ + if (ret == 0 && is_valid_sig != 1) + ret = SIG_VERIFY_E; } wc_FreeRng(&rng); @@ -156,6 +160,7 @@ static int SignFirmware(byte* hashBuf, word32 hashLen, byte* sigBuf, word32* sig int main(void) { int ret; + int firstErr = 0; byte hashBuf[WC_SHA256_DIGEST_SIZE]; word32 hashLen = WC_SHA256_DIGEST_SIZE; byte sigBuf[ECC_MAX_SIG_SIZE]; @@ -179,6 +184,10 @@ int main(void) printf("Firmware Signature %d: Ret %d, HashLen %d, SigLen %d\n", i, ret, hashLen, sigLen); + /* keep the first error: ret alone would report only the last round */ + if (ret != 0 && firstErr == 0) + firstErr = ret; + #ifdef ENABLE_BUF_PRINT PrintBuffer(hashBuf, hashLen); printf("\n"); @@ -191,5 +200,6 @@ int main(void) gMyKeyInit = 0; } - return ret; + /* not firstErr: an exit code is masked to 8 bits, so -256 would read as 0 */ + return (firstErr == 0) ? 0 : 1; } diff --git a/ecc/ecc-verify.c b/ecc/ecc-verify.c index 55ae3ca1c..411597ff3 100644 --- a/ecc/ecc-verify.c +++ b/ecc/ecc-verify.c @@ -25,6 +25,7 @@ #include #include #include +#include #if defined(WOLFSSL_CUSTOM_CURVES) && defined(HAVE_ECC_KOBLITZ) @@ -83,6 +84,10 @@ int hash_firmware_verify(const byte* fwAddr, word32 fwLen, const byte* sigBuf, w if (ret < 0) goto exit; + /* a bad signature also returns 0 here: the result is in verify, not ret */ + if (verify != 1) + ret = SIG_VERIFY_E; + exit: wc_Sha256Free(&sha); @@ -105,7 +110,7 @@ int main(void) ret = hash_firmware_verify(data, sizeof(data), sigBuf, sigLen); printf("hash_firmware_verify: %d\n", ret); - return 0; + return (ret == 0) ? 0 : 1; } #else diff --git a/embedded/Makefile b/embedded/Makefile index ddd21f584..af8a4263a 100644 --- a/embedded/Makefile +++ b/embedded/Makefile @@ -1,4 +1,4 @@ -# TLS Examples Makefile +# Embedded Examples Makefile CC = gcc WOLFSSL_INSTALL_DIR = /usr/local CFLAGS = -Wall -I$(WOLFSSL_INSTALL_DIR)/include @@ -22,9 +22,7 @@ LIBS+=$(DYN_LIB) # build targets SRC=$(wildcard *.c) TARGETS=$(patsubst %.c, %, $(SRC)) -LINUX_SPECIFIC=client-tls-perf \ - server-tls-epoll-perf \ - server-tls-epoll-threaded +LINUX_SPECIFIC= # Intel QuickAssist diff --git a/fullstack/freertos-wolfip-wolfssl-https/CMakeLists.txt b/fullstack/freertos-wolfip-wolfssl-https/CMakeLists.txt index 17c75fe67..dee111291 100644 --- a/fullstack/freertos-wolfip-wolfssl-https/CMakeLists.txt +++ b/fullstack/freertos-wolfip-wolfssl-https/CMakeLists.txt @@ -8,6 +8,9 @@ set(CMAKE_C_STANDARD_REQUIRED ON) # wolfSSL configuration add_definitions(-DWOLFSSL_USER_SETTINGS) add_definitions(-DWOLFSSL_WOLFIP) +# wolfip's httpd.h puts its whole body behind this, so without it the header +# includes cleanly and every http_* symbol is undeclared +add_definitions(-DWOLFIP_ENABLE_HTTP) # FreeRTOS Kernel source files for POSIX port set(FREERTOS_PORT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/freertos/FreeRTOS-Kernel/portable/ThirdParty/GCC/Posix) diff --git a/fullstack/freertos-wolfip-wolfssl-https/setup.sh b/fullstack/freertos-wolfip-wolfssl-https/setup.sh index 0d0e94c5d..c6ade020c 100755 --- a/fullstack/freertos-wolfip-wolfssl-https/setup.sh +++ b/fullstack/freertos-wolfip-wolfssl-https/setup.sh @@ -21,13 +21,18 @@ cd ../../../../ if [ ! -d "wolfssl" ]; then git clone --depth=1 https://github.com/wolfSSL/wolfssl.git cd wolfssl + # a git clone ships no Makefile; only release tarballs are pre-configured + ./autogen.sh + ./configure --enable-tls13 --enable-static make sudo make install cd .. fi if [ ! -d "wolfip" ]; then - git clone --depth=1 https://github.com/wolfSSL/wolfip.git + # pinned: wolfSSL is what this repo demonstrates, so wolfIP churn should not + # decide whether the example builds + git clone --depth=1 --branch v1.0 https://github.com/wolfSSL/wolfip.git cd wolfip make cd .. diff --git a/fullstack/freertos-wolfip-wolfssl-https/src/wolfip_freertos.c b/fullstack/freertos-wolfip-wolfssl-https/src/wolfip_freertos.c index e2e1731f6..4cfe6b488 100644 --- a/fullstack/freertos-wolfip-wolfssl-https/src/wolfip_freertos.c +++ b/fullstack/freertos-wolfip-wolfssl-https/src/wolfip_freertos.c @@ -59,7 +59,7 @@ static TaskHandle_t g_network_task = NULL; static int tap_fd = -1; /* TUN/TAP device functions */ -static int tap_init(struct ll *dev, const char *ifname) { +static int tap_init(struct wolfIP_ll_dev *dev, const char *ifname) { struct ifreq ifr; int sock_fd; @@ -114,7 +114,7 @@ static int tap_init(struct ll *dev, const char *ifname) { return 0; } -static int tap_poll(struct ll *ll, void *buf, uint32_t len) { +static int tap_poll(struct wolfIP_ll_dev *ll, void *buf, uint32_t len) { struct pollfd pfd; int ret; @@ -140,7 +140,7 @@ static int tap_poll(struct ll *ll, void *buf, uint32_t len) { return ret; } -static int tap_send(struct ll *ll, void *buf, uint32_t len) { +static int tap_send(struct wolfIP_ll_dev *ll, void *buf, uint32_t len) { return write(tap_fd, buf, len); } @@ -160,7 +160,7 @@ static void wolfIP_NetworkTask(void *pvParameters) { } int wolfIP_FreeRTOS_Init(void) { - struct ll *tapdev; + struct wolfIP_ll_dev *tapdev; /* Initialize wolfIP */ wolfIP_init_static(&g_wolfip); diff --git a/java/https-url/URLClient.java b/java/https-url/URLClient.java index 2a20ad07e..d1b547f1f 100644 --- a/java/https-url/URLClient.java +++ b/java/https-url/URLClient.java @@ -49,7 +49,6 @@ import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; -import com.wolfssl.provider.jsse.WolfSSLDebug; import com.wolfssl.provider.jsse.WolfSSLProvider; import com.wolfssl.WolfSSL; diff --git a/mynewt/client-tls-mn.c b/mynewt/client-tls-mn.c index f365dba8c..59c2acea1 100644 --- a/mynewt/client-tls-mn.c +++ b/mynewt/client-tls-mn.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -120,12 +121,12 @@ static const oc_handler_t omgr_oc_handler = { static void net_test_readable(void *arg, int err) { - console_printf("net_test_readable %x - %d\n", (int)arg, err); + console_printf("net_test_readable %lx - %d\n", (unsigned long)(uintptr_t)arg, err); } static void net_test_writable(void *arg, int err) { - console_printf("net_test_writable %x - %d\n", (int)arg, err); + console_printf("net_test_writable %lx - %d\n", (unsigned long)(uintptr_t)arg, err); } static const union mn_socket_cb net_test_cbs = { @@ -135,7 +136,8 @@ static const union mn_socket_cb net_test_cbs = { static int net_test_newconn(void *arg, struct mn_socket *new) { - console_printf("net_test_newconn %x - %x\n", (int)arg, (int)new); + console_printf("net_test_newconn %lx - %lx\n", (unsigned long)(uintptr_t)arg, + (unsigned long)(uintptr_t)new); mn_socket_set_cbs(new, NULL, &net_test_cbs); net_test_socket2 = new; return 0; @@ -161,12 +163,12 @@ net_cli(int argc, char **argv) } if (!strcmp(argv[1], "udp")) { rc = mn_socket(&net_test_socket, MN_PF_INET, MN_SOCK_DGRAM, 0); - console_printf("mn_socket(UDP) = %d %x\n", rc, - (int)net_test_socket); + console_printf("mn_socket(UDP) = %d %lx\n", rc, + (unsigned long)(uintptr_t)net_test_socket); } else if (!strcmp(argv[1], "tcp")) { rc = mn_socket(&net_test_socket, MN_PF_INET, MN_SOCK_STREAM, 0); - console_printf("mn_socket(TCP) = %d %x\n", rc, - (int)net_test_socket); + console_printf("mn_socket(TCP) = %d %lx\n", rc, + (unsigned long)(uintptr_t)net_test_socket); } else if (!strcmp(argv[1], "connect") || !strcmp(argv[1], "bind")) { char *addrStr = DEFAULT_IPADDR; int port = DEFAULT_PORT; diff --git a/mynewt/jenkins.sh b/mynewt/jenkins.sh index 2e26a8c5d..1e79f59ba 100755 --- a/mynewt/jenkins.sh +++ b/mynewt/jenkins.sh @@ -22,7 +22,7 @@ newt upgrade popd > /dev/null # deploy wolfssl source files to mynewt project -git clone https://github.com/wolfSSL/wolfssl.git +git clone ${WOLFSSL_REF:+--branch ${WOLFSSL_REF}} https://github.com/wolfSSL/wolfssl.git WOLFSSL=`pwd`/wolfssl ${WOLFSSL}/IDE/mynewt/setup.sh ${NEWTPROJ} diff --git a/ocsp/stapling/Makefile b/ocsp/stapling/Makefile index f6b5af5b1..27d57a6f6 100644 --- a/ocsp/stapling/Makefile +++ b/ocsp/stapling/Makefile @@ -32,10 +32,12 @@ debug: all %: %.c $(CC) -o $@ $< $(CFLAGS) $(LIBS) +# the signer must be issued by server1's own issuer, or wolfSSL rejects the +# response with BAD_OCSP_RESPONDER (RFC 6960 delegated responder) responder: openssl ocsp -index responder-certs/index.txt -port 22221 \ - -rsigner responder-certs/ocsp-responder-cert.pem \ - -rkey responder-certs/ocsp-responder-key.pem \ + -rsigner responder-certs/ocsp-responder-int1-cert.pem \ + -rkey responder-certs/ocsp-responder-int1-key.pem \ -CA client-certs/intermediate1-ca-cert.pem clean: diff --git a/ocsp/stapling/client-certs/intermediate1-ca-cert.pem b/ocsp/stapling/client-certs/intermediate1-ca-cert.pem index 911cce437..2a5a1a9ca 100644 --- a/ocsp/stapling/client-certs/intermediate1-ca-cert.pem +++ b/ocsp/stapling/client-certs/intermediate1-ca-cert.pem @@ -3,11 +3,11 @@ Certificate: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL intermediate CA 1, emailAddress = info@wolfssl.com + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL intermediate CA 1, emailAddress=facts@wolfssl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) @@ -38,7 +38,7 @@ Certificate: 83:C6:3A:89:2C:81:F4:02:D7:9D:4C:E2:2A:C0:71:82:64:44:DA:0E X509v3 Authority Key Identifier: keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com serial:63 X509v3 Key Usage: Certificate Sign, CRL Sign @@ -46,60 +46,60 @@ Certificate: OCSP - URI:http://127.0.0.1:22220 Signature Algorithm: sha256WithRSAEncryption Signature Value: - 75:57:f1:0c:87:8f:a2:70:3c:ce:e4:70:0e:99:6a:da:c4:80: - 94:2c:25:0c:de:0d:7b:f3:94:f1:e8:ad:6f:d0:de:9a:9d:f5: - 64:31:65:3f:18:e6:c3:f5:b5:1d:a2:be:5b:97:79:41:78:15: - 1c:b3:83:de:d0:00:ea:d2:70:43:c5:60:60:07:72:e5:76:59: - b8:0e:2f:47:c9:8d:a4:4c:f1:20:b0:40:3b:ed:e9:de:b2:46: - 10:90:1b:0f:96:16:e6:97:bc:d5:9a:93:aa:3c:e3:b3:6b:5f: - db:2c:af:2b:da:7c:36:36:aa:86:a1:65:70:c8:f1:34:d1:1f: - 10:96:71:e6:cf:69:5c:bf:0e:15:33:97:fe:40:42:be:30:48: - ad:fb:d7:0e:7b:73:dd:64:30:7e:10:81:ac:3b:0b:3c:e4:12: - 9f:31:8b:3d:f0:9b:84:dc:5b:32:33:39:de:eb:1a:17:89:d8: - 1b:00:33:2d:50:a4:1a:2c:11:a2:60:ac:c1:9a:0f:44:90:00: - cf:8d:6c:af:5b:71:23:7a:a7:4f:df:f5:3f:5c:ae:93:ca:4e: - ec:f0:1b:f4:fa:53:7d:d9:36:af:5e:4c:54:c7:3a:d5:e3:68: - ca:78:e5:1f:55:44:65:eb:00:2d:c3:c8:ba:0e:1f:47:1c:67: - 2e:a9:c1:6e + 1a:4e:f4:e6:eb:df:9e:b0:67:30:f2:ea:20:d6:f8:85:8f:5c: + e2:06:5b:16:98:9e:44:fe:e7:ce:5d:19:6d:7e:56:1a:4a:41: + e9:d8:b5:3a:1d:a9:fa:64:e6:e8:00:01:49:6a:63:59:e5:88: + dc:42:8f:c1:d1:5b:20:79:5c:16:a0:f1:75:15:9e:6a:86:a1: + 6d:19:d1:76:fa:25:92:a9:42:8a:ac:91:38:ef:e0:8c:89:a1: + 94:14:80:46:50:9c:84:8b:3a:c7:69:23:22:10:42:ad:a9:70: + 43:da:56:27:fd:7b:97:00:cd:a8:6a:87:f4:bb:46:3d:a6:ae: + 08:40:ee:eb:1c:ab:f2:44:79:13:81:68:d2:fb:de:78:b7:ee: + f3:e4:41:f7:aa:39:fc:48:fd:a6:69:4a:4c:02:f9:aa:ae:a7: + 5e:24:0f:94:81:a5:64:c8:38:1b:dc:e1:78:0c:00:45:dc:a4: + dd:94:da:8e:6a:d0:2c:8a:bf:57:bb:ea:74:1b:66:f0:e1:89: + f9:28:27:e8:cc:81:fe:b3:11:d4:76:b0:32:a3:00:1c:04:62: + 98:14:c7:7d:1e:79:fa:e2:6e:f9:65:13:dc:74:4a:38:7b:ef: + 4e:3b:bd:a9:db:52:e9:40:cc:dd:73:b3:95:e2:20:d6:a5:99: + ad:00:82:5b -----BEGIN CERTIFICATE----- -MIIE8DCCA9igAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx +MIIE8zCCA9ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBoTELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NMIGludGVy -bWVkaWF0ZSBDQSAxMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3rTIXHfgLbH1ua0WRzWgNWVl -xuFAqx60uRO3y4y7d6V22m2Hh/ZKTRPkJj4nh+5bx2o/RTBhVVz2NdFl+pgRo6dV -1b6Rgkv8vpDWUFNjmiwi4TUR3HgCl4rkRpKcUwh23h9TtrjKdz55brzQ4w0wW0z2 -lA0wKWSfBOXb+4lgZ7uvJoNRdyQvKwuhlIEQmOjrJqgefOTEbGcGlVVK3VL08mBt -ASsZkTVtpAhHBnEkANnexlbzi1Ms4pqWpfNi5cTjI/LS/CHqD2J2jdWZSM7cWMS7 -f9qULIB0g8XgsBV+Qf0O8vTweHZ7rSYNqkiWFy8h45UrJjf5qoAv/t72XryXfwID -AQABo4IBOTCCATUwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUg8Y6iSyB9ALXnUzi -KsBxgmRE2g4wgcQGA1UdIwSBvDCBuYAUc7AcpC+Cy89HpTjXsASCOn5yFSGhgZ2k -gZowgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH -DAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmlu -ZzEYMBYGA1UEAwwPd29sZlNTTCByb290IENBMR8wHQYJKoZIhvcNAQkBFhBpbmZv -QHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQwIgYI -KwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQELBQAD -ggEBAHVX8QyHj6JwPM7kcA6ZatrEgJQsJQzeDXvzlPHorW/Q3pqd9WQxZT8Y5sP1 -tR2ivluXeUF4FRyzg97QAOrScEPFYGAHcuV2WbgOL0fJjaRM8SCwQDvt6d6yRhCQ -Gw+WFuaXvNWak6o847NrX9ssryvafDY2qoahZXDI8TTRHxCWcebPaVy/DhUzl/5A -Qr4wSK371w57c91kMH4Qgaw7CzzkEp8xiz3wm4TcWzIzOd7rGheJ2BsAMy1QpBos -EaJgrMGaD0SQAM+NbK9bcSN6p0/f9T9crpPKTuzwG/T6U33ZNq9eTFTHOtXjaMp4 -5R9VRGXrAC3DyLoOH0ccZy6pwW4= +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgaIxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEiMCAGA1UEAwwZd29sZlNTTCBpbnRl +cm1lZGlhdGUgQ0EgMTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNzbC5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDetMhcd+AtsfW5rRZHNaA1 +ZWXG4UCrHrS5E7fLjLt3pXbabYeH9kpNE+QmPieH7lvHaj9FMGFVXPY10WX6mBGj +p1XVvpGCS/y+kNZQU2OaLCLhNRHceAKXiuRGkpxTCHbeH1O2uMp3PnluvNDjDTBb +TPaUDTApZJ8E5dv7iWBnu68mg1F3JC8rC6GUgRCY6OsmqB585MRsZwaVVUrdUvTy +YG0BKxmRNW2kCEcGcSQA2d7GVvOLUyzimpal82LlxOMj8tL8IeoPYnaN1ZlIztxY +xLt/2pQsgHSDxeCwFX5B/Q7y9PB4dnutJg2qSJYXLyHjlSsmN/mqgC/+3vZevJd/ +AgMBAAGjggE6MIIBNjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBSDxjqJLIH0Ated +TOIqwHGCZETaDjCBxQYDVR0jBIG9MIG6gBRzsBykL4LLz0elONewBII6fnIVIaGB +nqSBmzCBmDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNV +BAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVy +aW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZh +Y3RzQHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQw +IgYIKwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQEL +BQADggEBABpO9Obr356wZzDy6iDW+IWPXOIGWxaYnkT+585dGW1+VhpKQenYtTod +qfpk5ugAAUlqY1nliNxCj8HRWyB5XBag8XUVnmqGoW0Z0Xb6JZKpQoqskTjv4IyJ +oZQUgEZQnISLOsdpIyIQQq2pcEPaVif9e5cAzahqh/S7Rj2mrghA7uscq/JEeROB +aNL73ni37vPkQfeqOfxI/aZpSkwC+aqup14kD5SBpWTIOBvc4XgMAEXcpN2U2o5q +0CyKv1e76nQbZvDhifkoJ+jMgf6zEdR2sDKjABwEYpgUx30eefribvllE9x0Sjh7 +7047vanbUulAzN1zs5XiINalma0Agls= -----END CERTIFICATE----- Certificate: Data: Version: 3 (0x2) Serial Number: 99 (0x63) Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) @@ -130,7 +130,7 @@ Certificate: 73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 X509v3 Authority Key Identifier: keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com serial:63 X509v3 Key Usage: Certificate Sign, CRL Sign @@ -138,47 +138,47 @@ Certificate: OCSP - URI:http://127.0.0.1:22220 Signature Algorithm: sha256WithRSAEncryption Signature Value: - 76:e8:fa:f6:1e:5b:0e:ff:24:43:e0:cb:19:26:38:d9:df:18: - 5d:66:e1:4b:ac:e4:8e:b0:49:2c:d6:04:20:eb:4a:a8:06:d7: - 55:ec:6b:38:f8:0f:8c:e6:c9:ec:42:f0:ca:07:9f:88:7a:ee: - bf:af:3f:7d:d3:45:67:20:84:bb:c7:c5:32:69:ab:59:e1:e3: - 38:4b:ed:18:2e:de:da:88:ec:a0:b7:ff:c1:50:96:73:e3:03: - df:a1:e7:47:93:13:1d:fb:e6:6b:37:3e:50:a3:eb:5b:24:26: - d2:43:2e:6e:9c:83:9c:fb:79:ba:cd:fd:3b:e5:87:87:a7:0f: - 5f:f9:64:34:56:5e:8b:13:e2:c4:41:e3:9d:3e:36:2d:cb:d3: - 5f:d3:12:90:bf:78:c1:4c:df:eb:7b:99:e6:1e:ee:52:78:6f: - 0c:82:e1:59:d4:25:40:e5:24:95:3e:0f:cc:08:60:fe:b4:8c: - 48:42:bf:29:74:92:71:1a:85:00:a7:4c:f0:c0:32:47:f3:be: - f4:08:5c:f2:43:e0:b9:76:86:60:9a:3b:af:d6:32:41:5f:b0: - 04:12:44:2a:44:19:d4:27:d3:ce:71:7e:5b:16:1a:f5:0c:db: - 43:b0:a6:bb:76:02:f6:e0:30:4e:04:f4:f3:9b:cd:d4:ae:45: - 94:c5:8c:bb + 36:b1:86:d6:72:f8:e7:6a:ae:43:fb:c0:ed:f1:36:64:8a:da: + 8e:5f:f7:c4:ad:64:c8:29:03:74:58:b0:9e:ee:41:89:5b:2a: + 12:f4:82:a4:03:a5:f0:df:a2:84:cb:2b:b3:16:0f:dc:cf:cc: + 56:99:61:a9:f9:3d:3a:7e:e4:12:43:c3:b1:4f:58:26:79:e7: + e4:0d:a5:88:3d:79:33:a1:09:7d:78:af:bd:59:71:11:54:4a: + cc:d6:d2:6d:1f:88:27:ac:d5:bf:75:fc:c3:05:0b:cd:c8:0e: + 72:41:1d:d8:68:62:be:94:d7:60:be:05:4a:42:9c:50:b7:45: + 71:6d:83:9a:ef:08:5c:41:db:c8:62:33:3c:69:a2:8a:b4:0f: + db:65:c4:b7:92:0a:76:f7:55:06:77:8c:ff:8c:84:84:d9:dd: + 46:11:2a:2d:27:96:a7:f5:47:c1:43:4b:fe:53:d8:be:16:94: + 36:0a:d4:be:c3:6c:9b:0c:52:31:4a:eb:62:b4:81:4b:2d:f7: + f1:65:c1:ee:36:79:19:f7:ab:16:f8:38:d2:ea:87:8d:f8:f9: + 14:82:db:67:b6:94:a8:55:0b:90:6b:af:b0:e9:42:64:42:6d: + 2c:e3:f1:b6:e0:f9:58:ed:69:66:62:98:dc:5a:7b:fa:35:5a: + 23:84:91:0e -----BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx +MIIE6TCCA9GgAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBlzELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg -Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCrLLQvHQYJ704phoR+zL+meXzwwMFkJYx1txAF -ykgnDA4yHLD+mYU5trmi9yf/bTyMFnMpIX+LplRxkK3MBbmfFccKP19p9ApfjHG1 -LL9m4gOaMvTS7CqJS/k1iBQzR04uBXkB7WQ2drn4hc0BiKzFsrFZuM1a9AkJOJva -Ws/OeJkfST1B1gZ8UpnIl9GzgDqiTzbExZYwdzE4yHDM4WcGsysvk7Vpz4N+iFOb -D0YhTNYFNkSZYGhH5TIBEtQQc66aNJT6brhYT3tbipKXrf2XuXXKwtRFfRdrzS/z -Y3oOMLULqdmmfHRgncwJA0PxD5DTt/5sn9nNeEsVroxb+ZmBAgMBAAGjggE5MIIB -NTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRzsBykL4LLz0elONewBII6fnIVITCB -xAYDVR0jBIG8MIG5gBRzsBykL4LLz0elONewBII6fnIVIaGBnaSBmjCBlzELMAkG -A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx -EDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQD -DA93b2xmU1NMIHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j -b22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW -aHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEAduj69h5b -Dv8kQ+DLGSY42d8YXWbhS6zkjrBJLNYEIOtKqAbXVexrOPgPjObJ7ELwygefiHru -v68/fdNFZyCEu8fFMmmrWeHjOEvtGC7e2ojsoLf/wVCWc+MD36HnR5MTHfvmazc+ -UKPrWyQm0kMubpyDnPt5us39O+WHh6cPX/lkNFZeixPixEHjnT42LcvTX9MSkL94 -wUzf63uZ5h7uUnhvDILhWdQlQOUklT4PzAhg/rSMSEK/KXSScRqFAKdM8MAyR/O+ -9Ahc8kPguXaGYJo7r9YyQV+wBBJEKkQZ1CfTznF+WxYa9QzbQ7Cmu3YC9uAwTgT0 -85vN1K5FlMWMuw== +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEYMBYGA1UEAwwPd29sZlNTTCByb290 +IENBMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3NsLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKsstC8dBgnvTimGhH7Mv6Z5fPDAwWQljHW3 +EAXKSCcMDjIcsP6ZhTm2uaL3J/9tPIwWcykhf4umVHGQrcwFuZ8Vxwo/X2n0Cl+M +cbUsv2biA5oy9NLsKolL+TWIFDNHTi4FeQHtZDZ2ufiFzQGIrMWysVm4zVr0CQk4 +m9paz854mR9JPUHWBnxSmciX0bOAOqJPNsTFljB3MTjIcMzhZwazKy+TtWnPg36I +U5sPRiFM1gU2RJlgaEflMgES1BBzrpo0lPpuuFhPe1uKkpet/Ze5dcrC1EV9F2vN +L/Njeg4wtQup2aZ8dGCdzAkDQ/EPkNO3/myf2c14SxWujFv5mYECAwEAAaOCATow +ggE2MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFHOwHKQvgsvPR6U417AEgjp+chUh +MIHFBgNVHSMEgb0wgbqAFHOwHKQvgsvPR6U417AEgjp+chUhoYGepIGbMIGYMQsw +CQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRs +ZTEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcxGDAWBgNV +BAMMD3dvbGZTU0wgcm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNz +bC5jb22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AYYWaHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEANrGG +1nL452quQ/vA7fE2ZIrajl/3xK1kyCkDdFiwnu5BiVsqEvSCpAOl8N+ihMsrsxYP +3M/MVplhqfk9On7kEkPDsU9YJnnn5A2liD15M6EJfXivvVlxEVRKzNbSbR+IJ6zV +v3X8wwULzcgOckEd2GhivpTXYL4FSkKcULdFcW2Dmu8IXEHbyGIzPGmiirQP22XE +t5IKdvdVBneM/4yEhNndRhEqLSeWp/VHwUNL/lPYvhaUNgrUvsNsmwxSMUrrYrSB +Sy338WXB7jZ5GferFvg40uqHjfj5FILbZ7aUqFULkGuvsOlCZEJtLOPxtuD5WO1p +ZmKY3Fp7+jVaI4SRDg== -----END CERTIFICATE----- diff --git a/ocsp/stapling/client-certs/root-ca-cert.pem b/ocsp/stapling/client-certs/root-ca-cert.pem index 060acb0c0..a31a7872a 100644 --- a/ocsp/stapling/client-certs/root-ca-cert.pem +++ b/ocsp/stapling/client-certs/root-ca-cert.pem @@ -3,11 +3,11 @@ Certificate: Version: 3 (0x2) Serial Number: 99 (0x63) Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) @@ -38,7 +38,7 @@ Certificate: 73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 X509v3 Authority Key Identifier: keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com serial:63 X509v3 Key Usage: Certificate Sign, CRL Sign @@ -46,47 +46,47 @@ Certificate: OCSP - URI:http://127.0.0.1:22220 Signature Algorithm: sha256WithRSAEncryption Signature Value: - 76:e8:fa:f6:1e:5b:0e:ff:24:43:e0:cb:19:26:38:d9:df:18: - 5d:66:e1:4b:ac:e4:8e:b0:49:2c:d6:04:20:eb:4a:a8:06:d7: - 55:ec:6b:38:f8:0f:8c:e6:c9:ec:42:f0:ca:07:9f:88:7a:ee: - bf:af:3f:7d:d3:45:67:20:84:bb:c7:c5:32:69:ab:59:e1:e3: - 38:4b:ed:18:2e:de:da:88:ec:a0:b7:ff:c1:50:96:73:e3:03: - df:a1:e7:47:93:13:1d:fb:e6:6b:37:3e:50:a3:eb:5b:24:26: - d2:43:2e:6e:9c:83:9c:fb:79:ba:cd:fd:3b:e5:87:87:a7:0f: - 5f:f9:64:34:56:5e:8b:13:e2:c4:41:e3:9d:3e:36:2d:cb:d3: - 5f:d3:12:90:bf:78:c1:4c:df:eb:7b:99:e6:1e:ee:52:78:6f: - 0c:82:e1:59:d4:25:40:e5:24:95:3e:0f:cc:08:60:fe:b4:8c: - 48:42:bf:29:74:92:71:1a:85:00:a7:4c:f0:c0:32:47:f3:be: - f4:08:5c:f2:43:e0:b9:76:86:60:9a:3b:af:d6:32:41:5f:b0: - 04:12:44:2a:44:19:d4:27:d3:ce:71:7e:5b:16:1a:f5:0c:db: - 43:b0:a6:bb:76:02:f6:e0:30:4e:04:f4:f3:9b:cd:d4:ae:45: - 94:c5:8c:bb + 36:b1:86:d6:72:f8:e7:6a:ae:43:fb:c0:ed:f1:36:64:8a:da: + 8e:5f:f7:c4:ad:64:c8:29:03:74:58:b0:9e:ee:41:89:5b:2a: + 12:f4:82:a4:03:a5:f0:df:a2:84:cb:2b:b3:16:0f:dc:cf:cc: + 56:99:61:a9:f9:3d:3a:7e:e4:12:43:c3:b1:4f:58:26:79:e7: + e4:0d:a5:88:3d:79:33:a1:09:7d:78:af:bd:59:71:11:54:4a: + cc:d6:d2:6d:1f:88:27:ac:d5:bf:75:fc:c3:05:0b:cd:c8:0e: + 72:41:1d:d8:68:62:be:94:d7:60:be:05:4a:42:9c:50:b7:45: + 71:6d:83:9a:ef:08:5c:41:db:c8:62:33:3c:69:a2:8a:b4:0f: + db:65:c4:b7:92:0a:76:f7:55:06:77:8c:ff:8c:84:84:d9:dd: + 46:11:2a:2d:27:96:a7:f5:47:c1:43:4b:fe:53:d8:be:16:94: + 36:0a:d4:be:c3:6c:9b:0c:52:31:4a:eb:62:b4:81:4b:2d:f7: + f1:65:c1:ee:36:79:19:f7:ab:16:f8:38:d2:ea:87:8d:f8:f9: + 14:82:db:67:b6:94:a8:55:0b:90:6b:af:b0:e9:42:64:42:6d: + 2c:e3:f1:b6:e0:f9:58:ed:69:66:62:98:dc:5a:7b:fa:35:5a: + 23:84:91:0e -----BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx +MIIE6TCCA9GgAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBlzELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg -Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCrLLQvHQYJ704phoR+zL+meXzwwMFkJYx1txAF -ykgnDA4yHLD+mYU5trmi9yf/bTyMFnMpIX+LplRxkK3MBbmfFccKP19p9ApfjHG1 -LL9m4gOaMvTS7CqJS/k1iBQzR04uBXkB7WQ2drn4hc0BiKzFsrFZuM1a9AkJOJva -Ws/OeJkfST1B1gZ8UpnIl9GzgDqiTzbExZYwdzE4yHDM4WcGsysvk7Vpz4N+iFOb -D0YhTNYFNkSZYGhH5TIBEtQQc66aNJT6brhYT3tbipKXrf2XuXXKwtRFfRdrzS/z -Y3oOMLULqdmmfHRgncwJA0PxD5DTt/5sn9nNeEsVroxb+ZmBAgMBAAGjggE5MIIB -NTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRzsBykL4LLz0elONewBII6fnIVITCB -xAYDVR0jBIG8MIG5gBRzsBykL4LLz0elONewBII6fnIVIaGBnaSBmjCBlzELMAkG -A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx -EDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQD -DA93b2xmU1NMIHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j -b22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW -aHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEAduj69h5b -Dv8kQ+DLGSY42d8YXWbhS6zkjrBJLNYEIOtKqAbXVexrOPgPjObJ7ELwygefiHru -v68/fdNFZyCEu8fFMmmrWeHjOEvtGC7e2ojsoLf/wVCWc+MD36HnR5MTHfvmazc+ -UKPrWyQm0kMubpyDnPt5us39O+WHh6cPX/lkNFZeixPixEHjnT42LcvTX9MSkL94 -wUzf63uZ5h7uUnhvDILhWdQlQOUklT4PzAhg/rSMSEK/KXSScRqFAKdM8MAyR/O+ -9Ahc8kPguXaGYJo7r9YyQV+wBBJEKkQZ1CfTznF+WxYa9QzbQ7Cmu3YC9uAwTgT0 -85vN1K5FlMWMuw== +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEYMBYGA1UEAwwPd29sZlNTTCByb290 +IENBMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3NsLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKsstC8dBgnvTimGhH7Mv6Z5fPDAwWQljHW3 +EAXKSCcMDjIcsP6ZhTm2uaL3J/9tPIwWcykhf4umVHGQrcwFuZ8Vxwo/X2n0Cl+M +cbUsv2biA5oy9NLsKolL+TWIFDNHTi4FeQHtZDZ2ufiFzQGIrMWysVm4zVr0CQk4 +m9paz854mR9JPUHWBnxSmciX0bOAOqJPNsTFljB3MTjIcMzhZwazKy+TtWnPg36I +U5sPRiFM1gU2RJlgaEflMgES1BBzrpo0lPpuuFhPe1uKkpet/Ze5dcrC1EV9F2vN +L/Njeg4wtQup2aZ8dGCdzAkDQ/EPkNO3/myf2c14SxWujFv5mYECAwEAAaOCATow +ggE2MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFHOwHKQvgsvPR6U417AEgjp+chUh +MIHFBgNVHSMEgb0wgbqAFHOwHKQvgsvPR6U417AEgjp+chUhoYGepIGbMIGYMQsw +CQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRs +ZTEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcxGDAWBgNV +BAMMD3dvbGZTU0wgcm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNz +bC5jb22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AYYWaHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEANrGG +1nL452quQ/vA7fE2ZIrajl/3xK1kyCkDdFiwnu5BiVsqEvSCpAOl8N+ihMsrsxYP +3M/MVplhqfk9On7kEkPDsU9YJnnn5A2liD15M6EJfXivvVlxEVRKzNbSbR+IJ6zV +v3X8wwULzcgOckEd2GhivpTXYL4FSkKcULdFcW2Dmu8IXEHbyGIzPGmiirQP22XE +t5IKdvdVBneM/4yEhNndRhEqLSeWp/VHwUNL/lPYvhaUNgrUvsNsmwxSMUrrYrSB +Sy338WXB7jZ5GferFvg40uqHjfj5FILbZ7aUqFULkGuvsOlCZEJtLOPxtuD5WO1p +ZmKY3Fp7+jVaI4SRDg== -----END CERTIFICATE----- diff --git a/ocsp/stapling/responder-certs/index.txt b/ocsp/stapling/responder-certs/index.txt index b5ef6ab04..8b512748d 100644 --- a/ocsp/stapling/responder-certs/index.txt +++ b/ocsp/stapling/responder-certs/index.txt @@ -1 +1 @@ -V 161213070133Z 05 unknown /C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=www1.wolfssl.com/emailAddress=info@wolfssl.com +V 161213070133Z 05 unknown /C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=www1.wolfssl.com/emailAddress=facts@wolfssl.com diff --git a/ocsp/stapling/responder-certs/ocsp-responder-cert.pem b/ocsp/stapling/responder-certs/ocsp-responder-cert.pem deleted file mode 100644 index 5071c26ff..000000000 --- a/ocsp/stapling/responder-certs/ocsp-responder-cert.pem +++ /dev/null @@ -1,181 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 4 (0x4) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com - Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL OCSP Responder, emailAddress = info@wolfssl.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:b8:ba:23:b4:f6:c3:7b:14:c3:a4:f5:1d:61:a1: - f5:1e:63:b9:85:23:34:50:6d:f8:7c:a2:8a:04:8b: - d5:75:5c:2d:f7:63:88:d1:07:7a:ea:0b:45:35:2b: - eb:1f:b1:22:b4:94:41:38:e2:9d:74:d6:8b:30:22: - 10:51:c5:db:ca:3f:46:2b:fe:e5:5a:3f:41:74:67: - 75:95:a9:94:d5:c3:ee:42:f8:8d:eb:92:95:e1:d9: - 65:b7:43:c4:18:de:16:80:90:ce:24:35:21:c4:55: - ac:5a:51:e0:2e:2d:b3:0a:5a:4f:4a:73:31:50:ee: - 4a:16:bd:39:8b:ad:05:48:87:b1:99:e2:10:a7:06: - 72:67:ca:5c:d1:97:bd:c8:f1:76:f8:e0:4a:ec:bc: - 93:f4:66:4c:28:71:d1:d8:66:03:b4:90:30:bb:17: - b0:fe:97:f5:1e:e8:c7:5d:9b:8b:11:19:12:3c:ab: - 82:71:78:ff:ae:3f:32:b2:08:71:b2:1b:8c:27:ac: - 11:b8:d8:43:49:cf:b0:70:b1:f0:8c:ae:da:24:87: - 17:3b:d8:04:65:6c:00:76:50:ef:15:08:d7:b4:73: - 68:26:14:87:95:c3:5f:6e:61:b8:87:84:fa:80:1a: - 0a:8b:98:f3:e3:ff:4e:44:1c:65:74:7c:71:54:65: - e5:39 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - X509v3 Subject Key Identifier: - 32:67:E1:B1:79:D2:81:FC:9F:23:0C:70:40:50:B5:46:56:B8:30:36 - X509v3 Authority Key Identifier: - keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com - serial:63 - X509v3 Extended Key Usage: - OCSP Signing - Signature Algorithm: sha256WithRSAEncryption - Signature Value: - 4d:a2:d8:55:e0:2b:f4:ad:65:e2:92:35:cb:60:a0:a2:6b:a6: - 88:c1:86:58:57:37:bd:2e:28:6e:1c:56:2a:35:de:ff:3e:8e: - 3d:47:21:1a:e9:d3:c6:b4:e2:cb:3e:c6:af:9b:ef:23:88:56: - 95:73:2e:b3:ed:c5:11:4b:69:f7:13:3a:05:e1:af:ba:c9:59: - fd:e2:a0:81:a0:4c:0c:2c:cb:57:ad:96:3a:8c:32:a6:4a:f8: - 72:b8:ec:b3:26:69:d6:6a:4c:4c:78:18:3c:ca:19:f1:b5:8e: - 23:81:5b:27:90:e0:5c:2b:17:4d:78:99:6b:25:bd:2f:ae:1b: - aa:ce:84:b9:44:21:46:c0:34:6b:5b:b9:1b:ca:5c:60:f1:ef: - e6:66:bc:84:63:56:50:7d:bb:2c:2f:7b:47:b4:fd:58:77:87: - ee:27:20:96:72:8e:4c:7e:4f:93:eb:5f:8f:9c:1e:59:7a:96: - aa:53:77:22:41:d8:d3:f9:89:8f:e8:9d:65:bd:0c:71:3c:bb: - a3:07:bf:fb:a8:d1:18:0a:b4:c4:f7:83:b3:86:2b:f0:5b:05: - 28:c1:01:31:73:5c:2b:bd:60:97:a3:36:82:96:d7:83:df:75: - ee:29:42:97:86:41:55:b9:70:87:d5:02:85:13:41:f8:25:05: - ab:6a:aa:57 ------BEGIN CERTIFICATE----- -MIIEvjCCA6agAwIBAgIBBDANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx -EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM -B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBnjELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMR8wHQYDVQQDDBZ3b2xmU1NMIE9DU1Ag -UmVzcG9uZGVyMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMIIBIjAN -BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuLojtPbDexTDpPUdYaH1HmO5hSM0 -UG34fKKKBIvVdVwt92OI0Qd66gtFNSvrH7EitJRBOOKddNaLMCIQUcXbyj9GK/7l -Wj9BdGd1lamU1cPuQviN65KV4dllt0PEGN4WgJDOJDUhxFWsWlHgLi2zClpPSnMx -UO5KFr05i60FSIexmeIQpwZyZ8pc0Ze9yPF2+OBK7LyT9GZMKHHR2GYDtJAwuxew -/pf1HujHXZuLERkSPKuCcXj/rj8ysghxshuMJ6wRuNhDSc+wcLHwjK7aJIcXO9gE -ZWwAdlDvFQjXtHNoJhSHlcNfbmG4h4T6gBoKi5jz4/9ORBxldHxxVGXlOQIDAQAB -o4IBCjCCAQYwCQYDVR0TBAIwADAdBgNVHQ4EFgQUMmfhsXnSgfyfIwxwQFC1Rla4 -MDYwgcQGA1UdIwSBvDCBuYAUc7AcpC+Cy89HpTjXsASCOn5yFSGhgZ2kgZowgZcx -CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0 -dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEYMBYG -A1UEAwwPd29sZlNTTCByb290IENBMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZz -c2wuY29tggFjMBMGA1UdJQQMMAoGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IB -AQBNothV4Cv0rWXikjXLYKCia6aIwYZYVze9LihuHFYqNd7/Po49RyEa6dPGtOLL -Psavm+8jiFaVcy6z7cURS2n3EzoF4a+6yVn94qCBoEwMLMtXrZY6jDKmSvhyuOyz -JmnWakxMeBg8yhnxtY4jgVsnkOBcKxdNeJlrJb0vrhuqzoS5RCFGwDRrW7kbylxg -8e/mZryEY1ZQfbssL3tHtP1Yd4fuJyCWco5Mfk+T61+PnB5ZepaqU3ciQdjT+YmP -6J1lvQxxPLujB7/7qNEYCrTE94OzhivwWwUowQExc1wrvWCXozaClteD33XuKUKX -hkFVuXCH1QKFE0H4JQWraqpX ------END CERTIFICATE----- -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 99 (0x63) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com - Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:ab:2c:b4:2f:1d:06:09:ef:4e:29:86:84:7e:cc: - bf:a6:79:7c:f0:c0:c1:64:25:8c:75:b7:10:05:ca: - 48:27:0c:0e:32:1c:b0:fe:99:85:39:b6:b9:a2:f7: - 27:ff:6d:3c:8c:16:73:29:21:7f:8b:a6:54:71:90: - ad:cc:05:b9:9f:15:c7:0a:3f:5f:69:f4:0a:5f:8c: - 71:b5:2c:bf:66:e2:03:9a:32:f4:d2:ec:2a:89:4b: - f9:35:88:14:33:47:4e:2e:05:79:01:ed:64:36:76: - b9:f8:85:cd:01:88:ac:c5:b2:b1:59:b8:cd:5a:f4: - 09:09:38:9b:da:5a:cf:ce:78:99:1f:49:3d:41:d6: - 06:7c:52:99:c8:97:d1:b3:80:3a:a2:4f:36:c4:c5: - 96:30:77:31:38:c8:70:cc:e1:67:06:b3:2b:2f:93: - b5:69:cf:83:7e:88:53:9b:0f:46:21:4c:d6:05:36: - 44:99:60:68:47:e5:32:01:12:d4:10:73:ae:9a:34: - 94:fa:6e:b8:58:4f:7b:5b:8a:92:97:ad:fd:97:b9: - 75:ca:c2:d4:45:7d:17:6b:cd:2f:f3:63:7a:0e:30: - b5:0b:a9:d9:a6:7c:74:60:9d:cc:09:03:43:f1:0f: - 90:d3:b7:fe:6c:9f:d9:cd:78:4b:15:ae:8c:5b:f9: - 99:81 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:TRUE - X509v3 Subject Key Identifier: - 73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - X509v3 Authority Key Identifier: - keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com - serial:63 - X509v3 Key Usage: - Certificate Sign, CRL Sign - Authority Information Access: - OCSP - URI:http://127.0.0.1:22220 - Signature Algorithm: sha256WithRSAEncryption - Signature Value: - 76:e8:fa:f6:1e:5b:0e:ff:24:43:e0:cb:19:26:38:d9:df:18: - 5d:66:e1:4b:ac:e4:8e:b0:49:2c:d6:04:20:eb:4a:a8:06:d7: - 55:ec:6b:38:f8:0f:8c:e6:c9:ec:42:f0:ca:07:9f:88:7a:ee: - bf:af:3f:7d:d3:45:67:20:84:bb:c7:c5:32:69:ab:59:e1:e3: - 38:4b:ed:18:2e:de:da:88:ec:a0:b7:ff:c1:50:96:73:e3:03: - df:a1:e7:47:93:13:1d:fb:e6:6b:37:3e:50:a3:eb:5b:24:26: - d2:43:2e:6e:9c:83:9c:fb:79:ba:cd:fd:3b:e5:87:87:a7:0f: - 5f:f9:64:34:56:5e:8b:13:e2:c4:41:e3:9d:3e:36:2d:cb:d3: - 5f:d3:12:90:bf:78:c1:4c:df:eb:7b:99:e6:1e:ee:52:78:6f: - 0c:82:e1:59:d4:25:40:e5:24:95:3e:0f:cc:08:60:fe:b4:8c: - 48:42:bf:29:74:92:71:1a:85:00:a7:4c:f0:c0:32:47:f3:be: - f4:08:5c:f2:43:e0:b9:76:86:60:9a:3b:af:d6:32:41:5f:b0: - 04:12:44:2a:44:19:d4:27:d3:ce:71:7e:5b:16:1a:f5:0c:db: - 43:b0:a6:bb:76:02:f6:e0:30:4e:04:f4:f3:9b:cd:d4:ae:45: - 94:c5:8c:bb ------BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx -EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM -B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBlzELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg -Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCrLLQvHQYJ704phoR+zL+meXzwwMFkJYx1txAF -ykgnDA4yHLD+mYU5trmi9yf/bTyMFnMpIX+LplRxkK3MBbmfFccKP19p9ApfjHG1 -LL9m4gOaMvTS7CqJS/k1iBQzR04uBXkB7WQ2drn4hc0BiKzFsrFZuM1a9AkJOJva -Ws/OeJkfST1B1gZ8UpnIl9GzgDqiTzbExZYwdzE4yHDM4WcGsysvk7Vpz4N+iFOb -D0YhTNYFNkSZYGhH5TIBEtQQc66aNJT6brhYT3tbipKXrf2XuXXKwtRFfRdrzS/z -Y3oOMLULqdmmfHRgncwJA0PxD5DTt/5sn9nNeEsVroxb+ZmBAgMBAAGjggE5MIIB -NTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRzsBykL4LLz0elONewBII6fnIVITCB -xAYDVR0jBIG8MIG5gBRzsBykL4LLz0elONewBII6fnIVIaGBnaSBmjCBlzELMAkG -A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx -EDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQD -DA93b2xmU1NMIHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j -b22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW -aHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEAduj69h5b -Dv8kQ+DLGSY42d8YXWbhS6zkjrBJLNYEIOtKqAbXVexrOPgPjObJ7ELwygefiHru -v68/fdNFZyCEu8fFMmmrWeHjOEvtGC7e2ojsoLf/wVCWc+MD36HnR5MTHfvmazc+ -UKPrWyQm0kMubpyDnPt5us39O+WHh6cPX/lkNFZeixPixEHjnT42LcvTX9MSkL94 -wUzf63uZ5h7uUnhvDILhWdQlQOUklT4PzAhg/rSMSEK/KXSScRqFAKdM8MAyR/O+ -9Ahc8kPguXaGYJo7r9YyQV+wBBJEKkQZ1CfTznF+WxYa9QzbQ7Cmu3YC9uAwTgT0 -85vN1K5FlMWMuw== ------END CERTIFICATE----- diff --git a/ocsp/stapling/responder-certs/ocsp-responder-int1-cert.pem b/ocsp/stapling/responder-certs/ocsp-responder-int1-cert.pem new file mode 100644 index 000000000..dda802d91 --- /dev/null +++ b/ocsp/stapling/responder-certs/ocsp-responder-int1-cert.pem @@ -0,0 +1,273 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 10 (0xa) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL intermediate CA 1, emailAddress=facts@wolfssl.com + Validity + Not Before: Jun 26 15:58:51 2026 GMT + Not After : Mar 22 15:58:51 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL OCSP Responder Int1, emailAddress=facts@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:98:82:f0:e7:da:58:cf:85:0b:a4:de:34:41:3f: + 79:5a:ff:75:78:95:c6:89:5c:b7:2e:c4:6d:05:73: + a5:b1:45:58:72:3e:2c:e2:c0:17:87:fe:b4:64:82: + 00:fd:56:7d:8a:73:8d:6f:88:77:bb:98:56:a8:b6: + 28:36:a8:0c:9f:d6:7a:25:1d:ad:10:b8:d0:19:7c: + 80:70:9c:80:26:95:53:42:1c:90:4e:27:ed:f5:6e: + 87:6f:2e:eb:92:95:e0:6f:53:fe:be:17:a9:7f:e6: + b7:09:4b:63:9c:08:97:c8:b3:36:75:38:6d:3e:ff: + d8:e1:22:75:57:1a:5f:60:30:4d:1b:bc:2f:99:7f: + 02:ef:df:24:25:88:57:91:7b:2c:6f:f7:98:90:29: + 9f:12:66:a9:3e:73:c4:81:73:e7:9c:eb:22:f5:6c: + d5:23:e0:7b:ba:a6:ca:16:a3:33:f9:2e:52:a3:a8: + c9:f1:dd:85:1f:c1:94:0b:1e:8f:b7:48:be:20:d0: + da:bd:3b:85:8e:92:c1:f0:7c:ec:2e:c5:27:a0:4e: + 22:c5:c2:4d:1b:66:e7:ac:57:8c:34:2b:a5:55:e9: + 34:9c:7f:33:29:d0:4e:cb:1a:1a:02:17:b2:45:a3: + 49:05:5d:00:79:85:50:91:c0:3d:30:cb:84:0a:9a: + 2d:6d + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + X509v3 Subject Key Identifier: + 90:3C:B9:FB:15:20:AB:F6:6F:D3:F1:C9:71:B0:D0:1D:97:C6:A5:C5 + X509v3 Authority Key Identifier: + keyid:83:C6:3A:89:2C:81:F4:02:D7:9D:4C:E2:2A:C0:71:82:64:44:DA:0E + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com + serial:01 + X509v3 Extended Key Usage: + OCSP Signing + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + c8:4f:df:30:d3:5e:ba:2c:f7:2f:b2:d1:fc:0e:30:c1:86:52: + f3:95:ef:17:0a:e1:d9:46:20:4d:a0:6e:14:fb:9e:41:1d:cc: + 9c:68:bd:dd:9c:53:d6:f2:dc:bb:47:84:18:c4:ed:dc:9b:e3: + 0d:74:6a:cb:89:16:d6:21:57:6c:44:52:41:c5:36:42:05:a0: + ac:b5:dd:5c:90:ca:36:bc:d6:2c:fb:c1:95:a2:77:36:8f:00: + 42:e4:b4:e4:b3:9f:57:44:a2:46:0c:91:ef:03:00:50:e3:68: + ca:75:3d:d3:95:e1:21:e6:e7:8e:61:c1:f9:98:39:4a:c7:a2: + fd:9f:57:3e:dd:8d:a7:70:84:0e:91:e2:9e:f7:75:70:5c:e2: + a2:28:28:cb:e2:63:47:71:4d:b0:16:50:e9:05:2d:38:36:e0: + fd:c7:4b:85:50:a4:21:6b:75:bb:3e:f9:71:fa:f7:ba:b8:b1: + 68:44:72:01:b8:06:8c:9c:7b:ed:11:24:9a:36:65:51:94:6a: + 59:d6:ab:82:a2:9f:0e:98:2c:71:57:85:d7:0f:e0:d4:aa:a3: + 6e:5c:11:f6:47:ce:c0:12:23:c6:b3:c0:74:a7:26:f5:aa:13: + 53:dd:93:e4:9b:08:57:86:a6:72:e1:9a:e0:c3:69:12:4d:f5: + 54:6a:9e:9e +-----BEGIN CERTIFICATE----- +MIIE0DCCA7igAwIBAgIBCjANBgkqhkiG9w0BAQsFADCBojELMAkGA1UEBhMCVVMx +EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM +B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NM +IGludGVybWVkaWF0ZSBDQSAxMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3Ns +LmNvbTAeFw0yNjA2MjYxNTU4NTFaFw0yOTAzMjIxNTU4NTFaMIGkMQswCQYDVQQG +EwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEQMA4G +A1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcxJDAiBgNVBAMMG3dv +bGZTU0wgT0NTUCBSZXNwb25kZXIgSW50MTEgMB4GCSqGSIb3DQEJARYRZmFjdHNA +d29sZnNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYgvDn +2ljPhQuk3jRBP3la/3V4lcaJXLcuxG0Fc6WxRVhyPiziwBeH/rRkggD9Vn2Kc41v +iHe7mFaotig2qAyf1nolHa0QuNAZfIBwnIAmlVNCHJBOJ+31bodvLuuSleBvU/6+ +F6l/5rcJS2OcCJfIszZ1OG0+/9jhInVXGl9gME0bvC+ZfwLv3yQliFeReyxv95iQ +KZ8SZqk+c8SBc+ec6yL1bNUj4Hu6psoWozP5LlKjqMnx3YUfwZQLHo+3SL4g0Nq9 +O4WOksHwfOwuxSegTiLFwk0bZuesV4w0K6VV6TScfzMp0E7LGhoCF7JFo0kFXQB5 +hVCRwD0wy4QKmi1tAgMBAAGjggELMIIBBzAJBgNVHRMEAjAAMB0GA1UdDgQWBBSQ +PLn7FSCr9m/T8clxsNAdl8alxTCBxQYDVR0jBIG9MIG6gBSDxjqJLIH0AtedTOIq +wHGCZETaDqGBnqSBmzCBmDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0 +b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsM +C0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3QgQ0ExIDAeBgkqhkiG +9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tggEBMBMGA1UdJQQMMAoGCCsGAQUFBwMJ +MA0GCSqGSIb3DQEBCwUAA4IBAQDIT98w0166LPcvstH8DjDBhlLzle8XCuHZRiBN +oG4U+55BHcycaL3dnFPW8ty7R4QYxO3cm+MNdGrLiRbWIVdsRFJBxTZCBaCstd1c +kMo2vNYs+8GVonc2jwBC5LTks59XRKJGDJHvAwBQ42jKdT3TleEh5ueOYcH5mDlK +x6L9n1c+3Y2ncIQOkeKe93VwXOKiKCjL4mNHcU2wFlDpBS04NuD9x0uFUKQha3W7 +Pvlx+ve6uLFoRHIBuAaMnHvtESSaNmVRlGpZ1quCop8OmCxxV4XXD+DUqqNuXBH2 +R87AEiPGs8B0pyb1qhNT3ZPkmwhXhqZy4Zrgw2kSTfVUap6e +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com + Validity + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL intermediate CA 1, emailAddress=facts@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:de:b4:c8:5c:77:e0:2d:b1:f5:b9:ad:16:47:35: + a0:35:65:65:c6:e1:40:ab:1e:b4:b9:13:b7:cb:8c: + bb:77:a5:76:da:6d:87:87:f6:4a:4d:13:e4:26:3e: + 27:87:ee:5b:c7:6a:3f:45:30:61:55:5c:f6:35:d1: + 65:fa:98:11:a3:a7:55:d5:be:91:82:4b:fc:be:90: + d6:50:53:63:9a:2c:22:e1:35:11:dc:78:02:97:8a: + e4:46:92:9c:53:08:76:de:1f:53:b6:b8:ca:77:3e: + 79:6e:bc:d0:e3:0d:30:5b:4c:f6:94:0d:30:29:64: + 9f:04:e5:db:fb:89:60:67:bb:af:26:83:51:77:24: + 2f:2b:0b:a1:94:81:10:98:e8:eb:26:a8:1e:7c:e4: + c4:6c:67:06:95:55:4a:dd:52:f4:f2:60:6d:01:2b: + 19:91:35:6d:a4:08:47:06:71:24:00:d9:de:c6:56: + f3:8b:53:2c:e2:9a:96:a5:f3:62:e5:c4:e3:23:f2: + d2:fc:21:ea:0f:62:76:8d:d5:99:48:ce:dc:58:c4: + bb:7f:da:94:2c:80:74:83:c5:e0:b0:15:7e:41:fd: + 0e:f2:f4:f0:78:76:7b:ad:26:0d:aa:48:96:17:2f: + 21:e3:95:2b:26:37:f9:aa:80:2f:fe:de:f6:5e:bc: + 97:7f + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Key Identifier: + 83:C6:3A:89:2C:81:F4:02:D7:9D:4C:E2:2A:C0:71:82:64:44:DA:0E + X509v3 Authority Key Identifier: + keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com + serial:63 + X509v3 Key Usage: + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://127.0.0.1:22220 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 1a:4e:f4:e6:eb:df:9e:b0:67:30:f2:ea:20:d6:f8:85:8f:5c: + e2:06:5b:16:98:9e:44:fe:e7:ce:5d:19:6d:7e:56:1a:4a:41: + e9:d8:b5:3a:1d:a9:fa:64:e6:e8:00:01:49:6a:63:59:e5:88: + dc:42:8f:c1:d1:5b:20:79:5c:16:a0:f1:75:15:9e:6a:86:a1: + 6d:19:d1:76:fa:25:92:a9:42:8a:ac:91:38:ef:e0:8c:89:a1: + 94:14:80:46:50:9c:84:8b:3a:c7:69:23:22:10:42:ad:a9:70: + 43:da:56:27:fd:7b:97:00:cd:a8:6a:87:f4:bb:46:3d:a6:ae: + 08:40:ee:eb:1c:ab:f2:44:79:13:81:68:d2:fb:de:78:b7:ee: + f3:e4:41:f7:aa:39:fc:48:fd:a6:69:4a:4c:02:f9:aa:ae:a7: + 5e:24:0f:94:81:a5:64:c8:38:1b:dc:e1:78:0c:00:45:dc:a4: + dd:94:da:8e:6a:d0:2c:8a:bf:57:bb:ea:74:1b:66:f0:e1:89: + f9:28:27:e8:cc:81:fe:b3:11:d4:76:b0:32:a3:00:1c:04:62: + 98:14:c7:7d:1e:79:fa:e2:6e:f9:65:13:dc:74:4a:38:7b:ef: + 4e:3b:bd:a9:db:52:e9:40:cc:dd:73:b3:95:e2:20:d6:a5:99: + ad:00:82:5b +-----BEGIN CERTIFICATE----- +MIIE8zCCA9ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM +B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgaIxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEiMCAGA1UEAwwZd29sZlNTTCBpbnRl +cm1lZGlhdGUgQ0EgMTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNzbC5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDetMhcd+AtsfW5rRZHNaA1 +ZWXG4UCrHrS5E7fLjLt3pXbabYeH9kpNE+QmPieH7lvHaj9FMGFVXPY10WX6mBGj +p1XVvpGCS/y+kNZQU2OaLCLhNRHceAKXiuRGkpxTCHbeH1O2uMp3PnluvNDjDTBb +TPaUDTApZJ8E5dv7iWBnu68mg1F3JC8rC6GUgRCY6OsmqB585MRsZwaVVUrdUvTy +YG0BKxmRNW2kCEcGcSQA2d7GVvOLUyzimpal82LlxOMj8tL8IeoPYnaN1ZlIztxY +xLt/2pQsgHSDxeCwFX5B/Q7y9PB4dnutJg2qSJYXLyHjlSsmN/mqgC/+3vZevJd/ +AgMBAAGjggE6MIIBNjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBSDxjqJLIH0Ated +TOIqwHGCZETaDjCBxQYDVR0jBIG9MIG6gBRzsBykL4LLz0elONewBII6fnIVIaGB +nqSBmzCBmDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNV +BAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVy +aW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZh +Y3RzQHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQw +IgYIKwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQEL +BQADggEBABpO9Obr356wZzDy6iDW+IWPXOIGWxaYnkT+585dGW1+VhpKQenYtTod +qfpk5ugAAUlqY1nliNxCj8HRWyB5XBag8XUVnmqGoW0Z0Xb6JZKpQoqskTjv4IyJ +oZQUgEZQnISLOsdpIyIQQq2pcEPaVif9e5cAzahqh/S7Rj2mrghA7uscq/JEeROB +aNL73ni37vPkQfeqOfxI/aZpSkwC+aqup14kD5SBpWTIOBvc4XgMAEXcpN2U2o5q +0CyKv1e76nQbZvDhifkoJ+jMgf6zEdR2sDKjABwEYpgUx30eefribvllE9x0Sjh7 +7047vanbUulAzN1zs5XiINalma0Agls= +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 99 (0x63) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com + Validity + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:ab:2c:b4:2f:1d:06:09:ef:4e:29:86:84:7e:cc: + bf:a6:79:7c:f0:c0:c1:64:25:8c:75:b7:10:05:ca: + 48:27:0c:0e:32:1c:b0:fe:99:85:39:b6:b9:a2:f7: + 27:ff:6d:3c:8c:16:73:29:21:7f:8b:a6:54:71:90: + ad:cc:05:b9:9f:15:c7:0a:3f:5f:69:f4:0a:5f:8c: + 71:b5:2c:bf:66:e2:03:9a:32:f4:d2:ec:2a:89:4b: + f9:35:88:14:33:47:4e:2e:05:79:01:ed:64:36:76: + b9:f8:85:cd:01:88:ac:c5:b2:b1:59:b8:cd:5a:f4: + 09:09:38:9b:da:5a:cf:ce:78:99:1f:49:3d:41:d6: + 06:7c:52:99:c8:97:d1:b3:80:3a:a2:4f:36:c4:c5: + 96:30:77:31:38:c8:70:cc:e1:67:06:b3:2b:2f:93: + b5:69:cf:83:7e:88:53:9b:0f:46:21:4c:d6:05:36: + 44:99:60:68:47:e5:32:01:12:d4:10:73:ae:9a:34: + 94:fa:6e:b8:58:4f:7b:5b:8a:92:97:ad:fd:97:b9: + 75:ca:c2:d4:45:7d:17:6b:cd:2f:f3:63:7a:0e:30: + b5:0b:a9:d9:a6:7c:74:60:9d:cc:09:03:43:f1:0f: + 90:d3:b7:fe:6c:9f:d9:cd:78:4b:15:ae:8c:5b:f9: + 99:81 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Key Identifier: + 73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 + X509v3 Authority Key Identifier: + keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com + serial:63 + X509v3 Key Usage: + Certificate Sign, CRL Sign + Authority Information Access: + OCSP - URI:http://127.0.0.1:22220 + Signature Algorithm: sha256WithRSAEncryption + Signature Value: + 36:b1:86:d6:72:f8:e7:6a:ae:43:fb:c0:ed:f1:36:64:8a:da: + 8e:5f:f7:c4:ad:64:c8:29:03:74:58:b0:9e:ee:41:89:5b:2a: + 12:f4:82:a4:03:a5:f0:df:a2:84:cb:2b:b3:16:0f:dc:cf:cc: + 56:99:61:a9:f9:3d:3a:7e:e4:12:43:c3:b1:4f:58:26:79:e7: + e4:0d:a5:88:3d:79:33:a1:09:7d:78:af:bd:59:71:11:54:4a: + cc:d6:d2:6d:1f:88:27:ac:d5:bf:75:fc:c3:05:0b:cd:c8:0e: + 72:41:1d:d8:68:62:be:94:d7:60:be:05:4a:42:9c:50:b7:45: + 71:6d:83:9a:ef:08:5c:41:db:c8:62:33:3c:69:a2:8a:b4:0f: + db:65:c4:b7:92:0a:76:f7:55:06:77:8c:ff:8c:84:84:d9:dd: + 46:11:2a:2d:27:96:a7:f5:47:c1:43:4b:fe:53:d8:be:16:94: + 36:0a:d4:be:c3:6c:9b:0c:52:31:4a:eb:62:b4:81:4b:2d:f7: + f1:65:c1:ee:36:79:19:f7:ab:16:f8:38:d2:ea:87:8d:f8:f9: + 14:82:db:67:b6:94:a8:55:0b:90:6b:af:b0:e9:42:64:42:6d: + 2c:e3:f1:b6:e0:f9:58:ed:69:66:62:98:dc:5a:7b:fa:35:5a: + 23:84:91:0e +-----BEGIN CERTIFICATE----- +MIIE6TCCA9GgAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM +B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEYMBYGA1UEAwwPd29sZlNTTCByb290 +IENBMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3NsLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKsstC8dBgnvTimGhH7Mv6Z5fPDAwWQljHW3 +EAXKSCcMDjIcsP6ZhTm2uaL3J/9tPIwWcykhf4umVHGQrcwFuZ8Vxwo/X2n0Cl+M +cbUsv2biA5oy9NLsKolL+TWIFDNHTi4FeQHtZDZ2ufiFzQGIrMWysVm4zVr0CQk4 +m9paz854mR9JPUHWBnxSmciX0bOAOqJPNsTFljB3MTjIcMzhZwazKy+TtWnPg36I +U5sPRiFM1gU2RJlgaEflMgES1BBzrpo0lPpuuFhPe1uKkpet/Ze5dcrC1EV9F2vN +L/Njeg4wtQup2aZ8dGCdzAkDQ/EPkNO3/myf2c14SxWujFv5mYECAwEAAaOCATow +ggE2MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFHOwHKQvgsvPR6U417AEgjp+chUh +MIHFBgNVHSMEgb0wgbqAFHOwHKQvgsvPR6U417AEgjp+chUhoYGepIGbMIGYMQsw +CQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRs +ZTEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcxGDAWBgNV +BAMMD3dvbGZTU0wgcm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNz +bC5jb22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AYYWaHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEANrGG +1nL452quQ/vA7fE2ZIrajl/3xK1kyCkDdFiwnu5BiVsqEvSCpAOl8N+ihMsrsxYP +3M/MVplhqfk9On7kEkPDsU9YJnnn5A2liD15M6EJfXivvVlxEVRKzNbSbR+IJ6zV +v3X8wwULzcgOckEd2GhivpTXYL4FSkKcULdFcW2Dmu8IXEHbyGIzPGmiirQP22XE +t5IKdvdVBneM/4yEhNndRhEqLSeWp/VHwUNL/lPYvhaUNgrUvsNsmwxSMUrrYrSB +Sy338WXB7jZ5GferFvg40uqHjfj5FILbZ7aUqFULkGuvsOlCZEJtLOPxtuD5WO1p +ZmKY3Fp7+jVaI4SRDg== +-----END CERTIFICATE----- diff --git a/ocsp/stapling/responder-certs/ocsp-responder-int1-key.pem b/ocsp/stapling/responder-certs/ocsp-responder-int1-key.pem new file mode 100644 index 000000000..a73d0c2ac --- /dev/null +++ b/ocsp/stapling/responder-certs/ocsp-responder-int1-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCYgvDn2ljPhQuk +3jRBP3la/3V4lcaJXLcuxG0Fc6WxRVhyPiziwBeH/rRkggD9Vn2Kc41viHe7mFao +tig2qAyf1nolHa0QuNAZfIBwnIAmlVNCHJBOJ+31bodvLuuSleBvU/6+F6l/5rcJ +S2OcCJfIszZ1OG0+/9jhInVXGl9gME0bvC+ZfwLv3yQliFeReyxv95iQKZ8SZqk+ +c8SBc+ec6yL1bNUj4Hu6psoWozP5LlKjqMnx3YUfwZQLHo+3SL4g0Nq9O4WOksHw +fOwuxSegTiLFwk0bZuesV4w0K6VV6TScfzMp0E7LGhoCF7JFo0kFXQB5hVCRwD0w +y4QKmi1tAgMBAAECggEAExWnocvP+z/x4hKwRU31GK8I+yr66iuA/Mg1wE3leRZt +Z/Zh1YomJ61203D1QL52/UFSfJd+LCp3BautwpEq60GCjWx2QLZvzBCpXe4nlyxu +e8JpSG50t5a6Oe6MKg65RBUltpHtcwTi+LXHZDorDEFo2ihSe2S2tg2C04CIWNfh +CkvSCtth7HmLYtNtQJzjHY7N+I2PQDFW/VxeXBlnVHpyVFqJj3m3t6WFJS9P9Z+J +0VX3iz1UZjdSZec7V0KwIaKQS8+24f2gPIzNM4O488rh6sB8SVZBdHdioDdE3gVv +YuGEVaB1nLqCYKuuzhi5k16n020/OkXL/UdUFy6AIQKBgQDGm0qXuF6xfwW45CVM +cjMG5Q44XRAgfWe3s7N3wzC4ympbd6d/xZuiKKOJuQnHbGMRBwmB7qwjXdsz0hTw +ywC69JwzlCtur3ylfadUsQYhQJOnV2qO15+gnrOVWsJiNFpGRUlyUw3t4mcKbrsn +8VPNj4gKO+6hctkNGfKW+a/iyQKBgQDElZTDR4AgP9N2C2O6TbH585yRklp14Wy5 +NP2NwDyFQyLjb4Jo4K3yeBikA+77VSbsTZ84/cPrbs/5nBi4uRYuDY+2GdxH46jB +Ywm60UgkE0FP1YeAhpAoOIktpTDKWTTcablSHMBXkdKF4KZRxftFxC0T5JchwoD6 +vT+VPYkDhQKBgQDGI9GkUg0u2cH0trA7d0dPHqA0PSxErbgW/tISropiIZdAT7ys +7ZGakx6s3Q1Tht/C8hlbJqlX02BIb9PycyT0X+uiTbWTBMK/O///r2ilLg7hCYZG +ofogPZR+cgCyBvb1WlSvGQsxhAk20EgpzkrELukTBL3LFpBS0MtEMjB2eQKBgQCi +Ryhqm5d1B7sz8ur8XC7TOvrAYKQ0M0ZhDRFR9qL/DxC51s88bFyrj+AnZOfeqchb +wSfzD+ivbOZaEzWFJ6Tbl25O0MI6xgAExBDAGwsGXK7JjGcy/eH6kdEL0RWZtFIi +sVO+KOXOZB35Th1924U1bmAXz9fCkqGOWrMmK4nzUQKBgCgiCQcgsqpfSIfFknD6 +HTHlCV3+tJAeaimw9C9ctxvT6/JlfU/nWQCCi7cAiHp+cYoQmzE7TKAlhdIOgx5Z +MRPoZstFgVHu5VvLRJZEIXBXmGg5hEZilwOUpRXAtC2Nm7yA9J6vrjAyp10jnk+K +NbOQKX7lqmFEo8pmTXqIhwyg +-----END PRIVATE KEY----- diff --git a/ocsp/stapling/responder-certs/ocsp-responder-key.pem b/ocsp/stapling/responder-certs/ocsp-responder-key.pem deleted file mode 100644 index 61c5616a9..000000000 --- a/ocsp/stapling/responder-certs/ocsp-responder-key.pem +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAuLojtPbDexTDpPUdYaH1HmO5hSM0UG34fKKKBIvVdVwt92OI -0Qd66gtFNSvrH7EitJRBOOKddNaLMCIQUcXbyj9GK/7lWj9BdGd1lamU1cPuQviN -65KV4dllt0PEGN4WgJDOJDUhxFWsWlHgLi2zClpPSnMxUO5KFr05i60FSIexmeIQ -pwZyZ8pc0Ze9yPF2+OBK7LyT9GZMKHHR2GYDtJAwuxew/pf1HujHXZuLERkSPKuC -cXj/rj8ysghxshuMJ6wRuNhDSc+wcLHwjK7aJIcXO9gEZWwAdlDvFQjXtHNoJhSH -lcNfbmG4h4T6gBoKi5jz4/9ORBxldHxxVGXlOQIDAQABAoIBAGI2tR1VxYD+/TYL -DGAIV+acZtqeaQYKMf8x++eG4SrQo6/QP8HDFFqzO0yV2SC0cRtJZ5PzCHxCRSaG -Nd8EL2NMWOazUwW0c/yLtTypOPSeg2Mf+3SwLvgxOZ9CbFQ8YAJi+vbNOPLGCijL -N0HWEkcC1P1kWWgKCWIloR7eEt0IQOb5PPSCu3buq/rForb6qUf+L+ESpWed6bnc -uhIrHDuQ/PopW05fW1r61zI286wKdLRyatQsljNqPvVdFVhtCKqCqMHdIzMg2cbh -q9DJMWc/KLjzBk6YPMZKm/4k4RXj+IwS+iITbpUNrhYj2TMevBMPW3AIRobD823D -ehQv+rECgYEA3CWL+G9zJ5PXRDAdQ69lN+CE/Uf9444CN5idMO+qRQ+QE8hWYT/U -PFH/aUgd1k3WJZseR/GTWx29VsRPSDWZXzwzLfUNKnqvp0b2oZe/EdYiRSo8OCPp -kF07HbTKe4Cyma7HdgDkNkS+UW5JujnuLcuee+wTq6xU0289juwFBc8CgYEA1s/d -VtwXqBf3qMxfi+eMa77fqxptAFGtZNKNkYwX42Ow6Hehj8EnoPqYEF+9MzKn/BFh -ROnQ76axKBN8mkRUjpv7d2+zMlDnGrWul8q6VrfGiU2P7jd4L6GY/V1MYktnIBsd -Ld/jW8P0FFfI2RIREPWdrATxBhQpTJfXd/7rLncCgYB1wrvyBCQUSrg/KIGvADbj -wf1Bw23jeMZk2QVU9Q8e7ClE+8iBMvSj47T9q28SgQaJjUWQdIA/oFP1AwPp+4n0 -cK5r6gbF72Tg1Uv+ur6hmuswFlyqJ0O8TrLdvCUIFZr0LJNT4zwwb2tjAdz8ehqX -crFvVqRbE884XuwN9ODm7wKBgQDIEnKlI/kkpq4UmcWkGNXAxNauFr7PPUOyVCln -FoRpVcC/xCzGJ7ExTjWzing950BulgFynhPsIeV+3id/x4S6Dq34YCEXDCMzzWQA -HOHRQvm3iHY1+ZQHSQulb/Bk3LYAQUC8KXspTSlYiSqYgytCEIH6Zd/XOY/9tq8J -JHUHoQKBgHYIB2mRCuDK5C3dCspdPVeAUqptK1nnXxWY/MXA6v+M4wFsIxV7Iwg7 -HEjeD5yKH4619syPCFz3jrCxL0oJqVTD2tnrbLf8idEt2eaV/3o2mUGFjvWpTywg -F8DewhrGh6z7FWHp4cMrxpq1hkdi6k+481T1GKBJ1zBSTzskTHQB ------END RSA PRIVATE KEY----- diff --git a/ocsp/stapling/server-certs/server1-cert.pem b/ocsp/stapling/server-certs/server1-cert.pem index dfc0c7389..2b05e5467 100644 --- a/ocsp/stapling/server-certs/server1-cert.pem +++ b/ocsp/stapling/server-certs/server1-cert.pem @@ -3,11 +3,11 @@ Certificate: Version: 3 (0x2) Serial Number: 5 (0x5) Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL intermediate CA 1, emailAddress = info@wolfssl.com + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL intermediate CA 1, emailAddress=facts@wolfssl.com Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = www1.wolfssl.com, emailAddress = info@wolfssl.com + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=www1.wolfssl.com, emailAddress=facts@wolfssl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) @@ -38,7 +38,7 @@ Certificate: CC:55:15:00:E2:44:89:92:63:6D:10:5D:B9:9E:73:B6:5D:3A:19:CA X509v3 Authority Key Identifier: keyid:83:C6:3A:89:2C:81:F4:02:D7:9D:4C:E2:2A:C0:71:82:64:44:DA:0E - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com serial:01 X509v3 Key Usage: Digital Signature, Non Repudiation, Key Encipherment @@ -46,60 +46,60 @@ Certificate: OCSP - URI:http://127.0.0.1:22221 Signature Algorithm: sha256WithRSAEncryption Signature Value: - 7c:53:b6:71:1e:1a:9a:54:42:15:3a:81:06:d2:7c:bc:56:63: - 13:0a:4d:21:3f:59:68:4c:07:17:65:a1:26:ce:10:4c:90:f5: - 13:66:60:9b:9c:d9:85:7f:a3:da:9f:a6:d7:69:df:c7:b1:0b: - 4d:14:93:32:7f:df:7a:e6:ab:cc:74:de:a8:6d:c5:4c:55:be: - a1:8a:14:48:38:e0:34:76:5c:cb:27:6b:a1:31:de:6c:bc:ac: - ea:73:7e:ce:ad:86:e2:54:7b:0f:87:4f:b7:24:c0:06:83:17: - 0d:75:a7:09:5e:2f:74:c3:85:f5:2e:ec:84:21:b6:ce:93:0d: - bf:5c:39:24:5d:e0:63:25:04:5c:23:a7:d8:93:e8:1a:34:44: - fb:67:94:80:45:7c:78:31:20:d1:ed:a2:06:6b:84:1f:3a:99: - f2:de:14:cb:8e:cf:fd:dd:51:a3:af:17:8a:83:f3:f5:4e:ea: - a5:33:c8:fa:84:9a:17:7e:5d:6f:f8:90:2e:ac:88:66:b6:49: - 44:72:85:43:ca:58:d9:94:56:85:98:56:b8:34:d4:22:5d:8e: - 7a:35:ef:5a:96:15:29:2d:7b:f1:1f:55:98:7f:2f:d8:08:36: - ec:c9:a1:c6:05:3e:db:dd:e4:f8:2d:ca:92:e0:e8:a4:e4:7c: - 39:77:72:97 + 03:64:06:c9:cd:90:6c:bf:41:12:1c:91:b7:0b:3b:65:94:c1: + 0f:ae:40:73:4a:ad:b2:65:14:34:01:da:04:ac:f2:ab:44:e0: + b3:40:4d:70:8a:c0:ca:b4:ab:25:56:45:b7:94:41:2c:a4:7e: + 12:05:7a:c6:82:74:25:e4:d1:6c:de:a8:53:b7:e0:6c:aa:e1: + fe:fe:98:96:dc:7f:3a:99:aa:eb:2b:76:78:49:58:6d:8c:ab: + e6:c6:38:db:28:44:82:ff:2b:4a:dd:97:8a:94:b1:d4:68:d8: + 9e:76:71:dc:99:73:66:4e:95:d5:0c:4f:c4:23:13:5a:ac:2e: + c0:a9:77:0d:60:d1:92:30:0d:75:48:6f:78:ed:5a:4f:50:b8: + 74:1f:f7:29:25:c8:7b:79:46:3b:d4:b5:ff:45:a7:fc:21:71: + b7:3e:01:c1:94:91:bc:50:06:4b:ba:5a:08:80:4a:3b:83:98: + d3:77:db:26:9c:57:fe:b0:38:a6:df:26:56:a3:c4:da:71:9c: + 88:72:df:ce:c3:d7:ea:d1:50:7b:18:64:d4:30:b1:5f:5b:39: + b4:bb:99:b8:f4:6f:18:b0:e4:ee:0f:d7:2b:90:65:85:77:ca: + 79:65:c0:fb:b4:6f:3a:f8:47:5a:5e:c1:06:b3:2e:71:2e:09: + 73:c2:bb:ad -----BEGIN CERTIFICATE----- -MIIE7jCCA9agAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBoTELMAkGA1UEBhMCVVMx +MIIE8TCCA9mgAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBojELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NM -IGludGVybWVkaWF0ZSBDQSAxMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wu -Y29tMB4XDTI0MTIxODIxMjUzMVoXDTI3MDkxNDIxMjUzMVowgZgxCzAJBgNVBAYT -AlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYD -VQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEZMBcGA1UEAwwQd3d3 -MS53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOaWVXXPipdojLY49noFvjO2 -UUc3ivfbkb6Sa7cAjPLFJG4Y6ZIAgQHcs0woqbeA8ZbPI3ovrvjjDy3TXiPn20yy -XYkWF76+gdv7Em0oSxCgEgQnwcnQeZXv6I2MWZtOcn28SSsiTvhP4gzx6emX+d+M -WgqqOB1DBKOniaHig6RLtU5FiKYiXaypWGeIwdVh770RBSeUR7szpYrK7h+NwG4k -r83Kv4BHcZWsqfFdI2z1S7Sp4cRm++XEoZ+nUdF4zS60Py7igvN/xKf0Mc92Jz/b -LtJuw0cjgqNIQIynwRPwY1BUQ/ZxEuFvpXpYJvf9iztwGKBDugFrs/jVvgUTZDEC -AwEAAaOCATYwggEyMAkGA1UdEwQCMAAwHQYDVR0OBBYEFMxVFQDiRImSY20QXbme -c7ZdOhnKMIHEBgNVHSMEgbwwgbmAFIPGOoksgfQC151M4irAcYJkRNoOoYGdpIGa -MIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwH -U2VhdHRsZTEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcx -GDAWBgNVBAMMD3dvbGZTU0wgcm9vdCBDQTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3 -b2xmc3NsLmNvbYIBATALBgNVHQ8EBAMCBeAwMgYIKwYBBQUHAQEEJjAkMCIGCCsG -AQUFBzABhhZodHRwOi8vMTI3LjAuMC4xOjIyMjIxMA0GCSqGSIb3DQEBCwUAA4IB -AQB8U7ZxHhqaVEIVOoEG0ny8VmMTCk0hP1loTAcXZaEmzhBMkPUTZmCbnNmFf6Pa -n6bXad/HsQtNFJMyf9965qvMdN6obcVMVb6hihRIOOA0dlzLJ2uhMd5svKzqc37O -rYbiVHsPh0+3JMAGgxcNdacJXi90w4X1LuyEIbbOkw2/XDkkXeBjJQRcI6fYk+ga -NET7Z5SARXx4MSDR7aIGa4QfOpny3hTLjs/93VGjrxeKg/P1TuqlM8j6hJoXfl1v -+JAurIhmtklEcoVDyljZlFaFmFa4NNQiXY56Ne9alhUpLXvxH1WYfy/YCDbsyaHG -BT7b3eT4LcqS4Oik5Hw5d3KX +IGludGVybWVkaWF0ZSBDQSAxMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3Ns +LmNvbTAeFw0yNjA2MTEyMTQ0MzRaFw0yOTAzMDcyMTQ0MzRaMIGZMQswCQYDVQQG +EwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRsZTEQMA4G +A1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcxGTAXBgNVBAMMEHd3 +dzEud29sZnNzbC5jb20xIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29t +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5pZVdc+Kl2iMtjj2egW+ +M7ZRRzeK99uRvpJrtwCM8sUkbhjpkgCBAdyzTCipt4Dxls8jei+u+OMPLdNeI+fb +TLJdiRYXvr6B2/sSbShLEKASBCfBydB5le/ojYxZm05yfbxJKyJO+E/iDPHp6Zf5 +34xaCqo4HUMEo6eJoeKDpEu1TkWIpiJdrKlYZ4jB1WHvvREFJ5RHuzOlisruH43A +biSvzcq/gEdxlayp8V0jbPVLtKnhxGb75cShn6dR0XjNLrQ/LuKC83/Ep/Qxz3Yn +P9su0m7DRyOCo0hAjKfBE/BjUFRD9nES4W+lelgm9/2LO3AYoEO6AWuz+NW+BRNk +MQIDAQABo4IBNzCCATMwCQYDVR0TBAIwADAdBgNVHQ4EFgQUzFUVAOJEiZJjbRBd +uZ5ztl06GcowgcUGA1UdIwSBvTCBuoAUg8Y6iSyB9ALXnUziKsBxgmRE2g6hgZ6k +gZswgZgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH +DAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmlu +ZzEYMBYGA1UEAwwPd29sZlNTTCByb290IENBMSAwHgYJKoZIhvcNAQkBFhFmYWN0 +c0B3b2xmc3NsLmNvbYIBATALBgNVHQ8EBAMCBeAwMgYIKwYBBQUHAQEEJjAkMCIG +CCsGAQUFBzABhhZodHRwOi8vMTI3LjAuMC4xOjIyMjIxMA0GCSqGSIb3DQEBCwUA +A4IBAQADZAbJzZBsv0ESHJG3CztllMEPrkBzSq2yZRQ0AdoErPKrROCzQE1wisDK +tKslVkW3lEEspH4SBXrGgnQl5NFs3qhTt+BsquH+/piW3H86marrK3Z4SVhtjKvm +xjjbKESC/ytK3ZeKlLHUaNiednHcmXNmTpXVDE/EIxNarC7AqXcNYNGSMA11SG94 +7VpPULh0H/cpJch7eUY71LX/Raf8IXG3PgHBlJG8UAZLuloIgEo7g5jTd9smnFf+ +sDim3yZWo8TacZyIct/Ow9fq0VB7GGTUMLFfWzm0u5m49G8YsOTuD9crkGWFd8p5 +ZcD7tG86+EdaXsEGsy5xLglzwrut -----END CERTIFICATE----- Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL intermediate CA 1, emailAddress = info@wolfssl.com + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL intermediate CA 1, emailAddress=facts@wolfssl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) @@ -130,7 +130,7 @@ Certificate: 83:C6:3A:89:2C:81:F4:02:D7:9D:4C:E2:2A:C0:71:82:64:44:DA:0E X509v3 Authority Key Identifier: keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com serial:63 X509v3 Key Usage: Certificate Sign, CRL Sign @@ -138,60 +138,60 @@ Certificate: OCSP - URI:http://127.0.0.1:22220 Signature Algorithm: sha256WithRSAEncryption Signature Value: - 75:57:f1:0c:87:8f:a2:70:3c:ce:e4:70:0e:99:6a:da:c4:80: - 94:2c:25:0c:de:0d:7b:f3:94:f1:e8:ad:6f:d0:de:9a:9d:f5: - 64:31:65:3f:18:e6:c3:f5:b5:1d:a2:be:5b:97:79:41:78:15: - 1c:b3:83:de:d0:00:ea:d2:70:43:c5:60:60:07:72:e5:76:59: - b8:0e:2f:47:c9:8d:a4:4c:f1:20:b0:40:3b:ed:e9:de:b2:46: - 10:90:1b:0f:96:16:e6:97:bc:d5:9a:93:aa:3c:e3:b3:6b:5f: - db:2c:af:2b:da:7c:36:36:aa:86:a1:65:70:c8:f1:34:d1:1f: - 10:96:71:e6:cf:69:5c:bf:0e:15:33:97:fe:40:42:be:30:48: - ad:fb:d7:0e:7b:73:dd:64:30:7e:10:81:ac:3b:0b:3c:e4:12: - 9f:31:8b:3d:f0:9b:84:dc:5b:32:33:39:de:eb:1a:17:89:d8: - 1b:00:33:2d:50:a4:1a:2c:11:a2:60:ac:c1:9a:0f:44:90:00: - cf:8d:6c:af:5b:71:23:7a:a7:4f:df:f5:3f:5c:ae:93:ca:4e: - ec:f0:1b:f4:fa:53:7d:d9:36:af:5e:4c:54:c7:3a:d5:e3:68: - ca:78:e5:1f:55:44:65:eb:00:2d:c3:c8:ba:0e:1f:47:1c:67: - 2e:a9:c1:6e + 1a:4e:f4:e6:eb:df:9e:b0:67:30:f2:ea:20:d6:f8:85:8f:5c: + e2:06:5b:16:98:9e:44:fe:e7:ce:5d:19:6d:7e:56:1a:4a:41: + e9:d8:b5:3a:1d:a9:fa:64:e6:e8:00:01:49:6a:63:59:e5:88: + dc:42:8f:c1:d1:5b:20:79:5c:16:a0:f1:75:15:9e:6a:86:a1: + 6d:19:d1:76:fa:25:92:a9:42:8a:ac:91:38:ef:e0:8c:89:a1: + 94:14:80:46:50:9c:84:8b:3a:c7:69:23:22:10:42:ad:a9:70: + 43:da:56:27:fd:7b:97:00:cd:a8:6a:87:f4:bb:46:3d:a6:ae: + 08:40:ee:eb:1c:ab:f2:44:79:13:81:68:d2:fb:de:78:b7:ee: + f3:e4:41:f7:aa:39:fc:48:fd:a6:69:4a:4c:02:f9:aa:ae:a7: + 5e:24:0f:94:81:a5:64:c8:38:1b:dc:e1:78:0c:00:45:dc:a4: + dd:94:da:8e:6a:d0:2c:8a:bf:57:bb:ea:74:1b:66:f0:e1:89: + f9:28:27:e8:cc:81:fe:b3:11:d4:76:b0:32:a3:00:1c:04:62: + 98:14:c7:7d:1e:79:fa:e2:6e:f9:65:13:dc:74:4a:38:7b:ef: + 4e:3b:bd:a9:db:52:e9:40:cc:dd:73:b3:95:e2:20:d6:a5:99: + ad:00:82:5b -----BEGIN CERTIFICATE----- -MIIE8DCCA9igAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx +MIIE8zCCA9ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBoTELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NMIGludGVy -bWVkaWF0ZSBDQSAxMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3rTIXHfgLbH1ua0WRzWgNWVl -xuFAqx60uRO3y4y7d6V22m2Hh/ZKTRPkJj4nh+5bx2o/RTBhVVz2NdFl+pgRo6dV -1b6Rgkv8vpDWUFNjmiwi4TUR3HgCl4rkRpKcUwh23h9TtrjKdz55brzQ4w0wW0z2 -lA0wKWSfBOXb+4lgZ7uvJoNRdyQvKwuhlIEQmOjrJqgefOTEbGcGlVVK3VL08mBt -ASsZkTVtpAhHBnEkANnexlbzi1Ms4pqWpfNi5cTjI/LS/CHqD2J2jdWZSM7cWMS7 -f9qULIB0g8XgsBV+Qf0O8vTweHZ7rSYNqkiWFy8h45UrJjf5qoAv/t72XryXfwID -AQABo4IBOTCCATUwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUg8Y6iSyB9ALXnUzi -KsBxgmRE2g4wgcQGA1UdIwSBvDCBuYAUc7AcpC+Cy89HpTjXsASCOn5yFSGhgZ2k -gZowgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH -DAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmlu -ZzEYMBYGA1UEAwwPd29sZlNTTCByb290IENBMR8wHQYJKoZIhvcNAQkBFhBpbmZv -QHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQwIgYI -KwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQELBQAD -ggEBAHVX8QyHj6JwPM7kcA6ZatrEgJQsJQzeDXvzlPHorW/Q3pqd9WQxZT8Y5sP1 -tR2ivluXeUF4FRyzg97QAOrScEPFYGAHcuV2WbgOL0fJjaRM8SCwQDvt6d6yRhCQ -Gw+WFuaXvNWak6o847NrX9ssryvafDY2qoahZXDI8TTRHxCWcebPaVy/DhUzl/5A -Qr4wSK371w57c91kMH4Qgaw7CzzkEp8xiz3wm4TcWzIzOd7rGheJ2BsAMy1QpBos -EaJgrMGaD0SQAM+NbK9bcSN6p0/f9T9crpPKTuzwG/T6U33ZNq9eTFTHOtXjaMp4 -5R9VRGXrAC3DyLoOH0ccZy6pwW4= +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgaIxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEiMCAGA1UEAwwZd29sZlNTTCBpbnRl +cm1lZGlhdGUgQ0EgMTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNzbC5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDetMhcd+AtsfW5rRZHNaA1 +ZWXG4UCrHrS5E7fLjLt3pXbabYeH9kpNE+QmPieH7lvHaj9FMGFVXPY10WX6mBGj +p1XVvpGCS/y+kNZQU2OaLCLhNRHceAKXiuRGkpxTCHbeH1O2uMp3PnluvNDjDTBb +TPaUDTApZJ8E5dv7iWBnu68mg1F3JC8rC6GUgRCY6OsmqB585MRsZwaVVUrdUvTy +YG0BKxmRNW2kCEcGcSQA2d7GVvOLUyzimpal82LlxOMj8tL8IeoPYnaN1ZlIztxY +xLt/2pQsgHSDxeCwFX5B/Q7y9PB4dnutJg2qSJYXLyHjlSsmN/mqgC/+3vZevJd/ +AgMBAAGjggE6MIIBNjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBSDxjqJLIH0Ated +TOIqwHGCZETaDjCBxQYDVR0jBIG9MIG6gBRzsBykL4LLz0elONewBII6fnIVIaGB +nqSBmzCBmDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNV +BAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVy +aW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZh +Y3RzQHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQw +IgYIKwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQEL +BQADggEBABpO9Obr356wZzDy6iDW+IWPXOIGWxaYnkT+585dGW1+VhpKQenYtTod +qfpk5ugAAUlqY1nliNxCj8HRWyB5XBag8XUVnmqGoW0Z0Xb6JZKpQoqskTjv4IyJ +oZQUgEZQnISLOsdpIyIQQq2pcEPaVif9e5cAzahqh/S7Rj2mrghA7uscq/JEeROB +aNL73ni37vPkQfeqOfxI/aZpSkwC+aqup14kD5SBpWTIOBvc4XgMAEXcpN2U2o5q +0CyKv1e76nQbZvDhifkoJ+jMgf6zEdR2sDKjABwEYpgUx30eefribvllE9x0Sjh7 +7047vanbUulAzN1zs5XiINalma0Agls= -----END CERTIFICATE----- Certificate: Data: Version: 3 (0x2) Serial Number: 99 (0x63) Signature Algorithm: sha256WithRSAEncryption - Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Issuer: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Validity - Not Before: Dec 18 21:25:31 2024 GMT - Not After : Sep 14 21:25:31 2027 GMT - Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Engineering, CN = wolfSSL root CA, emailAddress = info@wolfssl.com + Not Before: Jun 11 21:44:34 2026 GMT + Not After : Mar 7 21:44:34 2029 GMT + Subject: C=US, ST=Washington, L=Seattle, O=wolfSSL, OU=Engineering, CN=wolfSSL root CA, emailAddress=facts@wolfssl.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) @@ -222,7 +222,7 @@ Certificate: 73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 X509v3 Authority Key Identifier: keyid:73:B0:1C:A4:2F:82:CB:CF:47:A5:38:D7:B0:04:82:3A:7E:72:15:21 - DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=info@wolfssl.com + DirName:/C=US/ST=Washington/L=Seattle/O=wolfSSL/OU=Engineering/CN=wolfSSL root CA/emailAddress=facts@wolfssl.com serial:63 X509v3 Key Usage: Certificate Sign, CRL Sign @@ -230,47 +230,47 @@ Certificate: OCSP - URI:http://127.0.0.1:22220 Signature Algorithm: sha256WithRSAEncryption Signature Value: - 76:e8:fa:f6:1e:5b:0e:ff:24:43:e0:cb:19:26:38:d9:df:18: - 5d:66:e1:4b:ac:e4:8e:b0:49:2c:d6:04:20:eb:4a:a8:06:d7: - 55:ec:6b:38:f8:0f:8c:e6:c9:ec:42:f0:ca:07:9f:88:7a:ee: - bf:af:3f:7d:d3:45:67:20:84:bb:c7:c5:32:69:ab:59:e1:e3: - 38:4b:ed:18:2e:de:da:88:ec:a0:b7:ff:c1:50:96:73:e3:03: - df:a1:e7:47:93:13:1d:fb:e6:6b:37:3e:50:a3:eb:5b:24:26: - d2:43:2e:6e:9c:83:9c:fb:79:ba:cd:fd:3b:e5:87:87:a7:0f: - 5f:f9:64:34:56:5e:8b:13:e2:c4:41:e3:9d:3e:36:2d:cb:d3: - 5f:d3:12:90:bf:78:c1:4c:df:eb:7b:99:e6:1e:ee:52:78:6f: - 0c:82:e1:59:d4:25:40:e5:24:95:3e:0f:cc:08:60:fe:b4:8c: - 48:42:bf:29:74:92:71:1a:85:00:a7:4c:f0:c0:32:47:f3:be: - f4:08:5c:f2:43:e0:b9:76:86:60:9a:3b:af:d6:32:41:5f:b0: - 04:12:44:2a:44:19:d4:27:d3:ce:71:7e:5b:16:1a:f5:0c:db: - 43:b0:a6:bb:76:02:f6:e0:30:4e:04:f4:f3:9b:cd:d4:ae:45: - 94:c5:8c:bb + 36:b1:86:d6:72:f8:e7:6a:ae:43:fb:c0:ed:f1:36:64:8a:da: + 8e:5f:f7:c4:ad:64:c8:29:03:74:58:b0:9e:ee:41:89:5b:2a: + 12:f4:82:a4:03:a5:f0:df:a2:84:cb:2b:b3:16:0f:dc:cf:cc: + 56:99:61:a9:f9:3d:3a:7e:e4:12:43:c3:b1:4f:58:26:79:e7: + e4:0d:a5:88:3d:79:33:a1:09:7d:78:af:bd:59:71:11:54:4a: + cc:d6:d2:6d:1f:88:27:ac:d5:bf:75:fc:c3:05:0b:cd:c8:0e: + 72:41:1d:d8:68:62:be:94:d7:60:be:05:4a:42:9c:50:b7:45: + 71:6d:83:9a:ef:08:5c:41:db:c8:62:33:3c:69:a2:8a:b4:0f: + db:65:c4:b7:92:0a:76:f7:55:06:77:8c:ff:8c:84:84:d9:dd: + 46:11:2a:2d:27:96:a7:f5:47:c1:43:4b:fe:53:d8:be:16:94: + 36:0a:d4:be:c3:6c:9b:0c:52:31:4a:eb:62:b4:81:4b:2d:f7: + f1:65:c1:ee:36:79:19:f7:ab:16:f8:38:d2:ea:87:8d:f8:f9: + 14:82:db:67:b6:94:a8:55:0b:90:6b:af:b0:e9:42:64:42:6d: + 2c:e3:f1:b6:e0:f9:58:ed:69:66:62:98:dc:5a:7b:fa:35:5a: + 23:84:91:0e -----BEGIN CERTIFICATE----- -MIIE5jCCA86gAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx +MIIE6TCCA9GgAwIBAgIBYzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM -IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjQx -MjE4MjEyNTMxWhcNMjcwOTE0MjEyNTMxWjCBlzELMAkGA1UEBhMCVVMxEzARBgNV -BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT -U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg -Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCrLLQvHQYJ704phoR+zL+meXzwwMFkJYx1txAF -ykgnDA4yHLD+mYU5trmi9yf/bTyMFnMpIX+LplRxkK3MBbmfFccKP19p9ApfjHG1 -LL9m4gOaMvTS7CqJS/k1iBQzR04uBXkB7WQ2drn4hc0BiKzFsrFZuM1a9AkJOJva -Ws/OeJkfST1B1gZ8UpnIl9GzgDqiTzbExZYwdzE4yHDM4WcGsysvk7Vpz4N+iFOb -D0YhTNYFNkSZYGhH5TIBEtQQc66aNJT6brhYT3tbipKXrf2XuXXKwtRFfRdrzS/z -Y3oOMLULqdmmfHRgncwJA0PxD5DTt/5sn9nNeEsVroxb+ZmBAgMBAAGjggE5MIIB -NTAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRzsBykL4LLz0elONewBII6fnIVITCB -xAYDVR0jBIG8MIG5gBRzsBykL4LLz0elONewBII6fnIVIaGBnaSBmjCBlzELMAkG -A1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUx -EDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQD -DA93b2xmU1NMIHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j -b22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW -aHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEAduj69h5b -Dv8kQ+DLGSY42d8YXWbhS6zkjrBJLNYEIOtKqAbXVexrOPgPjObJ7ELwygefiHru -v68/fdNFZyCEu8fFMmmrWeHjOEvtGC7e2ojsoLf/wVCWc+MD36HnR5MTHfvmazc+ -UKPrWyQm0kMubpyDnPt5us39O+WHh6cPX/lkNFZeixPixEHjnT42LcvTX9MSkL94 -wUzf63uZ5h7uUnhvDILhWdQlQOUklT4PzAhg/rSMSEK/KXSScRqFAKdM8MAyR/O+ -9Ahc8kPguXaGYJo7r9YyQV+wBBJEKkQZ1CfTznF+WxYa9QzbQ7Cmu3YC9uAwTgT0 -85vN1K5FlMWMuw== +IHJvb3QgQ0ExIDAeBgkqhkiG9w0BCQEWEWZhY3RzQHdvbGZzc2wuY29tMB4XDTI2 +MDYxMTIxNDQzNFoXDTI5MDMwNzIxNDQzNFowgZgxCzAJBgNVBAYTAlVTMRMwEQYD +VQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xm +U1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEYMBYGA1UEAwwPd29sZlNTTCByb290 +IENBMSAwHgYJKoZIhvcNAQkBFhFmYWN0c0B3b2xmc3NsLmNvbTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKsstC8dBgnvTimGhH7Mv6Z5fPDAwWQljHW3 +EAXKSCcMDjIcsP6ZhTm2uaL3J/9tPIwWcykhf4umVHGQrcwFuZ8Vxwo/X2n0Cl+M +cbUsv2biA5oy9NLsKolL+TWIFDNHTi4FeQHtZDZ2ufiFzQGIrMWysVm4zVr0CQk4 +m9paz854mR9JPUHWBnxSmciX0bOAOqJPNsTFljB3MTjIcMzhZwazKy+TtWnPg36I +U5sPRiFM1gU2RJlgaEflMgES1BBzrpo0lPpuuFhPe1uKkpet/Ze5dcrC1EV9F2vN +L/Njeg4wtQup2aZ8dGCdzAkDQ/EPkNO3/myf2c14SxWujFv5mYECAwEAAaOCATow +ggE2MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFHOwHKQvgsvPR6U417AEgjp+chUh +MIHFBgNVHSMEgb0wgbqAFHOwHKQvgsvPR6U417AEgjp+chUhoYGepIGbMIGYMQsw +CQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwHU2VhdHRs +ZTEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcxGDAWBgNV +BAMMD3dvbGZTU0wgcm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRZmFjdHNAd29sZnNz +bC5jb22CAWMwCwYDVR0PBAQDAgEGMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AYYWaHR0cDovLzEyNy4wLjAuMToyMjIyMDANBgkqhkiG9w0BAQsFAAOCAQEANrGG +1nL452quQ/vA7fE2ZIrajl/3xK1kyCkDdFiwnu5BiVsqEvSCpAOl8N+ihMsrsxYP +3M/MVplhqfk9On7kEkPDsU9YJnnn5A2liD15M6EJfXivvVlxEVRKzNbSbR+IJ6zV +v3X8wwULzcgOckEd2GhivpTXYL4FSkKcULdFcW2Dmu8IXEHbyGIzPGmiirQP22XE +t5IKdvdVBneM/4yEhNndRhEqLSeWp/VHwUNL/lPYvhaUNgrUvsNsmwxSMUrrYrSB +Sy338WXB7jZ5GferFvg40uqHjfj5FILbZ7aUqFULkGuvsOlCZEJtLOPxtuD5WO1p +ZmKY3Fp7+jVaI4SRDg== -----END CERTIFICATE----- diff --git a/pk/ecc/ecc_sign.c b/pk/ecc/ecc_sign.c index f9416de0d..99dffd5dd 100644 --- a/pk/ecc/ecc_sign.c +++ b/pk/ecc/ecc_sign.c @@ -263,9 +263,15 @@ int crypto_ecc_sign(const uint8_t *key, uint32_t keySz, &r, &s /* r/s as mp_int */ ); - /* export r/s */ - mp_to_unsigned_bin(&r, sig); - mp_to_unsigned_bin(&s, sig + curveSz); + /* export r/s, left-padded: verify reads them back at fixed curveSz + * offsets, and mp_to_unsigned_bin writes only the significant bytes, so + * an r or s with a leading zero (~1 in 256) would shift s and fail */ + if (ret == 0) { + ret = mp_to_unsigned_bin_len(&r, sig, curveSz); + } + if (ret == 0) { + ret = mp_to_unsigned_bin_len(&s, sig + curveSz, curveSz); + } } mp_clear(&r); diff --git a/pk/enc-through-sign-rsa/rsa-public-decrypt-app.c b/pk/enc-through-sign-rsa/rsa-public-decrypt-app.c index bc572a97d..ed4212fc5 100644 --- a/pk/enc-through-sign-rsa/rsa-public-decrypt-app.c +++ b/pk/enc-through-sign-rsa/rsa-public-decrypt-app.c @@ -91,6 +91,11 @@ int main(void) check_ret(ret, "wc_RsaSSL_Verify"); printf("Here is the recovered AES KEY!\n%s\n", plain); + /* wc_RsaSSL_Verify returns the recovered length, so only a negative value + * is an error */ + if (ret > 0) + ret = 0; + return ret; } diff --git a/pk/srp/Makefile b/pk/srp/Makefile index c1923055d..b671cb63c 100644 --- a/pk/srp/Makefile +++ b/pk/srp/Makefile @@ -1,5 +1,5 @@ CC=gcc -WOLFSSL_INSTALL_DIR=/usr/local/lib +WOLFSSL_INSTALL_DIR=/usr/local CFLAGS=-Wall -I$(WOLFSSL_INSTALL_DIR)/include -g #LIBS= -lwolfssl -lm LIBS= -L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl -lm diff --git a/pkcs11/Makefile b/pkcs11/Makefile index d649ce4e1..0827fc88b 100644 --- a/pkcs11/Makefile +++ b/pkcs11/Makefile @@ -1,4 +1,4 @@ -# ECC Examples Makefile +# PKCS11 Examples Makefile CC = gcc WOLFSSL_INSTALL_DIR = /usr/local CFLAGS = -Wall -I$(WOLFSSL_INSTALL_DIR)/include diff --git a/pkcs11/softhsm2-init.sh b/pkcs11/softhsm2-init.sh new file mode 100755 index 000000000..e8ed6c38c --- /dev/null +++ b/pkcs11/softhsm2-init.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +set -e + +cd "$(dirname "$0")" + +./mksofthsm2_conf.sh +SOFTHSM2_CONF="$PWD/softhsm2.conf" +export SOFTHSM2_CONF + +out=$(softhsm2-util --init-token --slot 0 --label SoftToken \ + --so-pin cryptoki --pin cryptoki) +echo "$out" + +# SoftHSM reassigns the token to a random slot, so the id cannot be hardcoded +slotid=$(echo "$out" | sed -n 's/.*reassigned to slot \([0-9][0-9]*\).*/\1/p') +if [ -z "$slotid" ] +then + echo "could not read the reassigned slot id from softhsm2-util" >&2 + exit 1 +fi + +exec ./softhsm2.sh "$slotid" "$@" diff --git a/pkcs11/softhsm2.sh b/pkcs11/softhsm2.sh index 31964c89e..bad363a66 100755 --- a/pkcs11/softhsm2.sh +++ b/pkcs11/softhsm2.sh @@ -3,31 +3,79 @@ if [ $# -gt 0 ] then SOFTHSM2_SLOTID=$1 + shift fi +# the README builds SoftHSM from source into /usr/local, but a distro package +# lands in /usr/lib; SOFTHSM2_LIB overrides both +if [ -z "$SOFTHSM2_LIB" ] +then + for lib in /usr/local/lib/softhsm/libsofthsm2.so \ + /usr/lib/softhsm/libsofthsm2.so \ + /usr/lib/x86_64-linux-gnu/softhsm/libsofthsm2.so \ + /opt/homebrew/lib/softhsm/libsofthsm2.so + do + if [ -f "$lib" ] + then + SOFTHSM2_LIB=$lib + break + fi + done +fi + +if [ ! -f "$SOFTHSM2_LIB" ] +then + echo "libsofthsm2.so not found, set SOFTHSM2_LIB to its path" >&2 + exit 1 +fi + +if [ -z "$SOFTHSM2_SLOTID" ] +then + echo "no slot id, pass it as \$1 or set SOFTHSM2_SLOTID" >&2 + exit 1 +fi + +rc=0 + +run_example() +{ + name=$1 + shift + echo + echo "# $name" + if ! "$@" "$SOFTHSM2_LIB" "$SOFTHSM2_SLOTID" SoftToken cryptoki + then + echo "# FAILED: $name" + rc=1 + fi +} + echo "# Using slot ID: $SOFTHSM2_SLOTID" +echo "# Using library: $SOFTHSM2_LIB" + +if [ $# -gt 0 ] +then + for example in "$@" + do + run_example "$example" "./$example" + done +else + run_example "RSA example" ./pkcs11_rsa + run_example "ECC example" ./pkcs11_ecc + run_example "Generate ECC example" ./pkcs11_genecc + run_example "AES-GCM example" ./pkcs11_aesgcm + run_example "AES-CBC example" ./pkcs11_aescbc + run_example "HMAC example" ./pkcs11_hmac + run_example "Random Number Generation example" ./pkcs11_rand + run_example "PKCS#11 test" ./pkcs11_test +fi + echo -echo "# RSA example" -./pkcs11_rsa /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# ECC example" -./pkcs11_ecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# Generate ECC example" -./pkcs11_genecc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# AES-GCM example" -./pkcs11_aesgcm /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# AES-CBC example" -./pkcs11_aescbc /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# HMAC example" -./pkcs11_hmac /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# Random Number Generation example" -./pkcs11_rand /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki -echo -echo "# PKCS#11 test" -./pkcs11_test /usr/local/lib/softhsm/libsofthsm2.so $SOFTHSM2_SLOTID SoftToken cryptoki +if [ $rc -eq 0 ] +then + echo "# All PKCS#11 examples passed" +else + echo "# One or more PKCS#11 examples FAILED" +fi +exit $rc diff --git a/pkcs7/Makefile b/pkcs7/Makefile index cf8689687..16c20397b 100644 --- a/pkcs7/Makefile +++ b/pkcs7/Makefile @@ -1,9 +1,10 @@ -# ECC Examples Makefile +# PKCS7 Examples Makefile CC = gcc WOLFSSL_INSTALL_DIR = /usr/local CFLAGS = -Wall -I$(WOLFSSL_INSTALL_DIR)/include +# only needed when linking wolfSSL statically; a shared libwolfssl built +# --with-libz already carries its own dependency on libz ZLIB = -#ZLIB += -lz PSA_LIB = -lmbedcrypto LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lm ${ZLIB} diff --git a/pkcs7/README.md b/pkcs7/README.md index 851909658..46665bb38 100644 --- a/pkcs7/README.md +++ b/pkcs7/README.md @@ -20,7 +20,7 @@ Note, some examples require additional features, such as "--with-libz" and "--enable-pwdbased". To build wolfSSL with support for all examples, use: ``` -$ ./configure --enable-pkcs7 --enable-pwdbased --enable-cryptocb --with-libz CFLAGS="-DWOLFSSL_DER_TO_PEM" +$ ./configure --enable-pkcs7 --enable-indef --enable-smime --enable-pwdbased --enable-cryptocb --with-libz CFLAGS="-DWOLFSSL_DER_TO_PEM" $ make $ sudo make install ``` diff --git a/pkcs7/scripts/openssl-verify.sh b/pkcs7/scripts/openssl-verify.sh index 22f4d97f9..4c10ead62 100755 --- a/pkcs7/scripts/openssl-verify.sh +++ b/pkcs7/scripts/openssl-verify.sh @@ -18,6 +18,7 @@ # generate the necessary DER-encoded bundles. EXPECTED_INNER_CONTENT="Hello World" +FAILURES=0 INNER_CONTENT_FILE="content.txt" AES256_KEY="0102030405060708010203040506070801020304050607080102030405060708" AES256_KEYID="02020304" @@ -36,8 +37,12 @@ if ! [ -x "$(command -v openssl)" ]; then fi -# Run all example applications that exist -eval "./scripts/runall.sh" +# Run all example applications that exist. Its status must gate the run: an app +# that failed produces no bundle, and a missing bundle is skipped silently below. +if ! ./scripts/runall.sh; then + echo "runall.sh reported a failure; not treating the run as verified" + FAILURES=$((FAILURES + 1)) +fi echo '' echo '---------------------------------------------' @@ -54,6 +59,7 @@ if [ -f 'encryptedData.der' ]; then echo -e '\tencryptedData.der:\t\t\t\tPASSED!' else echo -e '\tencryptedData.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi @@ -62,13 +68,20 @@ fi # Trying to verify CompressedData bundle(s) echo -e "\nVerifying CompressedData Bundles:" if [ -f 'compressedData.der' ]; then - OUTPUT=$(openssl cms -uncompress -in compressedData.der -inform der) - - if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then - echo -e '\tcompressedData.der:\t\t\t\tPASSED!' + # cms -uncompress needs an openssl built with zlib. Ubuntu's is not, so this + # is an openssl capability gap, not an example failure. + if openssl version -f 2>/dev/null | grep -q zlib; then + OUTPUT=$(openssl cms -uncompress -in compressedData.der -inform der) + + if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then + echo -e '\tcompressedData.der:\t\t\t\tPASSED!' + else + echo -e '\tcompressedData.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) + echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" + fi else - echo -e '\tcompressedData.der:\t\t\t\tFAILED!' - echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" + echo -e '\tcompressedData.der:\t\t\t\tSKIPPED (openssl has no zlib)' fi fi @@ -82,6 +95,7 @@ if [ -f 'envelopedDataKTRI.der' ]; then echo -e '\tenvelopedDataKTRI.der:\t\t\t\tPASSED!' else echo -e '\tenvelopedDataKTRI.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi @@ -93,6 +107,7 @@ if [ -f 'envelopedDataKARI.der' ]; then echo -e '\tenvelopedDataKARI.der:\t\t\t\tPASSED!' else echo -e '\tenvelopedDataKARI.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi @@ -104,6 +119,7 @@ if [ -f 'envelopedDataKEKRI.der' ]; then echo -e '\tenvelopedDataKEKRI.der:\t\t\t\tPASSED!' else echo -e '\tenvelopedDataKEKRI.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi @@ -115,6 +131,7 @@ if [ -f 'envelopedDataPWRI.der' ]; then echo -e '\tenvelopedDataPWRI.der:\t\t\t\tPASSED!' else echo -e '\tenvelopedDataPWRI.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi @@ -126,90 +143,95 @@ echo -e "\t[SKIPPING - openssl app doesn't support yet]" # Trying to verify SignedData bundle(s) echo -e "\nVerifying SignedData Bundles:" if [ -f 'signedData_attrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedData_attrs.der -inform der -CAfile $RSA_RECIP_CERT 2>/dev/null) + OUTPUT=$(openssl cms -verify -in signedData_attrs.der -inform der -CAfile $RSA_RECIP_CERT -purpose any 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then echo -e '\tsignedData_attrs.der:\t\t\t\tPASSED!' else echo -e '\tsignedData_attrs.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi if [ -f 'signedData_noattrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedData_noattrs.der -inform der -CAfile $RSA_RECIP_CERT 2>/dev/null) + OUTPUT=$(openssl cms -verify -in signedData_noattrs.der -inform der -CAfile $RSA_RECIP_CERT -certfile $RSA_RECIP_CERT -purpose any 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then echo -e '\tsignedData_noattrs.der:\t\t\t\tPASSED!' else echo -e '\tsignedData_noattrs.der:\t\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi if [ -f 'signedFirmwarePkgData_attrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedFirmwarePkgData_attrs.der -inform der -CAfile $RSA_RECIP_CERT 2>/dev/null) + OUTPUT=$(openssl cms -verify -in signedFirmwarePkgData_attrs.der -inform der -CAfile $RSA_RECIP_CERT -purpose any 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then echo -e '\tsignedFirmwarePkgData_attrs.der:\t\tPASSED!' else echo -e '\tsignedFirmwarePkgData_attrs.der:\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi if [ -f 'signedFirmwarePkgData_noattrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedFirmwarePkgData_noattrs.der -inform der -CAfile $RSA_RECIP_CERT 2>/dev/null) + OUTPUT=$(openssl cms -verify -in signedFirmwarePkgData_noattrs.der -inform der -CAfile $RSA_RECIP_CERT -purpose any 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then echo -e '\tsignedFirmwarePkgData_noattrs.der:\t\tPASSED!' else echo -e '\tsignedFirmwarePkgData_noattrs.der:\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi if [ -f 'signedData_detached_attrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedData_detached_attrs.der -inform der -CAfile $RSA_RECIP_CERT -content $INNER_CONTENT_FILE 2>/dev/null) + OUTPUT=$(openssl cms -verify -in signedData_detached_attrs.der -inform der -CAfile $RSA_RECIP_CERT -purpose any -content $INNER_CONTENT_FILE 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then echo -e '\tsignedData_detached_attrs.der:\t\t\tPASSED!' else echo -e '\tsignedData_detached_attrs.der:\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi if [ -f 'signedData_detached_noattrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedData_detached_noattrs.der -inform der -CAfile $RSA_RECIP_CERT -content $INNER_CONTENT_FILE 2>/dev/null) + OUTPUT=$(openssl cms -verify -in signedData_detached_noattrs.der -inform der -CAfile $RSA_RECIP_CERT -purpose any -content $INNER_CONTENT_FILE 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then echo -e '\tsignedData_detached_noattrs.der:\t\tPASSED!' else echo -e '\tsignedData_detached_noattrs.der:\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi fi -if [ -f 'signedData_cryptodev_attrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedData_cryptodev_attrs.der -inform der -CAfile $RSA_RECIP_CERT 2>/dev/null) +if [ -f 'signedData_cryptocb.der' ]; then + # signedData-cryptocb signs with the ECC client cert, not the RSA one. + OUTPUT=$(openssl cms -verify -in signedData_cryptocb.der -inform der -CAfile $ECC_RECIP_CERT -purpose any 2>/dev/null) if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then - echo -e '\tsignedData_cryptodev_attrs.der:\t\t\tPASSED!' + echo -e '\tsignedData_cryptocb.der:\t\t\tPASSED!' else - echo -e '\tsignedData_cryptodev_attrs.der:\t\t\tFAILED!' + echo -e '\tsignedData_cryptocb.der:\t\t\tFAILED!' + FAILURES=$((FAILURES + 1)) echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" fi +else + echo -e '\tsignedData_cryptocb.der:\t\t\tSKIPPED (needs --enable-cryptocb)' fi -if [ -f 'signedData_cryptodev_noattrs.der' ]; then - OUTPUT=$(openssl cms -verify -in signedData_cryptodev_noattrs.der -inform der -CAfile $RSA_RECIP_CERT 2>/dev/null) - - if [ "$OUTPUT" == "$EXPECTED_INNER_CONTENT" ]; then - echo -e '\tsignedData_cryptodev_noattrs.der:\t\tPASSED!' - else - echo -e '\tsignedData_cryptodev_noattrs.der:\t\tFAILED!' - echo -e "\t... output = $OUTPUT, expected '$EXPECTED_INNER_CONTENT'" - fi +if [ "$FAILURES" -ne 0 ]; then + echo "$FAILURES openssl verification(s) FAILED" + exit 1 fi - +echo "all openssl verifications passed" +exit 0 diff --git a/pkcs7/scripts/runall.sh b/pkcs7/scripts/runall.sh index c1797a2a0..7626d4ab8 100755 --- a/pkcs7/scripts/runall.sh +++ b/pkcs7/scripts/runall.sh @@ -32,9 +32,10 @@ fileArray=( # CMS EnvelopedData example apps "envelopedData-kari" - "envelopedDataDecode" "envelopedData-kekri" "envelopedData-ktri" + # must follow envelopedData-ktri, which produces the .der it decodes + "envelopedDataDecode" "envelopedData-ori" "envelopedData-pwri" @@ -46,7 +47,7 @@ fileArray=( "signedData-EncryptedFirmwareCB" "signedData-FirmwarePkgData" "signedData-DetachedSignature" - "signedData-cryptodev" + "signedData-cryptocb" ) echo "Running example applications..." @@ -62,7 +63,7 @@ do if [ $? -ne 0 ] then echo "Test FAILED" - exit + exit 1 fi fi done diff --git a/pq/ml_dsa/Makefile b/pq/ml_dsa/Makefile index 9757e7cb4..05ff5523f 100644 --- a/pq/ml_dsa/Makefile +++ b/pq/ml_dsa/Makefile @@ -15,4 +15,4 @@ ml_dsa_test: ml_dsa.c .PHONY: clean all clean: - rm -f *.o wolfssl_acert ml_dsa_test + rm -f *.o ml_dsa_test diff --git a/pq/ml_dsa/ml_dsa.c b/pq/ml_dsa/ml_dsa.c index b81c3a665..f68e305b3 100644 --- a/pq/ml_dsa/ml_dsa.c +++ b/pq/ml_dsa/ml_dsa.c @@ -7,7 +7,7 @@ /* wolfssl includes */ #include -#include +#include #include #include @@ -220,11 +220,14 @@ main(int argc, goto ml_dsa_exit; } - rc = wc_MlDsaKey_Sign(&key, sig, &sig_len, (const byte *) msg, strlen(msg), - &rng); + /* ctx=NULL/ctxLen=0 is FIPS 204 signing with an empty context. The older + * wc_MlDsaKey_Sign is pre-FIPS 204 and only exists under + * WOLFSSL_MLDSA_NO_CTX. */ + rc = wc_MlDsaKey_SignCtx(&key, NULL, 0, sig, &sig_len, + (const byte *) msg, strlen(msg), &rng); if (rc != 0) { - printf("error: wc_MlDsaKey_Sign returned %d\n", rc); + printf("error: wc_MlDsaKey_SignCtx returned %d\n", rc); goto ml_dsa_exit; } @@ -235,15 +238,15 @@ main(int argc, ml_dsa_dump_file((const uint8_t *) msg, strlen(msg), "msg.bin"); ml_dsa_dump_file(sig, sig_len, "signature.bin"); - rc = wc_MlDsaKey_Verify(&key, sig, sig_len, - (const byte *) msg, strlen(msg), - &verify_res); + rc = wc_MlDsaKey_VerifyCtx(&key, sig, sig_len, NULL, 0, + (const byte *) msg, strlen(msg), + &verify_res); if (rc == 0 && verify_res == 1) { printf("info: verify message good\n"); } else { - printf("error: wc_MlDsaKey_Verify returned: ret=%d, " + printf("error: wc_MlDsaKey_VerifyCtx returned: ret=%d, " "res=%d\n", rc, verify_res); rc = -1; goto ml_dsa_exit; @@ -445,5 +448,5 @@ ml_dsa_print_parms_and_die(void) printf("* from Tables 1 & 2 of FIPS 204:\n"); printf(" https://csrc.nist.gov/pubs/fips/204/final\n"); - exit(EXIT_FAILURE); + exit(EXIT_SUCCESS); } diff --git a/pq/ml_kem/Makefile b/pq/ml_kem/Makefile new file mode 100644 index 000000000..444569383 --- /dev/null +++ b/pq/ml_kem/Makefile @@ -0,0 +1,18 @@ +CC = gcc + +WOLFSSL_INSTALL_DIR = /usr/local + +WOLFSSL_CFLAGS = -Wextra -Werror -Wall -I$(WOLFSSL_INSTALL_DIR)/include +WOLFSSL_LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lm -lwolfssl + +DEBUG_FLAGS = -g -DDEBUG + +all: ml_kem + +ml_kem: ml_kem.c + $(CC) -o $@ $^ $(WOLFSSL_CFLAGS) $(WOLFSSL_LIBS) $(DEBUG_FLAGS) + +.PHONY: clean all + +clean: + rm -f *.o ml_kem diff --git a/pq/ml_kem/README.md b/pq/ml_kem/README.md index 479989afc..8fafd3db0 100644 --- a/pq/ml_kem/README.md +++ b/pq/ml_kem/README.md @@ -15,7 +15,7 @@ $ sudo ldconfig Build the ML-KEM example: ```sh -$ gcc -o ml_kem ml_kem.c -I/usr/local/include -L/usr/local/lib -lwolfssl +$ make ml_kem ``` # Usage diff --git a/pq/ml_kem/ml_kem.c b/pq/ml_kem/ml_kem.c index c5406ace5..791707920 100644 --- a/pq/ml_kem/ml_kem.c +++ b/pq/ml_kem/ml_kem.c @@ -49,7 +49,7 @@ char* to_hex_string(const unsigned char* array, size_t length) } -int main(int argc, char** argv) +int main(void) { MlKemKey AliceKey; MlKemKey BobKey; @@ -62,6 +62,8 @@ int main(int argc, char** argv) byte bob_ct[WC_ML_KEM_512_CIPHER_TEXT_SIZE]; byte alice_ss[WC_ML_KEM_SS_SZ]; byte bob_ss[WC_ML_KEM_SS_SZ]; + byte diff = 0; + int i; printf("Alice creates an ML-KEM-512 key pair\n\n"); @@ -133,6 +135,21 @@ int main(int argc, char** argv) printf("An error occurred\n"); } + if (ret == 0) { + /* the whole point of the KEM: both sides must derive the same secret. + * Accumulate rather than break early, the secrets are secret data. */ + for (i = 0; i < WC_ML_KEM_SS_SZ; i++) + diff |= (byte)(alice_ss[i] ^ bob_ss[i]); + + if (diff != 0) { + printf("Shared secrets do not match\n"); + ret = -1; + } + else { + printf("Shared secrets match\n"); + } + } + wc_ForceZero(alice_ss, sizeof(alice_ss)); wc_ForceZero(bob_ss, sizeof(bob_ss)); @@ -142,6 +159,7 @@ int main(int argc, char** argv) wc_MlKemKey_Free(&BobKey); if (rngInit) wc_FreeRng(&rng); - return ret; + /* not ret: an exit code is masked to 8 bits, so -256 would read as 0 */ + return (ret == 0) ? 0 : 1; } diff --git a/psa/Makefile b/psa/Makefile index 652807eea..dca3bb9d9 100644 --- a/psa/Makefile +++ b/psa/Makefile @@ -1,11 +1,11 @@ CC = gcc WOLFSSL_INSTALL_DIR = /usr/local -CFLAGS ?= -Wall -I$(INCLUDE_PATH) +CFLAGS ?= -Wall -I$(WOLFSSL_INSTALL_DIR)/include LIBS ?= -L$(WOLFSSL_INSTALL_DIR)/lib -lm # PSA implementation PSA_INCLUDE ?= -PSA_WOLFSSL_INSTALL_DIR ?= +PSA_LIB_PATH ?= # option variables DYN_LIB = -lwolfssl -lm @@ -20,8 +20,11 @@ CFLAGS+=$(OPTIMIZE) #LIBS+=$(STATIC_LIB) LIBS+=$(DYN_LIB) +# an empty PSA_INCLUDE would leave a bare -I that swallows the next flag +ifneq ($(PSA_INCLUDE),) CFLAGS += -I$(PSA_INCLUDE) -LIBS += $(PSA_WOLFSSL_INSTALL_DIR) +endif +LIBS += $(PSA_LIB_PATH) TARGETS=client-tls13-ecc-psa server-tls13-ecc-psa diff --git a/scripts/run-all-examples.sh b/scripts/run-all-examples.sh new file mode 100755 index 000000000..bdd0dbc97 --- /dev/null +++ b/scripts/run-all-examples.sh @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Build and run every example that can run on this machine. +# +# Drives the same manifest CI does (.github/examples-manifest.yml), so what you +# get locally is what CI gets -- there is no second list to keep in sync. +# +# ./scripts/run-all-examples.sh # every host example +# ./scripts/run-all-examples.sh pkcs7 # just one, by manifest id +# ./scripts/run-all-examples.sh --list # what would run, and what won't +# +# Expects a wolfSSL installed at /usr/local (what every README tells you to do): +# +# git clone --depth 1 https://github.com/wolfSSL/wolfssl && cd wolfssl +# ./autogen.sh && ./configure --enable-all && make && sudo make install && sudo ldconfig +# +# Note the manifest defines three wolfSSL profiles. A plain --enable-all covers +# most examples; pk/rsa (fastmath) and signature/rsa_vfy_only (cryptonly) need +# their own builds -- see `profiles:` in the manifest. + +set -uo pipefail + +REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +HARNESS="$REPO/.github/scripts/run_example.py" + +if ! python3 -c 'import yaml' 2>/dev/null; then + echo "PyYAML is required: pip install pyyaml" >&2 + exit 1 +fi + +if [ "${1:-}" = "--list" ]; then + exec python3 - "$REPO" <<'PY' +import sys +sys.path.insert(0, f"{sys.argv[1]}/.github/scripts") +import manifest as m +ex = m.load()["examples"] +for mode, title in (("run", "RUNS"), ("build-only", "BUILDS ONLY"), ("skip", "NOT BUILT")): + sel = [e for e in ex if e.get("mode", "run") == mode] + print(f"\n{title} ({len(sel)})") + for e in sorted(sel, key=lambda x: x["id"]): + why = e.get("reason", "") + print(f" {e['id']:34s} {e['path']:44s} {why[:60]}") +PY +fi + +if [ -n "${1:-}" ]; then + exec python3 "$HARNESS" --only "$1" +fi + +exec python3 "$HARNESS" --tier host diff --git a/signature/sigtest/Makefile b/signature/sigtest/Makefile index 25a58989e..56264e494 100644 --- a/signature/sigtest/Makefile +++ b/signature/sigtest/Makefile @@ -2,11 +2,18 @@ CC=gcc CFLAGS=-Wall LIBS= -OPENSSL_DIR=/usr/local/opt -OPENSSL_FLAGS=-I$(OPENSSL_DIR)/openssl/include -WOLFSSL_FLAGS= -OPENSSL_LIB=-L$(OPENSSL_DIR)/openssl/lib -lcrypto -lssl +# set OPENSSL_DIR only for a non-system OpenSSL (e.g. Homebrew: /usr/local/opt/openssl) +OPENSSL_DIR ?= +ifneq ($(OPENSSL_DIR),) +OPENSSL_FLAGS=-I$(OPENSSL_DIR)/include +OPENSSL_LIB=-L$(OPENSSL_DIR)/lib -lcrypto -lssl +else +OPENSSL_FLAGS= +OPENSSL_LIB=-lcrypto -lssl +endif + WOLFSSL_INSTALL_DIR = /usr/local +WOLFSSL_FLAGS=-I$(WOLFSSL_INSTALL_DIR)/include WOLFSSL_LIB= -L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl all:wolfsigtest opensigtest eccsiglentest diff --git a/staticmemory/Makefile b/staticmemory/Makefile index 72b278c08..ad46a4439 100644 --- a/staticmemory/Makefile +++ b/staticmemory/Makefile @@ -1,4 +1,4 @@ -# ECC Examples Makefile +# Static Memory Examples Makefile CC = gcc WOLFSSL_INSTALL_DIR = /usr/local CFLAGS = -Wall -I$(WOLFSSL_INSTALL_DIR)/include diff --git a/staticmemory/memory-bucket-optimizer/optimizer/Makefile b/staticmemory/memory-bucket-optimizer/optimizer/Makefile index 0a087d1e0..68367ca63 100644 --- a/staticmemory/memory-bucket-optimizer/optimizer/Makefile +++ b/staticmemory/memory-bucket-optimizer/optimizer/Makefile @@ -19,7 +19,9 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA CC = gcc -LDFLAGS = -lwolfssl +WOLFSSL_INSTALL_DIR = /usr/local +CFLAGS += -I$(WOLFSSL_INSTALL_DIR)/include +LDFLAGS = -L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl all: memory_bucket_optimizer diff --git a/staticmemory/memory-bucket-optimizer/tester/Makefile b/staticmemory/memory-bucket-optimizer/tester/Makefile index 4faf41202..e1b4df11e 100644 --- a/staticmemory/memory-bucket-optimizer/tester/Makefile +++ b/staticmemory/memory-bucket-optimizer/tester/Makefile @@ -19,8 +19,10 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA CC = gcc +WOLFSSL_INSTALL_DIR = /usr/local CFLAGS = -Wall -Wextra -O2 -g -LIBS = -lwolfssl +INCLUDES = -I$(WOLFSSL_INSTALL_DIR)/include +LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lwolfssl TARGET = memory_bucket_tester SOURCE = memory_bucket_tester.c diff --git a/tls/client-tls.c b/tls/client-tls.c index f3a568a86..052090619 100644 --- a/tls/client-tls.c +++ b/tls/client-tls.c @@ -36,7 +36,9 @@ #define DEFAULT_PORT 11111 -#define CERT_FILE "../certs/ca-cert.pem" +#define CERT_FILE "../certs/client-cert.pem" +#define KEY_FILE "../certs/client-key.pem" +#define CA_FILE "../certs/ca-cert.pem" @@ -111,11 +113,30 @@ int main(int argc, char** argv) goto ctx_cleanup; } - /* Load client certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CERT_FILE, NULL)) - != WOLFSSL_SUCCESS) { + /* Load client certificate into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); + ret = -1; + goto ctx_cleanup; + } + + /* Load client key into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + KEY_FILE); + ret = -1; + goto ctx_cleanup; + } + + /* Load CA certificate into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL)) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CA_FILE); + ret = -1; goto ctx_cleanup; } diff --git a/tls/client-tls13-resume.c b/tls/client-tls13-resume.c index d110622e9..70ac0ebb7 100644 --- a/tls/client-tls13-resume.c +++ b/tls/client-tls13-resume.c @@ -37,7 +37,9 @@ #define DEFAULT_PORT 11111 -#define CERT_FILE "../certs/ca-cert.pem" +#define CERT_FILE "../certs/client-cert.pem" +#define KEY_FILE "../certs/client-key.pem" +#define CA_FILE "../certs/ca-cert.pem" #if defined(WOLFSSL_TLS13) && defined(HAVE_SECRET_CALLBACK) @@ -160,11 +162,30 @@ int main(int argc, char** argv) goto exit; } - /* Load client certificates into WOLFSSL_CTX */ - if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CERT_FILE, NULL)) - != WOLFSSL_SUCCESS) { + /* Load client certificate into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_certificate_file(ctx, CERT_FILE, + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", CERT_FILE); + ret = -1; + goto exit; + } + + /* Load client key into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_use_PrivateKey_file(ctx, KEY_FILE, + WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + KEY_FILE); + ret = -1; + goto exit; + } + + /* Load CA certificate into WOLFSSL_CTX */ + if ((ret = wolfSSL_CTX_load_verify_locations(ctx, CA_FILE, NULL)) + != WOLFSSL_SUCCESS) { + fprintf(stderr, "ERROR: failed to load %s, please check the file.\n", + CA_FILE); + ret = -1; goto exit; } diff --git a/tls/server-tcp.c b/tls/server-tcp.c index 6fa7980a3..067d004be 100644 --- a/tls/server-tcp.c +++ b/tls/server-tcp.c @@ -38,6 +38,7 @@ int main() { int ret; int sockfd; + int reuse = 1; int connd; struct sockaddr_in servAddr; struct sockaddr_in clientAddr; @@ -71,6 +72,11 @@ int main() /* Bind the server socket to our port */ + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); ret = -1; diff --git a/tls/server-tls-callback.c b/tls/server-tls-callback.c index 958d39955..4e5da70f4 100644 --- a/tls/server-tls-callback.c +++ b/tls/server-tls-callback.c @@ -143,6 +143,7 @@ int my_IOSend(WOLFSSL* ssl, char* buff, int sz, void* ctx) int main() { + int reuse = 1; int sockfd = SOCKET_INVALID; int connd = SOCKET_INVALID; struct sockaddr_in servAddr; @@ -222,6 +223,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls-ecdhe.c b/tls/server-tls-ecdhe.c index 256a445e3..91b0c6ccb 100644 --- a/tls/server-tls-ecdhe.c +++ b/tls/server-tls-ecdhe.c @@ -45,6 +45,7 @@ int main() { + int reuse = 1; int sockfd = SOCKET_INVALID; int connd = SOCKET_INVALID; struct sockaddr_in servAddr; @@ -125,6 +126,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls-nonblocking.c b/tls/server-tls-nonblocking.c index e778c4832..746e86c72 100644 --- a/tls/server-tls-nonblocking.c +++ b/tls/server-tls-nonblocking.c @@ -93,6 +93,7 @@ static int tcp_select(SOCKET_T socketfd, int to_sec, int rx) int main() { + int reuse = 1; int ret, err; int sockfd = SOCKET_INVALID; int connd = SOCKET_INVALID; @@ -174,6 +175,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls-posthsauth.c b/tls/server-tls-posthsauth.c index 04b96fa63..d139c7dd2 100644 --- a/tls/server-tls-posthsauth.c +++ b/tls/server-tls-posthsauth.c @@ -271,6 +271,7 @@ int main(int argc, char** argv) } printf("Shutdown complete\n"); + ret = 0; exit: /* Cleanup and return */ diff --git a/tls/server-tls-threaded.c b/tls/server-tls-threaded.c index eebfd949e..b2d314827 100644 --- a/tls/server-tls-threaded.c +++ b/tls/server-tls-threaded.c @@ -162,6 +162,7 @@ void* ClientHandler(void* args) int main() { + int reuse = 1; int ret; int sockfd = SOCKET_INVALID; int connd; @@ -242,6 +243,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls-verifycallback.c b/tls/server-tls-verifycallback.c index 451993a12..140a01e7f 100644 --- a/tls/server-tls-verifycallback.c +++ b/tls/server-tls-verifycallback.c @@ -142,6 +142,7 @@ static int myVerifyCb(int preverify, WOLFSSL_X509_STORE_CTX* store) int main() { + int reuse = 1; int sockfd = SOCKET_INVALID; int connd = SOCKET_INVALID; struct sockaddr_in servAddr; @@ -224,6 +225,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls-writedup.c b/tls/server-tls-writedup.c index 72e9e370c..c967a7d6b 100644 --- a/tls/server-tls-writedup.c +++ b/tls/server-tls-writedup.c @@ -43,6 +43,7 @@ int main() { + int reuse = 1; int ret = 0; #ifdef HAVE_WRITE_DUP int sockfd = SOCKET_INVALID; @@ -114,6 +115,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls.c b/tls/server-tls.c index 0811bb025..1bbd7a304 100644 --- a/tls/server-tls.c +++ b/tls/server-tls.c @@ -43,6 +43,7 @@ int main() { + int reuse = 1; int sockfd = SOCKET_INVALID; int connd = SOCKET_INVALID; struct sockaddr_in servAddr; @@ -119,6 +120,11 @@ int main() + /* Reuse the port immediately: without this a restart hits TIME_WAIT + * and bind() fails with EADDRINUSE. */ + setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + (char*)&reuse, (socklen_t)sizeof(reuse)); + /* Bind the server socket to our port */ if (bind(sockfd, (struct sockaddr*)&servAddr, sizeof(servAddr)) == -1) { fprintf(stderr, "ERROR: failed to bind\n"); diff --git a/tls/server-tls13-certauth-clienthello.c b/tls/server-tls13-certauth-clienthello.c index 77b37168a..90bd72ebc 100644 --- a/tls/server-tls13-certauth-clienthello.c +++ b/tls/server-tls13-certauth-clienthello.c @@ -314,6 +314,7 @@ int main(int argc, char** argv) } printf("Shutdown complete\n"); + ret = 0; exit: /* Cleanup and return */ diff --git a/tls/server-tls13.c b/tls/server-tls13.c index 9309e7f75..9bf3d7e26 100644 --- a/tls/server-tls13.c +++ b/tls/server-tls13.c @@ -328,6 +328,7 @@ int main(int argc, char** argv) } printf("Shutdown complete\n"); + ret = 0; exit: /* Cleanup and return */ diff --git a/uefi-library/Makefile b/uefi-library/Makefile index 3aa672b0c..c7800579b 100644 --- a/uefi-library/Makefile +++ b/uefi-library/Makefile @@ -43,6 +43,7 @@ LIBGCC_I32 := /usr/lib/gcc-cross/i686-linux-gnu/14/libgcc.a CFLAGS_COMMON := \ -fpic -ffreestanding -fno-stack-protector -fno-stack-check \ -fshort-wchar -mno-red-zone -maccumulate-outgoing-args \ + -U__unix__ \ -DUEFI -DGNUEFI -DWOLFSSL_USER_SETTINGS -DNEED_DYNAMIC_TYPE_FIX_UEFI \ -I. -I/usr/include/efi -I/usr/include/efi/x86_64 \ -I$(WOLFSSL_PATH) \ @@ -72,7 +73,7 @@ OBJS_WOLFCRYPT := \ $(WOLFSSL_PATH)/wolfcrypt/src/cpuid.o \ $(WOLFSSL_PATH)/wolfcrypt/src/memory.o \ $(WOLFSSL_PATH)/wolfcrypt/src/rsa.o \ - $(WOLFSSL_PATH)/wolfcrypt/src/dilithium.o \ + $(WOLFSSL_PATH)/wolfcrypt/src/wc_mldsa.o \ $(WOLFSSL_PATH)/wolfcrypt/src/falcon.o \ $(WOLFSSL_PATH)/wolfcrypt/src/dh.o \ $(WOLFSSL_PATH)/wolfcrypt/src/kdf.o \ diff --git a/uefi-library/README.md b/uefi-library/README.md index c9b59d079..b82c98026 100644 --- a/uefi-library/README.md +++ b/uefi-library/README.md @@ -165,7 +165,7 @@ The protocol struct provides function pointers for: SHAKE-128, SHAKE-256 - **MAC**: HMAC - **Asymmetric**: RSA, ECC, DH, Curve25519, Ed25519 -- **Post-quantum**: ML-KEM (Kyber), Dilithium (ML-DSA), Falcon, SPHINCS+, XMSS, LMS +- **Post-quantum**: ML-KEM (Kyber), ML-DSA, Falcon, SPHINCS+, XMSS, LMS - **KDF**: PBKDF2, PKCS12-PBKDF, HKDF - **RNG**: hardware-seeded DRBG via UEFI `EFI_RNG_PROTOCOL` - **Misc**: logging, error strings, version diff --git a/uefi-library/src/driver.c b/uefi-library/src/driver.c index 410117c0a..a4c1e0478 100644 --- a/uefi-library/src/driver.c +++ b/uefi-library/src/driver.c @@ -42,8 +42,8 @@ #include #include #include -#ifdef HAVE_DILITHIUM -#include +#ifdef WOLFSSL_HAVE_MLDSA +#include #endif #ifdef HAVE_FALCON #include @@ -412,23 +412,25 @@ WRAP_FUNC(int, wc_MlKemKey_EncodePublicKey, #endif /* WOLFSSL_HAVE_MLKEM */ /* ------------------------------------------------------------------ */ -/* Dilithium wrappers */ -/* ------------------------------------------------------------------ */ -#ifdef HAVE_DILITHIUM -WRAP_FUNC(int, wc_dilithium_init, (dilithium_key* key), (key)) -WRAP_VOID(wc_dilithium_free, (dilithium_key* key), (key)) -WRAP_FUNC(int, wc_dilithium_set_level, (dilithium_key* key, byte level), (key, level)) -WRAP_FUNC(int, wc_dilithium_make_key, (dilithium_key* key, WC_RNG* rng), (key, rng)) -WRAP_FUNC(int, wc_dilithium_sign_msg, (const byte* in, word32 inLen, byte* out, word32* outLen, - dilithium_key* key, WC_RNG* rng), (in, inLen, out, outLen, key, rng)) -WRAP_FUNC(int, wc_dilithium_verify_msg, (const byte* sig, word32 sigLen, const byte* msg, - word32 msgLen, int* res, dilithium_key* key), (sig, sigLen, msg, msgLen, res, key)) -WRAP_FUNC(int, wc_dilithium_export_key, (dilithium_key* key, byte* priv, word32* privSz, +/* ML-DSA wrappers */ +/* ------------------------------------------------------------------ */ +#ifdef WOLFSSL_HAVE_MLDSA +WRAP_FUNC(int, wc_MlDsaKey_Init, (wc_MlDsaKey* key, void* heap, int devId), + (key, heap, devId)) +WRAP_VOID(wc_MlDsaKey_Free, (wc_MlDsaKey* key), (key)) +WRAP_FUNC(int, wc_MlDsaKey_SetParams, (wc_MlDsaKey* key, byte level), (key, level)) +WRAP_FUNC(int, wc_MlDsaKey_MakeKey, (wc_MlDsaKey* key, WC_RNG* rng), (key, rng)) +WRAP_FUNC(int, wc_MlDsaKey_Sign, (wc_MlDsaKey* key, byte* sig, word32* sigLen, + const byte* msg, word32 msgLen, WC_RNG* rng), + (key, sig, sigLen, msg, msgLen, rng)) +WRAP_FUNC(int, wc_MlDsaKey_Verify, (wc_MlDsaKey* key, const byte* sig, word32 sigLen, + const byte* msg, word32 msgLen, int* res), + (key, sig, sigLen, msg, msgLen, res)) +WRAP_FUNC(int, wc_MlDsaKey_ExportKey, (wc_MlDsaKey* key, byte* priv, word32* privSz, byte* pub, word32* pubSz), (key, priv, privSz, pub, pubSz)) -WRAP_FUNC(int, wc_dilithium_import_key, (const byte* priv, word32 privSz, - const byte* pub, word32 pubSz, dilithium_key* key), - (priv, privSz, pub, pubSz, key)) -#endif /* HAVE_DILITHIUM */ +WRAP_FUNC(int, wc_MlDsaKey_ImportKey, (wc_MlDsaKey* key, const byte* priv, word32 privSz, + const byte* pub, word32 pubSz), (key, priv, privSz, pub, pubSz)) +#endif /* WOLFSSL_HAVE_MLDSA */ /* ------------------------------------------------------------------ */ /* Falcon wrappers */ @@ -670,16 +672,16 @@ static WOLFCRYPT_PROTOCOL g_wolfcrypt_api = { .wc_MlKemKey_EncodePublicKey = wc_MlKemKey_EncodePublicKey_EfiAPI, #endif - /* Dilithium */ -#ifdef HAVE_DILITHIUM - .wc_dilithium_init = wc_dilithium_init_EfiAPI, - .wc_dilithium_free = wc_dilithium_free_EfiAPI, - .wc_dilithium_set_level = wc_dilithium_set_level_EfiAPI, - .wc_dilithium_make_key = wc_dilithium_make_key_EfiAPI, - .wc_dilithium_sign_msg = wc_dilithium_sign_msg_EfiAPI, - .wc_dilithium_verify_msg = wc_dilithium_verify_msg_EfiAPI, - .wc_dilithium_export_key = wc_dilithium_export_key_EfiAPI, - .wc_dilithium_import_key = wc_dilithium_import_key_EfiAPI, + /* ML-DSA */ +#ifdef WOLFSSL_HAVE_MLDSA + .wc_MlDsaKey_Init = wc_MlDsaKey_Init_EfiAPI, + .wc_MlDsaKey_Free = wc_MlDsaKey_Free_EfiAPI, + .wc_MlDsaKey_SetParams = wc_MlDsaKey_SetParams_EfiAPI, + .wc_MlDsaKey_MakeKey = wc_MlDsaKey_MakeKey_EfiAPI, + .wc_MlDsaKey_Sign = wc_MlDsaKey_Sign_EfiAPI, + .wc_MlDsaKey_Verify = wc_MlDsaKey_Verify_EfiAPI, + .wc_MlDsaKey_ExportKey = wc_MlDsaKey_ExportKey_EfiAPI, + .wc_MlDsaKey_ImportKey = wc_MlDsaKey_ImportKey_EfiAPI, #endif /* Falcon */ diff --git a/uefi-library/src/test_app.c b/uefi-library/src/test_app.c index 217a27870..200242fc4 100644 --- a/uefi-library/src/test_app.c +++ b/uefi-library/src/test_app.c @@ -32,9 +32,9 @@ #include #include #include -#include #include -#include +#include +#include #include "wolfcrypt_api.h" @@ -196,82 +196,158 @@ static const UINT8 kPbkdf2Expected[24] = { static const UINT8 kPkcs7Input[] = { 0x61,0x62,0x63,0x64,0x65 }; static const UINT8 kPkcs7Expected[] = { 0x61,0x62,0x63,0x64,0x65,0x03,0x03,0x03 }; -/* RSA-1024 private key DER (wolfSSL test asset) */ -static const UINT8 kRsaKeyDer1024[] = { - 0x30,0x82,0x02,0x5D,0x02,0x01,0x00,0x02,0x81,0x81, - 0x00,0xBE,0x70,0x70,0xB8,0x04,0x18,0xE5,0x28,0xFE, - 0x66,0xD8,0x90,0x88,0xE0,0xF1,0xB7,0xC3,0xD0,0xD2, - 0x3E,0xE6,0x4B,0x94,0x74,0xB0,0xFF,0xB0,0xF7,0x63, - 0xA5,0xAB,0x7E,0xAF,0xB6,0x2B,0xB7,0x38,0x16,0x1A, - 0x50,0xBF,0xF1,0xCA,0x87,0x3A,0xD5,0xB0,0xDA,0xF8, - 0x43,0x7A,0x15,0xB9,0x7E,0xEA,0x2A,0x80,0xD2,0x51, - 0xB0,0x35,0xAF,0x07,0xF3,0xF2,0x5D,0x24,0x3A,0x4B, - 0x87,0x56,0x48,0x1B,0x3C,0x24,0x9A,0xDA,0x70,0x80, - 0xBD,0x3C,0x8B,0x03,0x4A,0x0C,0x83,0x71,0xDE,0xE3, - 0x03,0x70,0xA2,0xB7,0x60,0x09,0x1B,0x5E,0xC7,0x3D, - 0xA0,0x64,0x60,0xE3,0xA9,0x06,0x8D,0xD3,0xFF,0x42, - 0xBB,0x0A,0x94,0x27,0x2D,0x57,0x42,0x0D,0xB0,0x2D, - 0xE0,0xBA,0x18,0x25,0x60,0x92,0x11,0x92,0xF3,0x02, - 0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x0E,0xEE,0x1D, - 0xC8,0x2F,0x7A,0x0C,0x2D,0x44,0x94,0xA7,0x91,0xDD, - 0x49,0x55,0x6A,0x04,0xCE,0x10,0x4D,0xA2,0x1C,0x76, - 0xCD,0x17,0x3B,0x54,0x92,0x70,0x9B,0x82,0x70,0x72, - 0x32,0x24,0x07,0x3F,0x3C,0x6C,0x5F,0xBC,0x4C,0xA6, - 0x86,0x27,0x94,0xAD,0x42,0xDD,0x87,0xDC,0xC0,0x6B, - 0x44,0x89,0xF3,0x3F,0x1A,0x3E,0x11,0x44,0x84,0x2E, - 0x69,0x4C,0xBB,0x4A,0x71,0x1A,0xBB,0x9A,0x52,0x3C, - 0x6B,0xDE,0xBC,0xB2,0x7C,0x51,0xEF,0x4F,0x8F,0x3A, - 0xDC,0x50,0x04,0x4E,0xB6,0x31,0x66,0xA8,0x8E,0x06, - 0x3B,0x51,0xA9,0xC1,0x8A,0xCB,0xC4,0x81,0xCA,0x2D, - 0x69,0xEC,0x88,0xFC,0x33,0x88,0xD1,0xD4,0x29,0x47, - 0x87,0x37,0xF9,0x6A,0x22,0x69,0xB9,0xC9,0xFE,0xEB, - 0x8C,0xC5,0x21,0x41,0x71,0x02,0x41,0x00,0xFD,0x17, - 0x98,0x42,0x54,0x1C,0x23,0xF8,0xD7,0x5D,0xEF,0x49, - 0x4F,0xAF,0xD9,0x35,0x6F,0x08,0xC6,0xC7,0x40,0x5C, - 0x7E,0x58,0x86,0xC2,0xB2,0x16,0x39,0x24,0xC5,0x06, - 0xB0,0x3D,0xAF,0x02,0xD2,0x87,0x77,0xD2,0x76,0xBA, - 0xE3,0x59,0x60,0x42,0xF1,0x16,0xEF,0x33,0x0B,0xF2, - 0x0B,0xBA,0x99,0xCC,0xB6,0x4C,0x46,0x3F,0x33,0xE4, - 0xD4,0x67,0x02,0x41,0x00,0xC0,0xA0,0x91,0x6D,0xFE, - 0x28,0xE0,0x81,0x5A,0x15,0xA7,0xC9,0xA8,0x98,0xC6, - 0x0A,0xAB,0x00,0xC5,0x40,0xC9,0x21,0xBB,0xB2,0x33, - 0x5A,0xA7,0xCB,0x6E,0xB8,0x08,0x56,0x4A,0x76,0x28, - 0xE8,0x6D,0xBD,0xF5,0x26,0x7B,0xBF,0xC5,0x46,0x45, - 0x0D,0xEC,0x7D,0xEE,0x82,0xD6,0xCA,0x5F,0x3D,0x6E, - 0xCC,0x94,0x73,0xCD,0xCE,0x86,0x6E,0x95,0x95,0x02, - 0x40,0x38,0xFD,0x28,0x1E,0xBF,0x5B,0xBA,0xC9,0xDC, - 0x8C,0xDD,0x45,0xAF,0xB8,0xD3,0xFB,0x11,0x2E,0x73, - 0xBC,0x08,0x05,0x0B,0xBA,0x19,0x56,0x1B,0xCD,0x9F, - 0x3E,0x65,0x53,0x15,0x3A,0x3E,0x7F,0x2F,0x32,0xAB, - 0xCB,0x6B,0x4A,0xB7,0xC8,0xB7,0x41,0x3B,0x92,0x43, - 0x78,0x46,0x17,0x51,0x86,0xC9,0xFC,0xEB,0x8B,0x8F, - 0x41,0xCA,0x08,0x9B,0xBF,0x02,0x41,0x00,0xAD,0x9B, - 0x89,0xB6,0xF2,0x8C,0x70,0xDA,0xE4,0x10,0x04,0x6B, - 0x11,0x92,0xAF,0x5A,0xCA,0x08,0x25,0xBF,0x60,0x07, - 0x11,0x1D,0x68,0x7F,0x5A,0x1F,0x55,0x28,0x74,0x0B, - 0x21,0x8D,0x21,0x0D,0x6A,0x6A,0xFB,0xD9,0xB5,0x4A, - 0x7F,0x47,0xF7,0xD0,0xB6,0xC6,0x41,0x02,0x97,0x07, - 0x49,0x93,0x1A,0x9B,0x33,0x68,0xB3,0xA2,0x61,0x32, - 0xA5,0x89,0x02,0x41,0x00,0x8F,0xEF,0xAD,0xB5,0xB0, - 0xB0,0x7E,0x86,0x03,0x43,0x93,0x6E,0xDD,0x3C,0x2D, - 0x9B,0x6A,0x55,0xFF,0x6F,0x3E,0x70,0x2A,0xD4,0xBF, - 0x1F,0x8C,0x93,0x60,0x9E,0x6D,0x2F,0x18,0x6C,0x11, - 0x36,0x98,0x3F,0x10,0x78,0xE8,0x3E,0x8F,0xFE,0x55, - 0xB9,0x9E,0xD5,0x5B,0x2E,0x87,0x1C,0x58,0xD0,0x37, - 0x89,0x96,0xEC,0x48,0x54,0xF5,0x9F,0x0F,0xB3, +/* RSA-2048 private key DER (wolfSSL certs/client-key.der). + * 2048, not the old 1024 asset: wolfSSL's RSA_MIN_SIZE defaults to 2048, so a + * 1024-bit key makes sign/verify fail and wc_CheckRsaKey report -262. */ +static const UINT8 kRsaKeyDer2048[] = { + 0x30,0x82,0x04,0xA4,0x02,0x01,0x00,0x02,0x82,0x01, + 0x01,0x00,0xC3,0x03,0xD1,0x2B,0xFE,0x39,0xA4,0x32, + 0x45,0x3B,0x53,0xC8,0x84,0x2B,0x2A,0x7C,0x74,0x9A, + 0xBD,0xAA,0x2A,0x52,0x07,0x47,0xD6,0xA6,0x36,0xB2, + 0x07,0x32,0x8E,0xD0,0xBA,0x69,0x7B,0xC6,0xC3,0x44, + 0x9E,0xD4,0x81,0x48,0xFD,0x2D,0x68,0xA2,0x8B,0x67, + 0xBB,0xA1,0x75,0xC8,0x36,0x2C,0x4A,0xD2,0x1B,0xF7, + 0x8B,0xBA,0xCF,0x0D,0xF9,0xEF,0xEC,0xF1,0x81,0x1E, + 0x7B,0x9B,0x03,0x47,0x9A,0xBF,0x65,0xCC,0x7F,0x65, + 0x24,0x69,0xA6,0xE8,0x14,0x89,0x5B,0xE4,0x34,0xF7, + 0xC5,0xB0,0x14,0x93,0xF5,0x67,0x7B,0x3A,0x7A,0x78, + 0xE1,0x01,0x56,0x56,0x91,0xA6,0x13,0x42,0x8D,0xD2, + 0x3C,0x40,0x9C,0x4C,0xEF,0xD1,0x86,0xDF,0x37,0x51, + 0x1B,0x0C,0xA1,0x3B,0xF5,0xF1,0xA3,0x4A,0x35,0xE4, + 0xE1,0xCE,0x96,0xDF,0x1B,0x7E,0xBF,0x4E,0x97,0xD0, + 0x10,0xE8,0xA8,0x08,0x30,0x81,0xAF,0x20,0x0B,0x43, + 0x14,0xC5,0x74,0x67,0xB4,0x32,0x82,0x6F,0x8D,0x86, + 0xC2,0x88,0x40,0x99,0x36,0x83,0xBA,0x1E,0x40,0x72, + 0x22,0x17,0xD7,0x52,0x65,0x24,0x73,0xB0,0xCE,0xEF, + 0x19,0xCD,0xAE,0xFF,0x78,0x6C,0x7B,0xC0,0x12,0x03, + 0xD4,0x4E,0x72,0x0D,0x50,0x6D,0x3B,0xA3,0x3B,0xA3, + 0x99,0x5E,0x9D,0xC8,0xD9,0x0C,0x85,0xB3,0xD9,0x8A, + 0xD9,0x54,0x26,0xDB,0x6D,0xFA,0xAC,0xBB,0xFF,0x25, + 0x4C,0xC4,0xD1,0x79,0xF4,0x71,0xD3,0x86,0x40,0x18, + 0x13,0xB0,0x63,0xB5,0x72,0x4E,0x30,0xC4,0x97,0x84, + 0x86,0x2D,0x56,0x2F,0xD7,0x15,0xF7,0x7F,0xC0,0xAE, + 0xF5,0xFC,0x5B,0xE5,0xFB,0xA1,0xBA,0xD3,0x02,0x03, + 0x01,0x00,0x01,0x02,0x82,0x01,0x01,0x00,0xA2,0xE6, + 0xD8,0x5F,0x10,0x71,0x64,0x08,0x9E,0x2E,0x6D,0xD1, + 0x6D,0x1E,0x85,0xD2,0x0A,0xB1,0x8C,0x47,0xCE,0x2C, + 0x51,0x6A,0xA0,0x12,0x9E,0x53,0xDE,0x91,0x4C,0x1D, + 0x6D,0xEA,0x59,0x7B,0xF2,0x77,0xAA,0xD9,0xC6,0xD9, + 0x8A,0xAB,0xD8,0xE1,0x16,0xE4,0x63,0x26,0xFF,0xB5, + 0x6C,0x13,0x59,0xB8,0xE3,0xA5,0xC8,0x72,0x17,0x2E, + 0x0C,0x9F,0x6F,0xE5,0x59,0x3F,0x76,0x6F,0x49,0xB1, + 0x11,0xC2,0x5A,0x2E,0x16,0x29,0x0D,0xDE,0xB7,0x8E, + 0xDC,0x40,0xD5,0xA2,0xEE,0xE0,0x1E,0xA1,0xF4,0xBE, + 0x97,0xDB,0x86,0x63,0x96,0x14,0xCD,0x98,0x09,0x60, + 0x2D,0x30,0x76,0x9C,0x3C,0xCD,0xE6,0x88,0xEE,0x47, + 0x92,0x79,0x0B,0x5A,0x00,0xE2,0x5E,0x5F,0x11,0x7C, + 0x7D,0xF9,0x08,0xB7,0x20,0x06,0x89,0x2A,0x5D,0xFD, + 0x00,0xAB,0x22,0xE1,0xF0,0xB3,0xBC,0x24,0xA9,0x5E, + 0x26,0x0E,0x1F,0x00,0x2D,0xFE,0x21,0x9A,0x53,0x5B, + 0x6D,0xD3,0x2B,0xAB,0x94,0x82,0x68,0x43,0x36,0xD8, + 0xF6,0x2F,0xC6,0x22,0xFC,0xB5,0x41,0x5D,0x0D,0x33, + 0x60,0xEA,0xA4,0x7D,0x7E,0xE8,0x4B,0x55,0x91,0x56, + 0xD3,0x5C,0x57,0x8F,0x1F,0x94,0x17,0x2F,0xAA,0xDE, + 0xE9,0x9E,0xA8,0xF4,0xCF,0x8A,0x4C,0x8E,0xA0,0xE4, + 0x56,0x73,0xB2,0xCF,0x4F,0x86,0xC5,0x69,0x3C,0xF3, + 0x24,0x20,0x8B,0x5C,0x96,0x0C,0xFA,0x6B,0x12,0x3B, + 0x9A,0x67,0xC1,0xDF,0xC6,0x96,0xB2,0xA5,0xD5,0x92, + 0x0D,0x9B,0x09,0x42,0x68,0x24,0x10,0x45,0xD4,0x50, + 0xE4,0x17,0x39,0x48,0xD0,0x35,0x8B,0x94,0x6D,0x11, + 0xDE,0x8F,0xCA,0x59,0x02,0x81,0x81,0x00,0xEA,0x24, + 0xA7,0xF9,0x69,0x33,0xE9,0x71,0xDC,0x52,0x7D,0x88, + 0x21,0x28,0x2F,0x49,0xDE,0xBA,0x72,0x16,0xE9,0xCC, + 0x47,0x7A,0x88,0x0D,0x94,0x57,0x84,0x58,0x16,0x3A, + 0x81,0xB0,0x3F,0xA2,0xCF,0xA6,0x6C,0x1E,0xB0,0x06, + 0x29,0x00,0x8F,0xE7,0x77,0x76,0xAC,0xDB,0xCA,0xC7, + 0xD9,0x5E,0x9B,0x3F,0x26,0x90,0x52,0xAE,0xFC,0x38, + 0x90,0x00,0x14,0xBB,0xB4,0x0F,0x58,0x94,0xE7,0x2F, + 0x6A,0x7E,0x1C,0x4F,0x41,0x21,0xD4,0x31,0x59,0x1F, + 0x4E,0x8A,0x1A,0x8D,0xA7,0x57,0x6C,0x22,0xD8,0xE5, + 0xF4,0x7E,0x32,0xA6,0x10,0xCB,0x64,0xA5,0x55,0x03, + 0x87,0xA6,0x27,0x05,0x8C,0xC3,0xD7,0xB6,0x27,0xB2, + 0x4D,0xBA,0x30,0xDA,0x47,0x8F,0x54,0xD3,0x3D,0x8B, + 0x84,0x8D,0x94,0x98,0x58,0xA5,0x02,0x81,0x81,0x00, + 0xD5,0x38,0x1B,0xC3,0x8F,0xC5,0x93,0x0C,0x47,0x0B, + 0x6F,0x35,0x92,0xC5,0xB0,0x8D,0x46,0xC8,0x92,0x18, + 0x8F,0xF5,0x80,0x0A,0xF7,0xEF,0xA1,0xFE,0x80,0xB9, + 0xB5,0x2A,0xBA,0xCA,0x18,0xB0,0x5D,0xA5,0x07,0xD0, + 0x93,0x8D,0xD8,0x9C,0x04,0x1C,0xD4,0x62,0x8E,0xA6, + 0x26,0x81,0x01,0xFF,0xCE,0x8A,0x2A,0x63,0x34,0x35, + 0x40,0xAA,0x6D,0x80,0xDE,0x89,0x23,0x6A,0x57,0x4D, + 0x9E,0x6E,0xAD,0x93,0x4E,0x56,0x90,0x0B,0x6D,0x9D, + 0x73,0x8B,0x0C,0xAE,0x27,0x3D,0xDE,0x4E,0xF0,0xAA, + 0xC5,0x6C,0x78,0x67,0x6C,0x94,0x52,0x9C,0x37,0x67, + 0x6C,0x2D,0xEF,0xBB,0xAF,0xDF,0xA6,0x90,0x3C,0xC4, + 0x47,0xCF,0x8D,0x96,0x9E,0x98,0xA9,0xB4,0x9F,0xC5, + 0xA6,0x50,0xDC,0xB3,0xF0,0xFB,0x74,0x17,0x02,0x81, + 0x80,0x5E,0x83,0x09,0x62,0xBD,0xBA,0x7C,0xA2,0xBF, + 0x42,0x74,0xF5,0x7C,0x1C,0xD2,0x69,0xC9,0x04,0x0D, + 0x85,0x7E,0x3E,0x3D,0x24,0x12,0xC3,0x18,0x7B,0xF3, + 0x29,0xF3,0x5F,0x0E,0x76,0x6C,0x59,0x75,0xE4,0x41, + 0x84,0x69,0x9D,0x32,0xF3,0xCD,0x22,0xAB,0xB0,0x35, + 0xBA,0x4A,0xB2,0x3C,0xE5,0xD9,0x58,0xB6,0x62,0x4F, + 0x5D,0xDE,0xE5,0x9E,0x0A,0xCA,0x53,0xB2,0x2C,0xF7, + 0x9E,0xB3,0x6B,0x0A,0x5B,0x79,0x65,0xEC,0x6E,0x91, + 0x4E,0x92,0x20,0xF6,0xFC,0xFC,0x16,0xED,0xD3,0x76, + 0x0C,0xE2,0xEC,0x7F,0xB2,0x69,0x13,0x6B,0x78,0x0E, + 0x5A,0x46,0x64,0xB4,0x5E,0xB7,0x25,0xA0,0x5A,0x75, + 0x3A,0x4B,0xEF,0xC7,0x3C,0x3E,0xF7,0xFD,0x26,0xB8, + 0x20,0xC4,0x99,0x0A,0x9A,0x73,0xBE,0xC3,0x19,0x02, + 0x81,0x81,0x00,0xBA,0x44,0x93,0x14,0xAC,0x34,0x19, + 0x3B,0x5F,0x91,0x60,0xAC,0xF7,0xB4,0xD6,0x81,0x05, + 0x36,0x51,0x53,0x3D,0xE8,0x65,0xDC,0xAF,0x2E,0xDC, + 0x61,0x3E,0xC9,0x7D,0xB8,0x7F,0x87,0xF0,0x3B,0x9B, + 0x03,0x82,0x29,0x37,0xCE,0x72,0x4E,0x11,0xD5,0xB1, + 0xC1,0x0C,0x07,0xA0,0x99,0x91,0x4A,0x8D,0x7F,0xEC, + 0x79,0xCF,0xF1,0x39,0xB5,0xE9,0x85,0xEC,0x62,0xF7, + 0xDA,0x7D,0xBC,0x64,0x4D,0x22,0x3C,0x0E,0xF2,0xD6, + 0x51,0xF5,0x87,0xD8,0x99,0xC0,0x11,0x20,0x5D,0x0F, + 0x29,0xFD,0x5B,0xE2,0xAE,0xD9,0x1C,0xD9,0x21,0x56, + 0x6D,0xFC,0x84,0xD0,0x5F,0xED,0x10,0x15,0x1C,0x18, + 0x21,0xE7,0xC4,0x3D,0x4B,0xD7,0xD0,0x9E,0x6A,0x95, + 0xCF,0x22,0xC9,0x03,0x7B,0x9E,0xE3,0x60,0x01,0xFC, + 0x2F,0x02,0x81,0x80,0x11,0xD0,0x4B,0xCF,0x1B,0x67, + 0xB9,0x9F,0x10,0x75,0x47,0x86,0x65,0xAE,0x31,0xC2, + 0xC6,0x30,0xAC,0x59,0x06,0x50,0xD9,0x0F,0xB5,0x70, + 0x06,0xF7,0xF0,0xD3,0xC8,0x62,0x7C,0xA8,0xDA,0x6E, + 0xF6,0x21,0x3F,0xD3,0x7F,0x5F,0xEA,0x8A,0xAB,0x3F, + 0xD9,0x2A,0x5E,0xF3,0x51,0xD2,0xC2,0x30,0x37,0xE3, + 0x2D,0xA3,0x75,0x0D,0x1E,0x4D,0x21,0x34,0xD5,0x57, + 0x70,0x5C,0x89,0xBF,0x72,0xEC,0x4A,0x6E,0x68,0xD5, + 0xCD,0x18,0x74,0x33,0x4E,0x8C,0x3A,0x45,0x8F,0xE6, + 0x96,0x40,0xEB,0x63,0xF9,0x19,0x86,0x3A,0x51,0xDD, + 0x89,0x4B,0xB0,0xF3,0xF9,0x9F,0x5D,0x28,0x95,0x38, + 0xBE,0x35,0xAB,0xCA,0x5C,0xE7,0x93,0x53,0x34,0xA1, + 0x45,0x5D,0x13,0x39,0x65,0x42,0x46,0xA1,0x9F,0xCD, + 0xF5,0xBF }; -static const UINT8 kRsaCiphertext[128] = { - 0x01,0x0c,0x1f,0xaf,0x1b,0x3c,0x5d,0xb6,0x6f,0x44,0xc5,0x6a, - 0xf6,0xbb,0x2c,0x52,0x36,0xd7,0x21,0xa2,0x25,0x41,0x28,0x36, - 0x0b,0xd8,0xa3,0xcd,0x74,0x43,0xe0,0xc3,0x76,0x73,0x3c,0x2b, - 0x96,0x93,0x68,0xfd,0x33,0x86,0xa6,0x09,0x39,0x14,0x6c,0x7b, - 0x9e,0xf5,0x68,0xf0,0x59,0x2d,0x0e,0x73,0xe3,0x12,0xf3,0xff, - 0xdb,0xce,0x31,0x37,0x54,0x30,0x36,0x57,0x7a,0x40,0xe4,0x34, - 0x43,0xa9,0x2f,0x33,0x57,0x38,0xc1,0x55,0x59,0x0b,0x68,0x4d, - 0x90,0x2a,0xd1,0x94,0x70,0x81,0x51,0x61,0xfb,0x85,0x96,0x1d, - 0x79,0x85,0x43,0xb1,0x4c,0x3b,0x57,0xff,0x57,0xa5,0x7d,0x58, - 0xaf,0xcd,0x61,0x74,0xae,0xe0,0xe8,0x22,0x52,0x12,0x91,0xf1, - 0x75,0xe4,0x16,0x47,0x40,0xd2,0x47,0xa1, +static const UINT8 kRsaCiphertext[256] = { + 0x58,0x42,0x91,0xBA,0x70,0x38,0x5B,0x5E,0x8B,0x84, + 0x2C,0x98,0xEC,0xF0,0xC3,0x0A,0xB3,0x13,0x9D,0xEE, + 0x59,0x01,0x61,0xA7,0x65,0x42,0xAE,0x03,0x03,0xA2, + 0x17,0x9E,0xB4,0xD8,0x62,0xE5,0x97,0xCC,0x78,0x2A, + 0x75,0xEB,0xDD,0x9A,0xEE,0x6F,0x11,0x31,0xC9,0xEC, + 0x73,0xD3,0xFC,0xF7,0xB3,0xD5,0x11,0x34,0x0D,0xAF, + 0x87,0x81,0x71,0x79,0x79,0x09,0x60,0x68,0x2A,0xC2, + 0x9E,0x2F,0xF2,0x14,0x4D,0x38,0x76,0xA7,0x94,0x2C, + 0x69,0x4D,0x26,0xCE,0x29,0x1A,0xC8,0x75,0xAC,0x9F, + 0x86,0xB2,0x38,0xE0,0xF3,0x3B,0x37,0xDC,0x9B,0x2D, + 0x94,0xB7,0xE2,0xB3,0x1B,0x48,0xFA,0x4E,0xBD,0x8B, + 0x03,0x27,0x70,0x55,0x43,0x8A,0xBF,0xC0,0xA4,0x0A, + 0x14,0x33,0x41,0xF5,0xE0,0x31,0x55,0x52,0x70,0xE1, + 0x65,0xE4,0x26,0xC6,0x41,0xD0,0x04,0x12,0x93,0x24, + 0x35,0xDA,0x51,0xE4,0x9C,0xEB,0xC6,0x68,0xBC,0x82, + 0x8A,0xBF,0x5D,0x5A,0x59,0x0D,0xB9,0xB8,0xD2,0x50, + 0x72,0xA6,0x80,0x9F,0xF6,0x61,0xBE,0x2B,0x51,0x28, + 0x00,0xAE,0x75,0x27,0x4F,0xCC,0xEC,0xE4,0xCD,0xE9, + 0x78,0x5D,0x8B,0x99,0x37,0xD8,0xFA,0x80,0x79,0x2A, + 0xC4,0x82,0xAD,0xCF,0x91,0x68,0x2A,0x91,0xA7,0x09, + 0xF4,0xBF,0x26,0x49,0x1B,0xED,0xB1,0xE2,0xBD,0xF0, + 0x26,0x77,0x22,0x46,0x94,0x8F,0xFF,0xD1,0x68,0xBA, + 0xF5,0x0A,0xA1,0x31,0x56,0x34,0xFB,0xCB,0x1A,0x00, + 0xE3,0xDE,0x9C,0x3B,0x04,0x8C,0x15,0xE2,0x9D,0xC1, + 0x84,0x80,0x58,0x6B,0x72,0xBE,0x40,0xDF,0x80,0x5C, + 0xB8,0x8E,0xE4,0x73,0x14,0x7E }; static const UINT8 kRsaPlain[] = { 'w','o','l','f','C','r','y','p','t' }; @@ -789,7 +865,7 @@ static EFI_STATUS TestRsa(void) WC_RNG rng; RsaKey key, pubKey, genKey; BOOLEAN rngInit = FALSE, keyInit = FALSE, pubInit = FALSE, genInit = FALSE; - UINT8 buffer[sizeof(kRsaKeyDer1024)]; + UINT8 buffer[sizeof(kRsaKeyDer2048)]; UINT8 cipher[sizeof(kRsaCiphertext)]; UINT8 plain[sizeof(kRsaCiphertext)]; word32 idx; @@ -804,7 +880,7 @@ static EFI_STATUS TestRsa(void) keyInit = TRUE; idx = 0; - ret = Api->wc_RsaPrivateKeyDecode(kRsaKeyDer1024, &idx, &key, (word32)sizeof(kRsaKeyDer1024)); + ret = Api->wc_RsaPrivateKeyDecode(kRsaKeyDer2048, &idx, &key, (word32)sizeof(kRsaKeyDer2048)); status = CheckWolfResult(ret, L"wc_RsaPrivateKeyDecode"); if (EFI_ERROR(status)) goto cleanup; ret = InitRngDet(&rng); @@ -831,8 +907,8 @@ static EFI_STATUS TestRsa(void) /* DER re-encode */ ret = Api->wc_RsaKeyToDer(&key, buffer, (word32)sizeof(buffer)); if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaKeyToDer"); goto cleanup; } - status = CheckCondition((ret == (int)sizeof(kRsaKeyDer1024)) && - BuffersEqual(buffer, kRsaKeyDer1024, sizeof(kRsaKeyDer1024)), + status = CheckCondition((ret == (int)sizeof(kRsaKeyDer2048)) && + BuffersEqual(buffer, kRsaKeyDer2048, sizeof(kRsaKeyDer2048)), L"RSA DER re-encode"); if (EFI_ERROR(status)) goto cleanup; @@ -1251,50 +1327,50 @@ static EFI_STATUS TestMlKem(void) #endif /* WOLFSSL_HAVE_MLKEM */ /* ------------------------------------------------------------------ */ -/* Dilithium (ML-DSA-44): keygen, sign, verify */ +/* ML-DSA-44: keygen, sign, verify */ /* ------------------------------------------------------------------ */ -#if defined(HAVE_DILITHIUM) -static EFI_STATUS TestDilithium(void) +#if defined(WOLFSSL_HAVE_MLDSA) +static EFI_STATUS TestMlDsa(void) { EFI_STATUS status = EFI_SUCCESS; int ret; WC_RNG rng; - dilithium_key key; + wc_MlDsaKey key; BOOLEAN rngInit = FALSE, keyInit = FALSE; - static const byte msg[] = "wolfCrypt UEFI Dilithium test"; - byte sig[DILITHIUM_MAX_SIG_SIZE]; + static const byte msg[] = "wolfCrypt UEFI ML-DSA test"; + byte sig[MLDSA_MAX_SIG_SIZE]; word32 sigLen = sizeof(sig); int verify = 0; ZeroMem(&rng, sizeof(rng)); ZeroMem(&key, sizeof(key)); ret = InitRngDet(&rng); - status = CheckWolfResult(ret, L"wc_InitRng Dilithium"); if (EFI_ERROR(status)) return status; + status = CheckWolfResult(ret, L"wc_InitRng ML-DSA"); if (EFI_ERROR(status)) return status; rngInit = TRUE; - ret = Api->wc_dilithium_init(&key); - status = CheckWolfResult(ret, L"wc_dilithium_init"); if (EFI_ERROR(status)) goto cleanup; + ret = Api->wc_MlDsaKey_Init(&key, NULL, INVALID_DEVID); + status = CheckWolfResult(ret, L"wc_MlDsaKey_Init"); if (EFI_ERROR(status)) goto cleanup; keyInit = TRUE; - ret = Api->wc_dilithium_set_level(&key, 2); /* ML-DSA-44 */ - status = CheckWolfResult(ret, L"wc_dilithium_set_level"); if (EFI_ERROR(status)) goto cleanup; + ret = Api->wc_MlDsaKey_SetParams(&key, WC_ML_DSA_44); + status = CheckWolfResult(ret, L"wc_MlDsaKey_SetParams"); if (EFI_ERROR(status)) goto cleanup; - ret = Api->wc_dilithium_make_key(&key, &rng); - status = CheckWolfResult(ret, L"wc_dilithium_make_key"); if (EFI_ERROR(status)) goto cleanup; + ret = Api->wc_MlDsaKey_MakeKey(&key, &rng); + status = CheckWolfResult(ret, L"wc_MlDsaKey_MakeKey"); if (EFI_ERROR(status)) goto cleanup; - ret = Api->wc_dilithium_sign_msg(msg, (word32)sizeof(msg)-1, sig, &sigLen, &key, &rng); - status = CheckWolfResult(ret, L"wc_dilithium_sign_msg"); if (EFI_ERROR(status)) goto cleanup; + ret = Api->wc_MlDsaKey_Sign(&key, sig, &sigLen, msg, (word32)sizeof(msg)-1, &rng); + status = CheckWolfResult(ret, L"wc_MlDsaKey_Sign"); if (EFI_ERROR(status)) goto cleanup; - ret = Api->wc_dilithium_verify_msg(sig, sigLen, msg, (word32)sizeof(msg)-1, &verify, &key); - status = CheckWolfResult(ret, L"wc_dilithium_verify_msg"); if (EFI_ERROR(status)) goto cleanup; - status = CheckCondition(verify == 1, L"Dilithium signature verified"); + ret = Api->wc_MlDsaKey_Verify(&key, sig, sigLen, msg, (word32)sizeof(msg)-1, &verify); + status = CheckWolfResult(ret, L"wc_MlDsaKey_Verify"); if (EFI_ERROR(status)) goto cleanup; + status = CheckCondition(verify == 1, L"ML-DSA signature verified"); cleanup: - if (keyInit) Api->wc_dilithium_free(&key); + if (keyInit) Api->wc_MlDsaKey_Free(&key); if (rngInit) Api->wc_FreeRng(&rng); return status; } -#endif /* HAVE_DILITHIUM */ +#endif /* WOLFSSL_HAVE_MLDSA */ /* ------------------------------------------------------------------ */ /* Test runner */ @@ -1319,8 +1395,8 @@ static EFI_STATUS RunAllTests(void) #if defined(WOLFSSL_HAVE_MLKEM) { L"ML-KEM", TestMlKem }, #endif -#if defined(HAVE_DILITHIUM) - { L"Dilithium", TestDilithium }, +#if defined(WOLFSSL_HAVE_MLDSA) + { L"ML-DSA", TestMlDsa }, #endif }; diff --git a/uefi-library/user_settings.h b/uefi-library/user_settings.h index aaebc65bc..525e182aa 100644 --- a/uefi-library/user_settings.h +++ b/uefi-library/user_settings.h @@ -51,9 +51,8 @@ extern int uefi_strncmp_wolfssl(const char* s1, const char* s2, size_t n); #define HAVE_CURVE448 #define HAVE_ED448 -/* Post-quantum: Dilithium (ML-DSA) — native wolfSSL implementation */ -#define HAVE_DILITHIUM -#define WOLFSSL_WC_DILITHIUM +/* Post-quantum: ML-DSA — native wolfSSL implementation */ +#define WOLFSSL_HAVE_MLDSA /* All levels enabled by default (use WOLFSSL_NO_ML_DSA_44/65/87 to disable) */ /* Falcon requires liboqs; omit unless liboqs is available */ diff --git a/uefi-library/wolfcrypt_api.h b/uefi-library/wolfcrypt_api.h index 619ffbc17..66029af55 100644 --- a/uefi-library/wolfcrypt_api.h +++ b/uefi-library/wolfcrypt_api.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include @@ -27,8 +27,8 @@ #include #include #include -#ifdef HAVE_DILITHIUM -#include +#ifdef WOLFSSL_HAVE_MLDSA +#include #endif #ifdef HAVE_FALCON #include @@ -371,26 +371,27 @@ typedef int (EFIAPI *wc_MlKemKey_EncodePublicKey_API)(MlKemKey* key, #endif /* WOLFSSL_HAVE_MLKEM */ /* ------------------------------------------------------------------ */ -/* Dilithium (ML-DSA) */ -/* ------------------------------------------------------------------ */ -#ifdef HAVE_DILITHIUM -typedef int (EFIAPI *wc_dilithium_init_API)(dilithium_key* key); -typedef void (EFIAPI *wc_dilithium_free_API)(dilithium_key* key); -typedef int (EFIAPI *wc_dilithium_set_level_API)(dilithium_key* key, byte level); -typedef int (EFIAPI *wc_dilithium_make_key_API)(dilithium_key* key, WC_RNG* rng); -typedef int (EFIAPI *wc_dilithium_sign_msg_API)(const byte* in, word32 inLen, - byte* out, word32* outLen, - dilithium_key* key, WC_RNG* rng); -typedef int (EFIAPI *wc_dilithium_verify_msg_API)(const byte* sig, word32 sigLen, - const byte* msg, word32 msgLen, - int* res, dilithium_key* key); -typedef int (EFIAPI *wc_dilithium_export_key_API)(dilithium_key* key, - byte* priv, word32* privSz, - byte* pub, word32* pubSz); -typedef int (EFIAPI *wc_dilithium_import_key_API)(const byte* priv, word32 privSz, - const byte* pub, word32 pubSz, - dilithium_key* key); -#endif /* HAVE_DILITHIUM */ +/* ML-DSA */ +/* ------------------------------------------------------------------ */ +#ifdef WOLFSSL_HAVE_MLDSA +typedef int (EFIAPI *wc_MlDsaKey_Init_API)(wc_MlDsaKey* key, void* heap, + int devId); +typedef void (EFIAPI *wc_MlDsaKey_Free_API)(wc_MlDsaKey* key); +typedef int (EFIAPI *wc_MlDsaKey_SetParams_API)(wc_MlDsaKey* key, byte level); +typedef int (EFIAPI *wc_MlDsaKey_MakeKey_API)(wc_MlDsaKey* key, WC_RNG* rng); +typedef int (EFIAPI *wc_MlDsaKey_Sign_API)(wc_MlDsaKey* key, byte* sig, + word32* sigLen, const byte* msg, + word32 msgLen, WC_RNG* rng); +typedef int (EFIAPI *wc_MlDsaKey_Verify_API)(wc_MlDsaKey* key, const byte* sig, + word32 sigLen, const byte* msg, + word32 msgLen, int* res); +typedef int (EFIAPI *wc_MlDsaKey_ExportKey_API)(wc_MlDsaKey* key, + byte* priv, word32* privSz, + byte* pub, word32* pubSz); +typedef int (EFIAPI *wc_MlDsaKey_ImportKey_API)(wc_MlDsaKey* key, + const byte* priv, word32 privSz, + const byte* pub, word32 pubSz); +#endif /* WOLFSSL_HAVE_MLDSA */ /* ------------------------------------------------------------------ */ /* Falcon */ @@ -635,16 +636,16 @@ typedef struct { wc_MlKemKey_EncodePublicKey_API wc_MlKemKey_EncodePublicKey; #endif - /* Dilithium */ -#ifdef HAVE_DILITHIUM - wc_dilithium_init_API wc_dilithium_init; - wc_dilithium_free_API wc_dilithium_free; - wc_dilithium_set_level_API wc_dilithium_set_level; - wc_dilithium_make_key_API wc_dilithium_make_key; - wc_dilithium_sign_msg_API wc_dilithium_sign_msg; - wc_dilithium_verify_msg_API wc_dilithium_verify_msg; - wc_dilithium_export_key_API wc_dilithium_export_key; - wc_dilithium_import_key_API wc_dilithium_import_key; + /* ML-DSA */ +#ifdef WOLFSSL_HAVE_MLDSA + wc_MlDsaKey_Init_API wc_MlDsaKey_Init; + wc_MlDsaKey_Free_API wc_MlDsaKey_Free; + wc_MlDsaKey_SetParams_API wc_MlDsaKey_SetParams; + wc_MlDsaKey_MakeKey_API wc_MlDsaKey_MakeKey; + wc_MlDsaKey_Sign_API wc_MlDsaKey_Sign; + wc_MlDsaKey_Verify_API wc_MlDsaKey_Verify; + wc_MlDsaKey_ExportKey_API wc_MlDsaKey_ExportKey; + wc_MlDsaKey_ImportKey_API wc_MlDsaKey_ImportKey; #endif /* Falcon */ diff --git a/uefi-static/Makefile b/uefi-static/Makefile index 83f921be3..caaa75fa3 100644 --- a/uefi-static/Makefile +++ b/uefi-static/Makefile @@ -4,21 +4,31 @@ WOLFSSL_REPO=https://github.com/wolfSSL/wolfssl CFLAGS=-fpie -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -static-libgcc -nostdlib # enable user settings CFLAGS+= -DWOLFSSL_USER_SETTINGS +# gcc still defines __unix__ when freestanding, which pulls wc_port.c's +# socket/fcntl helpers into a target that has no libc to link them against +CFLAGS+= -U__unix__ CFLAGS+=-I./wolfssl/ -I. -I/usr/include/efi CFLAGS+=-ggdb CC=gcc LD=ld -LDFLAGS_START=-static -pie --no-dynamic-linker -Bsymbolic -L/usr/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/ -Lgnu-efi-dir/x86_64/gnuefi -T/usr/lib/elf_x86_64_efi.lds /usr/lib/crt0-efi-x86_64.o $(LDFLAGS) +# libgcc and gnu-efi sit at different paths per distro (Arch: /usr/lib; Debian/Ubuntu: /usr/lib//gnuefi) +GCC_LIBDIR := $(shell dirname `$(CC) -print-libgcc-file-name`) +EFI_LIBDIR := $(firstword $(wildcard /usr/lib/x86_64-linux-gnu/gnuefi /usr/lib64/gnuefi /usr/lib)) +LDFLAGS_START=-static -pie --no-dynamic-linker -Bsymbolic -L/usr/lib -L$(GCC_LIBDIR) -Lgnu-efi-dir/x86_64/gnuefi -T$(EFI_LIBDIR)/elf_x86_64_efi.lds $(EFI_LIBDIR)/crt0-efi-x86_64.o $(LDFLAGS) LDFLAGS_END=-lgnuefi -lefi -lgcc _OBJS=sha256.o sha3.o misc.o coding.o hmac.o rsa.o random.o wolfmath.o \ integer.o tfm.o asm.o cpuid.o memory.o logging.o wc_port.o asn.o hash.o \ - main.o test.o error.o string.o aes.o wc_encrypt.o + main.o test.o error.o string.o aes.o wc_encrypt.o wolfentropy.o OBJS=$(addprefix $(BUILD_DIR)/,$(_OBJS)) $(shell mkdir -p $(BUILD_DIR)) +# The $(BUILD_DIR)/%.o rule needs these sources present while make builds its +# graph, so cloning from a prerequisite recipe is too late to be found. +$(shell [ -d wolfssl ] || git clone $(WOLFSSL_REPO)) + all: wolfcrypt.efi .PHONY: clone_repo diff --git a/x509_acert/Makefile b/x509_acert/Makefile index 23f5be2bc..023c9e7a5 100644 --- a/x509_acert/Makefile +++ b/x509_acert/Makefile @@ -1,13 +1,19 @@ CC = gcc WOLFSSL_INSTALL_DIR = /usr/local -OPENSSL_INSTALL_DIR = /usr/local WOLFSSL_CFLAGS = -Werror -Wall -I$(WOLFSSL_INSTALL_DIR)/include -DUSE_WOLFSSL WOLFSSL_LIBS = -L$(WOLFSSL_INSTALL_DIR)/lib -lm -lwolfssl +# empty = system OpenSSL; pointing this at /usr/local would shadow openssl/*.h with wolfSSL's opensslextra compat headers +OPENSSL_INSTALL_DIR ?= +ifneq ($(OPENSSL_INSTALL_DIR),) OPENSSL_CFLAGS = -Werror -Wall -I$(OPENSSL_INSTALL_DIR)/include -OPENSSL_LIBS = -L$(OPENSSL_INSTALL_DIR)/lib64/ -lm -lssl -lcrypto +OPENSSL_LIBS = -L$(OPENSSL_INSTALL_DIR)/lib -lm -lssl -lcrypto +else +OPENSSL_CFLAGS = -Werror -Wall +OPENSSL_LIBS = -lm -lssl -lcrypto +endif DEBUG_FLAGS = -g -DDEBUG diff --git a/x509_acert/README.md b/x509_acert/README.md index c6fcc054e..612ab384c 100644 --- a/x509_acert/README.md +++ b/x509_acert/README.md @@ -44,7 +44,7 @@ make wolfssl_acert Build the openssl example with: ```sh -make wolfssl_acert +make openssl_acert ``` Note: you may need to use this script to set your environment @@ -58,9 +58,9 @@ info: using env: /usr/local/lib64/:/usr/local/lib/ ### ACERT verification with pubkey ```sh -$./wolfssl_acert -f acerts/acert.pem -k acerts/acert_pubkey.pem -info: using acert file: acerts/acert.pem -info: using pubkey file: acerts/acert_pubkey.pem +$./wolfssl_acert -f certs/acert.pem -k certs/acert_pubkey.pem +info: using acert file: certs/acert.pem +info: using pubkey file: certs/acert_pubkey.pem info: PEM_read_bio_X509_ACERT: good info: acert version: 1 info: PEM_read_bio_PUBKEY: good