# HOWTO: Install wolfSSL FIPS-eval on Debian

This guide walks through installing the wolfSSL Full Linux FIPS-eval
channel on Debian Trixie (13) or Debian Bookworm (12).

## READ THIS FIRST

**This is a demo and presales evaluation channel. It is NOT supported
and is NOT for production use.**

The packages installed by this channel are NOT the FIPS-certified
wolfCrypt bundle. They are an unsupported best-effort build of the
upstream open-source wolfSSL that approximates the wolfCrypt FIPS 140-3
algorithm boundary (certs #4718 and #5041) so you can evaluate the
interface and integration story before purchasing the real thing.

The wolfCrypt cryptography engine itself is dual-licensed: **GPL-3.0
or commercial**. The GPL-3.0 build available through this channel
carries copyleft obligations. If GPL-3.0 is incompatible with your
product or distribution model, you need the commercial license.

**For supported FIPS 140-3 validated wolfCrypt, production licensing,
FIPS certificate and Operational Environment (OE) work, and any
production support: contact wolfSSL Inc. See "Getting help, support,
sales, licensing, and FIPS certification" at the bottom of this
document.**

FIPS-eval is unsupported. Use it to evaluate, demo, and prototype, and
then talk to us.

## Supported platforms

| Suite          | Architecture | Status |
|----------------|--------------|--------|
| Trixie  (13)   | amd64        | shipped, verified end-to-end |
| Bookworm (12)  | amd64        | shipped, verified end-to-end |
| Trixie  (13)   | arm64        | planned, not yet shipped |
| Bookworm (12)  | arm64        | planned, not yet shipped |

If you are on another Debian release or another `dpkg`-based distro, this
channel won't work; use the Fedora (`HOWTO-fedora.md`) or RHEL-family
(`HOWTO-el.md`) instructions if those apply, or contact wolfSSL for
guidance.

## Quick start

On a fresh Debian Trixie or Bookworm machine, as root (or via `sudo`):

```
curl -fsSL https://fips-eval.wolfssl.com/install | sudo bash
sudo apt update
sudo apt install wolfssl-fips-eval-trixie     # or -bookworm
```

That's it. Three lines.

The first line configures `apt` to trust the wolfSSL FIPS-eval repository.
The second line refreshes apt's index. The third line installs the
meta-package, which pulls in wolfSSL, wolfProvider, libwolfpkcs11,
gnutls-wolfssl, libgcrypt-wolfssl, and the FIPS-aligned variants of
libssl3 (the system OpenSSL runtime), cryptsetup, krb5, openssh, x11vnc,
and gnupg. After the install completes, wolfProvider is the active
OpenSSL default provider and libwolfpkcs11 is registered as a PKCS#11
module both with p11-kit and the system NSS database — no further
configuration required.

### Alternative: pre-built container image

If your evaluation target is a container rather than a real or
virtual machine, the same package set is also available as a pre-built
OCI container image, for both `linux/amd64` and `linux/arm64`. The
recipe is `curl` + `docker load` from
`https://fips-eval.wolfssl.com/oci/` rather than an apt install:

```
ARCH=$(dpkg --print-architecture)   # amd64 or arm64
curl -fsSLO https://fips-eval.wolfssl.com/oci/debian-trixie-fips-eval/latest/${ARCH}.tar
docker load -i ${ARCH}.tar
docker run --rm wolfssl/debian-trixie-fips-eval:latest openssl list -providers
```

The image is functionally identical to the apt-installed flavor — same
`libwolfssl` build, same `libwolfprov`, same patched system tools, same
algorithm surface. See [HOWTO-oci.md](HOWTO-oci.md) for the full guide
including SHA-256 verification, multi-arch `skopeo` recipe, and dated
tag pinning.

The container images are **not** pushed to Docker Hub, ECR Public, or
GHCR yet — registry-push coordination across those three vendors is
on the roadmap. In the meantime, the images are served directly from
the FIPS-eval CDN, symmetric with how the `.deb` packages are served.

## What the bootstrap script does

The `curl | bash` line runs
[`install-bootstrap.sh`](https://fips-eval.wolfssl.com/install) which:

1. Detects your Debian suite (Trixie or Bookworm) and architecture
   (amd64 or arm64) from `/etc/os-release` and `dpkg --print-architecture`.
2. Downloads the signed `wolfssl-fips-eval-archive-keyring` `.deb` from
   the wolfSSL FIPS-eval site, verifies it against a SHA-256 hash that's
   pinned in the bootstrap script itself (fail-closed: a tampered keyring
   will not install).
3. Installs the keyring `.deb` into `/usr/share/keyrings/`. This is the
   trust anchor for the apt repository.
4. Writes `/etc/apt/sources.list.d/wolfssl-fips-eval.list` pointing at
   `https://fips-eval.wolfssl.com/debian` with `signed-by=` referencing
   the keyring you just installed.
5. Writes `/etc/apt/preferences.d/wolfssl-fips-eval` setting Pin-Priority
   1001 on packages from the FIPS-eval repo. Priority 1001 means apt will
   prefer our versions over Debian's stock packages, even when our version
   number is numerically lower than the stock one.

The bootstrap script does NOT install any cryptography packages itself.
That step is explicit: you run `apt install ...` only after you've read
this far.

## What gets installed by the meta-package

`sudo apt install wolfssl-fips-eval-trixie` (or `-bookworm`) installs:

**Core wolfSSL + wolfProvider stack:**

- **libwolfssl 5.9.1**: the wolfSSL TLS/SSL + wolfCrypt cryptography
  library, built with the FIPS-approximating configure flags. The
  configure set matches the IGEL OS canonical recipe and DROPS
  curve25519/ed25519/curve448/ed448/MD5 — see "Algorithm coverage" below.
- **libwolfprov 1.1.0-1+fipseval3**: the OpenSSL 3.x provider that
  routes OpenSSL crypto calls into wolfSSL. Installs at
  `/usr/lib/<multiarch>/ossl-modules/libwolfprov.so`. The 1.1.0 base
  version is intentional — wolfProvider 1.1.1 has an unresolved
  upstream X25519 ECDHE bug in Mode 2 (replace-default) that this
  channel works around by holding at 1.1.0.

**Mode-2 replace-default libssl3:**

- **libssl3 3.0.20-1~deb12u1+fipseval2** (Bookworm) or
  **libssl3t64 3.5.6-1~deb13u1+fipseval2** (Trixie): Debian's stock
  libssl3 rebuilt with the canonical wolfProvider replace-default patch.
  Once installed, the OpenSSL `default` provider IS libwolfprov; no
  per-process `OPENSSL_CONF` configuration is required.

**libgcrypt + gnutls + PKCS#11 wrappers:**

- **libgcrypt20-1.11.0-wolfssl 1.11.0+wolfssl20260306+fipseval2**:
  libgcrypt rebuilt to use libwolfssl as its cryptographic backend.
  Provides `libgcrypt.so.20` as a drop-in replacement so gpg, gnupg-utils,
  libgcrypt-using apps run through wolfssl.
- **gnutls-wolfssl + wolfssl-gnutls-wrapper 0~git20260324+fipseval2**:
  GnuTLS 3.x rebuilt to route through wolfSSL via a wrapper shim. The
  `gnutls-wolfssl` package ships the **GnuTLS command-line tool set
  in `/usr/bin/`** (`certtool`, `gnutls-cli`, `gnutls-cli-debug`,
  `gnutls-serv`, `ocsptool`, `p11tool`, `psktool`, `srptool`) plus
  `libgnutls.so.30` and `libgnutlsxx.so.30` in `/usr/lib/`. The
  package declares `Provides: libgnutls30 (= 3.8.9)`, `Conflicts:
  libgnutls30`, `Replaces: libgnutls30` so any apt package that
  depends on `libgnutls30` is satisfied by our replacement. **Do NOT
  separately `apt install gnutls-bin`** — the CLI tools are already
  installed by `gnutls-wolfssl`, and installing `gnutls-bin` would
  pull in stock `libgnutls-dane0` which strict-pins stock
  `libgnutls30` (see "What FIPS-eval is NOT" for the libgnutls-dane0
  caveat).
- **libwolfpkcs11 2.0.0+fipseval1**: wolfSSL-backed PKCS#11 module.
- **libwolfpkcs11-p11kit 2.0.0+fipseval2**: registers libwolfpkcs11
  with both p11-kit (`/usr/share/p11-kit/modules/wolfpkcs11.module`) and
  the system NSS DB (`/etc/pki/nssdb`). Also ships a profile.d hook
  that auto-registers libwolfpkcs11 in per-user NSS databases (chromium
  `~/.pki/nssdb`, firefox profiles, thunderbird profiles) on login.
  See `/usr/share/doc/libwolfpkcs11-p11kit/README.Debian` for details
  and opt-out instructions.
- **libnss3 (+fipseval1)**: NSS rebuilt with the wolfSSL `osp/nss/`
  patch (`nss-fixes-3.87.patch` on Bookworm, `nss-fixes-2025-04-11`
  variant on Trixie). Three behavioral changes:
  1. **wolfPKCS11 becomes the default internal PKCS#11 module.** NSS no
     longer requires `pkcs11.txt` or `modutil -add` — `libwolfpkcs11.so`
     is hardcoded as the default backend via a patched
     `NSSUTIL_DEFAULT_INTERNAL_INIT1` string in `lib/util/utilparst.h`.
     Firefox, Thunderbird, Chromium, Evolution, sssd, and any other NSS
     consumer route their crypto primitives through wolfPKCS11 →
     wolfSSL.
  2. **NSS adapts to wolfPKCS11's advertised ECC curves** instead of
     assuming softoken's fixed curve list. New `ssl_TestKeyPair()`
     function probes the backend at runtime.
  3. **One-slot PKCS#11 fallback.** NSS's `PK11_GetInternalKeySlot()`
     hard-codes `slots[1]` (softoken's two-slot model); wolfPKCS11
     presents one slot, so the patch falls back to `slots[0]` when
     `slotCount == 1`.

  **Important behavior difference vs upstream NSS:** wolfPKCS11 stores
  tokens in its own file format under `~/.wolfPKCS11/` (or
  `$WOLFPKCS11_TOKEN_PATH`, or a TPM) — NOT in NSS's `cert9.db` /
  `key4.db` format. Existing NSS DBs are not migrated; fresh installs
  work cleanly. This matches the architecture shipped by wolfSSL to
  IGEL in Aug 2025 (`libnss3_3.87.1-1+wolfSSL-1`).

**Patched system tools (Mode-2-minimal):**

- **cryptsetup-bin**: with patches applied (default plain hash bumped
  to SHA-256 on Bookworm; Trixie already shipped SHA-256 upstream).
- **libkrb5-3 / libk5crypto3 (+fipseval2)**: TWO patches together:
  (a) PKINIT SSKDF fallback so certificate-based kinit works under
  wolfProvider, and (b) `--with-crypto-impl=openssl` in the krb5 build
  so libk5crypto links libcrypto.so.3 — meaning standard krb5
  operations (password-based kinit, AES-CTS ticket encryption,
  HMAC-SHA-2 integrity) ALSO route through wolfssl.
- **openssh-client / openssh-server (+fipseval1)**: with
  `chacha20-poly1305` removed from the default cipher list, leaving
  only FIPS-approved AEAD and CTR ciphers in the default offer.
- **x11vnc (+fipseval1)**: with the certificate-generation helper
  using SHA-256 + AES-256 by default instead of MD5 + 3DES.
- **gnupg / gpg / gpgv / gpg-agent / dirmngr / gpgsm / scdaemon
  (+fipseval1)**: the gpg startup path skips registering MD5 in its
  hardcoded weak-digest list when libgcrypt does not provide MD5.
  Without this patch, gpg refuses to start on the FIPS-eval channel
  because the libgcrypt-wolfssl wrapper does not expose MD5 (see
  "Algorithm coverage" below). Only the registration-time error is
  suppressed; the rest of gpg's MD5 rejection logic is unchanged.
- **libsnmp40 / libsnmp-base (+fipseval1)** (Bookworm) /
  **libsnmp40t64 / libsnmp-base (+fipseval1)** (Trixie): net-snmp
  rebuilt with `--disable-md5 --disable-des`. SNMPv3 USM requests for
  the legacy `usmHMACMD5AuthProtocol` (RFC 3414 default auth, MD5) or
  `usmDESPrivProtocol` (RFC 3414 default priv, DES) **fail cleanly**
  through net-snmp's existing error-reporting machinery
  (`usmStatsWrongDigests`, `usmStatsUnsupportedSecLevels`) rather than
  silently substituting algorithms on the wire. SNMPv3 USM with
  SHA-1/SHA-2 family auth + AES priv (RFC 7860 / RFC 3826) works
  normally. Out-of-scope behavioral note: legacy SNMP devices that
  only speak MD5/DES cannot be monitored from a FIPS-eval system.
  Upstream PR for a generic `--enable-fips-mode` net-snmp flag is in
  flight; see net-snmp issue #294.

If you only want the wolfSSL libraries and not the patched apps:

```
sudo apt install libwolfssl libwolfprov
```

## Algorithm coverage

The FIPS-eval libwolfssl on this channel is configured to match the
IGEL canonical wolfSSL build recipe (the same recipe wolfSSL ships to
the IGEL OS embedded Linux distribution). That subset deliberately
**omits** several algorithms that are present in a default wolfSSL build:

- **MD5** — disabled. Tools that depend on MD5 (legacy PGP key formats,
  some HMAC-MD5-based protocols, BSD `md5sum` if it routes through
  libcrypto) will not be able to compute MD5 hashes. This is intentional:
  MD5 is broken for collision resistance and has no place in a
  FIPS-evaluation channel.
- **Curve25519 / X25519** — disabled. TLS 1.3 clients will not advertise
  `x25519` in their `supported_groups` extension; servers will pick a
  NIST curve (P-256, P-384, P-521) for ECDHE instead.
- **Ed25519** — disabled. Ed25519 signatures are not supported; use
  RSA-PSS, ECDSA-P256, or ECDSA-P384 instead.
- **Curve448 / X448** — disabled.
- **Ed448** — disabled.

If your workload depends on any of these algorithms, this channel is
not yet usable for your evaluation. Talk to wolfSSL Inc. about whether
your real production deployment will need them and we can build you
a custom evaluation configuration.

The supported set covers the FIPS 140-3 algorithm boundary (AES-128/256
in GCM/CTR/CBC, SHA-2 family, SHA-3 family, RSA-2048/3072/4096 PKCS#1
v1.5 and PSS, ECDSA on P-256/P-384/P-521, ECDH on P-256/P-384/P-521,
HMAC, HKDF, PBKDF2, FFDHE-2048/3072/4096/6144/8192).

## How wolfProvider is activated

This channel uses the **replace-default** integration model
(wolfProvider "Mode 2"): the meta-package installs a libssl3 / libssl3t64
that has been rebuilt with wolfProvider's canonical
`openssl3-replace-default.patch`. When any application loads OpenSSL's
`default` provider, that load is rerouted internally to libwolfprov via
`DSO_load`. No `OPENSSL_CONF` setting is required; wolfProvider is
active for every OpenSSL-using application as soon as the package is
installed.

Verify wolfProvider is active with no extra configuration:

```
openssl list -providers
```

You should see:

```
Providers:
  default
    name: wolfSSL Provider
    version: 1.1.0
    status: active
```

The `default` provider name reports `wolfSSL Provider` rather than
`OpenSSL Default Provider` — that's the replace-default patch routing
the load through libwolfprov.

If you see `OpenSSL Default Provider` instead, the patched libssl3 is
not active (e.g., a previous install removed it). Reinstall:

```
sudo apt install --reinstall libssl3      # Bookworm
sudo apt install --reinstall libssl3t64   # Trixie
```

### Opting out for a single process

If a specific application needs the OpenSSL default provider rather
than wolfProvider, set `OPENSSL_CONF` to an empty config file:

```
OPENSSL_CONF=/dev/null some-application
```

This bypasses the openssl.cnf processing entirely.

### Application-level (developer integration)

If you're a developer integrating wolfProvider into your own application,
create a dedicated OpenSSL library context and load the provider
explicitly:

```c
#include <openssl/provider.h>

OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER *prov = OSSL_PROVIDER_load(ctx, "libwolfprov");
/* ... use ctx ... */
OSSL_PROVIDER_unload(prov);
OSSL_LIB_CTX_free(ctx);
```

This avoids modifying global state and lets you A/B-test wolfProvider
against the default provider in the same process.

## Verifying the install

The signed-by mechanism means apt will fail to install if any tampering
has happened to the repository between us and you. A successful
`apt update` already proves the cryptographic trust chain.

Beyond that:

### Verify the library is installed

```
dpkg -l libwolfssl libwolfprov | tail -4
```

You should see both packages with status `ii`.

### Verify the library exposes the public SP math API

```
nm -D /usr/lib/x86_64-linux-gnu/libwolfssl.so.44 | grep -c " T sp_"
```

On amd64 this should return `73`. This number is the count of public
single-precision big-integer math functions exposed by libwolfssl, which
wolfProvider requires for RSA and ECC operations. On arm64 the path is
`/usr/lib/aarch64-linux-gnu/libwolfssl.so.44`.

### Verify a real crypto operation goes through wolfSSL

No `OPENSSL_CONF` needed — wolfProvider is the default provider:

```
openssl list -digest-algorithms | grep -i wolf
```

You should see entries like:

```
{ 2.16.840.1.101.3.4.2.1, SHA2-256, SHA-256, SHA256 } @ default
{ 2.16.840.1.101.3.4.2.2, SHA-384, SHA2-384, SHA384 } @ default
```

(`default` here is the patched libssl3's default-provider slot, which
the replace-default patch rerouted to libwolfprov.)

For end-to-end proof, run a digest under `ltrace` and observe wolfSSL
function calls:

```
echo test | ltrace -e 'wc_*+wolfSSL_*+sp_*' openssl dgst -sha256 2>&1 | head
```

You should see `wc_InitSha256`, `wc_Sha256Update`, `wc_Sha256Final`,
`wc_Sha256Free` calls in the output — confirming OpenSSL routed the
SHA-256 operation through wolfProvider into wolfSSL.

### Verify libk5crypto routes through libcrypto

```
ldd /usr/lib/x86_64-linux-gnu/libk5crypto.so.3 | grep libcrypto
```

You should see `libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3`.
That linkage means standard Kerberos operations (password kinit,
ticket encryption with AES-CTS, HMAC-SHA-2 integrity) route through
libcrypto, which is the patched libssl3 routing through libwolfprov
into libwolfssl.

### Verify NSS routes through wolfPKCS11

NSS-using applications (Firefox, Thunderbird, Chromium, Evolution,
sssd, modutil/certutil) route their crypto through three independent
mechanisms on this channel, in priority order:

**(a) The patched libnss3 — the default-module mechanism.** The
patched `libnssutil3.so` contains the string
`library=libwolfpkcs11.so name=wolfPKCS11`, which becomes the default
PKCS#11 module that NSS loads at startup. No `modutil -add` or
`pkcs11.txt` entry is required.

```
strings /usr/lib/x86_64-linux-gnu/libnssutil3.so | grep wolfpkcs11
```

You should see `library=libwolfpkcs11.so name=wolfPKCS11 parameters=`.

**(b) p11-kit module config — for p11-kit-aware tools.** Applications
that use p11-kit instead of NSS directly (gnutls, evolution,
openconnect, sssd, GNOME Keyring) auto-discover libwolfpkcs11 via
the p11-kit module file:

```
ls /usr/share/p11-kit/modules/wolfpkcs11.module
```

**(c) System NSS DB registration — for tools that read
`/etc/pki/nssdb` directly.** The `libwolfpkcs11-p11kit` package
postinst runs `modutil -add` against the system NSS DB so older
NSS-using tools that bypass NSSUTIL_DEFAULT_INTERNAL_INIT1 still see
libwolfpkcs11:

```
modutil -dbdir sql:/etc/pki/nssdb -list | grep -i wolf
```

For per-user NSS databases (chromium, firefox, thunderbird), the
`/etc/profile.d/wolfpkcs11-nss-register.sh` script auto-registers
libwolfpkcs11 on each shell login. The registration is idempotent
and cached daily; check `~/.cache/wolfssl-fips-eval/nss-register.log`
for status.

### Verify SSH negotiates only FIPS-approved ciphers

If you installed `openssh-server` from the meta-package, you can capture a
local handshake:

```
sudo tcpdump -i lo -w /tmp/ssh-handshake.pcap -nn -s 0 'tcp port 22' &
ssh -v localhost true 2>&1 | grep "kex:"
sudo kill %1
strings /tmp/ssh-handshake.pcap | grep -oE 'chacha20-poly1305|aes[0-9]+-gcm|aes[0-9]+-ctr' | sort -u
```

`chacha20-poly1305` should be absent. AES-128-GCM, AES-256-GCM, AES-128-CTR
through AES-256-CTR should be present.

## What FIPS-eval is NOT (the honest list)

This is not optional reading. Every bullet matters.

- **It is not a FIPS 140-3 validated cryptographic module.** It is an
  open-source wolfSSL build that approximates the validated module's
  algorithm set so you can evaluate the interface and integration
  story. Production deployments that require FIPS validation must use
  the certified wolfCrypt module, which is a separate purchase. The
  CMVP-issued FIPS 140-3 certificates referenced by this channel
  (#4718, #5041) cover that certified module, NOT this evaluation
  build.
- **It is not the actual FIPS-certified bundle.** A FIPS-certified
  deployment requires the certified wolfCrypt module source, the
  matching Operational Environment (OE) from the CMVP certificate, and
  in many cases an OE add to extend the certificate to your specific
  platform. None of that is in this channel.
- **It is not supported.** No SLA, no CVE response process, no support
  pipeline.
- **It is not for production.** Treat it as a demo binary. Use it on
  evaluation laptops, lab machines, and CI sandboxes. Do not deploy it
  to anything that processes real data, real traffic, or real
  customers.
- **It does not include FIPS-mode operational self-tests.** The
  certified wolfCrypt module includes power-on self-tests (POST),
  continuous random-number-generator health tests, and integrity
  checking of the cryptographic boundary. This evaluation build does
  not run those tests at startup.
- **The license is GPL-3.0.** wolfCrypt and wolfSSL are dual-licensed:
  GPL-3.0 OR commercial. The build distributed by this channel is the
  GPL-3.0 build. If GPL-3.0 copyleft is incompatible with your
  product, you need a commercial license — contact wolfSSL.
- **Mode-2 patches are minimal.** The patches to cryptsetup, krb5,
  openssh, x11vnc, and gnupg redirect crypto through wolfProvider via
  OpenSSL's provider interface (or libgcrypt-wolfssl for gnupg); they
  do not rewire the applications' internal algorithm selection logic.
- **`apt upgrade` does not auto-pull new libwolfssl builds.** The
  binary `libwolfssl_*.deb` ships with an internal `Version` field of
  `5.9.1` (the upstream version) rather than the source-package
  revision (`5.9.1-1+fipseval3`). This is because wolfssl's upstream
  `debian/rules` doesn't propagate the source-package debian-revision
  into the binary deb's Version field. The customer-visible effect:
  if you already have `libwolfssl 5.9.1` installed and we publish a
  new `5.9.1-1+fipseval4` build, `apt upgrade` will NOT see it as a
  newer version and will skip it. Fresh installs work fine (apt
  resolves to the only available version, which is ours). To force a
  refresh on an already-installed host, run:
  ```
  sudo apt install --reinstall libwolfssl
  ```
  This pulls the current channel version of the file based on the
  apt-cache hash, regardless of the embedded Version field. The same
  workaround applies to `libwolfprov` if it ever ships a same-version
  update. Tracked as FullLinuxFIPS-c8w; will be fixed in a future
  libwolfssl rebuild that uses an explicit `dh_gencontrol` override
  to propagate the +fipseval suffix into the binary Version.
- **NSS uses wolfPKCS11 as its default PKCS#11 backend, but does NOT
  use NSS's `cert9.db` / `key4.db` on-disk format.** wolfPKCS11 stores
  tokens in its own file format under `~/.wolfPKCS11/`,
  `$WOLFPKCS11_TOKEN_PATH`, or a TPM. NSS clients (Firefox, Thunderbird,
  Chromium, Evolution) on this channel will create fresh wolfPKCS11
  databases on first run; existing user NSS DBs are NOT migrated. This
  is the architecture wolfSSL shipped to IGEL in Aug 2025 and is the
  intended design, not a gap.
- **NSS algorithm surface is wolfPKCS11's, not softoken's.** The
  patched NSS no longer advertises ChaCha20-Poly1305, static RSA key
  exchange, DSA, RC4, DES, 3DES, Camellia, or SEED cipher suites
  because wolfPKCS11 does not implement those PKCS#11 mechanisms.
  Curve25519/Curve448 are not exposed as PKCS#11 mechanisms either.
  Modern wolfPKCS11-supported algorithms (AES family, SHA-2 family,
  RSA, ECDSA/ECDH on NIST curves, FFDHE, HKDF, PBKDF2, HMAC) work
  normally. The `ssl_V3_SUITES_IMPLEMENTED` count drops from 71 to 28
  in the patched NSS.
- **`libgnutls-dane0` / `libgnutls-dane0t64` strict-pin scenarios may
  not coexist cleanly.** Our `gnutls-wolfssl` package declares
  `Provides: libgnutls30 (= 3.8.9)` which satisfies most
  `libgnutls30` dependencies (apt treats `Provides` as fulfilling
  unversioned dependency lines). However:
  1. The small set of apps that depend on `libgnutls-dane0` (on
     Bookworm) or `libgnutls-dane0t64` (on Trixie, after the time64
     transition) hit a problem: that package strict-pins stock
     `libgnutls30` / `libgnutls30t64` at the exact upstream Debian
     point-release version (e.g. `Depends: libgnutls30 (=
     3.7.9-2+deb12u7)`), and our `Provides: libgnutls30 (= 3.8.9)`
     does NOT satisfy a strict-equality dependency.
  2. On Trixie our current `Provides: libgnutls30` declaration uses
     the pre-t64 binary package name. Trixie ships
     `libgnutls30t64` instead; apt dep resolution may not find our
     replacement under the new name. Tracked as FullLinuxFIPS-35r.
  Practical workarounds:
  - Don't install `libgnutls-dane0` / `libgnutls-dane0t64` (and don't
    install `gnutls-bin`, which pulls it in). Our `gnutls-wolfssl`
    package already ships the CLI tools in `/usr/bin/` — see above.
  - If you absolutely need DNSSEC-DANE (e.g. for `gnutls-cli --dane`
    on an MTA), use the stock Debian GnuTLS for that one process and
    note that DNSSEC-DANE features are not currently wolfSSL-backed
    on this channel.
  Reverse-dependency surface area: ~34k popcon installs of
  `libgnutls-dane0`, declining since early 2026. Main consumers are
  `gnutls-bin` itself (the metapackage we recommend skipping) plus a
  small set of DNSSEC / DANE validators. Tracked as FullLinuxFIPS-m2z
  for further characterization.
- **TPM2-LUKS offline-precompute enrollment with ECC device keys is
  not supported on this channel.** This is a narrow, bounded
  limitation; read carefully because the bound matters.
  The affected workflow: `systemd-cryptenroll --tpm2-device-key=…`
  or `systemd-repart` with `arg_tpm2_device_key` set, computing a
  sealed LUKS blob *offline* (no attached TPM) against a target
  device's TPM2 public key, where that device key is an ECC primary
  rather than an RSA primary. This is a fleet-provisioning or
  golden-image-build path, not a runtime path. systemd's offline KDFe
  implementation calls `EVP_KDF_fetch(NULL, "SSKDF", NULL)` and
  systemd has no fallback when the fetch returns NULL.
  What still works on this channel:
  - Boot-time TPM2-LUKS unlock against an attached TPM: the TPM
    hardware performs the unseal; no host-side KDF runs. Unaffected.
  - Online enrollment with an attached TPM (`systemd-cryptenroll
    --tpm2-device=…` without `--tpm2-device-key`): the TPM hardware
    performs the seal. Unaffected.
  - Offline-precompute enrollment with an **RSA** device key: KBKDF is
    used, which wolfProvider does register. Works.
  Why this exists: wolfCrypt's SP 800-56C SSKDF implementation
  (`wc_KDA_KDF_onestep`) is not inside the wolfCrypt FIPS 5.x / 6.x
  module boundary covered by CMVP certificates #4718 and #5041 — it
  is gated by `WC_KDF_NIST_SP_800_56C`, defined only in non-FIPS
  builds. wolfProvider deliberately does not expose an `EVP_KDF`
  SSKDF entry point routed through a non-FIPS-validated function;
  doing so would silently break FIPS posture for any consumer that
  relies on wolfProvider for FIPS-validated crypto. This is a
  wolfCrypt FIPS-boundary scope decision, not a NIST policy
  constraint (SP 800-56C is NIST-approved). Forward-looking:
  wolfSSL's source tree carries a `FIPS_VERSION3_GE(7,0,0)` test
  gate around the SSKDF code path, indicating that
  `wc_KDA_KDF_onestep` is intended to be inside the validated
  boundary once wolfCrypt FIPS 7.0.0 completes CMVP lab validation.
  At that point wolfProvider can safely register the entry point.
  **wolfSSL has not published a CMVP-completion date for FIPS
  7.0.0**, so we cannot give you a date; we can promise only that
  this gap is on the path to closure when the next wolfCrypt FIPS
  module validation ships. Workaround in the meantime: use RSA TPM2
  device keys for offline-precompute enrollment, or perform
  enrollment online with an attached TPM. Tracked as TASKS-bg4.

If your evaluation hits a question like "does this exact configuration
pass FIPS 140-3 algorithm testing," the answer is: not from this
channel. Contact wolfSSL — see the next-to-last section of this
document — to discuss what would.

## Removing the FIPS-eval channel

```
sudo apt remove --purge \
    wolfssl-fips-eval-trixie wolfssl-fips-eval-bookworm \
    libwolfssl libwolfprov libwolfpkcs11 libwolfpkcs11-p11kit \
    libgcrypt20-1.11.0-wolfssl gnutls-wolfssl wolfssl-gnutls-wrapper \
    wolfssl-fips-eval-archive-keyring
sudo rm -f /etc/apt/sources.list.d/wolfssl-fips-eval.list
sudo rm -f /etc/apt/preferences.d/wolfssl-fips-eval
sudo rm -f /etc/default/libwolfpkcs11
sudo rm -f /etc/profile.d/wolfpkcs11-env.sh
sudo rm -f /etc/profile.d/wolfpkcs11-nss-register.sh
sudo rm -rf /etc/pki/nssdb        # if you do not have other NSS apps using it
sudo apt update
```

Note that the patched system packages (`libssl3` / `libssl3t64`,
`libnss3`, `cryptsetup-bin`, `libkrb5-3`, `libk5crypto3`, `openssh-*`,
`x11vnc`, `gpg`, `gnupg`, etc.) will remain installed at their
+fipseval versions (apt does not auto-downgrade on removal of the
meta-package). To revert
those to stock Debian versions:

```
sudo apt install --reinstall \
    libssl3 libnss3 libnss3-tools cryptsetup-bin libkrb5-3 libk5crypto3 \
    openssh-client openssh-server x11vnc \
    gpg gnupg gnupg-utils gpg-agent dirmngr gpgsm
```

(Use `libssl3t64` instead of `libssl3` on Trixie.)

With the FIPS-eval sources.list removed first, this pulls the stock
Debian versions back in place.

## Getting help, support, sales, licensing, and FIPS certification

This channel is unsupported. For everything that matters in a real
deployment — support, production licensing, the actual FIPS-certified
code, an actual FIPS certificate, and Operational Environment (OE)
work to extend that certificate to your platform — talk to wolfSSL Inc.

**Contact wolfSSL:**

- Email: <facts@wolfssl.com>
- Phone: +1 425 245 8247
- Web: <https://www.wolfssl.com/contact/>
- Products: <https://www.wolfssl.com/products/>
- FIPS 140-3 information: <https://www.wolfssl.com/license/fips/>
- Licensing: <https://www.wolfssl.com/license/>
- Support & Maintenance: <https://www.wolfssl.com/products/support-and-maintenance/>

**Download the supported, licensed wolfSSL:**
<https://www.wolfssl.com/download/>

**For reference, in case you want to inspect this evaluation channel:**

- Repository status page: <https://fips-eval.wolfssl.com/>
- Repository signing key fingerprint:
  `FA9A C397 4B00 99D4 15C7 3673 19D1 F0DB 1F30 4C7B`
  (ECDSA P-384, anchored in AWS KMS).
- The bootstrap script's source is at
  <https://fips-eval.wolfssl.com/install>. Read it before piping to
  bash.
