From 30ac6ef992bf57c82cc0caf53f16619eeb5eb387 Mon Sep 17 00:00:00 2001 From: night1rider Date: Fri, 6 Mar 2026 12:09:17 -0700 Subject: [PATCH] Fips ready readme and recipes for the linux kernel and standard library package --- README.md | 76 ++++++++- conf/wolfssl-fips-ready.conf.sample | 47 ++++++ .../gnutls-enable-wolfssl-modern.inc | 6 +- .../libgcrypt-enable-wolfssl-modern.inc | 11 +- ...-enable-wolfprovider-fips-ready-legacy.inc | 20 +++ ...-enable-wolfprovider-fips-ready-modern.inc | 20 +++ ...wolfssl-enable-wolfprovider-fips-ready.inc | 28 ++++ .../wolfssl-enable-gnutls-legacy.inc | 18 +++ .../wolfssl-enable-gnutls-modern.inc | 18 +++ .../wolfssl-enable-gnutls.inc | 28 ++++ .../wolfssl-enable-libgcrypt-legacy.inc | 21 +++ .../wolfssl-enable-libgcrypt-modern.inc | 21 +++ .../wolfssl-enable-libgcrypt.inc | 28 ++++ .../fips-image-minimal/fips-image-minimal.bb | 10 +- .../wolfssl-fips-ready.bbappend | 16 ++ .../files/wolfprovidertest.sh | 2 + .../gnutls/wolfssl-gnutls-wrapper_git.bb | 3 +- .../libgcrypt/libgcrypt_%.bbappend | 2 +- .../wolfprovider/wolfssl-fips-ready.bbappend | 23 +++ recipes-wolfssl/wolfssl/wolfssl-fips-ready.bb | 78 +++++++++ .../wolfssl/wolfssl-linuxkm-fips-ready.bb | 149 ++++++++++++++++++ 21 files changed, 608 insertions(+), 17 deletions(-) create mode 100644 conf/wolfssl-fips-ready.conf.sample create mode 100644 inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-legacy.inc create mode 100644 inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-modern.inc create mode 100644 inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc create mode 100644 inc/wolfssl-fips-ready/wolfssl-enable-gnutls-legacy.inc create mode 100644 inc/wolfssl-fips-ready/wolfssl-enable-gnutls-modern.inc create mode 100644 inc/wolfssl-fips-ready/wolfssl-enable-gnutls.inc create mode 100644 inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-legacy.inc create mode 100644 inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-modern.inc create mode 100644 inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc create mode 100644 recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips-ready.bbappend create mode 100644 recipes-wolfssl/wolfprovider/wolfssl-fips-ready.bbappend create mode 100644 recipes-wolfssl/wolfssl/wolfssl-fips-ready.bb create mode 100644 recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bb diff --git a/README.md b/README.md index 4e553b0..75cc656 100644 --- a/README.md +++ b/README.md @@ -561,8 +561,8 @@ For building commercial bundles of wolfSSL products, view the instructions in this [README](recipes-wolfssl/wolfssl/commercial/README.md). -For FIPS-Ready builds, view the instructions in this -[README](recipes-wolfssl/wolfssl/fips-ready/README.md). +For FIPS-Ready builds, see the [Using wolfssl-fips-ready +Recipe](#using-wolfssl-fips-ready-recipe) section below. To gain access to these bundles, contact support@wolfssl.com to get a quote. @@ -578,9 +578,9 @@ between open-source, FIPS, and commercial versions of wolfSSL. recipes: - `wolfssl` (open-source) - Default provider from meta-networking - `wolfssl-fips` (FIPS-validated) - Provided by this layer +- `wolfssl-fips-ready` (FIPS Ready - emulates FIPS 140-3 requirements + without full validation) - Provided by this layer - Future: `wolfssl-commercial` - For commercial non-FIPS bundles -- Future: `wolfssl-fips-ready` - For FIPS Ready bundle builds (Emulates FIPS -Requirements) When you set `PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips"`, all recipes that depend on `virtual/wolfssl` will automatically use the @@ -655,6 +655,72 @@ The `conf/wolfssl-fips.conf` file is automatically ignored by git (via `.gitignore`), keeping your bundle password and license information private. Only the `.sample` template is tracked in git. +### Using wolfssl-fips-ready Recipe + +The `wolfssl-fips-ready` recipe builds wolfSSL from a publicly available +**FIPS Ready** bundle (`wolfssl-x.x.x-gplv3-fips-ready.zip`, GPLv3). FIPS +Ready emulates the FIPS 140-3 module layout and self-tests but is **not** +a certified FIPS build — use it to develop and validate your integration +before acquiring a commercial FIPS bundle. + +A companion recipe, `wolfssl-linuxkm-fips-ready`, builds the wolfSSL FIPS +kernel module (`libwolfssl.ko`) from the same bundle, suitable for loading +via initramfs or modprobe. + +For a full working integration (RPi5 + QEMU aarch64, with libgcrypt, +GnuTLS, wolfProvider, and kernel-module loading via initramfs), see the +[meta-wolfssl-linux-fips](https://github.com/wolfSSL/wolfssl-examples/tree/master/meta-wolfssl-linux-fips) +example in the `wolfssl-examples` repo. + +#### Setup Instructions + +1. **Copy the configuration template:** + ```bash + cd meta-wolfssl + cp conf/wolfssl-fips-ready.conf.sample conf/wolfssl-fips-ready.conf + ``` + +2. **Download the FIPS Ready bundle** from + [wolfSSL's download page](https://www.wolfssl.com/download/) + (`wolfssl-x.x.x-gplv3-fips-ready.zip`) and place it anywhere on disk. + +3. **Edit `conf/wolfssl-fips-ready.conf`:** + - `WOLFSSL_VERSION` - Bundle version (e.g., `"5.8.4"`) + - `WOLFSSL_SRC` - Bundle name without extension + (e.g., `"wolfssl-5.8.4-gplv3-fips-ready"`) + - `WOLFSSL_BUNDLE_FILE` - Archive filename (`${WOLFSSL_SRC}.zip`) + - `WOLFSSL_SRC_SHA` - SHA256 of the `.zip` + - `WOLFSSL_SRC_DIR` - Absolute path to the directory containing the `.zip` + - `WOLFSSL_LICENSE_MD5` - MD5 of the `COPYING` (GPLv3) file inside the zip + - `FIPS_HASH` - Leave as placeholder when using `WOLFSSL_FIPS_HASH_MODE = + "auto"` (default); set manually after first build if using `"manual"` + +4. **Include the configuration in `build/conf/local.conf`:** + ```bitbake + require /path/to/meta-wolfssl/conf/wolfssl-fips-ready.conf + ``` + + This automatically sets + `PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips-ready"`. + +5. **Build your image:** + ```bash + bitbake + ``` + + Hash extraction (auto mode) runs transparently via QEMU during the + wolfSSL build. + +#### Kernel Module (wolfssl-linuxkm-fips-ready) + +To additionally build the FIPS Ready kernel module, depend on +`wolfssl-linuxkm-fips-ready` from an image recipe (typically via an +initramfs that includes it). The same `wolfssl-fips-ready.conf` values +apply — no separate bundle is required. + +See [README-linuxkm.md](recipes-wolfssl/wolfssl/README-linuxkm.md) for +module signing and initramfs integration details. + ### Commercial Bundles from Google Cloud Storage BitBake ships with a GCS fetcher. To use it with `wolfssl-fips`: @@ -733,8 +799,6 @@ This repository contains additional README files with detailed information: ### Commercial/FIPS - [recipes-wolfssl/wolfssl/commercial/README.md](recipes-wolfssl/wolfssl/commercial/README.md) - Commercial/FIPS bundle instructions -- [recipes-wolfssl/wolfssl/fips-ready/README.md](recipes-wolfssl/wolfssl/fips-ready/README.md) - - FIPS-Ready build instructions ### OSP Integrations - [recipes-support/libgcrypt/README.md](recipes-support/libgcrypt/README.md) diff --git a/conf/wolfssl-fips-ready.conf.sample b/conf/wolfssl-fips-ready.conf.sample new file mode 100644 index 0000000..3b178de --- /dev/null +++ b/conf/wolfssl-fips-ready.conf.sample @@ -0,0 +1,47 @@ +# wolfSSL FIPS Ready Configuration +# +# This file contains wolfSSL FIPS Ready bundle settings. +# Include this file in your local.conf: +# require /path/to/meta-wolfssl/conf/wolfssl-fips-ready.conf +# +# Instructions: +# 1. Set the variables below with your FIPS Ready bundle details +# 2. Set WOLFSSL_SRC_DIR to the directory containing your .zip bundle +# 3. Build once to get the FIPS_HASH value (if using manual mode) +# 4. Set FIPS_HASH and rebuild (if using manual mode) + +# Use wolfSSL FIPS Ready as the wolfSSL provider +PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips-ready" +PREFERRED_PROVIDER_wolfssl = "wolfssl-fips-ready" + +# FIPS hash mode: "auto" (QEMU-based extraction) or "manual" (use static FIPS_HASH) +WOLFSSL_FIPS_HASH_MODE ?= "auto" + +# ============================================================================ +# FIPS Ready Bundle Configuration - EDIT THESE VALUES +# ============================================================================ + +# Bundle version +WOLFSSL_VERSION = "" + +# Bundle name (extracted directory name, without extension) +WOLFSSL_SRC = "" + +# Bundle archive filename (including .zip extension) +WOLFSSL_BUNDLE_FILE = "" + +# Bundle SHA256 checksum +WOLFSSL_SRC_SHA = "" + +# Directory containing the .zip bundle (REQUIRED - must be set) +WOLFSSL_SRC_DIR = "" + +# MD5 of the COPYING (GPLv3) license file in the bundle +WOLFSSL_LICENSE_MD5 ?= "" + +# FIPS hash (only needed for manual mode - set after first build) +FIPS_HASH = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + +# ============================================================================ +# Contact support@wolfssl.com for commercial FIPS Ready bundles +# ============================================================================ diff --git a/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc b/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc index 9ecf9c0..4e5707c 100644 --- a/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc +++ b/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc @@ -19,8 +19,8 @@ SRCREV:class-target = "${AUTOREV}" S:class-target = "${WORKDIR}/git" B:class-target = "${S}" -# Enable FIPS mode only if using wolfssl-fips provider -PACKAGECONFIG:append:class-target = "${@' fips' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') == 'wolfssl-fips' else ''}" +# Enable FIPS mode when using a wolfSSL FIPS provider +PACKAGECONFIG:append:class-target = "${@' fips' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') in ('wolfssl-fips', 'wolfssl-fips-ready') else ''}" # Configure options for wolfSSL backend EXTRA_OECONF:class-target = "\ @@ -34,7 +34,7 @@ EXTRA_OECONF:class-target = "\ --disable-dependency-tracking \ --enable-srp-authentication \ --enable-fips140-mode \ - ${@'--enable-fips140-mode' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') == 'wolfssl-fips' else ''} \ + ${@'--enable-fips140-mode' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') in ('wolfssl-fips', 'wolfssl-fips-ready') else ''} \ " TARGET_CFLAGS:append:class-target = " -DGNUTLS_WOLFSSL" diff --git a/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc b/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc index d168294..0ad2cf0 100644 --- a/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc +++ b/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc @@ -1,7 +1,10 @@ # libgcrypt with wolfSSL FIPS backend # # This include file configures libgcrypt to use wolfSSL/wolfCrypt as the crypto backend. -# Only applied when wolfssl-fips is the active provider. +# Supports both wolfssl-fips and wolfssl-fips-ready providers. + +# Select the git branch based on the active wolfSSL provider +WOLFSSL_LIBGCRYPT_BRANCH = "${@'libgcrypt-1.11.0-wolfCrypt-fips-ready' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') == 'wolfssl-fips-ready' else 'libgcrypt-1.11.0-wolfCrypt'}" # Override to use custom git repo and version - TARGET ONLY @@ -15,7 +18,7 @@ LIC_FILES_CHKSUM:class-target = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a " # Override source to use wolfSSL-enabled git repo -SRC_URI:class-target = "git://github.com/wolfSSL/libgcrypt-wolfssl.git;protocol=https;branch=libgcrypt-1.11.0-wolfCrypt \ +SRC_URI:class-target = "git://github.com/wolfSSL/libgcrypt-wolfssl.git;protocol=https;branch=${WOLFSSL_LIBGCRYPT_BRANCH} \ file://run-ptest \ file://wc_ptest-fixes.patch \ " @@ -36,6 +39,10 @@ RDEPENDS:${PN}:append:class-target = " wolfssl" # Add wolfSSL FIPS configuration flag EXTRA_OECONF:append:class-target = " --enable-wolfssl-fips --with-wolfssl=${STAGING_EXECPREFIXDIR} --disable-jent-support --disable-doc" +# Additional CFLAGS for fips-ready: +# - AES_BLOCK_SIZE is not exported by fips-ready wolfSSL headers +CFLAGS:append:class-target = "${@' -DAES_BLOCK_SIZE=WC_AES_BLOCK_SIZE' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') == 'wolfssl-fips-ready' else ''}" + # In FIPS mode, some tests are excluded - install only tests that were actually built do_install_ptest:class-target() { cd ${B}/tests diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-legacy.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-legacy.inc new file mode 100644 index 0000000..c9ec116 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-legacy.inc @@ -0,0 +1,20 @@ +# Configuration to enable wolfprovider FIPS Ready support in wolfssl +# To enable debug add `--enable-debug --enable-keylog-export` to EXTRA_OECONF + +EXTRA_OECONF += " --enable-fips=ready --enable-opensslcoexist" +TARGET_CFLAGS += " -DWOLFSSL_OLD_OID_SUM -DWOLFSSL_DH_EXTRA" + +# Use a marker file to signal we are a FIPS Ready build +WOLFSSL_ISFIPS = "1" + +# bundle missing stamp-h.in required by automake +do_configure_prepend() { + if [ ! -f ${S}/stamp-h.in ]; then + touch ${S}/stamp-h.in + fi +} + +do_install_append() { + install -d ${D}${sysconfdir}/wolfssl + echo "1" > ${D}${sysconfdir}/wolfssl/fips-enabled +} diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-modern.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-modern.inc new file mode 100644 index 0000000..637d057 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-modern.inc @@ -0,0 +1,20 @@ +# Configuration to enable wolfprovider FIPS Ready support in wolfssl +# To enable debug add `--enable-debug --enable-keylog-export` to EXTRA_OECONF + +EXTRA_OECONF += " --enable-fips=ready --enable-opensslcoexist" +TARGET_CFLAGS += " -DWOLFSSL_OLD_OID_SUM -DWOLFSSL_DH_EXTRA" + +# Use a marker file to signal we are a FIPS Ready build +WOLFSSL_ISFIPS = "1" + +# bundle missing stamp-h.in required by automake +do_configure:prepend() { + if [ ! -f ${S}/stamp-h.in ]; then + touch ${S}/stamp-h.in + fi +} + +do_install:append() { + install -d ${D}${sysconfdir}/wolfssl + echo "1" > ${D}${sysconfdir}/wolfssl/fips-enabled +} diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc new file mode 100644 index 0000000..b7393b9 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfprovider_fips_ready_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfprovider-fips-ready.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready-legacy.inc') + + bb.note("wolfssl-enable-wolfprovider-fips-ready.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfprovider_fips_ready_inc(d)} diff --git a/inc/wolfssl-fips-ready/wolfssl-enable-gnutls-legacy.inc b/inc/wolfssl-fips-ready/wolfssl-enable-gnutls-legacy.inc new file mode 100644 index 0000000..a5aa612 --- /dev/null +++ b/inc/wolfssl-fips-ready/wolfssl-enable-gnutls-legacy.inc @@ -0,0 +1,18 @@ +EXTRA_OECONF += " \ + --enable-cmac \ + --enable-aesccm \ + --enable-keygen \ + --enable-fips=ready \ +" + +TARGET_CFLAGS += " \ + -DWOLFSSL_PUBLIC_ASN \ + -DHAVE_PUBLIC_FFDHE \ + -DHAVE_FFDHE_3072 \ + -DHAVE_FFDHE_4096 \ + -DWOLFSSL_DH_EXTRA \ + -DWOLFSSL_PSS_SALT_LEN_DISCOVER \ + -DWOLFSSL_PUBLIC_MP \ + -DWOLFSSL_RSA_KEY_CHECK \ + -DNO_MD5 \ +" diff --git a/inc/wolfssl-fips-ready/wolfssl-enable-gnutls-modern.inc b/inc/wolfssl-fips-ready/wolfssl-enable-gnutls-modern.inc new file mode 100644 index 0000000..a5aa612 --- /dev/null +++ b/inc/wolfssl-fips-ready/wolfssl-enable-gnutls-modern.inc @@ -0,0 +1,18 @@ +EXTRA_OECONF += " \ + --enable-cmac \ + --enable-aesccm \ + --enable-keygen \ + --enable-fips=ready \ +" + +TARGET_CFLAGS += " \ + -DWOLFSSL_PUBLIC_ASN \ + -DHAVE_PUBLIC_FFDHE \ + -DHAVE_FFDHE_3072 \ + -DHAVE_FFDHE_4096 \ + -DWOLFSSL_DH_EXTRA \ + -DWOLFSSL_PSS_SALT_LEN_DISCOVER \ + -DWOLFSSL_PUBLIC_MP \ + -DWOLFSSL_RSA_KEY_CHECK \ + -DNO_MD5 \ +" diff --git a/inc/wolfssl-fips-ready/wolfssl-enable-gnutls.inc b/inc/wolfssl-fips-ready/wolfssl-enable-gnutls.inc new file mode 100644 index 0000000..b5af39c --- /dev/null +++ b/inc/wolfssl-fips-ready/wolfssl-enable-gnutls.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_fips_ready_gnutls_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-fips-ready/wolfssl-enable-gnutls.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips-ready/wolfssl-enable-gnutls-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips-ready/wolfssl-enable-gnutls-legacy.inc') + + bb.note("wolfssl-fips-ready/wolfssl-enable-gnutls.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_fips_ready_gnutls_inc(d)} diff --git a/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-legacy.inc b/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-legacy.inc new file mode 100644 index 0000000..98f7cc5 --- /dev/null +++ b/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-legacy.inc @@ -0,0 +1,21 @@ +# Configure wolfSSL FIPS Ready for libgcrypt integration +# +# This include file configures wolfSSL with the necessary features +# to support libgcrypt-wolfssl (libgcrypt with wolfSSL/wolfCrypt backend) +# +# Required wolfSSL features: +# --enable-fips=ready : FIPS Ready mode +# --enable-keygen : Key generation support +# +# Required compile flags: +# HAVE_AES_ECB : AES ECB mode support +# WC_RSA_DIRECT : Direct RSA operations +# WC_RSA_NO_PADDING : RSA without padding +# WOLFSSL_PUBLIC_MP : Public multi-precision math +# WOLFSSL_RSA_KEY_CHECK : RSA key validation +# ACVP_VECTOR_TESTING : ACVP test vector support +# WOLFSSL_ECDSA_SET_K : ECDSA k value setting + +EXTRA_OECONF += " --enable-fips=ready --enable-keygen " + +TARGET_CFLAGS += "-DHAVE_AES_ECB -DWC_RSA_DIRECT -DWC_RSA_NO_PADDING -DWOLFSSL_PUBLIC_MP -DWOLFSSL_RSA_KEY_CHECK -DACVP_VECTOR_TESTING -DWOLFSSL_ECDSA_SET_K" diff --git a/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-modern.inc b/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-modern.inc new file mode 100644 index 0000000..98f7cc5 --- /dev/null +++ b/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-modern.inc @@ -0,0 +1,21 @@ +# Configure wolfSSL FIPS Ready for libgcrypt integration +# +# This include file configures wolfSSL with the necessary features +# to support libgcrypt-wolfssl (libgcrypt with wolfSSL/wolfCrypt backend) +# +# Required wolfSSL features: +# --enable-fips=ready : FIPS Ready mode +# --enable-keygen : Key generation support +# +# Required compile flags: +# HAVE_AES_ECB : AES ECB mode support +# WC_RSA_DIRECT : Direct RSA operations +# WC_RSA_NO_PADDING : RSA without padding +# WOLFSSL_PUBLIC_MP : Public multi-precision math +# WOLFSSL_RSA_KEY_CHECK : RSA key validation +# ACVP_VECTOR_TESTING : ACVP test vector support +# WOLFSSL_ECDSA_SET_K : ECDSA k value setting + +EXTRA_OECONF += " --enable-fips=ready --enable-keygen " + +TARGET_CFLAGS += "-DHAVE_AES_ECB -DWC_RSA_DIRECT -DWC_RSA_NO_PADDING -DWOLFSSL_PUBLIC_MP -DWOLFSSL_RSA_KEY_CHECK -DACVP_VECTOR_TESTING -DWOLFSSL_ECDSA_SET_K" diff --git a/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc b/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc new file mode 100644 index 0000000..0488d8c --- /dev/null +++ b/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_fips_ready_libgcrypt_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt-legacy.inc') + + bb.note("wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_fips_ready_libgcrypt_inc(d)} diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-image-minimal.bb b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-image-minimal.bb index e58cb50..3ea4d33 100644 --- a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-image-minimal.bb +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-image-minimal.bb @@ -9,11 +9,13 @@ python __anonymous() { virtual_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or '' wolfssl_provider = d.getVar('PREFERRED_PROVIDER_wolfssl') or '' - if virtual_provider != 'wolfssl-fips': - bb.fatal("fips-image-minimal requires PREFERRED_PROVIDER_virtual/wolfssl = 'wolfssl-fips'. Current value: '%s'. Please set 'require conf/wolfssl-fips.conf' in local.conf" % virtual_provider) + valid_fips_providers = ('wolfssl-fips', 'wolfssl-fips-ready') - if wolfssl_provider != 'wolfssl-fips': - bb.fatal("fips-image-minimal requires PREFERRED_PROVIDER_wolfssl = 'wolfssl-fips'. Current value: '%s'. Please set 'require conf/wolfssl-fips.conf' in local.conf" % wolfssl_provider) + if virtual_provider not in valid_fips_providers: + bb.fatal("fips-image-minimal requires PREFERRED_PROVIDER_virtual/wolfssl to be one of %s. Current value: '%s'. Please set 'require conf/wolfssl-fips.conf' or 'require conf/wolfssl-fips-ready.conf' in local.conf" % (valid_fips_providers, virtual_provider)) + + if wolfssl_provider not in valid_fips_providers: + bb.fatal("fips-image-minimal requires PREFERRED_PROVIDER_wolfssl to be one of %s. Current value: '%s'. Please set 'require conf/wolfssl-fips.conf' or 'require conf/wolfssl-fips-ready.conf' in local.conf" % (valid_fips_providers, wolfssl_provider)) wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfssl libgcrypt libgcrypt-ptest gnutls gnutls-dev gnutls-bin gnutls-fips wolfssl-gnutls-wrapper wolfssl-gnutls-wrapper-dev wolfprovider openssl openssl-bin openssh wolfprovidercmd wolfproviderenv pkgconfig ptest-runner bash make glibc-utils binutils ldd curl librelp-ptest') } diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips-ready.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips-ready.bbappend new file mode 100644 index 0000000..846b32b --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips-ready.bbappend @@ -0,0 +1,16 @@ +# Configure wolfSSL FIPS Ready for fips-image-minimal +# +# This bbappend configures wolfSSL FIPS Ready with libgcrypt, gnutls, and wolfProvider support + +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips-ready/wolfssl-enable-libgcrypt.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips-ready/wolfssl-enable-gnutls.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc + +# Fix for bundle missing stamp-h.in required by automake +do_configure_create_stamph() { + if [ ! -f ${S}/stamp-h.in ]; then + touch ${S}/stamp-h.in + fi +} + +addtask do_configure_create_stamph after do_patch before do_configure diff --git a/recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.sh b/recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.sh index 89be208..3387288 100644 --- a/recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.sh +++ b/recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.sh @@ -18,6 +18,8 @@ echo "==========================================" if [ -f /usr/bin/unit.test ]; then # Use a temp directory for the tests because they expect .libs to be present mkdir -p /tmp/.libs + # Symlink the installed provider library so the test can find it + ln -sf /usr/lib/libwolfprov.so /tmp/.libs/libwolfprov.so # Verify certificates are installed (CERTS_DIR is compiled to point here) echo "Verifying test certificates..." diff --git a/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb b/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb index 34c7267..3c767f1 100644 --- a/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb +++ b/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb @@ -33,7 +33,8 @@ EXTRA_OEMAKE = " \ " python __anonymous() { - wolfssl_varAppendNonOverride(d, 'CFLAGS', ' -I${STAGING_INCDIR} -DENABLE_WOLFSSL -fPIC') + fips_ready_cflags = ' -DAES_BLOCK_SIZE=WC_AES_BLOCK_SIZE' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') == 'wolfssl-fips-ready' else '' + wolfssl_varAppendNonOverride(d, 'CFLAGS', ' -I${STAGING_INCDIR} -DENABLE_WOLFSSL -fPIC' + fips_ready_cflags) wolfssl_varAppendNonOverride(d, 'LDFLAGS', ' -L${STAGING_LIBDIR} -Wl,-rpath,${libdir} -Wl,-rpath,${WOLFSSL_GNUTLS_PREFIX}/lib -Wl,--no-as-needed -Wl,-z,now') } diff --git a/recipes-support/libgcrypt/libgcrypt_%.bbappend b/recipes-support/libgcrypt/libgcrypt_%.bbappend index 7c7b53f..9269578 100644 --- a/recipes-support/libgcrypt/libgcrypt_%.bbappend +++ b/recipes-support/libgcrypt/libgcrypt_%.bbappend @@ -17,7 +17,7 @@ python __anonymous() { d, feature_name='libgcrypt', inc_file='inc/libgcrypt/libgcrypt-enable-wolfssl.inc', - allowed_providers=['wolfssl-fips'] # Only FIPS supported for now + allowed_providers=['wolfssl-fips', 'wolfssl-fips-ready'] ) } diff --git a/recipes-wolfssl/wolfprovider/wolfssl-fips-ready.bbappend b/recipes-wolfssl/wolfprovider/wolfssl-fips-ready.bbappend new file mode 100644 index 0000000..0521704 --- /dev/null +++ b/recipes-wolfssl/wolfprovider/wolfssl-fips-ready.bbappend @@ -0,0 +1,23 @@ +# Configure wolfSSL FIPS Ready to support wolfProvider +# +# This bbappend automatically configures wolfssl-fips-ready with the features +# needed by wolfprovider when 'wolfprovider' is in WOLFSSL_FEATURES or IMAGE_INSTALL +# +# Usage in local.conf: +# require conf/wolfssl-fips-ready.conf +# IMAGE_INSTALL += "wolfprovider" + +inherit wolfssl-osp-support + +python __anonymous() { + # wolfProvider FIPS Ready mode + wolfssl_conditional_include_ext( + d, + enable_for='wolfprovider', + inc_file='inc/wolfprovider/wolfssl-enable-wolfprovider-fips-ready.inc', + allowed_providers=['wolfssl-fips-ready'] + ) +} + +# Disable package check since this is configuration for wolfssl itself +deltask do_wolfssl_check_package diff --git a/recipes-wolfssl/wolfssl/wolfssl-fips-ready.bb b/recipes-wolfssl/wolfssl/wolfssl-fips-ready.bb new file mode 100644 index 0000000..b8d5cc1 --- /dev/null +++ b/recipes-wolfssl/wolfssl/wolfssl-fips-ready.bb @@ -0,0 +1,78 @@ +SUMMARY = "wolfSSL FIPS Ready Cryptography" +DESCRIPTION = "wolfSSL is a lightweight SSL/TLS library with FIPS Ready cryptography module. This recipe provides the FIPS Ready version of wolfSSL." + +# Default to a placeholder; users should set WOLFSSL_VERSION to their bundle version +WOLFSSL_VERSION ?= "0.0.0" +PV = "${WOLFSSL_VERSION}" +HOMEPAGE = "https://www.wolfssl.com/products/wolfssl-fips/" +BUGTRACKER = "https://github.com/wolfssl/wolfssl/issues" +SECTION = "libs" + +LICENSE = "GPL-3.0-only" +LIC_FILES_CHKSUM = "file://COPYING;md5=${WOLFSSL_LICENSE_MD5}" + +DEPENDS += "util-linux-native unzip-native" + +# This recipe provides: +# - wolfssl-fips-ready (automatic from recipe name) +# - virtual/wolfssl (build-time interface for switching implementations) +# At runtime, the wolfssl-fips-ready package provides wolfssl to satisfy package dependencies +PROVIDES += "wolfssl-fips-ready virtual/wolfssl" + +inherit autotools pkgconfig wolfssl-helper wolfssl-commercial wolfssl-fips-helper wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppend(d, 'RPROVIDES', '${PN}', ' wolfssl') +} + +# Lower preference so regular wolfssl is default +# Users must explicitly set PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips-ready" +DEFAULT_PREFERENCE = "-1" + +# FIPS Ready bundle source - user must set these in local.conf: +# WOLFSSL_VERSION = "x.x.x" +# WOLFSSL_SRC = "wolfssl-x.x.x-commercial-fips-ready" +# WOLFSSL_SRC_SHA = "sha256sum of bundle" +# WOLFSSL_SRC_DIR = "/path/to/directory/containing/zip" +# WOLFSSL_BUNDLE_FILE = "wolfssl-x.x.x-commercial-fips-ready.zip" +# WOLFSSL_LICENSE_MD5 = "md5sum of COPYING file" +# FIPS_HASH = "hash value after first build" (for FIPS validation, if using manual mode) + +# Commercial bundle configuration +# WOLFSSL_SRC_DIR must be set in local.conf to the directory containing the .zip bundle +# Optionally set WOLFSSL_SRC_DIRECTORY to point directly to already-extracted source +WOLFSSL_SRC_DIR ?= "" +WOLFSSL_SRC_DIRECTORY ?= "" +WOLFSSL_BUNDLE_FILE ?= "" + +# Map to commercial class variables +COMMERCIAL_BUNDLE_DIR = "${WOLFSSL_SRC_DIR}" +COMMERCIAL_BUNDLE_NAME = "${WOLFSSL_SRC}" +COMMERCIAL_BUNDLE_FILE = "${WOLFSSL_BUNDLE_FILE}" +COMMERCIAL_BUNDLE_PASS = "" +COMMERCIAL_BUNDLE_SHA = "${WOLFSSL_SRC_SHA}" +COMMERCIAL_BUNDLE_TARGET = "${WORKDIR}" +COMMERCIAL_BUNDLE_GCS_URI = "" +COMMERCIAL_BUNDLE_GCS_TOOL = "" +COMMERCIAL_BUNDLE_SRC_DIR = "${WOLFSSL_SRC_DIRECTORY}" + +# Use helper functions from wolfssl-commercial.bbclass for conditional configuration +SRC_URI = "${@get_commercial_src_uri(d)}" +S = "${@get_commercial_source_dir(d)}" + +# Skip the package check for wolfssl-fips-ready itself (it's the base library) +deltask do_wolfssl_check_package + +# Enable native/nativesdk variants when FIPS Ready is configured +BBCLASSEXTEND = "${@'native nativesdk' if (d.getVar('WOLFSSL_SRC') or '').strip() else ''}" + +# FIPS Ready configuration +# Note: FIPS hash is handled by wolfssl-fips-helper.bbclass +TARGET_CFLAGS += "-DFP_MAX_BITS=16384" +EXTRA_OECONF += " \ + --enable-fips=ready \ + --enable-reproducible-build \ + --enable-smallstack \ + --enable-sp-math-all \ + --disable-sp \ +" diff --git a/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bb b/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bb new file mode 100644 index 0000000..08e4333 --- /dev/null +++ b/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips-ready.bb @@ -0,0 +1,149 @@ +SUMMARY = "wolfSSL FIPS Ready Linux kernel module (libwolfssl.ko)" +DESCRIPTION = "Out-of-tree Linux kernel module for wolfSSL/wolfCrypt with FIPS Ready cryptography" + +# FIPS Ready bundles ship under GPL-3.0 +LICENSE = "GPL-3.0-only" +LIC_FILES_CHKSUM = "file://COPYING;md5=${WOLFSSL_LICENSE_MD5}" + +DEPENDS += "virtual/kernel openssl-native unzip-native" + +# This recipe provides: +# - wolfssl-linuxkm-fips-ready (automatic from recipe name) +# - virtual/wolfssl-linuxkm (build-time interface for switching implementations) +# At runtime, the package provides wolfssl-linuxkm to satisfy package dependencies +PROVIDES += "wolfssl-linuxkm-fips-ready virtual/wolfssl-linuxkm" + +# Build for target kernel +inherit module-base wolfssl-helper autotools wolfssl-commercial wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppend(d, 'RPROVIDES', '${PN}', ' wolfssl-linuxkm') + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${nonarch_base_libdir}/modules/${KERNEL_VERSION}/extra/libwolfssl.ko') + wolfssl_varAppend(d, 'FILES', '${PN}-dbg', ' ${nonarch_base_libdir}/modules/${KERNEL_VERSION}/extra/.debug') + wolfssl_varAppend(d, 'INSANE_SKIP', '${PN}', ' buildpaths debug-files') + wolfssl_varAppend(d, 'INSANE_SKIP', '${PN}-dbg', ' buildpaths') +} + +# Lower preference so regular wolfssl-linuxkm is default +# Users must explicitly set PREFERRED_PROVIDER_virtual/wolfssl-linuxkm = "wolfssl-linuxkm-fips-ready" +DEFAULT_PREFERENCE = "-1" + +# FIPS Ready bundle source - user must set these in local.conf: +# WOLFSSL_VERSION = "x.x.x" +# WOLFSSL_SRC = "wolfssl-x.x.x-commercial-fips-ready" +# WOLFSSL_SRC_SHA = "sha256sum of bundle" +# WOLFSSL_SRC_DIR = "/path/to/directory/containing/zip" +# WOLFSSL_BUNDLE_FILE = "wolfssl-x.x.x-commercial-fips-ready.zip" +# WOLFSSL_LICENSE_MD5 = "md5sum of COPYING file" +# FIPS_HASH_LINUXKM = "hash value after first build" (if using manual mode) + +# Commercial bundle configuration +WOLFSSL_SRC_DIR ?= "" +WOLFSSL_SRC_DIRECTORY ?= "" +WOLFSSL_BUNDLE_FILE ?= "" + +# Map to commercial class variables (no password for FIPS Ready zip bundles) +COMMERCIAL_BUNDLE_DIR = "${WOLFSSL_SRC_DIR}" +COMMERCIAL_BUNDLE_NAME = "${WOLFSSL_SRC}" +COMMERCIAL_BUNDLE_FILE = "${WOLFSSL_BUNDLE_FILE}" +COMMERCIAL_BUNDLE_PASS = "" +COMMERCIAL_BUNDLE_SHA = "${WOLFSSL_SRC_SHA}" +COMMERCIAL_BUNDLE_TARGET = "${WORKDIR}" +COMMERCIAL_BUNDLE_GCS_URI = "" +COMMERCIAL_BUNDLE_GCS_TOOL = "" +COMMERCIAL_BUNDLE_SRC_DIR = "${WOLFSSL_SRC_DIRECTORY}" + +# Kernel module FIPS hash configuration +# WOLFSSL_FIPS_HASH_MODE_LINUXKM controls whether to use manual hash or auto-generation +# - "manual": Use FIPS_HASH_LINUXKM from config +# - "auto": Let kernel module build system handle it (extract from error on first build) +WOLFSSL_FIPS_HASH_MODE_LINUXKM ?= "manual" +FIPS_HASH_LINUXKM ?= "" + +# Skip the package check for wolfssl itself (it's the base library) +deltask do_wolfssl_check_package + +# Fetch the bundle (or README placeholder if not configured) +SRC_URI = "${@get_commercial_src_uri(d)}" + +# After extraction, S points to the top directory of the bundle +S = "${@get_commercial_source_dir(d)}" +B = "${S}" + +# Build depends on the kernel +DEPENDS += "binutils-cross-${TARGET_ARCH}" + +# Make sure we package the .ko +PACKAGES = "${PN} ${PN}-dbg" + +# Tie package arch to machine +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# Set kernel arch to target arch +KERNEL_ARCH = "${@map_kernel_arch(d.getVar('TARGET_ARCH'), d)}" +EXTRA_OEMAKE += "OBJDUMP=${TARGET_PREFIX}objdump" +EXTRA_OEMAKE += "NM=${TARGET_PREFIX}nm" +EXTRA_OEMAKE += "READELF=${TARGET_PREFIX}readelf" +EXTRA_OEMAKE += "OBJCOPY=${TARGET_PREFIX}objcopy" + +# Configure params — FIPS Ready mode +EXTRA_OECONF = " \ + --enable-linuxkm \ + --enable-fips=ready \ + --with-linux-source=${STAGING_KERNEL_BUILDDIR} \ + --enable-crypttests \ + --enable-smallstack \ + --enable-sp-math-all \ + --disable-sp \ +" + +python __anonymous() { + # Pass FIPS hash as compile-time define (same approach as userspace wolfssl-fips-ready) + if d.getVar('WOLFSSL_FIPS_HASH_MODE_LINUXKM') == 'manual' and d.getVar('FIPS_HASH_LINUXKM'): + hash_val = d.getVar('FIPS_HASH_LINUXKM') + wolfssl_varAppendNonOverride(d, 'EXTRA_OEMAKE', ' KERNEL_EXTRA_CFLAGS="-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=' + hash_val + '"') +} + +do_configure_fips_hash_check() { + if [ "${WOLFSSL_FIPS_HASH_MODE_LINUXKM}" = "manual" ]; then + if [ -n "${FIPS_HASH_LINUXKM}" ]; then + bbnote "Kernel module manual FIPS mode - hash: ${FIPS_HASH_LINUXKM}" + else + bbwarn "WOLFSSL_FIPS_HASH_MODE_LINUXKM=manual but FIPS_HASH_LINUXKM is not set" + fi + else + bbnote "Kernel module auto FIPS mode - will use 'make module-with-matching-fips-hash-no-sign' to compute and embed the correct hash" + fi +} + +addtask do_configure_fips_hash_check after do_patch before do_configure + +do_compile() { + if [ "${WOLFSSL_FIPS_HASH_MODE_LINUXKM}" = "auto" ]; then + bbnote "Auto FIPS hash mode: running 'make module-with-matching-fips-hash-no-sign'" + bbnote "This will build the .ko, compute the FIPS hash, and patch it in-place." + + # The linuxkm Makefile's libwolfssl-user-build step builds a host-native + # userspace wolfSSL library (it unsets CC/LD itself, uses host cc), but + # Yocto's cross-compilation LDFLAGS (containing --sysroot=...) and CPPFLAGS + # would leak through and break the host build. Unset them here — the kernel + # module build itself goes through 'make -C $(KERNEL_ROOT)' which is + # self-contained. + unset LDFLAGS + unset CPPFLAGS + + # Run from top-level source dir so that the autotools-generated Makefile + # exports KERNEL_ROOT, KERNEL_ARCH, and other configure-derived variables + # to the linuxkm/ sub-make. Pass HOSTCC so the patched linuxkm Makefile + # uses the correct host-native compiler instead of bare 'cc'. + oe_runmake module-with-matching-fips-hash-no-sign HOSTCC=$(which ${BUILD_CC}) + else + oe_runmake + fi +} + +do_install() { + install -d ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/extra + install -m 0644 ${S}/linuxkm/libwolfssl.ko \ + ${D}${nonarch_base_libdir}/modules/${KERNEL_VERSION}/extra/ +}