diff --git a/.gitignore b/.gitignore index 2c9d045f..87eafc86 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ recipes-wolfssl/wolfssl/commercial/files/wolfssl* *.7z *.zip + +# User-specific FIPS configuration (created from conf/wolfssl-fips.conf.sample) +conf/wolfssl-fips.conf diff --git a/README.md b/README.md index 37f29ba2..45cdbebd 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,10 @@ This layer currently provides recipes for the following wolfSSL products: - [wolfCrypt-py A Python Wrapper for the wolfCrypt API](https://github.com/wolfSSL/wolfcrypt-py) - [wolfPKCS11 A PKCS#11 implementation using wolfSSL](https://github.com/wolfSSL/wolfpkcs11) +This layer also provides Open Source Package (OSP) integrations: + +- [libgcrypt with wolfSSL backend](recipes-support/libgcrypt/README.md) - Use wolfSSL FIPS as the crypto backend for libgcrypt + These recipes have been tested using these versions of yocto: - Scarthgap (v5.0) @@ -51,15 +55,34 @@ Clone meta-wolfssl onto your machine: git clone https://github.com/wolfSSL/meta-wolfssl.git ``` +### Layer Dependencies + +**For FIPS Builds Only:** If you plan to use the `wolfssl-fips` recipe, you must also include the `meta-openembedded/meta-oe` layer, which provides `p7zip-native` for extracting commercial FIPS bundles. Non-FIPS builds do not require this dependency. + +``` +git clone https://github.com/openembedded/meta-openembedded.git +``` + After installing your build's Yocto/OpenEmbedded components: 1. Insert the 'meta-wolfssl' layer in `build/conf/bblayers.conf` location into your build's bblayers.conf file, in the BBLAYERS section: + **For non-FIPS builds:** + ``` + BBLAYERS ?= " \ + ... + /path/to/yocto/poky/meta-wolfssl \ + ... + " + ``` + + **For FIPS builds (includes meta-oe):** ``` BBLAYERS ?= " \ ... + /path/to/meta-openembedded/meta-oe \ /path/to/yocto/poky/meta-wolfssl \ ... " @@ -119,6 +142,105 @@ After installing your build's Yocto/OpenEmbedded components: build, which could increase the size of the build and turn on uneeded features. +Using WOLFSSL_FEATURES Variable +-------------------------------- + +As an alternative to `IMAGE_INSTALL`, you can use the `WOLFSSL_FEATURES` variable +in your `local.conf` to enable specific wolfSSL features. This ensures wolfSSL +packages are configured correctly but doesn't automatically add them to every +image recipe: + +``` +WOLFSSL_FEATURES:append = " wolfclu wolfssh wolfmqtt wolftpm" +``` + +Add this to your `build/conf/local.conf` file. + +When you specify a package in `WOLFSSL_FEATURES` or `IMAGE_INSTALL`, the layer +automatically configures wolfSSL with the necessary `--enable-*` options for that +package. The key difference: +- `IMAGE_INSTALL`: Adds packages to your image AND configures wolfSSL +- `WOLFSSL_FEATURES`: Only configures wolfSSL, packages must be added separately + +**Method 3: Manual .bbappend (Advanced)** + +If you don't want to use `IMAGE_INSTALL` or `WOLFSSL_FEATURES`, you can manually +create a `wolfssl_%.bbappend` file in your own layer that includes the necessary +`.inc` files for the features you need. For example, if you need wolfclu and wolfssh +support, create a `wolfssl_%.bbappend` file: + +``` +# In your-layer/recipes-wolfssl/wolfssl/wolfssl_%.bbappend +require inc/wolfclu/wolfssl-enable-wolfclu.inc +require inc/wolfssh/wolfssl-enable-wolfssh.inc +``` + +Or point to the meta-wolfssl layer directly: + +``` +require ${COREBASE}/../meta-wolfssl/inc/wolfclu/wolfssl-enable-wolfclu.inc +require ${COREBASE}/../meta-wolfssl/inc/wolfssh/wolfssl-enable-wolfssh.inc +``` + +**Important**: When using this method, you must also create `.bbappend` files for each +package you want to use. A convenience `.inc` file is provided to disable the feature +check. For example: + +``` +# In your-layer/recipes-wolfssl/wolfclu/wolfclu_%.bbappend +require inc/wolfssl-manual-config.inc + +# In your-layer/recipes-wolfssl/wolfssh/wolfssh_%.bbappend +require inc/wolfssl-manual-config.inc +``` + +Or point to the meta-wolfssl layer directly: + +``` +require ${COREBASE}/../meta-wolfssl/inc/wolfssl-manual-config.inc +``` + +Commercial Bundles from Google Cloud Storage +-------------------------------------------- + +BitBake ships with a GCS fetcher. To use it with `wolfssl-fips`: + +1. Upload the commercial tarball to a private bucket (for example + `gs://wolfssl-commercial-artifacts/releases/5.8.2/wolfssl-5.8.2-commercial-fips-linux.tar.gz`). +2. Set the commercial variables plus the GCS URI in `conf/local.conf` (or your + distro .conf): + + ``` + WOLFSSL_SRC = "wolfssl-5.8.2-commercial-fips-linux" + WOLFSSL_SRC_SHA = "" + WOLFSSL_BUNDLE_FILE = "${WOLFSSL_SRC}.tar.gz" + WOLFSSL_BUNDLE_GCS_URI = "gs://wolfssl-commercial-artifacts/releases/5.8.2/${WOLFSSL_BUNDLE_FILE}" + ``` + +3. The recipe pulls in `${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-commercial-gcs.inc`, which: + - Points `SRC_URI` at the `gs://` location (with the checksum); + - Disables the custom 7zip extraction task; + - Lets BitBake handle download and unpack for tarballs. + +4. Host requirements for the BitBake GCS fetcher: + - Install the Google Cloud SDK (which provides the GCS client libraries) by following https://docs.cloud.google.com/sdk/docs/install. + - Ensure the Python `google` namespace is present; on RPM-based installs the `google-cloud-cli` package does **not** ship the Python libraries, so also install `python3-google-cloud-core` (or `pip install --user google-cloud-core`) before running BitBake. + - For private buckets, authenticate with `gcloud auth application-default login` or set `GOOGLE_APPLICATION_CREDENTIALS` to a service-account JSON before running BitBake. + +For password-protected `.7z` bundles, keep `WOLFSSL_BUNDLE_FILE` unset (the +class will assume `.7z`), provide `COMMERCIAL_BUNDLE_PASS`, and place the +archive where `COMMERCIAL_BUNDLE_DIR` points (or supply a `gs://…` URI plus +checksum). In that case the 7zip helper remains enabled and requires +`p7zip-native`. + +The `inc/wolfssl-manual-config.inc` file can be used for any wolfSSL package. It +disables the automatic validation check that looks for `IMAGE_INSTALL` or +`WOLFSSL_FEATURES`. Remember to also include the corresponding `wolfssl-enable-*.inc` +file(s) in your `wolfssl_%.bbappend` to configure wolfSSL with the necessary features. + +This gives you complete control over which wolfSSL features are enabled without +relying on automatic detection. + Once your image has been built, the default location for the wolfSSL library on your machine will be in the "/usr/lib" directory. @@ -244,6 +366,140 @@ When your image builds, these will be installed to the '/usr/bin' system directory. When inside your executing image, you can run them from the terminal. +wolfSSL Demo Images +------------------- + +This layer includes several pre-configured demo images for testing various wolfSSL +sub-packages. Each image is a minimal Yocto image based on `core-image-minimal` with +specific wolfSSL components installed and configured. + +For detailed information about each demo image, including structure, configuration +methods, and testing instructions, see [recipes-core/README.md](recipes-core/README.md). + +### Enabling Demo Images + +To enable a demo image, add the following to your `conf/local.conf`: + +``` +WOLFSSL_DEMOS = "wolfssl-image-minimal " +``` + +**Important**: All demo images (except `wolfssl-image-minimal` itself) require +`wolfssl-image-minimal` to be included in `WOLFSSL_DEMOS` because they inherit from it. + +You can then build the image with: + +``` +$ bitbake +``` + +### Available Demo Images + +1. **wolfssl-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal"` + - Provides: wolfSSL library, wolfcrypttest, wolfcryptbenchmark + - Description: Base minimal image with wolfSSL and core crypto testing tools + +2. **wolfclu-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal wolfclu-image-minimal"` + - Provides: Everything from `wolfssl-image-minimal` + wolfCLU + - Description: Demonstrates wolfCLU command-line tools + +3. **wolftpm-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal wolftpm-image-minimal"` + - Provides: Everything from `wolfssl-image-minimal` + wolfTPM + TPM 2.0 tools + - Requirements: Add to `local.conf`: + ``` + DISTRO_FEATURES += "security tpm tpm2" + MACHINE_FEATURES += "tpm tpm2" + KERNEL_FEATURES += "features/tpm/tpm.scc" + ``` + - Testing: Use `test-wolftpm.sh` script in the image directory to run with swtpm. + Once booted, run `/usr/bin/wolftpm-wrap-test` + +4. **wolfssl-py-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal wolfssl-py-image-minimal"` + - Provides: Everything from `wolfssl-image-minimal` + Python bindings (wolfssl-py, + wolfcrypt-py, wolf-py-tests) + Python 3 with cffi and pytest + - Note: For all wolfssl-py tests to pass, you will need to configure networking in + the QEMU environment (DNS resolvers, network connectivity, etc.) + +5. **wolfprovider-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal wolfprovider-image-minimal"` + - Provides: Everything from `wolfssl-image-minimal` + wolfProvider + + wolfprovidertest + OpenSSL 3.x + - Description: Demonstrates wolfProvider as an OpenSSL 3.x provider + +6. **wolfssl-combined-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal wolfssl-combined-image-minimal"` + - Provides: Everything from `wolfssl-image-minimal` + wolfssh + wolfmqtt + + wolfProvider + wolftpm + TPM 2.0 tools + - Requirements: Add to `local.conf`: + ``` + DISTRO_FEATURES += "security tpm tpm2" + MACHINE_FEATURES += "tpm tpm2" + KERNEL_FEATURES += "features/tpm/tpm.scc" + ``` + - Description: Comprehensive image combining multiple wolfSSL sub-packages + +7. **wolfclu-combined-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal wolfclu-combined-image-minimal"` + - Provides: Everything from `wolfssl-image-minimal` + wolfCLU + Python bindings + (wolfssl-py, wolfcrypt-py, wolf-py-tests) + Python 3 with cffi and pytest + + DNS configuration + ca-certificates + - Description: Combines wolfCLU with Python bindings and networking support + +8. **libgcrypt-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "wolfssl-image-minimal libgcrypt-image-minimal"` + - Requires: `require /path/to/meta-wolfssl/conf/wolfssl-fips.conf` (wolfSSL FIPS bundle) + - Provides: Everything from `wolfssl-image-minimal` + libgcrypt with wolfSSL backend + + libgcrypt-ptest + ptest-runner + - Description: Demonstrates libgcrypt using wolfSSL FIPS as the crypto backend. Enables + FIPS-validated cryptography for all applications using libgcrypt (GnuPG, systemd, etc.) + - Testing: Run `ptest-runner libgcrypt` in QEMU to verify the wolfSSL backend + - More Info: See [recipes-support/libgcrypt/README.md](recipes-support/libgcrypt/README.md) + and [recipes-core/images/libgcrypt-image-minimal/README.md](recipes-core/images/libgcrypt-image-minimal/README.md) + +### Building Multiple Demo Images + +You can enable multiple demo images by space-separating them. Remember to always +include `wolfssl-image-minimal` first: + +``` +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfclu-image-minimal wolfssl-py-image-minimal" +``` + +### Standalone Demo Images + +These images do not require `wolfssl-image-minimal` in WOLFSSL_DEMOS: + +1. **fips-image-minimal** + - Enable with: `WOLFSSL_DEMOS = "fips-image-minimal"` + - Requires: `require /path/to/meta-wolfssl/conf/wolfssl-fips.conf` (wolfSSL FIPS bundle) + - Provides: libgcrypt with wolfSSL FIPS backend + gnutls with wolfSSL FIPS backend + + wolfProvider in replace-default mode + OpenSSL 3.x + test utilities + - Description: Comprehensive FIPS image demonstrating wolfSSL FIPS integration with + libgcrypt, gnutls, and wolfProvider. All crypto operations use wolfSSL FIPS as the backend. + +Then build each image individually: + +``` +$ bitbake wolfssl-image-minimal +$ bitbake wolfclu-image-minimal +$ bitbake wolfssl-py-image-minimal +``` + +### Running Demo Images + +After building, run images with QEMU using: + +``` +$ runqemu +``` + +For images with special requirements (like `wolftpm-image-minimal`), use the provided +test scripts in the image directory. + Excluding Recipe from Build --------------------------- @@ -440,6 +696,84 @@ For building FIPS and/or commercial bundles of wolfSSL products view the instruc To gain access to these bundles contact support@wolfssl.com to get a qoute. +### Using wolfssl-fips Recipe + +The layer provides a `wolfssl-fips` recipe that uses BitBake's `virtual/wolfssl` provider mechanism, allowing you to seamlessly swap between open-source, FIPS, and commercial versions of wolfSSL. + +#### What is virtual/wolfssl? + +`virtual/wolfssl` is an abstract interface that can be provided by multiple recipes: +- `wolfssl` (open-source) - Default provider from meta-networking +- `wolfssl-fips` (FIPS-validated) - Provided by this layer +- Future: `wolfssl-commercial` - For commercial non-FIPS bundles + +When you set `PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips"`, all recipes that depend on `virtual/wolfssl` will automatically use the FIPS-validated version instead of the standard open-source version. + +#### Setup Instructions + +1. **Copy the configuration template:** + ```bash + cd meta-wolfssl + cp conf/wolfssl-fips.conf.sample conf/wolfssl-fips.conf + ``` + +2. **Edit `conf/wolfssl-fips.conf` with your FIPS bundle details:** + - `WOLFSSL_SRC_DIR` - Directory containing your commercial archive + - `WOLFSSL_SRC` - Logical bundle name (without extension) + - `WOLFSSL_BUNDLE_FILE` - Optional, set to `${WOLFSSL_SRC}.tar.gz` for tarballs + - `WOLFSSL_SRC_PASS` - Bundle password (only needed for `.7z`) + - `WOLFSSL_LICENSE` - License file name (typically in bundle) + - `WOLFSSL_LICENSE_MD5` - MD5 checksum of license file + - `FIPS_HASH` - FIPS integrity hash (auto-generated on first build if using auto mode) + - `WOLFSSL_FIPS_HASH_MODE` - `"auto"` (QEMU-based) or `"manual"` (static hash) + +3. **Include the configuration in your `build/conf/local.conf`:** + ```bitbake + # Use absolute path to the config file + require /path/to/meta-wolfssl/conf/wolfssl-fips.conf + ``` + + The configuration will automatically: + - Set `PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips"` + - Set `PREFERRED_PROVIDER_wolfssl = "wolfssl-fips"` + - Configure FIPS bundle extraction and validation + +4. **Build your image or package:** + ```bash + bitbake + ``` + +#### FIPS Hash Modes + +The layer supports two modes for FIPS integrity hash generation: + +**Auto Mode (Recommended):** +```bitbake +WOLFSSL_FIPS_HASH_MODE = "auto" +``` +- Automatically extracts hash by building with placeholder, running test binary via QEMU +- Works for all architectures +- No manual hash management needed + +**Manual Mode:** +```bitbake +WOLFSSL_FIPS_HASH_MODE = "manual" +FIPS_HASH = "YOUR_HASH_HERE" +``` +- Uses static hash value from config +- Requires you to obtain and set the hash manually + +#### File Security + +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. + +#### Benefits + +- **Seamless switching:** Change provider in one place, all recipes adapt +- **No recipe modifications:** Existing recipes work unchanged +- **Automatic configuration:** FIPS features and hash extraction handled automatically +- **Security:** Credentials stay local and private + Maintenance ----------- diff --git a/classes/wolfssl-commercial.bbclass b/classes/wolfssl-commercial.bbclass new file mode 100644 index 00000000..eea4a6e9 --- /dev/null +++ b/classes/wolfssl-commercial.bbclass @@ -0,0 +1,327 @@ +# wolfssl-commercial.bbclass +# +# This class provides helper functions for commercial wolfSSL bundles +# including password-protected 7z extraction and autogen disabling +# +# Usage in recipe: +# inherit wolfssl-commercial +# +# Required variables: +# COMMERCIAL_BUNDLE_DIR - Directory containing the commercial archive +# COMMERCIAL_BUNDLE_NAME - Logical bundle name (used as extracted directory) +# COMMERCIAL_BUNDLE_PASS - Password for .7z bundles (optional for .tar.gz) +# COMMERCIAL_BUNDLE_SHA - SHA256 checksum of the bundle +# COMMERCIAL_BUNDLE_TARGET - Target directory for extraction (usually WORKDIR) +# +# Example: +# COMMERCIAL_BUNDLE_DIR = "${@os.path.dirname(d.getVar('FILE'))}/commercial/files" +# COMMERCIAL_BUNDLE_NAME = "${WOLFSSL_SRC}" +# COMMERCIAL_BUNDLE_PASS = "${WOLFSSL_SRC_PASS}" +# COMMERCIAL_BUNDLE_SHA = "${WOLFSSL_SRC_SHA}" +# COMMERCIAL_BUNDLE_TARGET = "${WORKDIR}" +# +# Helper functions: +# get_commercial_src_uri(d) - Generates conditional SRC_URI +# get_commercial_source_dir(d) - Generates conditional source directory +# get_commercial_bbclassextend(d) - Returns BBCLASSEXTEND only if bundle configured +# get_commercial_bundle_archive(d) - Resolves bundle filename (supports .7z and .tar.gz) +# +# Optional format variables: +# COMMERCIAL_BUNDLE_FILE - Bundle filename including extension (defaults to .7z) +# COMMERCIAL_BUNDLE_GCS_URI - gs:// path to the protected bundle +# COMMERCIAL_BUNDLE_SRC_DIR - Direct path to already-extracted source directory (skips fetch/extract) + +# Commercial bundles already ship generated configure scripts, so skip autoreconf +AUTOTOOLS_AUTORECONF = "no" + +# Helper functions for conditional commercial bundle configuration +def append_libtool_sysroot(d): + """Override the default autotools helper to drop --with-libtool-sysroot for commercial bundles.""" + if d.getVar('COMMERCIAL_BUNDLE_ENABLED') == "1": + return '' + import bb + if not bb.data.inherits_class('native', d): + return '--with-libtool-sysroot=${STAGING_DIR_HOST}' + return '' + +def get_commercial_bundle_archive(d): + """Resolve the bundle filename with extension.""" + bundle_file = d.getVar('COMMERCIAL_BUNDLE_FILE') + if bundle_file and bundle_file.strip() and not bundle_file.startswith('${'): + return bundle_file + bundle_name = d.getVar('COMMERCIAL_BUNDLE_NAME') + if bundle_name and bundle_name.strip() and not bundle_name.startswith('${'): + return f'{bundle_name}.7z' + return '' + +def get_commercial_src_uri(d): + """Generate SRC_URI for commercial bundle if configured, dummy file otherwise""" + # Check for direct source directory first (skip fetch/extract) + src_dir = d.getVar('COMMERCIAL_BUNDLE_SRC_DIR') + if src_dir and src_dir.strip() and not src_dir.startswith('${'): + # Direct source directory - no fetch needed + return "" + + bundle_archive = d.getVar('COMMERCIAL_BUNDLE_ARCHIVE') + bundle_sha = d.getVar('COMMERCIAL_BUNDLE_SHA') + gcs_uri = d.getVar('COMMERCIAL_BUNDLE_GCS_URI') + placeholder = d.getVar('COMMERCIAL_BUNDLE_PLACEHOLDER') or '' + + if gcs_uri and bundle_archive: + unpack_flag = ';unpack=false' if bundle_archive.endswith('.7z') else '' + sha_flag = f';sha256sum={bundle_sha}' if bundle_sha else '' + filename_flag = f';downloadfilename={bundle_archive}' + return f'{gcs_uri}{filename_flag}{unpack_flag}{sha_flag}' + + bundle_dir = d.getVar('COMMERCIAL_BUNDLE_DIR') + + if bundle_archive and not gcs_uri: + unpack_flag = ';unpack=false' if bundle_archive.endswith('.7z') else '' + return f'file://{bundle_dir}/{bundle_archive}{unpack_flag};sha256sum={bundle_sha}' + + # Return dummy placeholder file when not configured + if placeholder: + return f'file://{placeholder}' + return "" + +def get_commercial_source_dir(d): + """Get source directory for commercial bundle if configured, WORKDIR otherwise""" + workdir = d.getVar('WORKDIR') + bundle_name = d.getVar('COMMERCIAL_BUNDLE_NAME') + + # Check for direct source directory - return the copy location in WORKDIR + src_dir = d.getVar('COMMERCIAL_BUNDLE_SRC_DIR') + if src_dir and src_dir.strip() and not src_dir.startswith('${'): + # do_commercial_extract will copy to WORKDIR/bundle_name + if bundle_name and bundle_name.strip() and not bundle_name.startswith('${'): + return f'{workdir}/{bundle_name}' + # Fallback to workdir if bundle_name not set + return workdir + + # Check if bundle_name is actually set (not empty, None, or unexpanded variable) + if bundle_name and bundle_name.strip() and not bundle_name.startswith('${'): + return f'{workdir}/{bundle_name}' + return workdir + +def get_commercial_bbclassextend(d): + """Return BBCLASSEXTEND variants only when commercial bundle is configured""" + bundle_name = d.getVar('COMMERCIAL_BUNDLE_NAME') + + # Check if bundle_name is actually set (not empty, None, or unexpanded variable) + if bundle_name and bundle_name.strip() and not bundle_name.startswith('${'): + return 'native nativesdk' + return '' + +# Generic variables for commercial bundle extraction +COMMERCIAL_BUNDLE_ENABLED ?= "0" +COMMERCIAL_BUNDLE_DIR ?= "" +COMMERCIAL_BUNDLE_NAME ?= "" +COMMERCIAL_BUNDLE_FILE ?= "" +COMMERCIAL_BUNDLE_PASS ?= "" +COMMERCIAL_BUNDLE_SHA ?= "" +COMMERCIAL_BUNDLE_TARGET ?= "${WORKDIR}" +COMMERCIAL_BUNDLE_PLACEHOLDER ?= "${WOLFSSL_LAYERDIR}/recipes-wolfssl/wolfssl/commercial/files/README.md" +COMMERCIAL_BUNDLE_GCS_URI ?= "" +COMMERCIAL_BUNDLE_SRC_DIR ?= "" +COMMERCIAL_BUNDLE_ARCHIVE = "${@get_commercial_bundle_archive(d)}" + +# Auto-detect extracted directory name from WOLFSSL_VERSION if not explicitly set +# This handles cases where tarball name differs from extracted directory +WOLFSSL_SRC_SUBDIR ?= "${@'wolfssl-' + d.getVar('WOLFSSL_VERSION') if d.getVar('WOLFSSL_VERSION') else d.getVar('WOLFSSL_SRC') or ''}" + +# Task to extract commercial bundle +python do_commercial_extract() { + import os + import bb + import bb.process + import bb.build + + enabled = d.getVar('COMMERCIAL_BUNDLE_ENABLED') + src_dir = d.getVar('COMMERCIAL_BUNDLE_SRC_DIR') + bundle_dir = d.getVar('COMMERCIAL_BUNDLE_DIR') + bundle_archive = d.getVar('COMMERCIAL_BUNDLE_ARCHIVE') + bundle_pass = d.getVar('COMMERCIAL_BUNDLE_PASS') + target_dir = d.getVar('COMMERCIAL_BUNDLE_TARGET') + bundle_sha = d.getVar('COMMERCIAL_BUNDLE_SHA') or '' + + if enabled != "1": + bb.note("COMMERCIAL_BUNDLE_ENABLED=0; skipping commercial extraction (standard fetch/unpack will run).") + return + + # If direct source directory is provided, skip extraction + if src_dir and src_dir.strip() and not src_dir.startswith('${'): + bb.note(f"COMMERCIAL_BUNDLE_SRC_DIR={src_dir}; copying source directory to WORKDIR.") + + # Copy source directory to WORKDIR to avoid polluting the original + import shutil + bundle_name = d.getVar('COMMERCIAL_BUNDLE_NAME') + dest_dir = os.path.join(target_dir, bundle_name) + + if os.path.exists(dest_dir): + bb.note(f"Removing existing build directory: {dest_dir}") + shutil.rmtree(dest_dir) + + bb.note(f"Copying {src_dir} to {dest_dir}") + shutil.copytree(src_dir, dest_dir, symlinks=True) + bb.note("Source directory copied successfully") + return + + if not bundle_dir: + bb.fatal("COMMERCIAL_BUNDLE_DIR not set. Please set the directory containing the commercial bundle.") + + if not bundle_archive: + bb.fatal("COMMERCIAL_BUNDLE_NAME/FILE not set. Please provide the bundle filename.") + + is_seven_zip = bundle_archive.endswith('.7z') + is_tarball = bundle_archive.endswith('.tar.gz') or bundle_archive.endswith('.tgz') + + if is_seven_zip and not bundle_pass: + bb.fatal("COMMERCIAL_BUNDLE_PASS not set. Please set bundle password for .7z archives.") + + if not is_seven_zip: + bb.note("Non-7z commercial bundle detected; letting BitBake unpack the archive.") + return + + bundle_path = os.path.join(bundle_dir, bundle_archive) + + if not os.path.exists(bundle_path): + bb.fatal(f"Commercial bundle not found: {bundle_path}\n" + + "Please download the commercial bundle and place it in the appropriate directory.\n" + + "Contact support@wolfssl.com for access to commercial bundles.") + + # Verify checksum locally (BitBake's file:// fetcher may skip it) + if bundle_sha: + import hashlib + h = hashlib.sha256() + with open(bundle_path, 'rb') as f: + for chunk in iter(lambda: f.read(1024 * 1024), b''): + h.update(chunk) + digest = h.hexdigest() + if digest != bundle_sha: + bb.fatal(f"SHA256 mismatch for {bundle_archive}:\n" + f" expected: {bundle_sha}\n" + f" actual: {digest}\n" + "Update WOLFSSL_SRC_SHA/COMMERCIAL_BUNDLE_SHA to the correct value.") + + # Copy bundle to target directory + bb.plain(f"Extracting commercial bundle: {bundle_archive}") + ret = os.system(f'cp -f "{bundle_path}" "{target_dir}"') + if ret != 0: + bb.fatal(f"Failed to copy bundle to {target_dir}") + + archive_in_target = os.path.join(target_dir, bundle_archive) + + if is_seven_zip: + # Locate 7zip binary from native sysroot or host + path = d.getVar('PATH') + seven_zip = bb.utils.which(path, '7za') or bb.utils.which(path, '7z') + + if not seven_zip: + bb.fatal("Failed to find either '7za' or '7z' in PATH.\n" + "Ensure p7zip-native is available or install p7zip on the build host.") + + cmd = [seven_zip, 'x', archive_in_target, f"-p{bundle_pass}", + f"-o{target_dir}", '-aoa'] + else: + bb.fatal(f"Unsupported commercial bundle format: {bundle_archive}. Expected .7z.") + + try: + bb.process.run(cmd) + except bb.process.ExecutionError as exc: + bb.fatal("Failed to extract bundle. Check credentials and bundle integrity.\n" + str(exc)) + + bb.plain("Commercial bundle extracted successfully") +} + +# Add task after fetch, before patch (place before do_patch so it still runs even if do_unpack is skipped) +addtask commercial_extract after do_fetch before do_patch + +# Conditionally add p7zip-native dependency only when commercial bundle variables are set +python __anonymous() { + enabled = d.getVar('COMMERCIAL_BUNDLE_ENABLED') + if not enabled or enabled == '0': + wolfssl_src = d.getVar('WOLFSSL_SRC') + wolfssl_src_dir = d.getVar('COMMERCIAL_BUNDLE_SRC_DIR') + + if (wolfssl_src and wolfssl_src.strip()) or (wolfssl_src_dir and wolfssl_src_dir.strip() and not wolfssl_src_dir.startswith('${')): + d.setVar('COMMERCIAL_BUNDLE_ENABLED', '1') + enabled = '1' + bb.debug(1, "COMMERCIAL_BUNDLE_ENABLED auto-detected as 1 based on WOLFSSL_SRC or COMMERCIAL_BUNDLE_SRC_DIR") + + src_dir = d.getVar('COMMERCIAL_BUNDLE_SRC_DIR') + archive = d.getVar('COMMERCIAL_BUNDLE_ARCHIVE') + + # Skip p7zip and unpack tasks if using direct source directory + # But keep commercial_extract to copy the source + if enabled == "1" and src_dir and src_dir.strip() and not src_dir.startswith('${'): + bb.build.deltask('do_fetch', d) + bb.build.deltask('do_unpack', d) + # do_commercial_extract will copy the source directory + return + + if enabled == "1" and archive and archive.endswith('.7z'): + d.appendVar('DEPENDS', ' p7zip-native') + d.appendVarFlag('do_commercial_extract', 'depends', ' p7zip-native:do_populate_sysroot') + # Older BitBake releases sometimes ignore 'unpack=false' on file:// URLs, + # causing do_unpack to run with no password and wipe the extracted tree. + # When we manage a passworded .7z ourselves, skip do_unpack entirely. + bb.build.deltask('do_unpack', d) + + # Commercial bundles ship preconfigured scripts; drop libtool sysroot flag + opts = d.getVar('CONFIGUREOPTS') or '' + import shlex + tokens = shlex.split(opts) + tokens = [t for t in tokens if not t.startswith('--with-libtool-sysroot=')] + d.setVar('CONFIGUREOPTS', ' '.join(tokens)) + d.setVar('CONFIGUREOPT_SYSROOT', '') +} + +# Skip autoreconf for commercial bundles and rely on bundled configure script +do_configure() { + bbnote "Commercial bundle detected, skipping autoreconf and running bundled configure" + # Ensure libtool sysroot option is stripped (not accepted by commercial bundles) + unset CONFIGUREOPT_SYSROOT + CONFIGUREOPTS="$(echo ${CONFIGUREOPTS} | sed 's/--with-libtool-sysroot=[^ ]*//g')" + if [ -e "${S}/configure.ac" ] && [ ! -f "${S}/stamp-h.in" ] && \ + grep -q "AC_CONFIG_FILES(\\[stamp-h\\]" "${S}/configure.ac"; then + bbnote "stamp-h.in missing; generating stub for preconfigured commercial source" + echo "timestamp" > "${S}/stamp-h.in" + fi + if [ -e "${CONFIGURE_SCRIPT}" ]; then + oe_runconf + else + bbfatal "configure script not found at ${CONFIGURE_SCRIPT}" + fi +} + +# Task to create stub autogen.sh for commercial bundles +do_commercial_stub_autogen() { + if [ "${COMMERCIAL_BUNDLE_ENABLED}" != "1" ]; then + bbnote "Commercial bundle disabled; skipping autogen stub." + exit 0 + fi + + if [ ! -d "${S}" ]; then + bbwarn "Source directory ${S} missing before autogen stub; skipping." + exit 0 + fi + + # Commercial bundles are pre-configured and don't need autogen.sh + # Create a no-op autogen.sh to prevent automatic execution + if [ ! -f ${S}/autogen.sh ]; then + echo '#!/bin/sh' > ${S}/autogen.sh + echo '# Commercial bundle - pre-configured, no autogen needed' >> ${S}/autogen.sh + echo 'exit 0' >> ${S}/autogen.sh + chmod +x ${S}/autogen.sh + bbplain "Created stub autogen.sh for commercial bundle" + else + bbplain "Replacing existing autogen.sh with stub for commercial bundle" + echo '#!/bin/sh' > ${S}/autogen.sh + echo '# Commercial bundle - pre-configured, no autogen needed' >> ${S}/autogen.sh + echo 'exit 0' >> ${S}/autogen.sh + chmod +x ${S}/autogen.sh + fi +} + +# Add task after unpack (or commercial_extract for 7z), before configure +addtask commercial_stub_autogen after do_unpack before do_configure diff --git a/classes/wolfssl-compatibility.bbclass b/classes/wolfssl-compatibility.bbclass new file mode 100644 index 00000000..1eaf29a4 --- /dev/null +++ b/classes/wolfssl-compatibility.bbclass @@ -0,0 +1,117 @@ +# wolfSSL Yocto Compatibility Helper Class +# Provides functions to work with both old (underscore) and new (colon) Yocto syntax + +def wolfssl_uses_colon_syntax(d): + """ + Detect if this Yocto version uses colon syntax (Honister 3.4+ / LAYERVERSION_core >= 14). + Falls back to checking DISTRO_VERSION if LAYERVERSION_core unavailable. + """ + try: + # Check OE-Core layer version (most reliable) + layer_version = d.getVar('LAYERVERSION_core') or d.getVar('LAYERVERSION_core', True) + if layer_version: + return int(layer_version) >= 14 + except: + pass + + # Fallback: check DISTRO_VERSION + try: + distro_version = d.getVar('DISTRO_VERSION') or d.getVar('DISTRO_VERSION', True) + if distro_version: + # Versions 2.x and 3.x before 3.4 use underscore + if distro_version.startswith('2.') or distro_version.startswith('3.0') or \ + distro_version.startswith('3.1') or distro_version.startswith('3.2') or \ + distro_version.startswith('3.3'): + return False + except: + pass + + # Default to colon syntax for unknown/newer versions + return True + +def wolfssl_varAppend(d, base_var, package_name, value): + """ + Appends a value to a package-specific variable, handling both old and new Yocto syntax. + + Args: + d: BitBake data store + base_var: Base variable name (e.g., 'RDEPENDS', 'FILES', 'RRECOMMENDS') + package_name: Package name (e.g., '${PN}') + value: Value to append + """ + import bb + + package_name_expanded = d.expand(package_name) + + if wolfssl_uses_colon_syntax(d): + var_name = base_var + ':' + package_name_expanded + else: + var_name = base_var + '_' + package_name_expanded + + d.appendVar(var_name, value) + +def wolfssl_varSet(d, base_var, package_name, value): + """ + Sets a package-specific variable, handling both old and new Yocto syntax. + + Args: + d: BitBake data store + base_var: Base variable name (e.g., 'RDEPENDS', 'FILES', 'RRECOMMENDS') + package_name: Package name (e.g., '${PN}') + value: Value to set + """ + import bb + + package_name_expanded = d.expand(package_name) + + if wolfssl_uses_colon_syntax(d): + var_name = base_var + ':' + package_name_expanded + else: + var_name = base_var + '_' + package_name_expanded + + d.setVar(var_name, value) + +def wolfssl_varGet(d, base_var, package_name): + """ + Gets a package-specific variable, handling both old and new Yocto syntax. + + Args: + d: BitBake data store + base_var: Base variable name (e.g., 'RDEPENDS', 'FILES', 'RRECOMMENDS') + package_name: Package name (e.g., '${PN}') + + Returns: + Variable value or None + """ + import bb + + package_name_expanded = d.expand(package_name) + + if wolfssl_uses_colon_syntax(d): + var_name = base_var + ':' + package_name_expanded + else: + var_name = base_var + '_' + package_name_expanded + + return d.getVar(var_name) or d.getVar(var_name, True) + +def wolfssl_varPrepend(d, var_name, value): + """ + Prepends a value to a variable (for things like FILESEXTRAPATHS, PACKAGECONFIG). + + Args: + d: BitBake data store + var_name: Variable name (e.g., 'FILESEXTRAPATHS', 'PACKAGECONFIG') + value: Value to prepend + """ + d.prependVar(var_name, value) + +def wolfssl_varAppendNonOverride(d, var_name, value): + """ + Appends a value to a variable (for things like PACKAGECONFIG, EXTRA_OECONF). + + Args: + d: BitBake data store + var_name: Variable name (e.g., 'PACKAGECONFIG', 'EXTRA_OECONF') + value: Value to append + """ + d.appendVar(var_name, value) diff --git a/classes/wolfssl-fips-helper.bbclass b/classes/wolfssl-fips-helper.bbclass new file mode 100644 index 00000000..1a64f2aa --- /dev/null +++ b/classes/wolfssl-fips-helper.bbclass @@ -0,0 +1,275 @@ +# wolfSSL FIPS Helper Class +# +# This class provides automatic FIPS hash generation for wolfSSL FIPS builds. +# It performs a two-pass build: +# 1. Build with placeholder hash, run test binary to extract real hash +# 2. Reconfigure and rebuild with the extracted hash +# +# Usage in recipe: +# inherit wolfssl-fips-helper +# WOLFSSL_FIPS_HASH_MODE ?= "auto" # or "manual" to use FIPS_HASH variable + +# FIPS hash configuration +WOLFSSL_FIPS_HASH_MODE ?= "auto" +WOLFSSL_FIPS_PLACEHOLDER ?= "0000000000000000000000000000000000000000000000000000000000000000" + +python __anonymous() { + # Set mode to manual for native/nativesdk builds + if bb.utils.contains('OVERRIDES', 'class-native', True, False, d) or bb.utils.contains('OVERRIDES', 'class-nativesdk', True, False, d): + d.setVar('WOLFSSL_FIPS_HASH_MODE', 'manual') +} + +# This will be set by anonymous Python based on mode (manual: FIPS_HASH, auto: function call) +WOLFSSL_GET_HASH_METHOD ?= "" + +# Test binary configuration +WOLFSSL_FIPS_TEST_BINARY ?= "${B}/wolfcrypt/test/.libs/testwolfcrypt" + +# Helper function: Get FIPS hash value (callable from shell during build) +# This function performs the actual hash retrieval and returns the value +get_wolfssl_fips_hash() { + local mode="${WOLFSSL_FIPS_HASH_MODE}" + + if [ "${mode}" != "auto" ]; then + # Manual mode: return the configured hash + echo "${FIPS_HASH}" + return 0 + fi + + # Auto mode: perform hash extraction + bbnote "wolfSSL FIPS auto mode: extracting hash from test binary" + + # Build test binary if not already built (configure should have enabled --enable-crypttests) + if [ ! -x "${WOLFSSL_FIPS_TEST_BINARY}" ]; then + bbnote "Building wolfCrypt test binary for FIPS hash generation" + # Ensure we're in the build directory (where Makefiles are) + cd ${B} || bbfatal "Failed to change to build directory ${B}" + # Build everything needed for the test (redirect output to log files, not stdout) + oe_runmake all 1>&2 + fi + + # Capture and return the hash directly (only hash goes to stdout) + local hash=$(wolfssl_fips_capture_hash) + local rc=$? + if [ ${rc} -ne 0 ] || [ -z "${hash}" ]; then + bberror "Failed to capture FIPS hash (rc=${rc})" + return 1 + fi + + # Return only the hash to stdout (no other messages) + echo "${hash}" + return 0 +} + +# QEMU wrapper command for running target binaries +# This uses the qemu_target_binary function from qemu.bbclass +WOLFSSL_QEMU_BINARY = "${RECIPE_SYSROOT_NATIVE}/usr/bin/${@qemu_target_binary(d)}" +# QEMU wrapper needs a real command as the first token; wrap the +# PSEUDO_UNLOAD override with `env` so it isn't mis-parsed as an executable +# when the command string is expanded via ${run_cmd}. +WOLFSSL_QEMU_WRAPPER = "env PSEUDO_UNLOAD=1 ${WOLFSSL_QEMU_BINARY} ${QEMU_OPTIONS} -L ${RECIPE_SYSROOT} -E LD_LIBRARY_PATH=${B}/src/.libs:${B}/wolfcrypt/src/.libs" + +# Clean function to prepend to do_configure +wolfssl_fips_clean_config() { + # Clean any leftover config files from source directory to prevent "already configured" errors + bbnote "wolfSSL FIPS: Cleaning config files from source directory" + rm -f ${S}/config.status ${S}/config.log ${S}/Makefile ${S}/config.h ${S}/libtool + rm -f ${S}/wolfssl/options.h ${S}/wolfssl/version.h + # Also clean from subdirectories if they exist + rm -f ${S}/wolfcrypt/src/fips_test.c.orig +} + +# Dynamic variable setup - handles dependencies, class inheritance, and task ordering +python __anonymous () { + import bb + + mode = d.getVar('WOLFSSL_FIPS_HASH_MODE') + distro_version = d.getVar('DISTRO_VERSION') + + # Add clean function to do_configure (version-compatible based on DISTRO_VERSION) + clean_command = 'wolfssl_fips_clean_config\n' + + if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): + # For Dunfell (3.x) and earlier - use old style variable + existing = d.getVar('do_configure_prepend') or '' + d.setVar('do_configure_prepend', clean_command + existing) + else: + # For Kirkstone (4.x) and later - use prefuncs + d.appendVarFlag('do_configure', 'prefuncs', ' wolfssl_fips_clean_config') + + # Only set up for auto mode + if mode == 'auto': + # Inherit qemu class for cross-compilation support + bb.parse.BBHandler.inherit('qemu', '', 0, d) + + # Add qemu-native dependency + d.appendVar('DEPENDS', ' qemu-native') + + # Include crypttests configuration for auto mode + include_file = d.expand('${WOLFSSL_LAYERDIR}/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc') + bb.parse.handle(include_file, d, True) + + bb.build.addtask('do_wolfssl_fips_capture_hash', 'do_compile', 'do_configure', d) + else: + # Manual mode task + bb.build.addtask('do_wolfssl_fips_capture_hash_manual', 'do_compile', 'do_configure', d) +} + +# Helper function: Capture FIPS hash from test binary +# Runs the test binary using QEMU for cross-builds or directly for native builds +# Returns 0 on success, 1 on failure +wolfssl_fips_capture_hash() { + if [ ! -x "${WOLFSSL_FIPS_TEST_BINARY}" ]; then + bberror "wolfCrypt test binary ${WOLFSSL_FIPS_TEST_BINARY} not found; cannot capture FIPS hash" + return 1 + fi + + # Use temporary file for output + local temp_log=$(mktemp) + + # Determine if we need QEMU (cross-compile) or can run natively + local run_cmd="" + if [ "${BUILD_ARCH}" = "${TARGET_ARCH}" ]; then + # Native build - use dynamic linker explicitly to avoid "not found" errors + bbnote "Native build detected - using host dynamic linker" + run_cmd="/lib64/ld-linux-x86-64.so.2 --library-path ${B}/src/.libs:${B}/wolfcrypt/src/.libs ${WOLFSSL_FIPS_TEST_BINARY}" + else + # Cross-compile - use QEMU + bbnote "Cross-compile detected - using QEMU wrapper" + run_cmd="${WOLFSSL_QEMU_WRAPPER} ${WOLFSSL_FIPS_TEST_BINARY}" + fi + + bbnote "Capturing wolfSSL FIPS hash from test binary" + bbnote "Command: ${run_cmd}" + + set +e + ${run_cmd} > ${temp_log} 2>&1 + local rc=$? + set -e + + # Check if we got output + if [ ! -s "${temp_log}" ]; then + bberror "wolfCrypt test produced no output (rc=${rc})" + bberror "Command was: ${run_cmd}" + cat ${temp_log} 2>/dev/null || true + rm -f ${temp_log} + return 1 + fi + + # Parse the hash from output + local parsed=$(grep -E "hash = " "${temp_log}" | tail -n1 | awk -F'=' '{print $2}' | tr -d '[:space:]' | tr '[:lower:]' '[:upper:]') + + # Debug: show output if parsing failed + if [ -z "${parsed}" ]; then + bberror "Failed to parse FIPS hash from test output" + bberror "Test output (first 30 lines):" + head -30 ${temp_log} || true + rm -f ${temp_log} + return 1 + fi + + rm -f ${temp_log} + bbnote "wolfSSL FIPS hash extracted: ${parsed}" + + # Return the hash value + echo "${parsed}" + return 0 +} + +# Task: Capture FIPS hash (only runs for auto mode) +do_wolfssl_fips_capture_hash() { + + # Place a placeholder hash in fips_test.c before capturing + PLACEHOLDER_HASH="FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + bbnote "Setting placeholder hash in fips_test.c: ${PLACEHOLDER_HASH}" + + if [ -f "${S}/wolfcrypt/src/fips_test.c" ]; then + cp ${S}/wolfcrypt/src/fips_test.c ${S}/wolfcrypt/src/fips_test.c.orig + sed "s/^\".*\";/\"${PLACEHOLDER_HASH}\";/" ${S}/wolfcrypt/src/fips_test.c.orig > ${S}/wolfcrypt/src/fips_test.c + # Force rebuild by removing test binary and touching source + rm -f ${B}/wolfcrypt/test/.libs/testwolfcrypt ${B}/wolfcrypt/test/testwolfcrypt + touch ${S}/wolfcrypt/src/fips_test.c + fi + + # Reconfigure to ensure placeholder is used + do_configure + + + # Capture the hash (eval to handle both function call and direct value) + set +e + CAPTURED_HASH=$(get_wolfssl_fips_hash) + local rc=$? + set -e + + if [ ${rc} -ne 0 ] || [ -z "${CAPTURED_HASH}" ]; then + bberror "Failed to capture wolfSSL FIPS hash (rc=${rc})" + bbfatal "FIPS hash capture failed - cannot continue" + fi + + # Display the captured hash + bbplain "==========================================" + bbplain "wolfSSL FIPS Hash (auto mode): ${CAPTURED_HASH}" + bbplain "==========================================" + + # Update fips_test.c with the captured hash (same as official fips-hash.sh) + if [ ! -f "${S}/wolfcrypt/src/fips_test.c" ]; then + bbfatal "fips_test.c not found at ${S}/wolfcrypt/src/fips_test.c" + fi + + # Create backup of original if it doesn't exist yet + if [ ! -f "${S}/wolfcrypt/src/fips_test.c.bak" ]; then + bbnote "Creating backup of original fips_test.c" + cp ${S}/wolfcrypt/src/fips_test.c ${S}/wolfcrypt/src/fips_test.c.bak + fi + + bbnote "Updating fips_test.c with captured hash" + sed "s/^\".*\";/\"${CAPTURED_HASH}\";/" ${S}/wolfcrypt/src/fips_test.c > ${S}/wolfcrypt/src/fips_test.c.tmp + mv ${S}/wolfcrypt/src/fips_test.c.tmp ${S}/wolfcrypt/src/fips_test.c + + bbnote "Updated fips_test.c with hash: ${CAPTURED_HASH}" + + # Run configure again + do_configure +} + +do_wolfssl_fips_capture_hash_manual() { + + # Manual mode: just use the configured FIPS_HASH value + CAPTURED_HASH=${FIPS_HASH} + + if [ -z "${CAPTURED_HASH}" ]; then + bbfatal "FIPS_HASH is not set in manual mode" + fi + + # Display the configured hash + bbplain "==========================================" + bbplain "wolfSSL FIPS Hash (manual mode): ${CAPTURED_HASH}" + bbplain "==========================================" + + # Update fips_test.c with the configured hash + if [ ! -f "${S}/wolfcrypt/src/fips_test.c" ]; then + bbfatal "fips_test.c not found at ${S}/wolfcrypt/src/fips_test.c" + fi + + # Create backup of original if it doesn't exist yet + if [ ! -f "${S}/wolfcrypt/src/fips_test.c.bak" ]; then + bbnote "Creating backup of original fips_test.c" + cp ${S}/wolfcrypt/src/fips_test.c ${S}/wolfcrypt/src/fips_test.c.bak + fi + + bbnote "Updating fips_test.c with configured hash" + sed "s/^\".*\";/\"${CAPTURED_HASH}\";/" ${S}/wolfcrypt/src/fips_test.c > ${S}/wolfcrypt/src/fips_test.c.tmp + mv ${S}/wolfcrypt/src/fips_test.c.tmp ${S}/wolfcrypt/src/fips_test.c + + bbnote "Updated fips_test.c with hash: ${CAPTURED_HASH}" + + # Reconfigure to pick up the updated hash + # Note: wolfssl_fips_clean_config will run automatically via prefuncs + do_configure +} + + +# Task metadata +do_wolfssl_fips_capture_hash[doc] = "Capture FIPS hash from test binary" +do_wolfssl_fips_capture_hash[dirs] = "${B} ${S}" +do_wolfssl_fips_capture_hash[nostamp] = "1" diff --git a/classes/wolfssl-helper.bbclass b/classes/wolfssl-helper.bbclass new file mode 100644 index 00000000..e1b927d8 --- /dev/null +++ b/classes/wolfssl-helper.bbclass @@ -0,0 +1,203 @@ +# wolfssl-helper.bbclass +# +# This class provides reusable helper functions for wolfSSL packages +# including verification that packages are properly configured +# +# Usage in recipe: +# inherit wolfssl-helper + +def wolfssl_conditional_require(d, package_name, inc_path): + """ + Conditionally include an .inc file if package is in IMAGE_INSTALL or WOLFSSL_FEATURES + + Args: + d: BitBake datastore + package_name: Name of the package to check for + inc_path: Relative path from layer root to the .inc file (e.g., 'inc/wolfclu/wolfssl-enable-wolfclu.inc') + """ + import os + import bb.parse + + if bb.utils.contains('WOLFSSL_FEATURES', package_name, True, False, d) or \ + bb.utils.contains('IMAGE_INSTALL', package_name, True, False, d): + # Get the meta-wolfssl layer directory from variable set in layer.conf + layerdir = d.getVar('WOLFSSL_LAYERDIR') + inc_file = os.path.join(layerdir, inc_path) + bb.parse.mark_dependency(d, inc_file) + bb.parse.handle(inc_file, d, True) + + +def wolfssl_conditional_require_mode(d, package_name, mode, inc_file=None): + """ + Conditionally include one or more .inc files based on a mode variable and + WOLFSSL_FEATURES. Supports space-separated modes (e.g., "replace-default + enable-tests") and a mapping of mode->inc_file so callers can configure + multiple modes in a single invocation. + + Args: + d: BitBake datastore + package_name: Name of the package to check for (e.g., 'wolfprovider') + mode: Either a string mode name or a dict mapping mode names to + inc-file paths. + inc_file: Relative path from layer root to the .inc file (required when + 'mode' is a single string) + + Returns: + True if configuration was included, False otherwise + + Example: + wolfssl_conditional_require_mode( + d, + package_name='wolfprovider', + mode='standalone', + inc_file='inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc' + ) + + # Multiple modes in one call: + wolfssl_conditional_require_mode( + d, + package_name='wolfprovider', + mode={ + 'standalone': 'inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc', + 'replace-default': 'inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc', + } + ) + + # Supports multiple modes in WOLFPROVIDER_MODE: + # WOLFPROVIDER_MODE = "replace-default enable-tests" + """ + import os + import bb.parse + + # Check if package is enabled + if not (bb.utils.contains('WOLFSSL_FEATURES', package_name, True, False, d) or \ + bb.utils.contains('IMAGE_INSTALL', package_name, True, False, d)): + bb.debug(2, f"{package_name} not in WOLFSSL_FEATURES or IMAGE_INSTALL - skipping") + return False + + # Build the mode variable name from package name (e.g., 'wolfprovider' -> 'WOLFPROVIDER_MODE') + mode_var_name = f"{package_name.upper()}_MODE" + current_mode_str = d.getVar(mode_var_name) or 'standalone' # Default to standalone + + # Support space-separated modes: split into list and check if expected mode is in the list + current_modes = [m.strip() for m in current_mode_str.split() if m.strip()] + + # Normalise callers passing a mapping vs a single mode + if isinstance(mode, dict): + mode_map = mode + else: + if inc_file is None: + bb.fatal(f"{package_name}: wolfssl_conditional_require_mode called without inc_file for mode '{mode}'") + mode_map = {mode: inc_file} + + included_any = False + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if not layerdir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + for single_mode, single_inc in mode_map.items(): + if single_mode not in current_modes: + bb.debug(2, f"{package_name}: {mode_var_name}='{current_mode_str}' does not contain '{single_mode}' - skipping") + continue + + bb.note(f"{package_name}: {mode_var_name}='{current_mode_str}' contains '{single_mode}' mode - including {single_inc}") + full_inc_file = os.path.join(layerdir, single_inc) + bb.parse.mark_dependency(d, full_inc_file) + try: + bb.parse.handle(full_inc_file, d, True) + included_any = True + except Exception as e: + bb.fatal(f"Failed to include {full_inc_file}: {e}") + + return included_any + + +def wolfssl_conditional_require_flag(d, flag_name, inc_file): + """ + Conditionally include an .inc file based solely on the current recipe's flags + variable (derived from PN). Flags are separate from modes - use for opt-in + features like tests, not OpenSSL configuration. + + Args: + d: BitBake datastore + flag_name: The flag to check for (e.g., 'enable-tests') + inc_file: Relative path from layer root to the .inc file + + Returns: + True if configuration was included, False otherwise + + Example: + wolfssl_conditional_require_flag( + d, + flag_name='enable-tests', + inc_file='inc/wolfprovider/wolfprovider-enable-test.inc' + ) + + # Usage in local.conf: + # WOLFPROVIDER_FLAGS = "enable-tests" # PN=wolfprovider -> WOLFPROVIDER_FLAGS + """ + import os + import bb.parse + + package_name = d.getVar('PN') + if not package_name: + bb.fatal("wolfssl_conditional_require_flag called without PN set") + + # Build the flags variable name from the current package name (e.g., wolfprovider -> WOLFPROVIDER_FLAGS) + flags_var_name = f"{package_name.upper()}_FLAGS" + current_flags_str = d.getVar(flags_var_name) or '' + + # Support space-separated flags: split into list and check if expected flag is in the list + current_flags = [f.strip() for f in current_flags_str.split() if f.strip()] + + # Check if expected flag is in the current flags list + if flag_name not in current_flags: + bb.debug(2, f"{package_name}: {flags_var_name}='{current_flags_str}' does not contain '{flag_name}' - skipping") + return False + + # Flag found in list - include the configuration + bb.note(f"{package_name}: {flags_var_name}='{current_flags_str}' contains '{flag_name}' flag - including {inc_file}") + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if not layerdir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + full_inc_file = os.path.join(layerdir, inc_file) + bb.parse.mark_dependency(d, full_inc_file) + try: + bb.parse.handle(full_inc_file, d, True) + return True + except Exception as e: + bb.fatal(f"Failed to include {full_inc_file}: {e}") + +python do_wolfssl_check_package() { + """ + Task to check if package is enabled via IMAGE_INSTALL or WOLFSSL_FEATURES + Only runs when recipe is actually being built + """ + package_name = d.getVar('PN') + image_install = d.getVar('IMAGE_INSTALL') or '' + wolfssl_features = d.getVar('WOLFSSL_FEATURES') or '' + + # Check if this package is in either IMAGE_INSTALL or WOLFSSL_FEATURES + if package_name not in image_install and package_name not in wolfssl_features: + bb.fatal("%s requires either:\n" \ + " - '%s' in IMAGE_INSTALL, or\n" \ + " - 'WOLFSSL_FEATURES = \"%s\"' in local.conf\n" \ + "to ensure wolfSSL is built with proper support." % (package_name, package_name, package_name)) +} + +# Add the check task before configure +addtask wolfssl_check_package before do_configure after do_fetch + +python() { + distro_version = d.getVar('DISTRO_VERSION', True) + autogen_command = 'cd ${S}; if [ -f ${S}/autogen.sh ]; then ./autogen.sh; fi' + if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): + # For Dunfell and earlier + d.appendVar('do_configure_prepend', autogen_command) + else: + # For Kirkstone and later + d.appendVar('do_configure:prepend', autogen_command) +} diff --git a/classes/wolfssl-initramfs.bbclass b/classes/wolfssl-initramfs.bbclass new file mode 100644 index 00000000..f6efa74b --- /dev/null +++ b/classes/wolfssl-initramfs.bbclass @@ -0,0 +1,128 @@ +# classes/wolfssl-initramfs.bbclass +# +# Purpose: +# Provide reusable functions that allow initramfs images to: +# - include wolfssl-linuxkm +# - run depmod inside the initramfs rootfs +# - optionally inject `modprobe libwolfssl` into /init +# +# IMPORTANT: +# This class does *not* automatically modify ROOTFS_POSTPROCESS_COMMAND. +# The consuming image recipe must explicitly opt-in: +# +# inherit wolfssl-initramfs +# PACKAGE_INSTALL:append = " wolfssl-linuxkm" +# ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_run_depmod; " +# ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_inject_after_modalias; " +# +# Available injection functions are documented below. + +### ───────────────────────────────────────────────────────────── +### 0. Common helper +### ───────────────────────────────────────────────────────────── + +wolfssl_initramfs_has_module() { + find "${IMAGE_ROOTFS}/lib/modules" -name 'libwolfssl.ko' >/dev/null 2>&1 +} + +wolfssl_initramfs_has_init() { + [ -f "${IMAGE_ROOTFS}/init" ] +} + +### ───────────────────────────────────────────────────────────── +### 1. Run depmod inside the initramfs +### ───────────────────────────────────────────────────────────── + +wolfssl_initramfs_run_depmod() { + echo "wolfssl-initramfs: running depmod" >&2 + + if [ ! -d "${IMAGE_ROOTFS}/lib/modules" ]; then + echo "wolfssl-initramfs: no modules directory found; skipping depmod" >&2 + return 0 + fi + + if ! command -v depmod >/dev/null 2>&1; then + echo "wolfssl-initramfs: depmod not available; skipping" >&2 + return 0 + fi + + for kdir in "${IMAGE_ROOTFS}"/lib/modules/*; do + [ -d "$kdir" ] || continue + + kver=$(basename "$kdir") + echo "wolfssl-initramfs: depmod -a -b ${IMAGE_ROOTFS} ${kver}" >&2 + + depmod -a -b "${IMAGE_ROOTFS}" "${kver}" || \ + echo "wolfssl-initramfs: WARNING: depmod failed for ${kver}" >&2 + done +} + +### ───────────────────────────────────────────────────────────── +### 2. Injection methods for /init +### ───────────────────────────────────────────────────────────── + +# Common injection wrapper +wolfssl_initramfs_try_inject() { + local anchor="$1" + local sed_expr="$2" + local desc="$3" + + if grep -q "$anchor" "${IMAGE_ROOTFS}/init"; then + echo "wolfssl-initramfs: injecting modprobe at: $desc" >&2 + sed -i "$sed_expr" "${IMAGE_ROOTFS}/init" || \ + echo "wolfssl-initramfs: WARNING: failed to inject at $desc" >&2 + fi +} + +### 2A: Inject after modalias scan loop +wolfssl_initramfs_inject_after_modalias() { + echo "wolfssl-initramfs: checking modalias injection" >&2 + + wolfssl_initramfs_has_init || { echo "… no /init, skip"; return 0; } + wolfssl_initramfs_has_module || { echo "… module missing, skip"; return 0; } + + wolfssl_initramfs_try_inject \ + "find /sys -name modalias" \ + '/find \/sys -name modalias/a\ +modprobe libwolfssl || echo "wolfssl-initramfs: failed to load libwolfssl" >&2' \ + "modalias section" +} + +### 2B: Inject after '# Load and run modules' +wolfssl_initramfs_inject_after_loadmodules() { + echo "wolfssl-initramfs: checking loadmodules injection" >&2 + + wolfssl_initramfs_has_init || { echo "… no /init, skip"; return 0; } + wolfssl_initramfs_has_module || { echo "… module missing, skip"; return 0; } + + wolfssl_initramfs_try_inject \ + '^# Load and run modules' \ + '/^# Load and run modules/a\ +modprobe libwolfssl || echo "wolfssl-initramfs: failed to load libwolfssl" >&2' \ + "Load-and-run-modules section" +} + +### 2C: Last-resort: Inject after kmsg redirect +wolfssl_initramfs_inject_after_kmsg() { + echo "wolfssl-initramfs: checking kmsg injection" >&2 + + wolfssl_initramfs_has_init || { echo "… no /init, skip"; return 0; } + wolfssl_initramfs_has_module || { echo "… module missing, skip"; return 0; } + + wolfssl_initramfs_try_inject \ + 'exec > /dev/kmsg' \ + '/exec > \/dev\/kmsg 2>&1/a\ +modprobe libwolfssl || echo "wolfssl-initramfs: failed to load libwolfssl" >&2' \ + "kmsg redirection section" +} + +### ───────────────────────────────────────────────────────────── +### 3. Documentation (shown in bitbake -e or debugging) +### ───────────────────────────────────────────────────────────── + +WOLFSSL_INITRAMFS_FUNCTIONS = "\ + wolfssl_initramfs_run_depmod \ + wolfssl_initramfs_inject_after_modalias \ + wolfssl_initramfs_inject_after_loadmodules \ + wolfssl_initramfs_inject_after_kmsg \ +" diff --git a/classes/wolfssl-kernel-random.bbclass b/classes/wolfssl-kernel-random.bbclass new file mode 100644 index 00000000..9829a568 --- /dev/null +++ b/classes/wolfssl-kernel-random.bbclass @@ -0,0 +1,66 @@ +# wolfssl-kernel-random.bbclass +# +# This class applies wolfSSL random callback patches to the Linux kernel. +# It fetches patches directly from the wolfSSL GitHub repository. +# +# Usage: In your kernel bbappend (e.g., linux-jammy-nvidia-tegra.bbappend): +# +# inherit wolfssl-kernel-random +# WOLFSSL_KERNEL_RANDOM_PATCH = "5.17-ubuntu-jammy-tegra" +# +# Available patches: https://github.com/wolfSSL/wolfssl/tree/master/linuxkm/patches +# +# Common values for WOLFSSL_KERNEL_RANDOM_PATCH: +# - "5.10.17" +# - "5.10.236" +# - "5.15" +# - "5.17" +# - "5.17-ubuntu-jammy-tegra" (for NVIDIA Tegra/Jetson) +# - "6.1.73" +# - "6.12" +# - "6.15" + +# User must set this to the patch directory name +WOLFSSL_KERNEL_RANDOM_PATCH ?= "" + +# wolfSSL repository for fetching patches +WOLFSSL_PATCHES_REPO ?= "git://github.com/wolfSSL/wolfssl.git;protocol=https;branch=master" +WOLFSSL_PATCHES_SRCREV ?= "${AUTOREV}" + +# Add wolfSSL source fetch for patches +SRC_URI += "${WOLFSSL_PATCHES_REPO};name=wolfssl-patches;destsuffix=wolfssl-patches;nobranch=1" +SRCREV_wolfssl-patches = "${WOLFSSL_PATCHES_SRCREV}" + +# Apply wolfSSL kernel randomness patches +do_patch:prepend() { + if [ -n "${WOLFSSL_KERNEL_RANDOM_PATCH}" ]; then + patch_dir="${WORKDIR}/wolfssl-patches/linuxkm/patches/${WOLFSSL_KERNEL_RANDOM_PATCH}" + + if [ ! -d "$patch_dir" ]; then + bbfatal "wolfSSL: Patch directory not found: $patch_dir" + bbfatal "wolfSSL: Check available patches at https://github.com/wolfSSL/wolfssl/tree/master/linuxkm/patches" + fi + + bbnote "wolfSSL: Applying kernel randomness patches from: $patch_dir" + + # Apply all patches in the directory + for patch_file in "$patch_dir"/*.patch; do + if [ -f "$patch_file" ]; then + bbnote "wolfSSL: Applying patch: $(basename $patch_file)" + + # Check if patch is already applied + if patch -p1 -R --dry-run -d ${S} < "$patch_file" >/dev/null 2>&1; then + bbnote "wolfSSL: Patch already applied, skipping: $(basename $patch_file)" + else + patch -p1 -d ${S} < "$patch_file" || { + bbfatal "wolfSSL: Failed to apply patch: $patch_file" + } + fi + fi + done + + bbnote "wolfSSL: Kernel randomness patches applied successfully." + else + bbnote "wolfSSL: WOLFSSL_KERNEL_RANDOM_PATCH not set, skipping kernel patching." + fi +} diff --git a/classes/wolfssl-osp-support.bbclass b/classes/wolfssl-osp-support.bbclass new file mode 100644 index 00000000..17d74f87 --- /dev/null +++ b/classes/wolfssl-osp-support.bbclass @@ -0,0 +1,236 @@ +# wolfSSL Open Source Package Support Class +# +# This class provides helper functions for conditionally enabling wolfSSL backends +# in open source packages (like libgcrypt, OpenSSH, etc.) +# +# Usage Examples: +# +# Example 1: Package that only works with FIPS (like libgcrypt) +# inherit wolfssl-osp-support +# +# python __anonymous() { +# wolfssl_osp_conditional_include( +# d, +# feature_name='libgcrypt', +# inc_file='recipes-support/libgcrypt/libgcrypt-enable-wolfssl.inc', +# allowed_providers=['wolfssl-fips'] # FIPS only +# ) +# } +# +# Example 2: Package that works with both standard and FIPS (hypothetical) +# inherit wolfssl-osp-support +# +# python __anonymous() { +# wolfssl_osp_conditional_include( +# d, +# feature_name='openssh', +# inc_file='recipes-connectivity/openssh/openssh-enable-wolfssl.inc', +# allowed_providers=['wolfssl', 'wolfssl-fips'] # Both supported +# ) +# } +# +# Example 3: Package that only works with standard wolfSSL (hypothetical) +# inherit wolfssl-osp-support +# +# python __anonymous() { +# wolfssl_osp_conditional_include( +# d, +# feature_name='curl', +# inc_file='recipes-support/curl/curl-enable-wolfssl.inc', +# allowed_providers=['wolfssl'] # Standard only +# ) +# } + +def wolfssl_osp_conditional_include(d, feature_name, inc_file, allowed_providers=None): + """ + Conditionally include a configuration file based on WOLFSSL_FEATURES and provider. + + Args: + d: BitBake datastore + feature_name: Name to check in WOLFSSL_FEATURES (e.g., 'libgcrypt') + inc_file: Relative path to .inc file from layer root + allowed_providers: List of allowed providers (e.g., ['wolfssl', 'wolfssl-fips']) + If None, defaults to ['wolfssl', 'wolfssl-fips'] + + Returns: + True if configuration was included, False otherwise + """ + import os + + # Default to allowing both providers if not specified + if allowed_providers is None: + allowed_providers = ['wolfssl', 'wolfssl-fips'] + + # Check if feature is explicitly enabled in WOLFSSL_FEATURES + wolfssl_features = d.getVar('WOLFSSL_FEATURES') or '' + feature_enabled = feature_name in wolfssl_features.split() + + if not feature_enabled: + bb.debug(2, f"{feature_name} not in WOLFSSL_FEATURES - skipping wolfSSL backend") + return False + + # Check current provider + current_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or 'wolfssl' + + # Check if current provider is in the allowed list + if current_provider not in allowed_providers: + bb.note(f"{feature_name}: PREFERRED_PROVIDER is '{current_provider}', but only {allowed_providers} are supported - skipping wolfSSL backend") + return False + + # Both conditions met - include the configuration + bb.note(f"{feature_name}: WOLFSSL_FEATURES enabled + provider '{current_provider}' allowed - enabling wolfSSL backend") + + # Resolve full path to include file + layer_dir = d.getVar('WOLFSSL_LAYERDIR') + if not layer_dir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + full_inc_file = os.path.join(layer_dir, inc_file) + + # Include the configuration file + try: + bb.parse.handle(full_inc_file, d, include=True) + bb.debug(1, f"Successfully included {full_inc_file}") + return True + except FileNotFoundError: + bb.fatal(f"Configuration file not found: {full_inc_file}") + except Exception as e: + bb.fatal(f"Failed to include {full_inc_file}: {e}") + + return False + +def wolfssl_conditional_include_ext(d, enable_for, inc_file, allowed_providers=None): + """ + Conditionally include a configuration file based on IMAGE_INSTALL, WOLFSSL_FEATURES, and provider. + + Args: + d: BitBake datastore + enable_for: Name to check in IMAGE_INSTALL and WOLFSSL_FEATURES (e.g., 'wolfprovider') + inc_file: Relative path to .inc file from layer root + allowed_providers: List of allowed providers (e.g., ['wolfssl', 'wolfssl-fips']) + If None, defaults to ['wolfssl', 'wolfssl-fips'] + + Returns: + True if configuration was included, False otherwise + """ + import os + + # Default to allowing both providers if not specified + if allowed_providers is None: + allowed_providers = ['wolfssl', 'wolfssl-fips'] + + # Check if feature is in IMAGE_INSTALL or WOLFSSL_FEATURES + if not (bb.utils.contains('WOLFSSL_FEATURES', enable_for, True, False, d) or + bb.utils.contains('IMAGE_INSTALL', enable_for, True, False, d)): + bb.debug(2, f"{enable_for} not in WOLFSSL_FEATURES or IMAGE_INSTALL - skipping wolfSSL backend") + return False + + # Check current provider + current_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or 'wolfssl' + + # Check if current provider is in the allowed list + if current_provider not in allowed_providers: + bb.note(f"{enable_for}: PREFERRED_PROVIDER is '{current_provider}', but only {allowed_providers} are supported - skipping wolfSSL backend") + return False + + # All conditions met - include the configuration + bb.note(f"{enable_for}: IMAGE_INSTALL/WOLFSSL_FEATURES enabled + provider '{current_provider}' allowed - enabling wolfSSL backend") + + # Resolve full path to include file + layer_dir = d.getVar('WOLFSSL_LAYERDIR') + if not layer_dir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + full_inc_file = os.path.join(layer_dir, inc_file) + + # Include the configuration file + try: + bb.parse.handle(full_inc_file, d, include=True) + bb.debug(1, f"Successfully included {full_inc_file}") + return True + except FileNotFoundError: + bb.fatal(f"Configuration file not found: {full_inc_file}") + except Exception as e: + bb.fatal(f"Failed to include {full_inc_file}: {e}") + + return False + +def wolfssl_osp_check_provider(d, allowed_providers=None): + """ + Check if the current wolfSSL provider is in the allowed list. + + Args: + d: BitBake datastore + allowed_providers: List of allowed providers + + Returns: + Current provider if allowed, None otherwise + """ + if allowed_providers is None: + allowed_providers = ['wolfssl', 'wolfssl-fips'] + + current_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or 'wolfssl' + + if current_provider in allowed_providers: + return current_provider + + return None + +def wolfssl_osp_check_feature(d, feature_name): + """ + Check if a feature is enabled in WOLFSSL_FEATURES. + + Args: + d: BitBake datastore + feature_name: Name to check in WOLFSSL_FEATURES + + Returns: + True if enabled, False otherwise + """ + wolfssl_features = d.getVar('WOLFSSL_FEATURES') or '' + return feature_name in wolfssl_features.split() + +def wolfssl_osp_include_if_provider(d, inc_file, allowed_providers): + """ + Include a configuration file if the current provider is in the allowed list. + Used for image-specific configurations without WOLFSSL_FEATURES check. + + Args: + d: BitBake datastore + inc_file: Relative path to .inc file from layer root + allowed_providers: List of allowed providers (e.g., ['wolfssl-fips']) + + Returns: + True if configuration was included, False otherwise + """ + import os + + # Check current provider + current_provider = d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') or 'wolfssl' + + # Check if current provider is in the allowed list + if current_provider not in allowed_providers: + bb.debug(2, f"Current provider '{current_provider}' not in {allowed_providers} - skipping configuration") + return False + + bb.note(f"Provider '{current_provider}' matches - including {inc_file}") + + # Resolve full path to include file + layer_dir = d.getVar('WOLFSSL_LAYERDIR') + if not layer_dir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + full_inc_file = os.path.join(layer_dir, inc_file) + + # Include the configuration file + try: + bb.parse.handle(full_inc_file, d, include=True) + bb.debug(1, f"Successfully included {full_inc_file}") + return True + except FileNotFoundError: + bb.fatal(f"Configuration file not found: {full_inc_file}") + except Exception as e: + bb.fatal(f"Failed to include {full_inc_file}: {e}") + + return False + diff --git a/conf/layer.conf b/conf/layer.conf index 1d03b63b..d1dcbd8d 100644 --- a/conf/layer.conf +++ b/conf/layer.conf @@ -1,89 +1,49 @@ # We have a conf and classes directory, add to BBPATH BBPATH := "${LAYERDIR}:${BBPATH}" +# Make meta-wolfssl layer directory available to all recipes and bbappends +WOLFSSL_LAYERDIR = "${LAYERDIR}" + # We have a packages directory, add to BBFILES BBFILES += "${LAYERDIR}/recipes-wolfssl/wolfssl/*.bb \ - ${LAYERDIR}/recipes-wolfssl/wolfssl/*.bbappend" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfssl', \ - '${LAYERDIR}/recipes-wolfssl/wolfssl/*.bb ${LAYERDIR}/recipes-wolfssl/wolfssl/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfclu', \ - '${LAYERDIR}/recipes-wolfssl/wolfclu/*.bb ${LAYERDIR}/recipes-wolfssl/wolfclu/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfcryptbenchmark', \ - '${LAYERDIR}/recipes-examples/wolfcrypt/wolfcryptbenchmark/*.bb ${LAYERDIR}/recipes-examples/wolfcrypt/wolfcryptbenchmark/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfcrypttest', \ - '${LAYERDIR}/recipes-examples/wolfcrypt/wolfcrypttest/*.bb ${LAYERDIR}/recipes-examples/wolfcrypt/wolfcrypttest/*.bbappend' , \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfssh', \ - '${LAYERDIR}/recipes-wolfssl/wolfssh/*.bb ${LAYERDIR}/recipes-wolfssl/wolfssh/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfmqtt', \ - '${LAYERDIR}/recipes-wolfssl/wolfmqtt/*.bb ${LAYERDIR}/recipes-wolfssl/wolfmqtt/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfpkcs11', \ - '${LAYERDIR}/recipes-wolfssl/wolfpkcs11/*.bb ${LAYERDIR}/recipes-wolfssl/wolfpkcs11/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolftpm', \ - '${LAYERDIR}/recipes-wolfssl/wolftpm/*.bb ${LAYERDIR}/recipes-wolfssl/wolftpm/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolftpm-wrap-test', \ - '${LAYERDIR}/recipes-examples/wolftpm/*.bb ${LAYERDIR}/recipes-examples/wolftpm/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfssl-py', \ - '${LAYERDIR}/recipes-wolfssl/wolfssl-py/*.bb ${LAYERDIR}/recipes-wolfssl/wolfssl-py/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfcrypt-py', \ - '${LAYERDIR}/recipes-wolfssl/wolfcrypt-py/*.bb ${LAYERDIR}/recipes-wolfssl/wolfcrypt-py/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolf-py-tests', \ - '${LAYERDIR}/recipes-examples/wolfssl-py/wolf-py-tests/*.bb ${LAYERDIR}/recipes-examples/wolfssl-py/wolf-py-tests/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfprovider', \ - '${LAYERDIR}/recipes-wolfssl/wolfprovider/*.bb ${LAYERDIR}/recipes-wolfssl/wolfprovider/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfprovidertest', \ - '${LAYERDIR}/recipes-examples/wolfprovider/wolfprovidertest/*.bb', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfengine', \ - '${LAYERDIR}/recipes-wolfssl/wolfengine/*.bb ${LAYERDIR}/recipes-wolfssl/wolfengine/*.bbappend', \ - '', d)}" - -BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ - 'wolfenginetest', \ - '${LAYERDIR}/recipes-examples/wolfengine/wolfenginetest/*.bb ${LAYERDIR}/recipes-examples/wolfengine/wolfenginetest/*.bbappend', \ - '', d)}" + ${LAYERDIR}/recipes-wolfssl/wolfssl/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfclu/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfclu/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfssh/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfssh/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfmqtt/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfmqtt/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolftpm/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolftpm/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfpkcs11/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfpkcs11/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfssl-py/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfssl-py/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfcrypt-py/*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfcrypt-py/*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfprovider/wolfprovider*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfprovider/wolfprovider*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfprovider/wolfssl*.bbappend \ + ${LAYERDIR}/recipes-wolfssl/wolfengine/wolfengine*.bb \ + ${LAYERDIR}/recipes-wolfssl/wolfengine/wolfssl*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfcrypt/wolfcryptbenchmark/*.bb \ + ${LAYERDIR}/recipes-examples/wolfcrypt/wolfcryptbenchmark/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfcrypt/wolfcrypttest/*.bb \ + ${LAYERDIR}/recipes-examples/wolfcrypt/wolfcrypttest/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolftpm/*.bb \ + ${LAYERDIR}/recipes-examples/wolftpm/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfssl-py/wolf-py-tests/*.bb \ + ${LAYERDIR}/recipes-examples/wolfssl-py/wolf-py-tests/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfprovider/wolfprovidertest/*.bb \ + ${LAYERDIR}/recipes-examples/wolfprovider/wolfprovidertest/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfprovider/wolfprovidercmd/*.bb \ + ${LAYERDIR}/recipes-examples/wolfprovider/wolfprovidercmd/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfprovider/wolfproviderenv/*.bb \ + ${LAYERDIR}/recipes-examples/wolfprovider/wolfproviderenv/*.bbappend \ + ${LAYERDIR}/recipes-examples/wolfengine/wolfenginetest/*.bb \ + ${LAYERDIR}/recipes-examples/wolfengine/wolfenginetest/*.bbappend \ + ${LAYERDIR}/recipes-support/gnutls/*.bbappend \ + ${LAYERDIR}/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb" # Uncomment if building bind with wolfSSL. #BBFILES += "${LAYERDIR}/recipes-connectivity/bind/*.bbappend" @@ -123,8 +83,23 @@ BBFILES += "${@bb.utils.contains('IMAGE_INSTALL', \ BBFILE_COLLECTIONS += "wolfssl" BBFILE_PATTERN_wolfssl := "^${LAYERDIR}/" +# When doing a build with replace default mode enabled, we need to prioritize the wolfssl layer BBFILE_PRIORITY_wolfssl = "5" +# Weak default preferred providers for wolf libraries +# These can be overridden by local.conf or distro configurations +PREFERRED_PROVIDER_virtual/wolfssl ??= "wolfssl" +PREFERRED_PROVIDER_wolfssl ??= "wolfssl" +PREFERRED_PROVIDER_wolfssh ??= "wolfssh" +PREFERRED_PROVIDER_wolfmqtt ??= "wolfmqtt" +PREFERRED_PROVIDER_wolftpm ??= "wolftpm" +PREFERRED_PROVIDER_wolfclu ??= "wolfclu" +PREFERRED_PROVIDER_wolfpkcs11 ??= "wolfpkcs11" +PREFERRED_PROVIDER_wolfssl-py ??= "wolfssl-py" +PREFERRED_PROVIDER_wolfcrypt-py ??= "wolfcrypt-py" +PREFERRED_PROVIDER_wolfprovider ??= "wolfprovider" +PREFERRED_PROVIDER_wolfengine ??= "wolfengine" + BBFILES += "${@bb.utils.contains('WOLFSSL_TYPE', \ 'fips', \ '${LAYERDIR}/recipes-wolfssl/wolfssl/commercial/*.bbappend ${LAYERDIR}/recipes-wolfssl/wolfssl/commercial/fips-details/*.bbappend', \ @@ -161,6 +136,11 @@ BBFILES += "${@bb.utils.contains('WOLFTPM_TYPE', \ '${LAYERDIR}/recipes-wolfssl/wolftpm/commercial/*.bbappend ${LAYERDIR}/recipes-wolfssl/wolftpm/commercial/commercial-details/*.bbappend', \ '', d)}" +BBFILES += "${@bb.utils.contains('WOLFPKCS11_TYPE', \ + 'commercial', \ + '${LAYERDIR}/recipes-wolfssl/wolfpkcs11/commercial/*.bbappend ${LAYERDIR}/recipes-wolfssl/wolfpkcs11/commercial/commercial-details/*.bbappend', \ + '', d)}" + BBFILES += "${@bb.utils.contains('WOLFENGINE_TYPE', \ 'commercial', \ '${LAYERDIR}/recipes-wolfssl/wolfengine/commercial/*.bbappend ${LAYERDIR}/recipes-wolfssl/wolfengine/commercial/commercial-details/*.bbappend', \ @@ -171,5 +151,27 @@ BBFILES += "${@bb.utils.contains('WOLFPROVIDER_TYPE', \ '${LAYERDIR}/recipes-wolfssl/wolfprovider/commercial/*.bbappend ${LAYERDIR}/recipes-wolfssl/wolfprovider/commercial/commercial-details/*.bbappend', \ '', d)}" +# Conditionally include openssl bbappends when wolfengine is in IMAGE_INSTALL or WOLFSSL_FEATURES +BBFILES += "${@'${LAYERDIR}/recipes-wolfssl/wolfengine/openssl_1.%.bbappend' if (bb.utils.contains('WOLFSSL_FEATURES', 'wolfengine', True, False, d) or bb.utils.contains('IMAGE_INSTALL', 'wolfengine', True, False, d)) else ''}" + +# Conditionally include openssl bbappends when wolfprovider is in IMAGE_INSTALL or WOLFSSL_FEATURES +BBFILES += "${@'${LAYERDIR}/recipes-wolfssl/wolfprovider/openssl_3.%.bbappend' if (bb.utils.contains('WOLFSSL_FEATURES', 'wolfprovider', True, False, d) or bb.utils.contains('IMAGE_INSTALL', 'wolfprovider', True, False, d)) else ''}" + +# Conditionally include demo images when enabled via WOLFSSL_DEMOS +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfssl-image-minimal', '${LAYERDIR}/recipes-core/images/wolfssl-minimal-image/*.bb ${LAYERDIR}/recipes-core/images/wolfssl-minimal-image/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfclu-image-minimal', '${LAYERDIR}/recipes-core/images/wolfclu-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfclu-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolftpm-image-minimal', '${LAYERDIR}/recipes-core/images/wolftpm-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolftpm-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfssl-py-image-minimal', '${LAYERDIR}/recipes-core/images/wolfssl-py-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfssl-py-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfprovider-image-minimal', '${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfprovider-fips-image-minimal', '${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfprovider-replace-default-image-minimal', '${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfprovider-replace-default-fips-image-minimal', '${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-fips-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-fips-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfssl-combined-image-minimal', '${LAYERDIR}/recipes-core/images/wolfssl-combined-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfssl-combined-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'wolfclu-combined-image-minimal', '${LAYERDIR}/recipes-core/images/wolfclu-combined-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfclu-combined-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'libgcrypt-image-minimal', '${LAYERDIR}/recipes-core/images/libgcrypt-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/libgcrypt-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'gnutls-image-minimal', '${LAYERDIR}/recipes-core/images/gnutls-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/gnutls-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'gnutls-nonfips-image-minimal', '${LAYERDIR}/recipes-core/images/gnutls-nonfips-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/gnutls-nonfips-image-minimal/*.bbappend', '', d)}" +BBFILES += "${@bb.utils.contains('WOLFSSL_DEMOS', 'fips-image-minimal', '${LAYERDIR}/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/*.bb ${LAYERDIR}/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/*.bbappend', '', d)}" + # Versions of OpenEmbedded-Core which layer has been tested against LAYERSERIES_COMPAT_wolfssl = "sumo thud warrior zeus hardknott gatesgarth dunfell kirkstone nanbield langdale scarthgap" diff --git a/conf/wolfssl-fips.conf.sample b/conf/wolfssl-fips.conf.sample new file mode 100644 index 00000000..2c34885b --- /dev/null +++ b/conf/wolfssl-fips.conf.sample @@ -0,0 +1,58 @@ +# wolfSSL FIPS Configuration +# +# This file contains wolfSSL FIPS bundle settings. +# Include this file in your local.conf: +# require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +# +# Instructions: +# 1. Uncomment and set the variables below with your FIPS bundle details +# 2. Place your FIPS bundle in recipes-wolfssl/wolfssl/commercial/files/ +# (or set WOLFSSL_SRC_DIR to a custom location) +# 3. Build once to get the FIPS_HASH value +# 4. Set FIPS_HASH and rebuild + +# Use wolfSSL FIPS as the wolfSSL provider +PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips" +PREFERRED_PROVIDER_wolfssl = "wolfssl-fips" + +# Optional: Use wolfSSL FIPS Linux kernel module +# Uncomment to use the FIPS-validated kernel module instead of the standard one +#PREFERRED_PROVIDER_virtual/wolfssl-linuxkm = "wolfssl-linuxkm-fips" +#PREFERRED_PROVIDER_wolfssl-linuxkm = "wolfssl-linuxkm-fips" + +# FIPS hash mode: "auto" (QEMU-based extraction) or "manual" (use static FIPS_HASH) +WOLFSSL_FIPS_HASH_MODE ?= "manual" + +# ============================================================================ +# FIPS Bundle Configuration - EDIT THESE VALUES +# ============================================================================ + +# Bundle version +WOLFSSL_VERSION = "" + +# Bundle filename (without extension, used as extracted directory) +WOLFSSL_SRC = "" + +# Optional: override archive filename (e.g., .tar.gz instead of .7z) +#WOLFSSL_BUNDLE_FILE = "" + +# Bundle SHA256 checksum +WOLFSSL_SRC_SHA = "" + +# Bundle password (required for .7z archives, leave empty for tarballs) +WOLFSSL_SRC_PASS = "" + +# License file location and MD5 +WOLFSSL_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" +WOLFSSL_LICENSE_MD5 ?= "" + +# FIPS hash (set after first build - see instructions in commercial/README.md) +FIPS_HASH = "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + +# Optional: Custom bundle directory (uncomment to override default) +WOLFSSL_SRC_DIR = "" + +# ============================================================================ +# Contact support@wolfssl.com for commercial FIPS bundles +# See recipes-wolfssl/wolfssl/commercial/README.md for detailed instructions +# ============================================================================ diff --git a/inc/curl/curl-enable-wolfprovider-fips.inc b/inc/curl/curl-enable-wolfprovider-fips.inc new file mode 100644 index 00000000..14c1f6d5 --- /dev/null +++ b/inc/curl/curl-enable-wolfprovider-fips.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def curl_get_wolfprovider_fips_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("curl-enable-wolfprovider-fips.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/curl/%s/curl-enable-wolfprovider-fips-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/curl/%s/curl-enable-wolfprovider-fips-legacy.inc' % codename) + + bb.note("curl-enable-wolfprovider-fips.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@curl_get_wolfprovider_fips_inc(d)} diff --git a/inc/curl/scarthgap/curl-enable-wolfprovider-fips-modern.inc b/inc/curl/scarthgap/curl-enable-wolfprovider-fips-modern.inc new file mode 100644 index 00000000..4c889664 --- /dev/null +++ b/inc/curl/scarthgap/curl-enable-wolfprovider-fips-modern.inc @@ -0,0 +1,10 @@ +# Disable SHA-512/256 for wolfSSL FIPS compatibility +# +# wolfSSL FIPS does not include SHA-512/256 in its validated algorithm list. +# When using wolfProvider with wolfSSL FIPS, curl's SHA-512/256 based HTTP +# Digest authentication will fail at runtime since the algorithm is unavailable. +# +# By defining CURL_DISABLE_SHA512_256 at compile time, curl properly reports +# the feature as unavailable and tests that require it are skipped rather than +# failing. +CFLAGS:append = " -DCURL_DISABLE_SHA512_256" diff --git a/inc/gnupg/gnupg-enable-libgcrypt-wolfssl.inc b/inc/gnupg/gnupg-enable-libgcrypt-wolfssl.inc new file mode 100644 index 00000000..e0d9f9f3 --- /dev/null +++ b/inc/gnupg/gnupg-enable-libgcrypt-wolfssl.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def gnupg_get_libgcrypt_wolfssl_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("gnupg-enable-libgcrypt-wolfssl.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/gnupg/%s/gnupg-enable-libgcrypt-wolfssl-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/gnupg/%s/gnupg-enable-libgcrypt-wolfssl-legacy.inc' % codename) + + bb.note("gnupg-enable-libgcrypt-wolfssl.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@gnupg_get_libgcrypt_wolfssl_inc(d)} \ No newline at end of file diff --git a/inc/gnupg/scarthgap/files/gnupg-2.4.8-use-pkgconfig-for-libgcrypt.patch b/inc/gnupg/scarthgap/files/gnupg-2.4.8-use-pkgconfig-for-libgcrypt.patch new file mode 100644 index 00000000..9e1156d7 --- /dev/null +++ b/inc/gnupg/scarthgap/files/gnupg-2.4.8-use-pkgconfig-for-libgcrypt.patch @@ -0,0 +1,39 @@ +From 1234567890abcdef1234567890abcdef12345678 Mon Sep 17 00:00:00 2001 +From: Yocto User +Date: Wed, 26 Nov 2025 12:00:00 +0000 +Subject: [PATCH] configure.ac: use pkgconfig for libgcrypt detection + +Replace AM_PATH_LIBGCRYPT with PKG_CHECK_MODULES to use pkg-config +instead of libgcrypt-config for detection. + +Upstream-Status: Inappropriate [OE-specific] +Signed-off-by: Yocto User +--- + configure.ac | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 1234567..abcdefg 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -812,12 +812,12 @@ fi + # + # Libgcrypt is our generic crypto library + # +-AM_PATH_LIBGCRYPT("$NEED_LIBGCRYPT_API:$NEED_LIBGCRYPT_VERSION", +- have_libgcrypt=yes,have_libgcrypt=no) +-# And, then, check if it's newer than 1.9.0 so that we can +-# conditionally build some programs. +-# Note: This is not anymore needed but keep the code commented in case +-# we need it again with some future libgcrypt. ++PKG_CHECK_MODULES([LIBGCRYPT], [libgcrypt >= $NEED_LIBGCRYPT_VERSION], [ ++ have_libgcrypt=yes ++ LIBGCRYPT_VERSION=`$PKG_CONFIG --modversion libgcrypt` ++], [have_libgcrypt=no]) ++AC_SUBST(LIBGCRYPT_CFLAGS) ++AC_SUBST(LIBGCRYPT_LIBS) + #have_libgcrypt_newer=no + #if test $ok = yes; then + # if test "$major" -gt 1; then +-- +2.34.1 diff --git a/inc/gnupg/scarthgap/gnupg-enable-libgcrypt-wolfssl-modern.inc b/inc/gnupg/scarthgap/gnupg-enable-libgcrypt-wolfssl-modern.inc new file mode 100644 index 00000000..7e2bad53 --- /dev/null +++ b/inc/gnupg/scarthgap/gnupg-enable-libgcrypt-wolfssl-modern.inc @@ -0,0 +1,3 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +SRC_URI += "file://gnupg-2.4.8-use-pkgconfig-for-libgcrypt.patch" diff --git a/inc/gnutls/gnutls-enable-wolfssl.inc b/inc/gnutls/gnutls-enable-wolfssl.inc new file mode 100644 index 00000000..06a9e87d --- /dev/null +++ b/inc/gnutls/gnutls-enable-wolfssl.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def gnutls_get_wolfssl_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("gnutls-enable-wolfssl.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/gnutls/%s/gnutls-enable-wolfssl-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/gnutls/%s/gnutls-enable-wolfssl-legacy.inc' % codename) + + bb.note("gnutls-enable-wolfssl.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@gnutls_get_wolfssl_inc(d)} diff --git a/inc/gnutls/scarthgap/files/0001-creating-hmac-file-should-be-excuted-in-target-envi.patch b/inc/gnutls/scarthgap/files/0001-creating-hmac-file-should-be-excuted-in-target-envi.patch new file mode 100644 index 00000000..4633213f --- /dev/null +++ b/inc/gnutls/scarthgap/files/0001-creating-hmac-file-should-be-excuted-in-target-envi.patch @@ -0,0 +1,32 @@ +From b729a356538d499fe25e82bfc78ea663bdaca0a8 Mon Sep 17 00:00:00 2001 +From: Reda Chouk +Date: Wed, 12 Nov 2025 11:10:00 +0000 +Subject: [PATCH] Creating .hmac file should be executed in target environment + +Creating .hmac file should be executed in target environment during +post-installation, not during the cross-compilation build process. +This avoids the need to run target binaries during cross-compilation. + +Upstream-Status: Inappropriate [cross-compilation issue for Yocto/OE builds] + +Signed-off-by: Reda Chouk +--- + lib/Makefile.am | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/Makefile.am b/lib/Makefile.am +index 56576b65f..a90a74655 100644 +--- a/lib/Makefile.am ++++ b/lib/Makefile.am +@@ -257,8 +257,7 @@ hmac_file = .libs/.$(gnutls_so).hmac + + all-local: $(hmac_file) + +-$(hmac_file): libgnutls.la fipshmac +- $(AM_V_GEN) $(builddir)/fipshmac > $@-t && mv $@-t $@ ++$(hmac_file): + + CLEANFILES = $(hmac_file) + endif +-- +2.25.1 diff --git a/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc b/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc new file mode 100644 index 00000000..9ecf9c0f --- /dev/null +++ b/inc/gnutls/scarthgap/gnutls-enable-wolfssl-modern.inc @@ -0,0 +1,61 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +# Override version and source for target builds only +PV:class-target = "3.8.11+git${SRCPV}" +LIC_FILES_CHKSUM:class-target = "file://COPYING;md5=1ebbd3e34237af26da5dc08a4e440464 \ + file://COPYING.LESSERv2;md5=4bf661c1e3793e55c8d1051bc5e0ae21" + +# Add gnutls-wolfssl specific dependencies +DEPENDS:append:class-target = " virtual/wolfssl libunistring gmp nettle libtasn1 p11-kit zlib \ + bison-native libtasn1-native gperf-native gtk-doc-native gettext-native \ + autoconf-native automake-native libtool-native" +RDEPENDS:${PN}:append:class-target = " wolfssl" + +# Use wolfSSL fork of gnutls +SRC_URI:class-target = "git://github.com/wolfSSL/gnutls.git;protocol=https;branch=gnutls-wolfssl-3.8.11 \ + file://0001-creating-hmac-file-should-be-excuted-in-target-envi.patch \ +" +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 ''}" + +# Configure options for wolfSSL backend +EXTRA_OECONF:class-target = "\ + --disable-doc \ + --disable-manpages \ + --disable-gtk-doc \ + --disable-gost \ + --disable-dsa \ + --disable-full-test-suite \ + --disable-valgrind-tests \ + --disable-dependency-tracking \ + --enable-srp-authentication \ + --enable-fips140-mode \ + ${@'--enable-fips140-mode' if d.getVar('PREFERRED_PROVIDER_virtual/wolfssl') == 'wolfssl-fips' else ''} \ +" + +TARGET_CFLAGS:append:class-target = " -DGNUTLS_WOLFSSL" + +# Create dummy files so base prepend doesn't fail +do_configure:prepend:class-target() { + touch ${WORKDIR}/04939b75417cc95b7372c6f208c4bda4579bdc34 + touch ${WORKDIR}/5477db1bb507a35e8833c758ce344f4b5b246d8e + touch ${WORKDIR}/3e94dcdff862ef5d6db8b5cc8e59310b5f0cdfe2 +} + +do_configure:class-target() { + cd ${S} + if [ ! -f configure ]; then + bbnote "Running bootstrap..." + ./bootstrap + fi + bbnote "Running autoreconf..." + autoreconf -fvi + bbnote "Running configure..." + oe_runconf +} + +do_configure[network] = "1" diff --git a/inc/libgcrypt/libgcrypt-enable-wolfssl.inc b/inc/libgcrypt/libgcrypt-enable-wolfssl.inc new file mode 100644 index 00000000..0bbdbeb5 --- /dev/null +++ b/inc/libgcrypt/libgcrypt-enable-wolfssl.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def libgcrypt_get_wolfssl_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("libgcrypt-enable-wolfssl.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/libgcrypt/%s/libgcrypt-enable-wolfssl-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/libgcrypt/%s/libgcrypt-enable-wolfssl-legacy.inc' % codename) + + bb.note("libgcrypt-enable-wolfssl.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@libgcrypt_get_wolfssl_inc(d)} \ No newline at end of file diff --git a/inc/libgcrypt/scarthgap/files/wc_ptest-fixes.patch b/inc/libgcrypt/scarthgap/files/wc_ptest-fixes.patch new file mode 100644 index 00000000..0d3d05ee --- /dev/null +++ b/inc/libgcrypt/scarthgap/files/wc_ptest-fixes.patch @@ -0,0 +1,38 @@ +Disable gpg-error.h include and problematic tests in ptest. +The gpg-error.h include is optional and not needed for building testdrv. +The fips186-dsa and dsa-rfc6979 tests are not installed on the system. +The benchmark tests will hang due to GCM implementation in wolfSSL/libgcrypt port. + +Upstream-Status: Inappropriate +Signed-off-by: wolfSSL + +diff --git a/tests/testdrv.c b/tests/testdrv.c +index bfca4c23..88fae58f 100644 +--- a/tests/testdrv.c ++++ b/tests/testdrv.c +@@ -32,7 +32,6 @@ + # include + # include + #endif +-#include /* For some macros. */ + + #include "stopwatch.h" + +@@ -67,17 +66,13 @@ static struct { + { "hashtest" }, + { "t-kdf" }, + { "keygrip" }, +- { "fips186-dsa" }, + { "aeswrap" }, + { "pkcs1v2" }, + { "random" }, +- { "dsa-rfc6979" }, + { "t-ed25519" }, + { "t-cv25519" }, + { "t-x448" }, + { "t-ed448" }, +- { "benchmark" }, +- { "bench-slope" }, + { "hashtest-6g", "hashtest", "--hugeblock --gigs 6 SHA1 SHA256 SHA512 " + "SHA3-512 SM3 BLAKE2S_256 " + "BLAKE2B_512 CRC32 " diff --git a/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc b/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc new file mode 100644 index 00000000..d168294b --- /dev/null +++ b/inc/libgcrypt/scarthgap/libgcrypt-enable-wolfssl-modern.inc @@ -0,0 +1,52 @@ +# 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. + +# Override to use custom git repo and version - TARGET ONLY + +# Set your desired version +PV:class-target = "1.11.0" + +# Update license checksums for version 1.11.0 +LIC_FILES_CHKSUM:class-target = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263 \ + file://COPYING.LIB;md5=4fbd65380cdd255951079008b364516c \ + file://LICENSES;md5=034b4e369944ad4b52a68368f1cf98b8 \ + " + +# 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 \ + file://run-ptest \ + file://wc_ptest-fixes.patch \ + " + +# Set to specific commit hash or use "${AUTOREV}" for latest +SRCREV:class-target = "${AUTOREV}" + +# Source directory for git checkouts +S:class-target = "${WORKDIR}/git" + +# Add patch directory to file search path +# Patches are in files/ subdirectory relative to this .inc file +FILESEXTRAPATHS:prepend:class-target := "${WOLFSSL_LAYERDIR}/inc/libgcrypt/scarthgap/files:" +# Add wolfssl as dependency +DEPENDS:append:class-target = " virtual/wolfssl" +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" + +# In FIPS mode, some tests are excluded - install only tests that were actually built +do_install_ptest:class-target() { + cd ${B}/tests + oe_runmake testdrv-build testdrv + for f in testdrv $(srcdir=${S}/tests ./testdrv-build --files | sort | uniq); do + if [ -f "$f" ]; then + install "$f" ${D}${PTEST_PATH} + fi + done + # Install the run-ptest script from the base recipe + if [ -f ${WORKDIR}/run-ptest ]; then + install -m 0755 ${WORKDIR}/run-ptest ${D}${PTEST_PATH} + fi +} diff --git a/inc/librelp/librelp-ptest.inc b/inc/librelp/librelp-ptest.inc new file mode 100644 index 00000000..60296ac2 --- /dev/null +++ b/inc/librelp/librelp-ptest.inc @@ -0,0 +1,31 @@ +# Check Yocto version and include appropriate file +def librelp_get_ptest_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("librelp-ptest.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + # Determine file type + file_type = 'modern' if use_modern else 'legacy' + + # Use codename-specific path + layerdir = d.getVar('WOLFSSL_LAYERDIR') + inc_file = os.path.join(layerdir, 'inc/librelp/%s/librelp-ptest-%s.inc' % (codename, file_type)) + + bb.note("librelp-ptest.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@librelp_get_ptest_inc(d)} diff --git a/inc/librelp/scarthgap/files/librelp-ptest.patch b/inc/librelp/scarthgap/files/librelp-ptest.patch new file mode 100644 index 00000000..0c9a7570 --- /dev/null +++ b/inc/librelp/scarthgap/files/librelp-ptest.patch @@ -0,0 +1,71 @@ +From 8ad60c7887c78364fd208e96359f3cf033cb8e48 Mon Sep 17 00:00:00 2001 +From: WolfSSL +Date: Tue, 16 Dec 2025 18:55:00 -0800 +Subject: [PATCH] tests: add Valgrind suppression for glibc ld.so strlen false + positives + +glibc's dynamic loader uses optimized strlen() implementations +that may read past the end of allocated strings while loading +shared objects via dlopen(). + +Valgrind reports this behavior as "Invalid read of size 16", +even though it is safe and expected. This causes noise when +running the librelp test suite under Valgrind, especially when +TLS backends are loaded dynamically. + +Add a Valgrind suppression file and enable it in the test +framework to filter out these known false positives. + +No functional changes. + +Signed-off-by: WolfSSL +--- + tests/test-framework.sh | 8 ++++---- + tests/valgrind.supp | 11 +++++++++++ + 2 files changed, 15 insertions(+), 4 deletions(-) + create mode 100644 tests/valgrind.supp + +diff --git a/tests/test-framework.sh b/tests/test-framework.sh +index 9ac2c56..b4d489f 100644 +--- a/tests/test-framework.sh ++++ b/tests/test-framework.sh +@@ -4,9 +4,9 @@ + # Copyright (C) 2018 by Rainer Gerhards + + # "config settings" for the testbench +-TB_TIMEOUT_STARTUP=400 # 40 seconds - Solaris sometimes needs this... ++TB_TIMEOUT_STARTUP=2000 # Extend timeout for FIPS + export LIBRELP_DYN="$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head --bytes 4)" +-export valgrind="valgrind --malloc-fill=ff --free-fill=fe --log-fd=1" ++export valgrind="valgrind --malloc-fill=ff --free-fill=fe --log-fd=1 --suppressions=$PWD/valgrind.supp" + # **** use the line below for very hard to find leaks! ***** + # export valgrind="valgrind --malloc-fill=ff --free-fill=fe --log-fd=1 --leak-check=full --show-leak-kinds=all" + # export OPT_VERBOSE=-v # uncomment for debugging +@@ -67,8 +67,8 @@ startup_receiver_valgrind() { + printf 'libtool command not available, cannot run under valgrind\n' + exit 77 + fi +- printf 'Starting Receiver...\n' +- libtool --mode=execute $valgrind ./receive $TLSLIB -p $TESTPORT -O $OUTFILE.2 -F $RECEIVE_PIDFILE $OPT_VERBOSE $* & ++ printf 'Starting Receiver with extended timeout for FIPS and valgrind...\n' ++ libtool --mode=execute $valgrind ./receive $TLSLIB -W 300 -p $TESTPORT -O $OUTFILE.2 -F $RECEIVE_PIDFILE $OPT_VERBOSE $* & + export RECEIVE_PID=$! + printf "got $RECEIVE_PID $RECEIVE_PIDFILE\n" + wait_process_startup_via_pidfile $RECEIVE_PIDFILE +diff --git a/tests/valgrind.supp b/tests/valgrind.supp +new file mode 100644 +index 0000000..c8807f3 +--- /dev/null ++++ b/tests/valgrind.supp +@@ -0,0 +1,11 @@ ++# Suppress glibc ld.so false positives caused by ++# optimized strlen() reading past the NUL terminator ++# Seen when librelp dynamically loads TLS backends ++ ++{ ++ glibc_ldso_dlopen_strlen ++ Memcheck:Addr16 ++ fun:strlen ++ fun:_dl_new_object ++ ... ++} diff --git a/inc/librelp/scarthgap/librelp-ptest-modern.inc b/inc/librelp/scarthgap/librelp-ptest-modern.inc new file mode 100644 index 00000000..93df8959 --- /dev/null +++ b/inc/librelp/scarthgap/librelp-ptest-modern.inc @@ -0,0 +1,2 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" +SRC_URI:append:class-target = " file://librelp-ptest.patch" diff --git a/inc/libssh/libssh-enable-libgcrypt-wolfssl.inc b/inc/libssh/libssh-enable-libgcrypt-wolfssl.inc new file mode 100644 index 00000000..fb4e9cf1 --- /dev/null +++ b/inc/libssh/libssh-enable-libgcrypt-wolfssl.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def libssh_get_libgcrypt_wolfssl_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("libssh-enable-libgcrypt-wolfssl.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/libssh/%s/libssh-enable-libgcrypt-wolfssl-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/libssh/%s/libssh-enable-libgcrypt-wolfssl-legacy.inc' % codename) + + bb.note("libssh-enable-libgcrypt-wolfssl.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@libssh_get_libgcrypt_wolfssl_inc(d)} diff --git a/inc/libssh/scarthgap/files/enable-fips-mode.patch b/inc/libssh/scarthgap/files/enable-fips-mode.patch new file mode 100644 index 00000000..d5227ae2 --- /dev/null +++ b/inc/libssh/scarthgap/files/enable-fips-mode.patch @@ -0,0 +1,29 @@ +From: WolfSSL +Date: Tue, 17 Dec 2024 00:00:00 +0000 +Subject: [PATCH] Enable FIPS mode for libssh with libgcrypt backend + +Hardcode ssh_fips_mode() to return true to enable FIPS mode in libssh +when using the libgcrypt backend. + +Upstream-Status: Inappropriate [configuration] + +Signed-off-by: WolfSSL +--- + include/libssh/libgcrypt.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/libssh/libgcrypt.h b/include/libssh/libgcrypt.h +index 1234567..abcdefg 100644 +--- a/include/libssh/libgcrypt.h ++++ b/include/libssh/libgcrypt.h +@@ -115,7 +115,7 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp, + enum gcry_mpi_format informat, + enum gcry_mpi_format outformat); + +-#define ssh_fips_mode() false ++#define ssh_fips_mode() true + + #ifdef __cplusplus + } +-- +2.34.1 diff --git a/inc/libssh/scarthgap/libssh-enable-libgcrypt-wolfssl-modern.inc b/inc/libssh/scarthgap/libssh-enable-libgcrypt-wolfssl-modern.inc new file mode 100644 index 00000000..68c3d24b --- /dev/null +++ b/inc/libssh/scarthgap/libssh-enable-libgcrypt-wolfssl-modern.inc @@ -0,0 +1,5 @@ +# Disable chacha20-poly1305 in libssh when using libgcrypt-wolfssl backend +# wolfSSL-backed libgcrypt does not support chacha20 cipher in FIPS mode + +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" +SRC_URI += "file://enable-fips-mode.patch" diff --git a/inc/nettle/nettle.inc b/inc/nettle/nettle.inc new file mode 100644 index 00000000..f8e83872 --- /dev/null +++ b/inc/nettle/nettle.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def nettle_get_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("nettle.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/nettle/%s/nettle-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/nettle/%s/nettle-legacy.inc' % codename) + + bb.note("nettle.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@nettle_get_inc(d)} diff --git a/inc/nettle/scarthgap/files/run-ptest b/inc/nettle/scarthgap/files/run-ptest new file mode 100644 index 00000000..61a43c78 --- /dev/null +++ b/inc/nettle/scarthgap/files/run-ptest @@ -0,0 +1,40 @@ +#! /bin/sh + +cd testsuite + +failed=0 +all=0 + +for f in *-test; do + case "$f" in + "sha1-huge-test") + echo "SKIP: $f (long run time)" + ;; + "symbols-test") + echo "SKIP: $f (needs static libraries)" + ;; + *) + "./$f" + case "$?" in + 0) + echo "PASS: $f" + all=$((all + 1)) + ;; + 77) + echo "SKIP: $f" + ;; + *) + echo "FAIL: $f" + failed=$((failed + 1)) + all=$((all + 1)) + ;; + esac + ;; + esac +done + +if [ "$failed" -eq 0 ] ; then + echo "All $all tests passed" +else + echo "$failed of $all tests failed" +fi diff --git a/inc/nettle/scarthgap/nettle-modern.inc b/inc/nettle/scarthgap/nettle-modern.inc new file mode 100644 index 00000000..bc044e7e --- /dev/null +++ b/inc/nettle/scarthgap/nettle-modern.inc @@ -0,0 +1,62 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" + +PV = "3.10" +SUMMARY = "A low level cryptographic library" +DESCRIPTION = "Nettle is a cryptographic library that is designed to fit easily in more or less any context: In crypto toolkits for object-oriented languages (C++, Python, Pike, ...), in applications like LSH or GNUPG, or even in kernel space." +HOMEPAGE = "http://www.lysator.liu.se/~nisse/nettle/" +DESCRIPTION = "It tries to solve a problem of providing a common set of \ +cryptographic algorithms for higher-level applications by implementing a \ +context-independent set of cryptographic algorithms" +SECTION = "libs" +LICENSE = "LGPL-3.0-or-later | GPL-2.0-or-later" + +LIC_FILES_CHKSUM = "file://COPYING.LESSERv3;md5=6a6a8e020838b23406c81b19c1d46df6 \ + file://COPYINGv2;md5=b234ee4d69f5fce4486a80fdaf4a4263 \ + file://serpent-decrypt.c;beginline=14;endline=36;md5=ca0d220bc413e1842ecc507690ce416e \ + file://serpent-set-key.c;beginline=14;endline=36;md5=ca0d220bc413e1842ecc507690ce416e" + +DEPENDS += "gmp" + +SRC_URI = "${GNU_MIRROR}/${BPN}/${BP}.tar.gz \ + file://run-ptest \ + " + +SRC_URI[sha256sum] = "b4c518adb174e484cb4acea54118f02380c7133771e7e9beb98a0787194ee47c" + +UPSTREAM_CHECK_REGEX = "nettle-(?P\d+(\.\d+)+)\.tar" + +inherit autotools ptest multilib_header lib_package + +EXTRA_AUTORECONF += "--exclude=aclocal" + +EXTRA_OECONF = "--disable-openssl" + +EXTRA_OECONF:append:armv7a = "${@bb.utils.contains("TUNE_FEATURES","neon",""," --disable-arm-neon --disable-fat",d)}" +EXTRA_OECONF:append:armv7ve = "${@bb.utils.contains("TUNE_FEATURES","neon",""," --disable-arm-neon --disable-fat",d)}" + +do_compile_ptest() { + oe_runmake -C testsuite +} + +# Note: Removed do_install:append() with oe_multilib_header +# nettle 3.10's version.h has no arch-specific content and doesn't need multilib handling + +do_install_ptest() { + install -d ${D}${PTEST_PATH}/testsuite/ + install ${B}/testsuite/*-test ${D}${PTEST_PATH}/testsuite/ + install ${S}/testsuite/*-test ${D}${PTEST_PATH}/testsuite/ + install ${S}/testsuite/gold-bug.txt ${D}${PTEST_PATH}/testsuite/ + install ${S}/testsuite/sc-valgrind.sh ${D}${PTEST_PATH}/testsuite/ + + # Install a symlink for dlopen-test + ln -sr ${D}${libdir}/libnettle.so.*.* ${D}${PTEST_PATH}/libnettle.so + # These examples are needed for pkcs1-conv-test + install ${B}/examples/rsa-sign ${B}/examples/rsa-verify ${D}${PTEST_PATH}/testsuite/ + # Fix build-time relative paths + sed -i -e 's|../tools/|${bindir}/|g' ${D}${PTEST_PATH}/testsuite/*-test + sed -i -e 's|../examples/|./|g' ${D}${PTEST_PATH}/testsuite/*-test +} + +RDEPENDS:${PN}-ptest += "${PN}-bin" + +BBCLASSEXTEND = "native nativesdk" diff --git a/inc/rsyslog/rsyslog-enable-fips-crypto.inc b/inc/rsyslog/rsyslog-enable-fips-crypto.inc new file mode 100644 index 00000000..e1fa70e7 --- /dev/null +++ b/inc/rsyslog/rsyslog-enable-fips-crypto.inc @@ -0,0 +1,30 @@ +# Check Yocto version and include appropriate file +def rsyslog_get_fips_crypto_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("rsyslog-enable-fips-crypto.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if use_modern: + inc_file = os.path.join(layerdir, 'inc/rsyslog/%s/rsyslog-enable-fips-crypto-modern.inc' % codename) + else: + inc_file = os.path.join(layerdir, 'inc/rsyslog/%s/rsyslog-enable-fips-crypto-legacy.inc' % codename) + + bb.note("rsyslog-enable-fips-crypto.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@rsyslog_get_fips_crypto_inc(d)} diff --git a/inc/rsyslog/scarthgap/files/rsyslog-libgcrypt-wolfssl-fips.conf b/inc/rsyslog/scarthgap/files/rsyslog-libgcrypt-wolfssl-fips.conf new file mode 100644 index 00000000..45f23957 --- /dev/null +++ b/inc/rsyslog/scarthgap/files/rsyslog-libgcrypt-wolfssl-fips.conf @@ -0,0 +1,31 @@ +# FIPS-compliant encryption configuration for rsyslog +# This configuration enforces FIPS 140-2/140-3 approved ciphers + +# Load encryption support module +$ModLoad lmcry_gcry + +# Global encryption defaults (FIPS-compliant) +# Use AES256 with CBC mode for maximum security +global( + defaultNetstreamDriverCAFile="/etc/rsyslog.d/ca.pem" + defaultNetstreamDriverCertFile="/etc/rsyslog.d/cert.pem" + defaultNetstreamDriverKeyFile="/etc/rsyslog.d/key.pem" +) + +# Example: Encrypted log file with FIPS-approved cipher +# Uncomment and configure as needed: +# +# action(type="omfile" +# file="/var/log/encrypted.log" +# cry.provider="gcry" +# cry.algo="AES256" +# cry.mode="CBC" +# cry.keyfile="/etc/rsyslog.d/encryption.key" +# ) +# +# FIPS-Approved Encryption Options: +# cry.algo: AES128, AES192, AES256 +# cry.mode: CBC, CTR +# +# Non-FIPS algorithms (DO NOT USE in FIPS mode): +# 3DES, BLOWFISH, DES, CAST5, ARCFOUR, TWOFISH, SERPENT diff --git a/inc/rsyslog/scarthgap/rsyslog-enable-fips-crypto-modern.inc b/inc/rsyslog/scarthgap/rsyslog-enable-fips-crypto-modern.inc new file mode 100644 index 00000000..7150d231 --- /dev/null +++ b/inc/rsyslog/scarthgap/rsyslog-enable-fips-crypto-modern.inc @@ -0,0 +1,16 @@ +# Enable FIPS-compliant encryption configuration for rsyslog +# This keeps libgcrypt for log file encryption while using wolfSSL for TLS/SSL + +FILESEXTRAPATHS:prepend := "${THISDIR}/files:" +SRC_URI += "file://rsyslog-libgcrypt-wolfssl-fips.conf" +PACKAGECONFIG:append = " libgcrypt" +FILES:${PN} += "${sysconfdir}/rsyslog.d/rsyslog-libgcrypt-wolfssl-fips.conf" + +# Install FIPS crypto configuration +do_install_rsyslog_fips_config() { + install -d ${D}${sysconfdir}/rsyslog.d + install -m 0644 ${WORKDIR}/rsyslog-libgcrypt-wolfssl-fips.conf ${D}${sysconfdir}/rsyslog.d/ +} + +addtask do_install_rsyslog_fips_config after do_install before do_package +do_install_rsyslog_fips_config[fakeroot] = "1" diff --git a/inc/wolf-py-tests/wolfcrypt-py-enable-tests-legacy.inc b/inc/wolf-py-tests/wolfcrypt-py-enable-tests-legacy.inc new file mode 100644 index 00000000..86e56b07 --- /dev/null +++ b/inc/wolf-py-tests/wolfcrypt-py-enable-tests-legacy.inc @@ -0,0 +1,33 @@ +# Enable test directory installation for wolfcrypt-py +# +# This include file configures wolfcrypt-py to install its test directory +# to the target system for running Python binding tests. + +WOLFCRYPT_PY_TEST_DIR = "${S}" +WOLFCRYPT_PY_DIR = "/home/root/wolf-py-tests/wolfcrypt-py-test" +WOLFCRYPT_PY_TEST_TARGET_DIR = "${D}${WOLFCRYPT_PY_DIR}" + +python () { + distro_version = d.getVar('DISTRO_VERSION', True) + wolfcrypt_py_test_dir = d.getVar('WOLFCRYPT_PY_TEST_DIR', True) + wolfcrypt_py_test_target_dir = d.getVar('WOLFCRYPT_PY_TEST_TARGET_DIR', True) + + installDirCmd = 'install -m 0755 -d "%s"\n' % wolfcrypt_py_test_target_dir + cpWolfcryptPyTestCmd = 'cp -r %s/* %s\n' % (wolfcrypt_py_test_dir, wolfcrypt_py_test_target_dir) + + d.appendVar('do_install', installDirCmd) + d.appendVar('do_install', cpWolfcryptPyTestCmd) + + pn = d.getVar('PN', True) + wolfcrypt_py_dir = d.getVar('WOLFCRYPT_PY_DIR', True) + + # Legacy always uses underscore syntax + files_var_name = 'FILES_' + pn + + current_files = d.getVar(files_var_name, True) or "" + new_files = current_files + ' ' + wolfcrypt_py_dir + '/*' + d.setVar(files_var_name, new_files) +} + +# Python Specific option +export PYTHONDONTWRITEBYTECODE = "1" diff --git a/inc/wolf-py-tests/wolfcrypt-py-enable-tests-modern.inc b/inc/wolf-py-tests/wolfcrypt-py-enable-tests-modern.inc new file mode 100644 index 00000000..a128fcc5 --- /dev/null +++ b/inc/wolf-py-tests/wolfcrypt-py-enable-tests-modern.inc @@ -0,0 +1,35 @@ +# Enable test directory installation for wolfcrypt-py +# +# This include file configures wolfcrypt-py to install its test directory +# to the target system for running Python binding tests. + +WOLFCRYPT_PY_TEST_DIR = "${S}" +WOLFCRYPT_PY_DIR = "/home/root/wolf-py-tests/wolfcrypt-py-test" +WOLFCRYPT_PY_TEST_TARGET_DIR = "${D}${WOLFCRYPT_PY_DIR}" + +python () { + distro_version = d.getVar('DISTRO_VERSION', True) + wolfcrypt_py_test_dir = d.getVar('WOLFCRYPT_PY_TEST_DIR', True) + wolfcrypt_py_test_target_dir = d.getVar('WOLFCRYPT_PY_TEST_TARGET_DIR', True) + + installDirCmd = 'install -m 0755 -d "%s"\n' % wolfcrypt_py_test_target_dir + cpWolfcryptPyTestCmd = 'cp -r %s/* %s\n' % (wolfcrypt_py_test_dir, wolfcrypt_py_test_target_dir) + + d.appendVar('do_install', installDirCmd) + d.appendVar('do_install', cpWolfcryptPyTestCmd) + + pn = d.getVar('PN', True) + wolfcrypt_py_dir = d.getVar('WOLFCRYPT_PY_DIR', True) + + if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): + files_var_name = 'FILES_' + pn + else: + files_var_name = 'FILES:' + pn + + current_files = d.getVar(files_var_name, True) or "" + new_files = current_files + ' ' + wolfcrypt_py_dir + '/*' + d.setVar(files_var_name, new_files) +} + +# Python Specific option +export PYTHONDONTWRITEBYTECODE = "1" diff --git a/inc/wolf-py-tests/wolfcrypt-py-enable-tests.inc b/inc/wolf-py-tests/wolfcrypt-py-enable-tests.inc new file mode 100644 index 00000000..0b021a08 --- /dev/null +++ b/inc/wolf-py-tests/wolfcrypt-py-enable-tests.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfcrypt_py_get_tests_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfcrypt-py-enable-tests.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/wolf-py-tests/wolfcrypt-py-enable-tests-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolf-py-tests/wolfcrypt-py-enable-tests-legacy.inc') + + bb.note("wolfcrypt-py-enable-tests.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfcrypt_py_get_tests_inc(d)} \ No newline at end of file diff --git a/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-legacy.inc b/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-legacy.inc new file mode 100644 index 00000000..694b0e89 --- /dev/null +++ b/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-legacy.inc @@ -0,0 +1,33 @@ +# Configuration to enable wolf-py-tests support in wolfssl +# Python tests may need specific features enabled +EXTRA_OECONF += "--enable-shared" + +WOLFSSL_PY_TEST_CERTS_DIR = "/home/root/wolf-py-tests/certs" +WOLFSSL_PY_CERTS_DIR = "/certs" +WOLFSSL_PY_CERTS_INSTALL_DIR = "${D}${WOLFSSL_PY_TEST_CERTS_DIR}" +WOLFSSL_PY_CERTS_SOURCE_DIR = "${S}${WOLFSSL_PY_CERTS_DIR}" + +python () { + distro_version = d.getVar('DISTRO_VERSION', True) + wolfssl_py_certs_install_dir = d.getVar('WOLFSSL_PY_CERTS_INSTALL_DIR', True) + wolfssl_py_certs_source_dir = d.getVar('WOLFSSL_PY_CERTS_SOURCE_DIR', True) + + bbnote = 'bbnote "Installing Certs Directory for wolf-py Tests"\n' + installDir = 'install -m 0755 -d "%s"\n' % (wolfssl_py_certs_install_dir) + cpDer = 'cp -r %s/*.der %s\n' % (wolfssl_py_certs_source_dir, wolfssl_py_certs_install_dir) + cpPem = 'cp -r %s/*.pem %s\n' % (wolfssl_py_certs_source_dir, wolfssl_py_certs_install_dir) + + d.appendVar('do_install', bbnote) + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpDer) + d.appendVar('do_install', cpPem) + + pn = d.getVar('PN', True) + wolfssl_py_test_certs_dir = d.getVar('WOLFSSL_PY_TEST_CERTS_DIR', True) + # Legacy always uses underscore syntax + files_var_name = 'FILES_' + pn + + current_files = d.getVar(files_var_name, True) or "" + new_files = current_files + ' ' + wolfssl_py_test_certs_dir + '/*' + d.setVar(files_var_name, new_files) +} diff --git a/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-modern.inc b/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-modern.inc new file mode 100644 index 00000000..efc75ecf --- /dev/null +++ b/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-modern.inc @@ -0,0 +1,35 @@ +# Configuration to enable wolf-py-tests support in wolfssl +# Python tests may need specific features enabled +EXTRA_OECONF += "--enable-shared" + +WOLFSSL_PY_TEST_CERTS_DIR = "/home/root/wolf-py-tests/certs" +WOLFSSL_PY_CERTS_DIR = "/certs" +WOLFSSL_PY_CERTS_INSTALL_DIR = "${D}${WOLFSSL_PY_TEST_CERTS_DIR}" +WOLFSSL_PY_CERTS_SOURCE_DIR = "${S}${WOLFSSL_PY_CERTS_DIR}" + +python () { + distro_version = d.getVar('DISTRO_VERSION', True) + wolfssl_py_certs_install_dir = d.getVar('WOLFSSL_PY_CERTS_INSTALL_DIR', True) + wolfssl_py_certs_source_dir = d.getVar('WOLFSSL_PY_CERTS_SOURCE_DIR', True) + + bbnote = 'bbnote "Installing Certs Directory for wolf-py Tests"\n' + installDir = 'install -m 0755 -d "%s"\n' % (wolfssl_py_certs_install_dir) + cpDer = 'cp -r %s/*.der %s\n' % (wolfssl_py_certs_source_dir, wolfssl_py_certs_install_dir) + cpPem = 'cp -r %s/*.pem %s\n' % (wolfssl_py_certs_source_dir, wolfssl_py_certs_install_dir) + + d.appendVar('do_install', bbnote) + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpDer) + d.appendVar('do_install', cpPem) + + pn = d.getVar('PN', True) + wolfssl_py_test_certs_dir = d.getVar('WOLFSSL_PY_TEST_CERTS_DIR', True) + if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): + files_var_name = 'FILES_' + pn + else: + files_var_name = 'FILES:' + pn + + current_files = d.getVar(files_var_name, True) or "" + new_files = current_files + ' ' + wolfssl_py_test_certs_dir + '/*' + d.setVar(files_var_name, new_files) +} diff --git a/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests.inc b/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests.inc new file mode 100644 index 00000000..2d1f354d --- /dev/null +++ b/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolf_py_tests_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolf-py-tests.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/wolf-py-tests/wolfssl-enable-wolf-py-tests-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolf-py-tests/wolfssl-enable-wolf-py-tests-legacy.inc') + + bb.note("wolfssl-enable-wolf-py-tests.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolf_py_tests_inc(d)} \ No newline at end of file diff --git a/inc/wolf-py-tests/wolfssl-py-enable-tests-legacy.inc b/inc/wolf-py-tests/wolfssl-py-enable-tests-legacy.inc new file mode 100644 index 00000000..4ec62595 --- /dev/null +++ b/inc/wolf-py-tests/wolfssl-py-enable-tests-legacy.inc @@ -0,0 +1,34 @@ +# Enable test directory installation for wolfssl-py +# +# This include file configures wolfssl-py to install its test directory +# to the target system for running Python binding tests. + +WOLFSSL_PY_TEST_DIR = "${S}" +WOLFSSL_PY_DIR = "/home/root/wolf-py-tests/wolfssl-py-test" +WOLFSSL_PY_TEST_TARGET_DIR = "${D}${WOLFSSL_PY_DIR}" + +python () { + distro_version = d.getVar('DISTRO_VERSION', True) + wolfssl_py_test_dir = d.getVar('WOLFSSL_PY_TEST_DIR', True) + wolfssl_py_test_target_dir = d.getVar('WOLFSSL_PY_TEST_TARGET_DIR', True) + + installDir = 'install -m 0755 -d "%s"\n' % (wolfssl_py_test_target_dir) + cpWolfsslPyTest = 'cp -r %s/* %s\n' % (wolfssl_py_test_dir, wolfssl_py_test_target_dir) + + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpWolfsslPyTest) + + # Append to FILES_${PN} within the Python function + pn = d.getVar('PN', True) + wolfssl_py_dir = d.getVar('WOLFSSL_PY_DIR', True) + + # Legacy always uses underscore syntax + files_var_name = 'FILES_' + pn + + current_files = d.getVar(files_var_name, True) or "" + new_files = current_files + ' ' + wolfssl_py_dir + '/*' + d.setVar(files_var_name, new_files) +} + +# Python Specific option +export PYTHONDONTWRITEBYTECODE = "1" diff --git a/inc/wolf-py-tests/wolfssl-py-enable-tests-modern.inc b/inc/wolf-py-tests/wolfssl-py-enable-tests-modern.inc new file mode 100644 index 00000000..1b229a2b --- /dev/null +++ b/inc/wolf-py-tests/wolfssl-py-enable-tests-modern.inc @@ -0,0 +1,36 @@ +# Enable test directory installation for wolfssl-py +# +# This include file configures wolfssl-py to install its test directory +# to the target system for running Python binding tests. + +WOLFSSL_PY_TEST_DIR = "${S}" +WOLFSSL_PY_DIR = "/home/root/wolf-py-tests/wolfssl-py-test" +WOLFSSL_PY_TEST_TARGET_DIR = "${D}${WOLFSSL_PY_DIR}" + +python () { + distro_version = d.getVar('DISTRO_VERSION', True) + wolfssl_py_test_dir = d.getVar('WOLFSSL_PY_TEST_DIR', True) + wolfssl_py_test_target_dir = d.getVar('WOLFSSL_PY_TEST_TARGET_DIR', True) + + installDir = 'install -m 0755 -d "%s"\n' % (wolfssl_py_test_target_dir) + cpWolfsslPyTest = 'cp -r %s/* %s\n' % (wolfssl_py_test_dir, wolfssl_py_test_target_dir) + + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpWolfsslPyTest) + + # Append to FILES:${PN} within the Python function + pn = d.getVar('PN', True) + wolfssl_py_dir = d.getVar('WOLFSSL_PY_DIR', True) + + if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): + files_var_name = 'FILES_' + pn + else: + files_var_name = 'FILES:' + pn + + current_files = d.getVar(files_var_name, True) or "" + new_files = current_files + ' ' + wolfssl_py_dir + '/*' + d.setVar(files_var_name, new_files) +} + +# Python Specific option +export PYTHONDONTWRITEBYTECODE = "1" diff --git a/inc/wolf-py-tests/wolfssl-py-enable-tests.inc b/inc/wolf-py-tests/wolfssl-py-enable-tests.inc new file mode 100644 index 00000000..3d731133 --- /dev/null +++ b/inc/wolf-py-tests/wolfssl-py-enable-tests.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_py_get_tests_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-py-enable-tests.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/wolf-py-tests/wolfssl-py-enable-tests-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolf-py-tests/wolfssl-py-enable-tests-legacy.inc') + + bb.note("wolfssl-py-enable-tests.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_py_get_tests_inc(d)} \ No newline at end of file diff --git a/inc/wolfclu/wolfssl-enable-wolfclu-legacy.inc b/inc/wolfclu/wolfssl-enable-wolfclu-legacy.inc new file mode 100644 index 00000000..987e8700 --- /dev/null +++ b/inc/wolfclu/wolfssl-enable-wolfclu-legacy.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolfclu support in wolfssl +EXTRA_OECONF += "--enable-wolfclu" diff --git a/inc/wolfclu/wolfssl-enable-wolfclu-modern.inc b/inc/wolfclu/wolfssl-enable-wolfclu-modern.inc new file mode 100644 index 00000000..987e8700 --- /dev/null +++ b/inc/wolfclu/wolfssl-enable-wolfclu-modern.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolfclu support in wolfssl +EXTRA_OECONF += "--enable-wolfclu" diff --git a/inc/wolfclu/wolfssl-enable-wolfclu.inc b/inc/wolfclu/wolfssl-enable-wolfclu.inc new file mode 100644 index 00000000..f5bb875d --- /dev/null +++ b/inc/wolfclu/wolfssl-enable-wolfclu.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfclu_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfclu.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/wolfclu/wolfssl-enable-wolfclu-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfclu/wolfssl-enable-wolfclu-legacy.inc') + + bb.note("wolfssl-enable-wolfclu.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfclu_inc(d)} \ No newline at end of file diff --git a/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-legacy.inc b/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-legacy.inc new file mode 100644 index 00000000..561236a4 --- /dev/null +++ b/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-legacy.inc @@ -0,0 +1,3 @@ +# Configuration to enable wolfcrypt-py support in wolfssl +# Python bindings need specific crypto features enabled +EXTRA_OECONF += " --enable-aes --enable-aesctr --enable-des3 --enable-chacha --enable-aesgcm-stream --enable-aesgcm --enable-sha --enable-sha384 --enable-sha512 --enable-sha3 --enable-hkdf --enable-rsa --enable-rsapss --enable-ecc --enable-ed25519 --enable-ed448 --enable-curve25519 --enable-keygen --enable-pwdbased --enable-pkcs7 --enable-dtls --enable-tls13 --enable-tlsx" diff --git a/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-modern.inc b/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-modern.inc new file mode 100644 index 00000000..561236a4 --- /dev/null +++ b/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-modern.inc @@ -0,0 +1,3 @@ +# Configuration to enable wolfcrypt-py support in wolfssl +# Python bindings need specific crypto features enabled +EXTRA_OECONF += " --enable-aes --enable-aesctr --enable-des3 --enable-chacha --enable-aesgcm-stream --enable-aesgcm --enable-sha --enable-sha384 --enable-sha512 --enable-sha3 --enable-hkdf --enable-rsa --enable-rsapss --enable-ecc --enable-ed25519 --enable-ed448 --enable-curve25519 --enable-keygen --enable-pwdbased --enable-pkcs7 --enable-dtls --enable-tls13 --enable-tlsx" diff --git a/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py.inc b/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py.inc new file mode 100644 index 00000000..09a4a327 --- /dev/null +++ b/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfcrypt_py_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfcrypt-py.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/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py-legacy.inc') + + bb.note("wolfssl-enable-wolfcrypt-py.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfcrypt_py_inc(d)} \ No newline at end of file diff --git a/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-legacy.inc b/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-legacy.inc new file mode 100644 index 00000000..53ea8163 --- /dev/null +++ b/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-legacy.inc @@ -0,0 +1,19 @@ +# Configuration to enable wolfcryptbenchmark support in wolfssl +EXTRA_OECONF += "--enable-crypttests" + +python () { + files_var = 'FILES_' + d.getVar('PN') + d.appendVar(files_var, ' ${bindir}/wolfcryptbenchmark') +} + +do_install_append() { + bbnote "Installing wolfCrypt Benchmarks" + if [ ! -x "${B}/wolfcrypt/benchmark/.libs/benchmark" ]; then + bbwarn "wolfCrypt benchmark binary missing at ${B}/wolfcrypt/benchmark/.libs/benchmark" + return + fi + + install -Dm0755 "${B}/wolfcrypt/benchmark/.libs/benchmark" "${D}${bindir}/wolfcryptbenchmark" +} + +TARGET_CFLAGS += "-DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -DBENCH_EMBEDDED" diff --git a/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-modern.inc b/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-modern.inc new file mode 100644 index 00000000..de8c7334 --- /dev/null +++ b/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-modern.inc @@ -0,0 +1,19 @@ +# Configuration to enable wolfcryptbenchmark support in wolfssl +EXTRA_OECONF += "--enable-crypttests" + +python () { + files_var = 'FILES:' + d.getVar('PN') + d.appendVar(files_var, ' ${bindir}/wolfcryptbenchmark') +} + +do_install:append() { + bbnote "Installing wolfCrypt Benchmarks" + if [ ! -x "${B}/wolfcrypt/benchmark/.libs/benchmark" ]; then + bbwarn "wolfCrypt benchmark binary missing at ${B}/wolfcrypt/benchmark/.libs/benchmark" + return + fi + + install -Dm0755 "${B}/wolfcrypt/benchmark/.libs/benchmark" "${D}${bindir}/wolfcryptbenchmark" +} + +TARGET_CFLAGS += "-DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -DBENCH_EMBEDDED" diff --git a/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc b/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc new file mode 100644 index 00000000..138c3cf1 --- /dev/null +++ b/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfcryptbenchmark_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfcryptbenchmark.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/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark-legacy.inc') + + bb.note("wolfssl-enable-wolfcryptbenchmark.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfcryptbenchmark_inc(d)} diff --git a/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-legacy.inc b/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-legacy.inc new file mode 100644 index 00000000..28bd9e63 --- /dev/null +++ b/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-legacy.inc @@ -0,0 +1,19 @@ +# Configuration to enable wolfcrypttest support in wolfssl +EXTRA_OECONF += "--enable-crypttests" + +python () { + files_var = 'FILES_' + d.getVar('PN') + d.appendVar(files_var, ' ${bindir}/wolfcrypttest') +} + +do_install_append() { + bbnote "Installing wolfCrypt Tests" + if [ ! -x "${B}/wolfcrypt/test/.libs/testwolfcrypt" ]; then + bbwarn "wolfCrypt test binary missing at ${B}/wolfcrypt/test/.libs/testwolfcrypt" + return + fi + + install -Dm0755 "${B}/wolfcrypt/test/.libs/testwolfcrypt" "${D}${bindir}/wolfcrypttest" +} + +TARGET_CFLAGS += "-DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -DWOLFSSL_RSA_KEY_CHECK -DNO_WRITE_TEMP_FILES" diff --git a/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-modern.inc b/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-modern.inc new file mode 100644 index 00000000..efd6f147 --- /dev/null +++ b/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-modern.inc @@ -0,0 +1,19 @@ +# Configuration to enable wolfcrypttest support in wolfssl +EXTRA_OECONF += "--enable-crypttests" + +python () { + files_var = 'FILES:' + d.getVar('PN') + d.appendVar(files_var, ' ${bindir}/wolfcrypttest') +} + +do_install:append() { + bbnote "Installing wolfCrypt Tests" + if [ ! -x "${B}/wolfcrypt/test/.libs/testwolfcrypt" ]; then + bbwarn "wolfCrypt test binary missing at ${B}/wolfcrypt/test/.libs/testwolfcrypt" + return + fi + + install -Dm0755 "${B}/wolfcrypt/test/.libs/testwolfcrypt" "${D}${bindir}/wolfcrypttest" +} + +TARGET_CFLAGS += "-DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -DWOLFSSL_RSA_KEY_CHECK -DNO_WRITE_TEMP_FILES" diff --git a/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc b/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc new file mode 100644 index 00000000..9c6d103a --- /dev/null +++ b/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfcrypttest_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfcrypttest.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/wolfcrypttest/wolfssl-enable-wolfcrypttest-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfcrypttest/wolfssl-enable-wolfcrypttest-legacy.inc') + + bb.note("wolfssl-enable-wolfcrypttest.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfcrypttest_inc(d)} diff --git a/inc/wolfengine/openssl/openssl-enable-wolfengine-legacy.inc b/inc/wolfengine/openssl/openssl-enable-wolfengine-legacy.inc new file mode 100644 index 00000000..ef093d12 --- /dev/null +++ b/inc/wolfengine/openssl/openssl-enable-wolfengine-legacy.inc @@ -0,0 +1 @@ +EXTRA_OECONF += " shared " diff --git a/inc/wolfengine/openssl/openssl-enable-wolfengine-modern.inc b/inc/wolfengine/openssl/openssl-enable-wolfengine-modern.inc new file mode 100644 index 00000000..ef093d12 --- /dev/null +++ b/inc/wolfengine/openssl/openssl-enable-wolfengine-modern.inc @@ -0,0 +1 @@ +EXTRA_OECONF += " shared " diff --git a/inc/wolfengine/openssl/openssl-enable-wolfengine.inc b/inc/wolfengine/openssl/openssl-enable-wolfengine.inc new file mode 100644 index 00000000..4f68fa40 --- /dev/null +++ b/inc/wolfengine/openssl/openssl-enable-wolfengine.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def openssl_get_wolfengine_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("openssl-enable-wolfengine.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/wolfengine/openssl/openssl-enable-wolfengine-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfengine/openssl/openssl-enable-wolfengine-legacy.inc') + + bb.note("openssl-enable-wolfengine.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@openssl_get_wolfengine_inc(d)} \ No newline at end of file diff --git a/inc/wolfengine/wolfssl-enable-wolfengine-legacy.inc b/inc/wolfengine/wolfssl-enable-wolfengine-legacy.inc new file mode 100644 index 00000000..6f46433f --- /dev/null +++ b/inc/wolfengine/wolfssl-enable-wolfengine-legacy.inc @@ -0,0 +1,14 @@ +# Configuration to enable wolfengine support in wolfssl + +python() { + # Get the package revision (PR) for wolfssl + wolfssl_pr = d.getVar('PR', True) + + # Based on the revision, conditionally append to EXTRA_OECONF + if wolfssl_pr == 'commerical.fips': + d.appendVar('EXTRA_OECONF', ' --enable-engine=fips-v5') + elif wolfssl_pr == 'fipsReady': + d.appendVar('EXTRA_OECONF', ' --enable-engine=fips-ready') + else: + d.appendVar('EXTRA_OECONF', ' --enable-engine=no-fips') +} diff --git a/inc/wolfengine/wolfssl-enable-wolfengine-modern.inc b/inc/wolfengine/wolfssl-enable-wolfengine-modern.inc new file mode 100644 index 00000000..6f46433f --- /dev/null +++ b/inc/wolfengine/wolfssl-enable-wolfengine-modern.inc @@ -0,0 +1,14 @@ +# Configuration to enable wolfengine support in wolfssl + +python() { + # Get the package revision (PR) for wolfssl + wolfssl_pr = d.getVar('PR', True) + + # Based on the revision, conditionally append to EXTRA_OECONF + if wolfssl_pr == 'commerical.fips': + d.appendVar('EXTRA_OECONF', ' --enable-engine=fips-v5') + elif wolfssl_pr == 'fipsReady': + d.appendVar('EXTRA_OECONF', ' --enable-engine=fips-ready') + else: + d.appendVar('EXTRA_OECONF', ' --enable-engine=no-fips') +} diff --git a/inc/wolfengine/wolfssl-enable-wolfengine.inc b/inc/wolfengine/wolfssl-enable-wolfengine.inc new file mode 100644 index 00000000..5546091d --- /dev/null +++ b/inc/wolfengine/wolfssl-enable-wolfengine.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfengine_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfengine.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/wolfengine/wolfssl-enable-wolfengine-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfengine/wolfssl-enable-wolfengine-legacy.inc') + + bb.note("wolfssl-enable-wolfengine.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfengine_inc(d)} \ No newline at end of file diff --git a/inc/wolfenginetest/wolfengine-enable-test-legacy.inc b/inc/wolfenginetest/wolfengine-enable-test-legacy.inc new file mode 100644 index 00000000..2ab8498d --- /dev/null +++ b/inc/wolfenginetest/wolfengine-enable-test-legacy.inc @@ -0,0 +1,6 @@ +# Enable debug mode for wolfengine when testing +# +# This include file configures wolfengine with debug enabled +# for wolfenginetest integration. + +EXTRA_OECONF += " --enable-debug " diff --git a/inc/wolfenginetest/wolfengine-enable-test-modern.inc b/inc/wolfenginetest/wolfengine-enable-test-modern.inc new file mode 100644 index 00000000..2ab8498d --- /dev/null +++ b/inc/wolfenginetest/wolfengine-enable-test-modern.inc @@ -0,0 +1,6 @@ +# Enable debug mode for wolfengine when testing +# +# This include file configures wolfengine with debug enabled +# for wolfenginetest integration. + +EXTRA_OECONF += " --enable-debug " diff --git a/inc/wolfenginetest/wolfengine-enable-test.inc b/inc/wolfenginetest/wolfengine-enable-test.inc new file mode 100644 index 00000000..38f10b79 --- /dev/null +++ b/inc/wolfenginetest/wolfengine-enable-test.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfengine_get_test_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfengine-enable-test.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/wolfenginetest/wolfengine-enable-test-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfenginetest/wolfengine-enable-test-legacy.inc') + + bb.note("wolfengine-enable-test.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfengine_get_test_inc(d)} \ No newline at end of file diff --git a/inc/wolfenginetest/wolfssl-enable-wolfenginetest-legacy.inc b/inc/wolfenginetest/wolfssl-enable-wolfenginetest-legacy.inc new file mode 100644 index 00000000..13b494a0 --- /dev/null +++ b/inc/wolfenginetest/wolfssl-enable-wolfenginetest-legacy.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolfenginetest support in wolfssl +EXTRA_OECONF += "--enable-engine" diff --git a/inc/wolfenginetest/wolfssl-enable-wolfenginetest-modern.inc b/inc/wolfenginetest/wolfssl-enable-wolfenginetest-modern.inc new file mode 100644 index 00000000..13b494a0 --- /dev/null +++ b/inc/wolfenginetest/wolfssl-enable-wolfenginetest-modern.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolfenginetest support in wolfssl +EXTRA_OECONF += "--enable-engine" diff --git a/inc/wolfenginetest/wolfssl-enable-wolfenginetest.inc b/inc/wolfenginetest/wolfssl-enable-wolfenginetest.inc new file mode 100644 index 00000000..b98f8f7c --- /dev/null +++ b/inc/wolfenginetest/wolfssl-enable-wolfenginetest.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfenginetest_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfenginetest.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/wolfenginetest/wolfssl-enable-wolfenginetest-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfenginetest/wolfssl-enable-wolfenginetest-legacy.inc') + + bb.note("wolfssl-enable-wolfenginetest.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfenginetest_inc(d)} \ No newline at end of file diff --git a/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-legacy.inc b/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-legacy.inc new file mode 100644 index 00000000..770bd8fa --- /dev/null +++ b/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-legacy.inc @@ -0,0 +1,2 @@ +EXTRA_OECONF += "--enable-aes --enable-aescfb --enable-aescbc --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt" +TARGET_CFLAGS += "-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP -DWOLFSSL_AES_DIRECT" diff --git a/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-modern.inc b/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-modern.inc new file mode 100644 index 00000000..770bd8fa --- /dev/null +++ b/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-modern.inc @@ -0,0 +1,2 @@ +EXTRA_OECONF += "--enable-aes --enable-aescfb --enable-aescbc --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt" +TARGET_CFLAGS += "-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP -DWOLFSSL_AES_DIRECT" diff --git a/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11.inc b/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11.inc new file mode 100644 index 00000000..d24cacd8 --- /dev/null +++ b/inc/wolfpkcs11/wolfssl-enable-wolfpkcs11.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfpkcs11_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfpkcs11.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/wolfpkcs11/wolfssl-enable-wolfpkcs11-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfpkcs11/wolfssl-enable-wolfpkcs11-legacy.inc') + + bb.note("wolfssl-enable-wolfpkcs11.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfpkcs11_inc(d)} \ No newline at end of file diff --git a/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc b/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc new file mode 100644 index 00000000..edef0656 --- /dev/null +++ b/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc @@ -0,0 +1,41 @@ +# Check Yocto version and include appropriate file +def openssh_get_wolfprovider_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("openssh-enable-wolfprovider.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + # Determine file type + file_type = 'modern' if use_modern else 'legacy' + + # Try codename-specific directory first, fallback to scarthgap (most recent stable) + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if codename: + codename_dir = os.path.join(layerdir, 'inc/wolfprovider/openssh/%s' % codename) + if os.path.isdir(codename_dir): + # Use codename-specific file + inc_file = os.path.join(codename_dir, 'openssh-enable-wolfprovider-%s.inc' % file_type) + else: + # Fallback to scarthgap (most recent stable version) + inc_file = os.path.join(layerdir, 'inc/wolfprovider/openssh/scarthgap/openssh-enable-wolfprovider-%s.inc' % file_type) + else: + # If no codename detected, use scarthgap as default + inc_file = os.path.join(layerdir, 'inc/wolfprovider/openssh/scarthgap/openssh-enable-wolfprovider-%s.inc' % file_type) + + bb.note("openssh-enable-wolfprovider.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@openssh_get_wolfprovider_inc(d)} diff --git a/inc/wolfprovider/openssh/scarthgap/files/run-ptest b/inc/wolfprovider/openssh/scarthgap/files/run-ptest new file mode 100644 index 00000000..0b9db9dd --- /dev/null +++ b/inc/wolfprovider/openssh/scarthgap/files/run-ptest @@ -0,0 +1,70 @@ +#!/bin/sh + +export TEST_SHELL=sh +# Enable unit tests - don't skip them +# export SKIP_UNIT=1 + +# Required for test environment permissions +export TEST_SSH_UNSAFE_PERMISSIONS=1 + +# Enable FIPS mode for tests (used by openssh-FIPS-wolfprov.patch) +export FIPS_MODE=1 + +cd regress + +# copied from openssh-portable/.github/run_test.sh +output_failed_logs() { + for i in failed*.log; do + if [ -f "$i" ]; then + echo ------------------------------------------------------------------------- + echo LOGFILE $i + cat $i + echo ------------------------------------------------------------------------- + fi + done +} +trap output_failed_logs 0 + +sed -i "/\t\tagent-ptrace /d" Makefile + +# wolfProvider CI style: run file-tests, interop-tests, extra-tests, and unit +# Skip t-exec as it takes too long +make -k BUILDDIR=`pwd`/.. .OBJDIR=`pwd` .CURDIR=`pwd` SUDO="" FIPS_MODE=1 \ + file-tests interop-tests extra-tests unit \ + | sed -u -e 's/^skipped/SKIP: /g' -e 's/^ok /PASS: /g' -e 's/^failed/FAIL: /g' + +SSHAGENT=`which ssh-agent` +GDB=`which gdb` + +if [ -z "${SSHAGENT}" -o -z "${GDB}" ]; then + echo "SKIP: agent-ptrace" + exit +fi + +useradd openssh-test + +eval `su -c "${SSHAGENT} -s" openssh-test` > /dev/null +r=$? +if [ $r -ne 0 ]; then + echo "FAIL: could not start ssh-agent: exit code $r" +else + su -c "gdb -p ${SSH_AGENT_PID}" openssh-test > /tmp/gdb.out 2>&1 << EOF + quit +EOF + r=$? + if [ $r -ne 0 ]; then + echo "gdb failed: exit code $r" + fi + egrep 'ptrace: Operation not permitted.|procfs:.*Permission denied.|ttrace.*Permission denied.|procfs:.*: Invalid argument.|Unable to access task ' >/dev/null /tmp/gdb.out + r=$? + rm -f /tmp/gdb.out + if [ $r -ne 0 ]; then + echo "FAIL: ptrace agent" + else + echo "PASS: ptrace agent" + fi + + ${SSHAGENT} -k > /dev/null +fi +userdel openssh-test + diff --git a/inc/wolfprovider/openssh/scarthgap/openssh-enable-wolfprovider-modern.inc b/inc/wolfprovider/openssh/scarthgap/openssh-enable-wolfprovider-modern.inc new file mode 100644 index 00000000..70e4a681 --- /dev/null +++ b/inc/wolfprovider/openssh/scarthgap/openssh-enable-wolfprovider-modern.inc @@ -0,0 +1,38 @@ +# OpenSSH wolfProvider FIPS mode configuration +# Include this file for standard wolfProvider integration as a provider plugin + +# Bring in the openssh patch from the OSP repository (target only) +SRC_URI:append:class-target = " \ + git://github.com/wolfSSL/osp.git;protocol=https;branch=master;name=osp;destsuffix=git/osp \ +" + +# Track the revision for the OSP auxiliary repo fetch +SRCREV_osp = "${AUTOREV}" + +# Ensure BitBake can locate the updated run-ptest script in this include's files directory +FILESEXTRAPATHS:prepend := "${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssh/scarthgap/files:" +SRC_URI:append:class-target = " file://run-ptest" + +# Apply the patch for the correct version of OpenSSH +python do_patch:append:class-target () { + import os, subprocess + # Only run this when FIPS is enabled + if not bb.utils.contains('IMAGE_FEATURES', 'fips', True, False, d): + bb.note("FIPS not enabled; skipping openssh-V_9_6_P1-FIPS-wolfprov.patch") + return + patch_path = os.path.join(d.getVar("WORKDIR"), "git/osp/wolfProvider/openssh/openssh-V_9_6_P1-FIPS-wolfprov.patch") + s = d.getVar("S") + + # Try to apply the patch; if it fails with "already applied", log it and continue + try: + result = subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path, "--dry-run"], + capture_output=True, text=True, check=False) + if result.returncode == 0: + bb.note(f"{patch_path} can be applied, applying now...") + subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path], check=True) + else: + bb.note(f"{patch_path} already applied or cannot apply, skipping") + bb.debug(1, f"Patch check output: {result.stderr}") + except Exception as e: + bb.warn(f"{patch_path}: Error applying patch: {e}") +} diff --git a/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc b/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc new file mode 100644 index 00000000..c53b8a9f --- /dev/null +++ b/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc @@ -0,0 +1,41 @@ +# Check Yocto version and include appropriate file +def openssl_get_wolfprovider_replace_default_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("openssl-enable-wolfprovider-replace-default.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + # Determine file type + file_type = 'modern' if use_modern else 'legacy' + + # Try codename-specific directory first, fallback to scarthgap (most recent stable) + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if codename: + codename_dir = os.path.join(layerdir, 'inc/wolfprovider/openssl/%s' % codename) + if os.path.isdir(codename_dir): + # Use codename-specific file + inc_file = os.path.join(codename_dir, 'openssl-enable-wolfprovider-replace-default-%s.inc' % file_type) + else: + # Fallback to scarthgap (most recent stable version) + inc_file = os.path.join(layerdir, 'inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-replace-default-%s.inc' % file_type) + else: + # If no codename detected, use scarthgap as default + inc_file = os.path.join(layerdir, 'inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-replace-default-%s.inc' % file_type) + + bb.note("openssl-enable-wolfprovider-replace-default.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@openssl_get_wolfprovider_replace_default_inc(d)} diff --git a/inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc b/inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc new file mode 100644 index 00000000..aaa9cff4 --- /dev/null +++ b/inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc @@ -0,0 +1,41 @@ +# Check Yocto version and include appropriate file +def openssl_get_wolfprovider_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("openssl-enable-wolfprovider.inc: LAYERSERIES_CORENAMES = %s" % layerseries) + + # Check if version is 3.1 or newer (dunfell and later) + use_modern = False + codename = None + if layerseries: + series_list = layerseries.split() + modern_series = ['dunfell', 'gatesgarth', 'hardknott', 'honister', 'kirkstone', 'langdale', 'mickledore', 'nanbield', 'scarthgap'] + for series in series_list: + codename = series + if series in modern_series: + use_modern = True + break + + # Determine file type + file_type = 'modern' if use_modern else 'legacy' + + # Try codename-specific directory first, fallback to scarthgap (most recent stable) + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if codename: + codename_dir = os.path.join(layerdir, 'inc/wolfprovider/openssl/%s' % codename) + if os.path.isdir(codename_dir): + # Use codename-specific file + inc_file = os.path.join(codename_dir, 'openssl-enable-wolfprovider-%s.inc' % file_type) + else: + # Fallback to scarthgap (most recent stable version) + inc_file = os.path.join(layerdir, 'inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-%s.inc' % file_type) + else: + # If no codename detected, use scarthgap as default + inc_file = os.path.join(layerdir, 'inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-%s.inc' % file_type) + + bb.note("openssl-enable-wolfprovider.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@openssl_get_wolfprovider_inc(d)} \ No newline at end of file diff --git a/inc/wolfprovider/openssl/scarthgap/files/openssl-disable-internal-keymgmt-tests.patch b/inc/wolfprovider/openssl/scarthgap/files/openssl-disable-internal-keymgmt-tests.patch new file mode 100644 index 00000000..5afd0d28 --- /dev/null +++ b/inc/wolfprovider/openssl/scarthgap/files/openssl-disable-internal-keymgmt-tests.patch @@ -0,0 +1,27 @@ +Description: Disable internal keymgmt tests when using FIPS provider (wolfProvider) +Upstream-Status: Inappropriate [configuration-specific; not suitable for upstream] +Signed-off-by: WolfSSL Team + +diff --git a/test/recipes/02-test_internal_keymgmt.t b/test/recipes/02-test_internal_keymgmt.t +index 28f510f164..1a7bbc129a 100644 +--- a/test/recipes/02-test_internal_keymgmt.t ++++ b/test/recipes/02-test_internal_keymgmt.t +@@ -7,15 +7,6 @@ + # https://www.openssl.org/source/license.html + + use strict; +-use OpenSSL::Test qw(:DEFAULT bldtop_dir srctop_file); +-use OpenSSL::Test::Utils; +- +-setup("test_internal_keymgmt"); +- +-plan tests => 1; +- +-$ENV{OPENSSL_MODULES} = bldtop_dir("test"); +- +-ok(run(test(["keymgmt_internal_test", +- srctop_file("test", "certs", "ee-cert.pem")])), +- "running test_internal_keymgmt"); ++use warnings; ++use OpenSSL::Test; ++plan skip_all => "Disabled under wolfprovider FIPS mode"; diff --git a/inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-modern.inc b/inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-modern.inc new file mode 100644 index 00000000..15f70449 --- /dev/null +++ b/inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-modern.inc @@ -0,0 +1,41 @@ +# OpenSSL standalone wolfProvider mode configuration +# Include this file for standard wolfProvider integration as a provider plugin + +EXTRA_OECONF += " no-fips shared " + +do_install:append() { + install -d ${D}${sysconfdir}/openssl + echo "0" > ${D}${sysconfdir}/openssl/replace-default-enabled +} + +# Disable internal keymgmt tests under wolfprovider FIPS mode which +# fails on the FACTOR3 and EXPONENT3 and COEFFICIENT2 parameters which +# are not supported by wolfProvider. +python do_patch:append:class-target () { + import os, subprocess + # Only run this when FIPS is enabled + if not bb.utils.contains('IMAGE_FEATURES', 'fips', True, False, d): + bb.note("FIPS not enabled; skipping openssl-disable-internal-keymgmt-tests.patch") + return + + s = d.getVar("S") + # Construct full path directly from layer directory (no need for FILESEXTRAPATHS) + patch_path = os.path.join(d.getVar("WOLFSSL_LAYERDIR"), "inc/wolfprovider/openssl/scarthgap/files/openssl-disable-internal-keymgmt-tests.patch") + # Check if patch file exists + if not os.path.exists(patch_path): + bb.warn(f"openssl-disable-internal-keymgmt-tests.patch not found at {patch_path}") + return + + # Try to apply the patch; if it fails with "already applied", log it and continue + try: + result = subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path, "--dry-run"], + capture_output=True, text=True, check=False) + if result.returncode == 0: + bb.note("openssl-disable-internal-keymgmt-tests.patch can be applied, applying now...") + subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path], check=True) + else: + bb.note("openssl-disable-internal-keymgmt-tests.patch already applied or cannot apply, skipping") + bb.debug(1, f"Patch check output: {result.stderr}") + except Exception as e: + bb.warn(f"openssl-disable-internal-keymgmt-tests.patch: Error applying patch: {e}") +} diff --git a/inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-replace-default-modern.inc b/inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-replace-default-modern.inc new file mode 100644 index 00000000..11aa9313 --- /dev/null +++ b/inc/wolfprovider/openssl/scarthgap/openssl-enable-wolfprovider-replace-default-modern.inc @@ -0,0 +1,182 @@ +# OpenSSL wolfProvider REPLACE-DEFAULT mode configuration +# This file is included when wolfProvider is configured to replace OpenSSL's default crypto provider +# It should be included from the image recipe when replace-default mode is desired + +# Build OpenSSL as plain, non-FIPS OpenSSL +# wolfProvider will provide FIPS functionality using wolfSSL FIPS + +PACKAGECONFIG:class-target = "" +EXTRA_OECONF:append:class-target = " no-fips shared " + +# OpenSSL target-only tweaks for replace-default mode +do_configure:prepend:class-target () { + set -eu + + # Be explicit about where we are + echo "TARGET do_configure prepend: S='${S}', B='${B}'" + + vfile="${S}/VERSION.dat" + + # Sanity check: VERSION.dat must exist at the top of the OpenSSL tree + if [ ! -f $vfile ]; then + echo "ERROR: $vfile not found in ${S}" >&2 + exit 1 + fi + + echo "Injecting BUILD_METADATA into VERSION.dat (target only)" + sed -i 's/^BUILD_METADATA=.*/BUILD_METADATA=wolfProvider/' $vfile + + # Optional FIPS tag based on image features + if echo "${IMAGE_FEATURES}" | grep -qw "fips"; then + sed -i 's/^BUILD_METADATA=.*/BUILD_METADATA=wolfProvider-fips/' $vfile + fi + +} + +# Override do_configure to filter enable-fips from the actual configure command +do_configure:append:class-target () { + # The base do_configure uses ${PACKAGECONFIG_CONFARGS} which still has enable-fips + # We need to regenerate it without enable-fips + # Re-run configure with enable-fips explicitly removed + if [ -f "${B}/configdata.pm" ] && grep -q "enable-fips" "${B}/configdata.pm" 2>/dev/null; then + bbwarn "REPLACE-DEFAULT MODE: FIPS detected in config, forcing reconfigure without FIPS" + cd "${B}" + # Derive the correct OpenSSL Configure target from TARGET_ARCH (mirrors the recipe's mapping) + case "${TARGET_ARCH}" in + aarch64|arm64) target="linux-aarch64" ;; + arm*) target="linux-armv4" ;; + riscv64) target="linux-generic64" ;; + riscv32) target="linux-generic32" ;; + powerpc64le) target="linux-ppc64le" ;; + powerpc64) target="linux-ppc64" ;; + powerpc) target="linux-ppc" ;; + x86_64) target="linux-x86_64" ;; + i?86) target="linux-x86" ;; + *) bbwarn "REPLACE-DEFAULT MODE: unknown TARGET_ARCH=${TARGET_ARCH}, using linux-generic64" + target="linux-generic64" ;; + esac + # Reconfigure without enable-fips + HASHBANGPERL="/usr/bin/env perl" PERL=perl PERL5LIB="${S}/external/perl/Text-Template-1.46/lib/" \ + perl "${S}/Configure" no-fips shared ${EXTRA_OECONF} ${DEPRECATED_CRYPTO_FLAGS} \ + --prefix=${prefix} --openssldir=${libdir}/ssl-3 --libdir=${libdir} "$target" + perl "${B}/configdata.pm" --dump + fi +} + +# Ensure provider is present on TARGET runtime (doesn't touch -native/-nativesdk) +RDEPENDS:libcrypto3:append:class-target = " wolfprovider" + +# Bring in the replace-default patch (target only) +SRC_URI:append:class-target = " \ + git://github.com/wolfSSL/wolfProvider.git;protocol=https;nobranch=1;rev=v1.1.0;destsuffix=git/wolfProvider \ +" + +python do_patch:append:class-target () { + import os, subprocess + s = d.getVar("S") + patch_path = os.path.join(d.getVar("WORKDIR"), "git/wolfProvider/patches/openssl3-replace-default.patch") + bb.note("REPLACE-DEFAULT MODE: Checking if patch needs to be applied") + # Try to apply patch; if it fails with "already applied", log it and continue + try: + # First check with --dry-run to see if patch can be applied + result = subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path, "--dry-run"], + capture_output=True, text=True, check=False) + if result.returncode == 0: + bb.note("REPLACE-DEFAULT MODE: Patch can be applied, applying now...") + subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path], check=True) + else: + bb.note("REPLACE-DEFAULT MODE: Patch already applied or cannot apply, skipping") + bb.debug(1, f"Patch check output: {result.stderr}") + except Exception as e: + bb.warn(f"REPLACE-DEFAULT MODE: Error applying patch: {e}") + + # Export ossl_provider_* symbols by patching libcrypto.num + # This is required for replace-default unit tests to link + libcrypto_num = os.path.join(s, "util", "libcrypto.num") + if os.path.exists(libcrypto_num): + bb.note("REPLACE-DEFAULT MODE: Exporting ossl_provider_* symbols in libcrypto.num") + try: + # Read the file to find the last symbol number and version + with open(libcrypto_num, 'r') as f: + lines = f.readlines() + + # Find the last symbol number and version + last_num = 0 + last_version = "3.0.0" + for line in lines: + parts = line.split() + if len(parts) >= 2: + try: + num = int(parts[1]) + if num > last_num: + last_num = num + if len(parts) >= 3: + last_version = parts[2] + except ValueError: + pass + + # Check if symbols are already added + with open(libcrypto_num, 'r') as f: + content = f.read() + if 'ossl_provider_new' in content: + bb.note("REPLACE-DEFAULT MODE: ossl_provider_* symbols already in libcrypto.num") + return + + # Append the 6 provider symbols + symbols_to_add = [ + ("ossl_provider_new", last_num + 1), + ("ossl_provider_activate", last_num + 2), + ("ossl_provider_deactivate", last_num + 3), + ("ossl_provider_add_to_store", last_num + 4), + ("ossl_provider_free", last_num + 5), + ("ossl_default_provider_init", last_num + 6), + ] + + with open(libcrypto_num, 'a') as f: + for symbol_name, symbol_num in symbols_to_add: + # Format: symbol_name NUM VERSION EXIST::FUNCTION: + f.write(f"{symbol_name:<40} {symbol_num}\t{last_version}\tEXIST::FUNCTION:\n") + + bb.note(f"REPLACE-DEFAULT MODE: Added {len(symbols_to_add)} provider symbols to libcrypto.num") + except Exception as e: + bb.warn(f"REPLACE-DEFAULT MODE: Error patching libcrypto.num: {e}") + else: + bb.warn(f"REPLACE-DEFAULT MODE: libcrypto.num not found at {libcrypto_num}") +} + +# Disable internal keymgmt tests under wolfprovider FIPS mode which +# fails on the FACTOR3 and EXPONENT3 and COEFFICIENT2 parameters which +# are not supported by wolfProvider. +python do_patch:append:class-target () { + import os, subprocess + # Only run this when FIPS is enabled + if not bb.utils.contains('IMAGE_FEATURES', 'fips', True, False, d): + bb.note("FIPS not enabled; skipping openssl-disable-internal-keymgmt-tests.patch") + return + + s = d.getVar("S") + # Construct full path directly from layer directory (no need for FILESEXTRAPATHS) + patch_path = os.path.join(d.getVar("WOLFSSL_LAYERDIR"), "inc/wolfprovider/openssl/scarthgap/files/openssl-disable-internal-keymgmt-tests.patch") + # Check if patch file exists + if not os.path.exists(patch_path): + bb.warn(f"openssl-disable-internal-keymgmt-tests.patch not found at {patch_path}") + return + + # Try to apply the patch; if it fails with "already applied", log it and continue + try: + result = subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path, "--dry-run"], + capture_output=True, text=True, check=False) + if result.returncode == 0: + bb.note("openssl-disable-internal-keymgmt-tests.patch can be applied, applying now...") + subprocess.run(["patch", "-d", s, "-p1", "-i", patch_path], check=True) + else: + bb.note("openssl-disable-internal-keymgmt-tests.patch already applied or cannot apply, skipping") + bb.debug(1, f"Patch check output: {result.stderr}") + except Exception as e: + bb.warn(f"openssl-disable-internal-keymgmt-tests.patch: Error applying patch: {e}") +} + +do_install:append() { + install -d ${D}${sysconfdir}/openssl + echo "1" > ${D}${sysconfdir}/openssl/replace-default-enabled +} diff --git a/inc/wolfprovider/wolfprovider-enable-replace-default-unittest-legacy.inc b/inc/wolfprovider/wolfprovider-enable-replace-default-unittest-legacy.inc new file mode 100644 index 00000000..b7069575 --- /dev/null +++ b/inc/wolfprovider/wolfprovider-enable-replace-default-unittest-legacy.inc @@ -0,0 +1,12 @@ +# Enable replace default unit tests with wolfProvider + +# Also export as environment variable for configure script compatibility +export WOLFPROV_REPLACE_DEFAULT = "1" +export WOLFPROV_REPLACE_DEFAULT_TESTING = "1" + +# Enable unit tests that use internal OpenSSL provider functions +# These functions (ossl_provider_new, ossl_provider_activate, etc.) are only available +# when OpenSSL is patched with the replace-default patch +CPPFLAGS_append = " -DWOLFPROV_REPLACE_DEFAULT" +CPPFLAGS_append = " -DWOLFPROV_REPLACE_DEFAULT_UNIT_TEST" +CPPFLAGS_append = " -DWOLFPROV_QUICKTEST" diff --git a/inc/wolfprovider/wolfprovider-enable-replace-default-unittest-modern.inc b/inc/wolfprovider/wolfprovider-enable-replace-default-unittest-modern.inc new file mode 100644 index 00000000..e2889f21 --- /dev/null +++ b/inc/wolfprovider/wolfprovider-enable-replace-default-unittest-modern.inc @@ -0,0 +1,12 @@ +# Enable replace default unit tests with wolfProvider + +# Also export as environment variable for configure script compatibility +export WOLFPROV_REPLACE_DEFAULT = "1" +export WOLFPROV_REPLACE_DEFAULT_TESTING = "1" + +# Enable unit tests that use internal OpenSSL provider functions +# These functions (ossl_provider_new, ossl_provider_activate, etc.) are only available +# when OpenSSL is patched with the replace-default patch +CPPFLAGS:append = " -DWOLFPROV_REPLACE_DEFAULT" +CPPFLAGS:append = " -DWOLFPROV_REPLACE_DEFAULT_UNIT_TEST" +CPPFLAGS:append = " -DWOLFPROV_QUICKTEST" diff --git a/inc/wolfprovider/wolfprovider-enable-replace-default-unittest.inc b/inc/wolfprovider/wolfprovider-enable-replace-default-unittest.inc new file mode 100644 index 00000000..8b18ce91 --- /dev/null +++ b/inc/wolfprovider/wolfprovider-enable-replace-default-unittest.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfprovider_get_replace_default_unittest_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfprovider-enable-replace-default-unittest.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/wolfprovider-enable-replace-default-unittest-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfprovider/wolfprovider-enable-replace-default-unittest-legacy.inc') + + bb.note("wolfprovider-enable-replace-default-unittest.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfprovider_get_replace_default_unittest_inc(d)} \ No newline at end of file diff --git a/inc/wolfprovider/wolfprovider-enable-unittest-legacy.inc b/inc/wolfprovider/wolfprovider-enable-unittest-legacy.inc new file mode 100644 index 00000000..ef17789a --- /dev/null +++ b/inc/wolfprovider/wolfprovider-enable-unittest-legacy.inc @@ -0,0 +1,92 @@ +# Configuration to enable wolfProvider unit tests +# Modeled exactly after wolfcrypttest approach - simple and clean + +# Set FILESEXTRAPATHS and SRC_URI early using Python to ensure correct evaluation order +python __anonymous() { + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if not layerdir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + # Set FILESEXTRAPATHS first, then SRC_URI + filespath = layerdir + "/recipes-examples/wolfprovider/wolfprovidertest/files:" + existing_paths = d.getVar('FILESEXTRAPATHS') or '' + d.setVar('FILESEXTRAPATHS', filespath + existing_paths) + + # Add SRC_URI entry + d.appendVar('SRC_URI', ' file://wolfprovidertest.sh') +} + +# Unit test directory and binary names +WOLFPROVIDER_TEST_DIR = "${B}/test/.libs" +WOLFPROVIDER_TEST = "unit.test" +WOLFPROVIDER_TEST_YOCTO = "unit.test" +WOLFPROVIDER_INSTALL_DIR = "${D}${bindir}" +WOLFPROVIDER_CERTS_DIR = "${S}/certs" +WOLFPROVIDER_CERTS_INSTALL_DIR = "${D}${datadir}/wolfprovider-test/certs" + +# Override CERTS_DIR to point to the installed location instead of build directory +# First undefine CERTS_DIR (in case autotools defined it), then redefine it +CFLAGS_append = ' -UCERTS_DIR -DCERTS_DIR=\\"/usr/share/wolfprovider-test/certs\\"' +CXXFLAGS_append = ' -UCERTS_DIR -DCERTS_DIR=\\"/usr/share/wolfprovider-test/certs\\"' + +# Simple installation using Python function, exactly like wolfcrypttest +python () { + # Get the environment variables + test_dir = d.getVar('WOLFPROVIDER_TEST_DIR', True) + test_bin = d.getVar('WOLFPROVIDER_TEST', True) + test_yocto = d.getVar('WOLFPROVIDER_TEST_YOCTO', True) + install_dir = d.getVar('WOLFPROVIDER_INSTALL_DIR', True) + certs_dir = d.getVar('WOLFPROVIDER_CERTS_DIR', True) + certs_install_dir = d.getVar('WOLFPROVIDER_CERTS_INSTALL_DIR', True) + + bbnote = 'bbnote "Installing wolfProvider Tests"\n' + installDir = 'install -m 0755 -d "%s"\n' % (install_dir) + + # Try multiple locations for the test binary (exactly like wolfcrypttest) + cpTest = 'if [ -f "%s/%s" ]; then cp "%s/%s" "%s/%s"; ' % (test_dir, test_bin, test_dir, test_bin, install_dir, test_yocto) + cpTest += 'elif [ -f "${B}/test/%s" ]; then cp "${B}/test/%s" "%s/%s"; ' % (test_bin, test_bin, install_dir, test_yocto) + cpTest += 'elif [ -f "${B}/%s" ]; then cp "${B}/%s" "%s/%s"; fi\n' % (test_bin, test_bin, install_dir, test_yocto) + + # Install wrapper script + installScript = 'cp "${WORKDIR}/wolfprovidertest.sh" "%s/wolfprovidertest"\n' % (install_dir) + installScript += 'chmod 755 "%s/wolfprovidertest"\n' % (install_dir) + + # Install certificates + installCerts = 'bbnote "Installing wolfProvider Certificates"\n' + installCerts += 'install -m 0755 -d "%s"\n' % (certs_install_dir) + installCerts += 'if [ -d "%s" ]; then cp -r %s/*.pem %s/ 2>/dev/null || true; fi\n' % (certs_dir, certs_dir, certs_install_dir) + + d.appendVar('do_install', bbnote) + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpTest) + d.appendVar('do_install', installScript) + d.appendVar('do_install', installCerts) +} + +# Append test files and library files to FILES using Python +python __anonymous() { + pn = d.getVar('PN') + + # Get existing FILES value (set by autotools class and base recipe) + existing_files = d.getVar('FILES_' + pn) or '' + + # Append our test files (don't re-add library files - they're in base recipe FILES) + new_files = existing_files + ' ' + ' '.join([ + '${bindir}/wolfprovidertest', + '${bindir}/unit.test', + '${datadir}/wolfprovider-test/certs/*' + ]) + + # Set the combined value (this avoids the "replaces original key" warning) + d.setVar('FILES_' + pn, new_files) + + # Same approach for RDEPENDS + existing_rdepends = d.getVar('RDEPENDS_' + pn) or '' + new_rdepends = existing_rdepends + ' bash wolfproviderenv' + d.setVar('RDEPENDS_' + pn, new_rdepends) + + # Same approach for INSANE_SKIP + existing_skip = d.getVar('INSANE_SKIP_' + pn) or '' + new_skip = existing_skip + ' dev-so build-deps' + d.setVar('INSANE_SKIP_' + pn, new_skip) +} diff --git a/inc/wolfprovider/wolfprovider-enable-unittest-modern.inc b/inc/wolfprovider/wolfprovider-enable-unittest-modern.inc new file mode 100644 index 00000000..7b11d256 --- /dev/null +++ b/inc/wolfprovider/wolfprovider-enable-unittest-modern.inc @@ -0,0 +1,92 @@ +# Configuration to enable wolfProvider unit tests +# Modeled exactly after wolfcrypttest approach - simple and clean + +# Set FILESEXTRAPATHS and SRC_URI early using Python to ensure correct evaluation order +python __anonymous() { + layerdir = d.getVar('WOLFSSL_LAYERDIR') + if not layerdir: + bb.fatal("WOLFSSL_LAYERDIR not set - ensure meta-wolfssl layer is properly configured") + + # Set FILESEXTRAPATHS first, then SRC_URI + filespath = layerdir + "/recipes-examples/wolfprovider/wolfprovidertest/files:" + existing_paths = d.getVar('FILESEXTRAPATHS') or '' + d.setVar('FILESEXTRAPATHS', filespath + existing_paths) + + # Add SRC_URI entry + d.appendVar('SRC_URI', ' file://wolfprovidertest.sh') +} + +# Unit test directory and binary names +WOLFPROVIDER_TEST_DIR = "${B}/test/.libs" +WOLFPROVIDER_TEST = "unit.test" +WOLFPROVIDER_TEST_YOCTO = "unit.test" +WOLFPROVIDER_INSTALL_DIR = "${D}${bindir}" +WOLFPROVIDER_CERTS_DIR = "${S}/certs" +WOLFPROVIDER_CERTS_INSTALL_DIR = "${D}${datadir}/wolfprovider-test/certs" + +# Override CERTS_DIR to point to the installed location instead of build directory +# First undefine CERTS_DIR (in case autotools defined it), then redefine it +CFLAGS:append = ' -UCERTS_DIR -DCERTS_DIR=\\"/usr/share/wolfprovider-test/certs\\"' +CXXFLAGS:append = ' -UCERTS_DIR -DCERTS_DIR=\\"/usr/share/wolfprovider-test/certs\\"' + +# Simple installation using Python function, exactly like wolfcrypttest +python () { + # Get the environment variables + test_dir = d.getVar('WOLFPROVIDER_TEST_DIR', True) + test_bin = d.getVar('WOLFPROVIDER_TEST', True) + test_yocto = d.getVar('WOLFPROVIDER_TEST_YOCTO', True) + install_dir = d.getVar('WOLFPROVIDER_INSTALL_DIR', True) + certs_dir = d.getVar('WOLFPROVIDER_CERTS_DIR', True) + certs_install_dir = d.getVar('WOLFPROVIDER_CERTS_INSTALL_DIR', True) + + bbnote = 'bbnote "Installing wolfProvider Tests"\n' + installDir = 'install -m 0755 -d "%s"\n' % (install_dir) + + # Try multiple locations for the test binary (exactly like wolfcrypttest) + cpTest = 'if [ -f "%s/%s" ]; then cp "%s/%s" "%s/%s"; ' % (test_dir, test_bin, test_dir, test_bin, install_dir, test_yocto) + cpTest += 'elif [ -f "${B}/test/%s" ]; then cp "${B}/test/%s" "%s/%s"; ' % (test_bin, test_bin, install_dir, test_yocto) + cpTest += 'elif [ -f "${B}/%s" ]; then cp "${B}/%s" "%s/%s"; fi\n' % (test_bin, test_bin, install_dir, test_yocto) + + # Install wrapper script + installScript = 'cp "${WORKDIR}/wolfprovidertest.sh" "%s/wolfprovidertest"\n' % (install_dir) + installScript += 'chmod 755 "%s/wolfprovidertest"\n' % (install_dir) + + # Install certificates + installCerts = 'bbnote "Installing wolfProvider Certificates"\n' + installCerts += 'install -m 0755 -d "%s"\n' % (certs_install_dir) + installCerts += 'if [ -d "%s" ]; then cp -r %s/*.pem %s/ 2>/dev/null || true; fi\n' % (certs_dir, certs_dir, certs_install_dir) + + d.appendVar('do_install', bbnote) + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpTest) + d.appendVar('do_install', installScript) + d.appendVar('do_install', installCerts) +} + +# Append test files and library files to FILES using Python +python __anonymous() { + pn = d.getVar('PN') + + # Get existing FILES value (set by autotools class and base recipe) + existing_files = d.getVar('FILES:' + pn) or '' + + # Append our test files (don't re-add library files - they're in base recipe FILES) + new_files = existing_files + ' ' + ' '.join([ + '${bindir}/wolfprovidertest', + '${bindir}/unit.test', + '${datadir}/wolfprovider-test/certs/*' + ]) + + # Set the combined value (this avoids the "replaces original key" warning) + d.setVar('FILES:' + pn, new_files) + + # Same approach for RDEPENDS + existing_rdepends = d.getVar('RDEPENDS:' + pn) or '' + new_rdepends = existing_rdepends + ' bash wolfproviderenv' + d.setVar('RDEPENDS:' + pn, new_rdepends) + + # Same approach for INSANE_SKIP + existing_skip = d.getVar('INSANE_SKIP:' + pn) or '' + new_skip = existing_skip + ' dev-so build-deps' + d.setVar('INSANE_SKIP:' + pn, new_skip) +} diff --git a/inc/wolfprovider/wolfprovider-enable-unittest.inc b/inc/wolfprovider/wolfprovider-enable-unittest.inc new file mode 100644 index 00000000..35245204 --- /dev/null +++ b/inc/wolfprovider/wolfprovider-enable-unittest.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfprovider_get_unittest_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfprovider-enable-unittest.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/wolfprovider-enable-unittest-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfprovider/wolfprovider-enable-unittest-legacy.inc') + + bb.note("wolfprovider-enable-unittest.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfprovider_get_unittest_inc(d)} \ No newline at end of file diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-legacy.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-legacy.inc new file mode 100644 index 00000000..5c7c6bc4 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-legacy.inc @@ -0,0 +1,20 @@ +# Configuration to enable wolfprovider FIPS support in wolfssl +# To enable debug add `--enable-debug --enable-keylog-export` to EXTRA_OECONF + +EXTRA_OECONF += " --enable-fips=v5 --enable-opensslcoexist" +TARGET_CFLAGS += " -DWOLFSSL_OLD_OID_SUM -DWOLFSSL_DH_EXTRA" + +# Use a marker file to signal we are a FIPS build +WOLFSSL_ISFIPS = "1" + +# commercial bundle missing stamp-h.in required by automake with 5.2.1 +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-modern.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-modern.inc new file mode 100644 index 00000000..7c58cbe1 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips-modern.inc @@ -0,0 +1,20 @@ +# Configuration to enable wolfprovider FIPS support in wolfssl +# To enable debug add `--enable-debug --enable-keylog-export` to EXTRA_OECONF + +EXTRA_OECONF += " --enable-fips=v5 --enable-opensslcoexist" +TARGET_CFLAGS += " -DWOLFSSL_OLD_OID_SUM -DWOLFSSL_DH_EXTRA" + +# Use a marker file to signal we are a FIPS build +WOLFSSL_ISFIPS = "1" + +# commercial bundle missing stamp-h.in required by automake with 5.2.1 +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.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc new file mode 100644 index 00000000..251a8c4d --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfprovider_fips_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfprovider-fips.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-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfprovider/wolfssl-enable-wolfprovider-fips-legacy.inc') + + bb.note("wolfssl-enable-wolfprovider-fips.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfprovider_fips_inc(d)} \ No newline at end of file diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider-legacy.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-legacy.inc new file mode 100644 index 00000000..c7eed480 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-legacy.inc @@ -0,0 +1,13 @@ +# Configuration to enable wolfprovider support in wolfssl +# To enable debug add `--enable-debug --enable-keylog-export` to EXTRA_OECONF + +EXTRA_OECONF += " --enable-all-crypto --with-eccminsz=192 --with-max-ecc-bits=1024 --enable-opensslcoexist --enable-sha" +TARGET_CFLAGS += " -DWC_RSA_NO_PADDING -DWOLFSSL_PUBLIC_MP -DHAVE_PUBLIC_FFDHE -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_PSS_SALT_LEN_DISCOVER -DRSA_MIN_SIZE=1024 -DWOLFSSL_OLD_OID_SUM" + +# Use a marker file to signal we are a non-FIPS build +WOLFSSL_ISFIPS = "0" + +do_install_append() { + install -d ${D}${sysconfdir}/wolfssl + echo "0" > ${D}${sysconfdir}/wolfssl/fips-enabled +} diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider-modern.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider-modern.inc new file mode 100644 index 00000000..782b9f01 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider-modern.inc @@ -0,0 +1,13 @@ +# Configuration to enable wolfprovider support in wolfssl +# To enable debug add `--enable-debug --enable-keylog-export` to EXTRA_OECONF + +EXTRA_OECONF += " --enable-all-crypto --with-eccminsz=192 --with-max-ecc-bits=1024 --enable-opensslcoexist --enable-sha" +TARGET_CFLAGS += " -DWC_RSA_NO_PADDING -DWOLFSSL_PUBLIC_MP -DHAVE_PUBLIC_FFDHE -DHAVE_FFDHE_6144 -DHAVE_FFDHE_8192 -DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_PSS_SALT_LEN_DISCOVER -DRSA_MIN_SIZE=1024 -DWOLFSSL_OLD_OID_SUM" + +# Use a marker file to signal we are a non-FIPS build +WOLFSSL_ISFIPS = "0" + +do_install:append() { + install -d ${D}${sysconfdir}/wolfssl + echo "0" > ${D}${sysconfdir}/wolfssl/fips-enabled +} diff --git a/inc/wolfprovider/wolfssl-enable-wolfprovider.inc b/inc/wolfprovider/wolfssl-enable-wolfprovider.inc new file mode 100644 index 00000000..59ca7ae2 --- /dev/null +++ b/inc/wolfprovider/wolfssl-enable-wolfprovider.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfprovider_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfprovider.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-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfprovider/wolfssl-enable-wolfprovider-legacy.inc') + + bb.note("wolfssl-enable-wolfprovider.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfprovider_inc(d)} \ No newline at end of file diff --git a/inc/wolfssh/wolfssl-enable-wolfssh-legacy.inc b/inc/wolfssh/wolfssl-enable-wolfssh-legacy.inc new file mode 100644 index 00000000..343c1672 --- /dev/null +++ b/inc/wolfssh/wolfssl-enable-wolfssh-legacy.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolfssh support in wolfssl +EXTRA_OECONF += "--enable-ssh" diff --git a/inc/wolfssh/wolfssl-enable-wolfssh-modern.inc b/inc/wolfssh/wolfssl-enable-wolfssh-modern.inc new file mode 100644 index 00000000..343c1672 --- /dev/null +++ b/inc/wolfssh/wolfssl-enable-wolfssh-modern.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolfssh support in wolfssl +EXTRA_OECONF += "--enable-ssh" diff --git a/inc/wolfssh/wolfssl-enable-wolfssh.inc b/inc/wolfssh/wolfssl-enable-wolfssh.inc new file mode 100644 index 00000000..5978a2ec --- /dev/null +++ b/inc/wolfssh/wolfssl-enable-wolfssh.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfssh_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfssh.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/wolfssh/wolfssl-enable-wolfssh-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssh/wolfssl-enable-wolfssh-legacy.inc') + + bb.note("wolfssl-enable-wolfssh.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfssh_inc(d)} \ No newline at end of file diff --git a/inc/wolfssl-fips/wolfssl-commercial-gcs-legacy.inc b/inc/wolfssl-fips/wolfssl-commercial-gcs-legacy.inc new file mode 100644 index 00000000..6128fb59 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-commercial-gcs-legacy.inc @@ -0,0 +1,33 @@ +# Use Yocto's native GCS/tarball fetch path instead of the 7z helper when +# WOLFSSL_BUNDLE_GCS_URI is provided. This disables the custom commercial +# extraction task and lets BitBake handle download + unpack. +WOLFSSL_BUNDLE_GCS_URI ?= "" + +python () { + import bb + import bb.build + + uri = d.getVar('WOLFSSL_BUNDLE_GCS_URI') + if not uri or not uri.strip(): + return + + sha = d.getVar('WOLFSSL_SRC_SHA') or '' + bundle_file = d.getVar('WOLFSSL_BUNDLE_FILE') or d.getVar('COMMERCIAL_BUNDLE_ARCHIVE') or '' + + flags = '' + if bundle_file: + flags += f';downloadfilename={bundle_file}' + if sha: + flags += f';sha256sum={sha}' + + d.setVar('SRC_URI', f"{uri}{flags}") + + # Use WOLFSSL_SRC_SUBDIR if set, otherwise fall back to WOLFSSL_SRC + src_subdir = d.getVar('WOLFSSL_SRC_SUBDIR') or d.getVar('WOLFSSL_SRC') + d.setVar('S', f"{d.getVar('WORKDIR')}/{src_subdir}") + d.setVar('COMMERCIAL_BUNDLE_ENABLED', '0') + d.setVar('COMMERCIAL_BUNDLE_DIR', '${DL_DIR}') + + # Only tarballs are expected on this path; rely on BitBake unpack + bb.build.deltask('do_commercial_extract', d) +} diff --git a/inc/wolfssl-fips/wolfssl-commercial-gcs-modern.inc b/inc/wolfssl-fips/wolfssl-commercial-gcs-modern.inc new file mode 100644 index 00000000..6128fb59 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-commercial-gcs-modern.inc @@ -0,0 +1,33 @@ +# Use Yocto's native GCS/tarball fetch path instead of the 7z helper when +# WOLFSSL_BUNDLE_GCS_URI is provided. This disables the custom commercial +# extraction task and lets BitBake handle download + unpack. +WOLFSSL_BUNDLE_GCS_URI ?= "" + +python () { + import bb + import bb.build + + uri = d.getVar('WOLFSSL_BUNDLE_GCS_URI') + if not uri or not uri.strip(): + return + + sha = d.getVar('WOLFSSL_SRC_SHA') or '' + bundle_file = d.getVar('WOLFSSL_BUNDLE_FILE') or d.getVar('COMMERCIAL_BUNDLE_ARCHIVE') or '' + + flags = '' + if bundle_file: + flags += f';downloadfilename={bundle_file}' + if sha: + flags += f';sha256sum={sha}' + + d.setVar('SRC_URI', f"{uri}{flags}") + + # Use WOLFSSL_SRC_SUBDIR if set, otherwise fall back to WOLFSSL_SRC + src_subdir = d.getVar('WOLFSSL_SRC_SUBDIR') or d.getVar('WOLFSSL_SRC') + d.setVar('S', f"{d.getVar('WORKDIR')}/{src_subdir}") + d.setVar('COMMERCIAL_BUNDLE_ENABLED', '0') + d.setVar('COMMERCIAL_BUNDLE_DIR', '${DL_DIR}') + + # Only tarballs are expected on this path; rely on BitBake unpack + bb.build.deltask('do_commercial_extract', d) +} diff --git a/inc/wolfssl-fips/wolfssl-commercial-gcs.inc b/inc/wolfssl-fips/wolfssl-commercial-gcs.inc new file mode 100644 index 00000000..9fcad4ac --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-commercial-gcs.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_commercial_gcs_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-commercial-gcs.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/wolfssl-commercial-gcs-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips/wolfssl-commercial-gcs-legacy.inc') + + bb.note("wolfssl-commercial-gcs.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_commercial_gcs_inc(d)} diff --git a/inc/wolfssl-fips/wolfssl-enable-gnutls-legacy.inc b/inc/wolfssl-fips/wolfssl-enable-gnutls-legacy.inc new file mode 100644 index 00000000..172e1128 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-enable-gnutls-legacy.inc @@ -0,0 +1,18 @@ +EXTRA_OECONF += " \ + --enable-cmac \ + --enable-aesccm \ + --enable-keygen \ + --enable-fips=v5 \ +" + +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/wolfssl-enable-gnutls-modern.inc b/inc/wolfssl-fips/wolfssl-enable-gnutls-modern.inc new file mode 100644 index 00000000..172e1128 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-enable-gnutls-modern.inc @@ -0,0 +1,18 @@ +EXTRA_OECONF += " \ + --enable-cmac \ + --enable-aesccm \ + --enable-keygen \ + --enable-fips=v5 \ +" + +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/wolfssl-enable-gnutls.inc b/inc/wolfssl-fips/wolfssl-enable-gnutls.inc new file mode 100644 index 00000000..86e987a0 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-enable-gnutls.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_gnutls_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("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/wolfssl-enable-gnutls-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips/wolfssl-enable-gnutls-legacy.inc') + + bb.note("wolfssl-enable-gnutls.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_gnutls_inc(d)} diff --git a/inc/wolfssl-fips/wolfssl-enable-libgcrypt-legacy.inc b/inc/wolfssl-fips/wolfssl-enable-libgcrypt-legacy.inc new file mode 100644 index 00000000..c2e13134 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-enable-libgcrypt-legacy.inc @@ -0,0 +1,21 @@ +# Configure wolfSSL 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=v5 : FIPS 140-3 validation +# --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=v5 --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/wolfssl-enable-libgcrypt-modern.inc b/inc/wolfssl-fips/wolfssl-enable-libgcrypt-modern.inc new file mode 100644 index 00000000..c2e13134 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-enable-libgcrypt-modern.inc @@ -0,0 +1,21 @@ +# Configure wolfSSL 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=v5 : FIPS 140-3 validation +# --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=v5 --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/wolfssl-enable-libgcrypt.inc b/inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc new file mode 100644 index 00000000..56a2c259 --- /dev/null +++ b/inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_libgcrypt_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("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/wolfssl-enable-libgcrypt-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-fips/wolfssl-enable-libgcrypt-legacy.inc') + + bb.note("wolfssl-enable-libgcrypt.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_libgcrypt_inc(d)} \ No newline at end of file diff --git a/inc/wolfssl-manual-config-legacy.inc b/inc/wolfssl-manual-config-legacy.inc new file mode 100644 index 00000000..669aceb1 --- /dev/null +++ b/inc/wolfssl-manual-config-legacy.inc @@ -0,0 +1,13 @@ +# Include this file in any wolfSSL package bbappend when manually configuring wolfSSL. +# This will disable the feature check task that validates IMAGE_INSTALL or WOLFSSL_FEATURES. +# +# Usage in your-layer/recipes-wolfssl//_%.bbappend: +# require inc/wolfssl-manual-config.inc +# +# Or with full path: +# require ${COREBASE}/../meta-wolfssl/inc/wolfssl-manual-config.inc +# +# Note: You also need to configure wolfSSL by including the appropriate +# wolfssl-enable-*.inc file(s) in your wolfssl_%.bbappend file. + +deltask do_wolfssl_check_package diff --git a/inc/wolfssl-manual-config-modern.inc b/inc/wolfssl-manual-config-modern.inc new file mode 100644 index 00000000..669aceb1 --- /dev/null +++ b/inc/wolfssl-manual-config-modern.inc @@ -0,0 +1,13 @@ +# Include this file in any wolfSSL package bbappend when manually configuring wolfSSL. +# This will disable the feature check task that validates IMAGE_INSTALL or WOLFSSL_FEATURES. +# +# Usage in your-layer/recipes-wolfssl//_%.bbappend: +# require inc/wolfssl-manual-config.inc +# +# Or with full path: +# require ${COREBASE}/../meta-wolfssl/inc/wolfssl-manual-config.inc +# +# Note: You also need to configure wolfSSL by including the appropriate +# wolfssl-enable-*.inc file(s) in your wolfssl_%.bbappend file. + +deltask do_wolfssl_check_package diff --git a/inc/wolfssl-manual-config.inc b/inc/wolfssl-manual-config.inc new file mode 100644 index 00000000..aa9281ee --- /dev/null +++ b/inc/wolfssl-manual-config.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_manual_config_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-manual-config.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-manual-config-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-manual-config-legacy.inc') + + bb.note("wolfssl-manual-config.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_manual_config_inc(d)} \ No newline at end of file diff --git a/inc/wolfssl-py/wolfssl-enable-wolfssl-py-legacy.inc b/inc/wolfssl-py/wolfssl-enable-wolfssl-py-legacy.inc new file mode 100644 index 00000000..85da6094 --- /dev/null +++ b/inc/wolfssl-py/wolfssl-enable-wolfssl-py-legacy.inc @@ -0,0 +1,5 @@ +# Configuration to enable wolfssl-py support in wolfssl +# Python bindings need specific features enabled +EXTRA_OECONF += "--enable-sni --enable-opensslextra --enable-opensslall --enable-dtls13 --enable-dtls --enable-crl --enable-tlsx --enable-secure-renegotiation" + +TARGET_CFLAGS += "-DKEEP_PEER_CERT -DFP_MAX_BITS=8192 -DHAVE_EX_DATA -DOPENSSL_COMPATIBLE_DEFAULTS" diff --git a/inc/wolfssl-py/wolfssl-enable-wolfssl-py-modern.inc b/inc/wolfssl-py/wolfssl-enable-wolfssl-py-modern.inc new file mode 100644 index 00000000..85da6094 --- /dev/null +++ b/inc/wolfssl-py/wolfssl-enable-wolfssl-py-modern.inc @@ -0,0 +1,5 @@ +# Configuration to enable wolfssl-py support in wolfssl +# Python bindings need specific features enabled +EXTRA_OECONF += "--enable-sni --enable-opensslextra --enable-opensslall --enable-dtls13 --enable-dtls --enable-crl --enable-tlsx --enable-secure-renegotiation" + +TARGET_CFLAGS += "-DKEEP_PEER_CERT -DFP_MAX_BITS=8192 -DHAVE_EX_DATA -DOPENSSL_COMPATIBLE_DEFAULTS" diff --git a/inc/wolfssl-py/wolfssl-enable-wolfssl-py.inc b/inc/wolfssl-py/wolfssl-enable-wolfssl-py.inc new file mode 100644 index 00000000..715bb876 --- /dev/null +++ b/inc/wolfssl-py/wolfssl-enable-wolfssl-py.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolfssl_py_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolfssl-py.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-py/wolfssl-enable-wolfssl-py-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolfssl-py/wolfssl-enable-wolfssl-py-legacy.inc') + + bb.note("wolfssl-enable-wolfssl-py.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolfssl_py_inc(d)} \ No newline at end of file diff --git a/inc/wolfssl/wolfssl-enable-gnutls.inc b/inc/wolfssl/wolfssl-enable-gnutls.inc new file mode 100644 index 00000000..4778668a --- /dev/null +++ b/inc/wolfssl/wolfssl-enable-gnutls.inc @@ -0,0 +1,33 @@ +# Non-FIPS wolfSSL configuration for GnuTLS +EXTRA_OECONF += " \ + --enable-cmac \ + --with-eccminsz=192 \ + --enable-ed25519 \ + --enable-ed448 \ + --enable-md5 \ + --enable-curve25519 \ + --enable-curve448 \ + --enable-aesccm \ + --enable-aesxts \ + --enable-aescfb \ + --enable-keygen \ + --enable-shake128 \ + --enable-shake256 \ +" + +TARGET_CFLAGS += " \ + -DWOLFSSL_PUBLIC_ASN \ + -DHAVE_FFDHE_3072 \ + -DHAVE_FFDHE_4096 \ + -DWOLFSSL_DH_EXTRA \ + -DWOLFSSL_PSS_SALT_LEN_DISCOVER \ + -DWOLFSSL_PUBLIC_MP \ + -DWOLFSSL_RSA_KEY_CHECK \ + -DHAVE_FFDHE_Q \ + -DHAVE_FFDHE_6144 \ + -DHAVE_FFDHE_8192 \ + -DWOLFSSL_ECDSA_DETERMINISTIC_K \ + -DWOLFSSL_VALIDATE_ECC_IMPORT \ + -DRSA_MIN_SIZE=1024 \ + -DWOLFSSL_AES_COUNTER \ +" diff --git a/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-legacy.inc b/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-legacy.inc new file mode 100644 index 00000000..870816de --- /dev/null +++ b/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-legacy.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolftpm-wrap-test support in wolfssl +EXTRA_OECONF += "--enable-wolftpm" diff --git a/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-modern.inc b/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-modern.inc new file mode 100644 index 00000000..870816de --- /dev/null +++ b/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-modern.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolftpm-wrap-test support in wolfssl +EXTRA_OECONF += "--enable-wolftpm" diff --git a/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test.inc b/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test.inc new file mode 100644 index 00000000..f6b8c9cc --- /dev/null +++ b/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolftpm_wrap_test_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolftpm-wrap-test.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/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test-legacy.inc') + + bb.note("wolfssl-enable-wolftpm-wrap-test.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolftpm_wrap_test_inc(d)} \ No newline at end of file diff --git a/inc/wolftpm-tests/wolftpm-enable-wrap-test-legacy.inc b/inc/wolftpm-tests/wolftpm-enable-wrap-test-legacy.inc new file mode 100644 index 00000000..8b0ba462 --- /dev/null +++ b/inc/wolftpm-tests/wolftpm-enable-wrap-test-legacy.inc @@ -0,0 +1,28 @@ +# Enable wrap_test installation for wolfTPM +# +# This include file configures wolfTPM to build and install the wrap_test +# example to the target system for testing. + +WOLFTPM_TEST_DIR = "${B}/examples/wrap/.libs" +WOLFTPM_TEST = "wrap_test" +WOLFTPM_TEST_YOCTO = "wolftpm-wrap-test" +WOLFTPM_INSTALL_DIR = "${D}${bindir}" + +# Configurations (--enable-devtpm is required for the TPM simulator to work) +EXTRA_OECONF += "--enable-devtpm" + +python () { + # Get the environment variables WOLFTPM_TEST_DIR, WOLFTPM_TEST, + # WOLFTPM_TEST_YOCTO, and WOLFTPM_INSTALL_DIR + wolftpm_test_dir = d.getVar('WOLFTPM_TEST_DIR', True) + wolftpm_test = d.getVar('WOLFTPM_TEST', True) + wolftpm_test_yocto = d.getVar('WOLFTPM_TEST_YOCTO', True) + wolftpm_install_dir = d.getVar('WOLFTPM_INSTALL_DIR', True) + + installDir = 'install -m 0755 -d "%s"\n' % (wolftpm_install_dir) + cpWrapTest = 'cp "%s/%s" "%s/%s"\n' % (wolftpm_test_dir, wolftpm_test, + wolftpm_install_dir, wolftpm_test_yocto) + + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpWrapTest) +} diff --git a/inc/wolftpm-tests/wolftpm-enable-wrap-test-modern.inc b/inc/wolftpm-tests/wolftpm-enable-wrap-test-modern.inc new file mode 100644 index 00000000..8b0ba462 --- /dev/null +++ b/inc/wolftpm-tests/wolftpm-enable-wrap-test-modern.inc @@ -0,0 +1,28 @@ +# Enable wrap_test installation for wolfTPM +# +# This include file configures wolfTPM to build and install the wrap_test +# example to the target system for testing. + +WOLFTPM_TEST_DIR = "${B}/examples/wrap/.libs" +WOLFTPM_TEST = "wrap_test" +WOLFTPM_TEST_YOCTO = "wolftpm-wrap-test" +WOLFTPM_INSTALL_DIR = "${D}${bindir}" + +# Configurations (--enable-devtpm is required for the TPM simulator to work) +EXTRA_OECONF += "--enable-devtpm" + +python () { + # Get the environment variables WOLFTPM_TEST_DIR, WOLFTPM_TEST, + # WOLFTPM_TEST_YOCTO, and WOLFTPM_INSTALL_DIR + wolftpm_test_dir = d.getVar('WOLFTPM_TEST_DIR', True) + wolftpm_test = d.getVar('WOLFTPM_TEST', True) + wolftpm_test_yocto = d.getVar('WOLFTPM_TEST_YOCTO', True) + wolftpm_install_dir = d.getVar('WOLFTPM_INSTALL_DIR', True) + + installDir = 'install -m 0755 -d "%s"\n' % (wolftpm_install_dir) + cpWrapTest = 'cp "%s/%s" "%s/%s"\n' % (wolftpm_test_dir, wolftpm_test, + wolftpm_install_dir, wolftpm_test_yocto) + + d.appendVar('do_install', installDir) + d.appendVar('do_install', cpWrapTest) +} diff --git a/inc/wolftpm-tests/wolftpm-enable-wrap-test.inc b/inc/wolftpm-tests/wolftpm-enable-wrap-test.inc new file mode 100644 index 00000000..38d1ee50 --- /dev/null +++ b/inc/wolftpm-tests/wolftpm-enable-wrap-test.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolftpm_get_wrap_test_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolftpm-enable-wrap-test.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/wolftpm-tests/wolftpm-enable-wrap-test-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolftpm-tests/wolftpm-enable-wrap-test-legacy.inc') + + bb.note("wolftpm-enable-wrap-test.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolftpm_get_wrap_test_inc(d)} \ No newline at end of file diff --git a/inc/wolftpm/wolfssl-enable-wolftpm-legacy.inc b/inc/wolftpm/wolfssl-enable-wolftpm-legacy.inc new file mode 100644 index 00000000..dac0999b --- /dev/null +++ b/inc/wolftpm/wolfssl-enable-wolftpm-legacy.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolftpm support in wolfssl +EXTRA_OECONF += "--enable-certgen --enable-certreq --enable-certext --enable-pkcs7 --enable-cryptocb" diff --git a/inc/wolftpm/wolfssl-enable-wolftpm-modern.inc b/inc/wolftpm/wolfssl-enable-wolftpm-modern.inc new file mode 100644 index 00000000..dac0999b --- /dev/null +++ b/inc/wolftpm/wolfssl-enable-wolftpm-modern.inc @@ -0,0 +1,2 @@ +# Configuration to enable wolftpm support in wolfssl +EXTRA_OECONF += "--enable-certgen --enable-certreq --enable-certext --enable-pkcs7 --enable-cryptocb" diff --git a/inc/wolftpm/wolfssl-enable-wolftpm.inc b/inc/wolftpm/wolfssl-enable-wolftpm.inc new file mode 100644 index 00000000..962b24cf --- /dev/null +++ b/inc/wolftpm/wolfssl-enable-wolftpm.inc @@ -0,0 +1,28 @@ +# Check Yocto version and include appropriate file +def wolfssl_get_wolftpm_inc(d): + import os + layerseries = d.getVar('LAYERSERIES_CORENAMES') or "" + + bb.note("wolfssl-enable-wolftpm.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/wolftpm/wolfssl-enable-wolftpm-modern.inc') + else: + inc_file = os.path.join(layerdir, 'inc/wolftpm/wolfssl-enable-wolftpm-legacy.inc') + + bb.note("wolfssl-enable-wolftpm.inc: Including file: %s" % inc_file) + return inc_file + +# Include the appropriate file +require ${@wolfssl_get_wolftpm_inc(d)} \ No newline at end of file diff --git a/recipes-connectivity/bind/bind_9.11.22.bbappend b/recipes-connectivity/bind/bind_9.11.22.bbappend index 6607a9c6..5a1c6f43 100644 --- a/recipes-connectivity/bind/bind_9.11.22.bbappend +++ b/recipes-connectivity/bind/bind_9.11.22.bbappend @@ -2,5 +2,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://bind-9.11.22.patch" DEPENDS_remove = "openssl" EXTRA_OECONF_remove = "--with-openssl=${STAGING_DIR_HOST}${prefix}" -DEPENDS += " wolfssl" +DEPENDS += " virtual/wolfssl" EXTRA_OECONF += " --with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-connectivity/openssh/openssh_8.5p1.bbappend b/recipes-connectivity/openssh/openssh_8.5p1.bbappend index 51f912af..58b0d2e2 100644 --- a/recipes-connectivity/openssh/openssh_8.5p1.bbappend +++ b/recipes-connectivity/openssh/openssh_8.5p1.bbappend @@ -1,5 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://openssh-8.5p1.patch" DEPENDS_remove = "openssl" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-connectivity/socat/1.7.3.4/socat_1.7.3.4.bbappend b/recipes-connectivity/socat/1.7.3.4/socat_1.7.3.4.bbappend index b93eb1e2..5a51a0e1 100644 --- a/recipes-connectivity/socat/1.7.3.4/socat_1.7.3.4.bbappend +++ b/recipes-connectivity/socat/1.7.3.4/socat_1.7.3.4.bbappend @@ -1,5 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += " file://socat-1.7.3.4.patch" DEPENDS_remove = "openssl" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-connectivity/socat/1.8.0.0/socat_1.8.0.0.bbappend b/recipes-connectivity/socat/1.8.0.0/socat_1.8.0.0.bbappend index 27ebccf4..9f00c441 100644 --- a/recipes-connectivity/socat/1.8.0.0/socat_1.8.0.0.bbappend +++ b/recipes-connectivity/socat/1.8.0.0/socat_1.8.0.0.bbappend @@ -2,5 +2,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += " file://socat-1.8.0.0.patch" DEPENDS_remove = "openssl" EXTRA_AUTORECONF_remove = "--exclude=autoheader" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-core/README.md b/recipes-core/README.md new file mode 100644 index 00000000..f08f4177 --- /dev/null +++ b/recipes-core/README.md @@ -0,0 +1,264 @@ +# wolfSSL Demo Images + +This directory contains demonstration images for testing various wolfSSL sub-packages. Each image is a minimal Yocto image based on `core-image-minimal` with specific wolfSSL components installed and configured. + +## Enabling Demo Images + +To enable a demo image, add the following to your `conf/local.conf`: + +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal " +``` + +**Important:** All demo images (except `wolfssl-image-minimal` itself) require `wolfssl-image-minimal` to be included in `WOLFSSL_DEMOS` because they inherit from it. + +You can then build the image with: + +```bash +bitbake +``` + +## Available Demo Images + +### 1. wolfssl-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal" +``` + +**Provides:** +- wolfSSL library (with reproducible build configuration) +- wolfcrypttest - wolfSSL crypto test suite +- wolfcryptbenchmark - wolfSSL crypto benchmark utility + +**Description:** Base minimal image with wolfSSL and its core crypto testing tools. This serves as the foundation for all other demo images. + +--- + +### 2. wolfclu-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfclu-image-minimal" +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfCLU - Command-line utility for wolfSSL crypto operations + +**Description:** Demonstrates wolfCLU command-line tools for performing cryptographic operations. + +--- + +### 3. wolftpm-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolftpm-image-minimal" +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfTPM library +- wolftpm-wrap-test - wolfTPM wrapper test application +- TPM 2.0 tools (tpm2-tools, tpm2-tss, libtss2) +- bash shell + +**Requirements:** +Add to your `conf/local.conf`: +```bitbake +DISTRO_FEATURES += "security tpm tpm2" +MACHINE_FEATURES += "tpm tpm2" +KERNEL_FEATURES += "features/tpm/tpm.scc" +``` + +**Description:** Demonstrates wolfTPM integration with TPM 2.0 hardware/software support. Includes validation checks to ensure TPM features are properly enabled. + +**Testing:** +1. Use the included `test-wolftpm.sh` script in the image directory to run the image with a software TPM simulator (swtpm) in QEMU +2. Once booted into the QEMU image, run the test binary: + ```bash + /usr/bin/wolftpm-wrap-test + ``` + +--- + +### 4. wolfssl-py-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfssl-py-image-minimal" +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfssl-py - Python bindings for wolfSSL/TLS +- wolfcrypt-py - Python bindings for wolfCrypt +- wolf-py-tests - Test suite for Python bindings +- Python 3 with cffi and pytest + +**Description:** Demonstrates Python integration with wolfSSL. A simple image focused on Python bindings without additional networking features. + +**Note:** For all wolfssl-py tests to pass, you will need to configure networking in the QEMU environment (DNS resolvers, network connectivity, etc.). + +--- + +### 5. wolfprovider-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfprovider-image-minimal" +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfProvider - OpenSSL 3.x provider using wolfSSL +- wolfprovidertest - Test application for wolfProvider +- OpenSSL 3.x library and binaries +- bash shell + +**Description:** Demonstrates wolfProvider as an OpenSSL 3.x provider, allowing OpenSSL 3.x applications to use wolfSSL's crypto implementation. The image includes OpenSSL configured for wolfProvider compatibility. + +--- + +### 6. wolfssl-combined-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfssl-combined-image-minimal" +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfssh - SSH library implementation +- wolfmqtt - MQTT client library +- wolfProvider with OpenSSL 3.x +- wolfprovidertest +- wolftpm with wrap-test and TPM 2.0 tools +- bash shell + +**Requirements:** +Add to your `conf/local.conf`: +```bitbake +DISTRO_FEATURES += "security tpm tpm2" +MACHINE_FEATURES += "tpm tpm2" +KERNEL_FEATURES += "features/tpm/tpm.scc" +``` + +**Description:** A comprehensive image combining multiple wolfSSL sub-packages (SSH, MQTT, Provider, TPM) for testing interoperability and integration scenarios. + +--- + +### 7. wolfclu-combined-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfclu-combined-image-minimal" +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfCLU - Command-line utility +- wolfssl-py - Python bindings for wolfSSL/TLS +- wolfcrypt-py - Python bindings for wolfCrypt +- wolf-py-tests - Python test suite +- Python 3 with cffi and pytest +- Networking support with DNS configuration +- ca-certificates + +**Description:** Combines wolfCLU command-line tools with Python bindings, providing both CLI and Python interfaces to wolfSSL. Includes automatic DNS configuration for network-based Python tests. + +--- + +### 8. libgcrypt-image-minimal + +**Enable with:** +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal libgcrypt-image-minimal" +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +**Provides:** +- Everything from `wolfssl-image-minimal` +- wolfSSL FIPS (configured for libgcrypt support) +- libgcrypt 1.11.0 with wolfSSL backend +- libgcrypt-ptest - Test suite +- ptest-runner - Test execution tool + +**Special Requirements:** +- Requires wolfSSL FIPS commercial bundle +- Must set `require conf/wolfssl-fips.conf` in `local.conf` + +**Description:** Demonstrates libgcrypt configured to use wolfSSL FIPS as the cryptographic backend. This enables FIPS 140-3 validated cryptography for all applications using libgcrypt (GnuPG, systemd, NetworkManager, cryptsetup, etc.). + +**Testing:** +```bash +# In QEMU +ptest-runner libgcrypt +``` + +**More Information:** +- [OSP Integration README](../../recipes-support/libgcrypt/README.md) +- [Image-specific README](libgcrypt-image-minimal/README.md) + +--- + +## Image Structure + +All demo images follow this structure: + +``` +recipes-core/images// +├── .bb # Main image recipe +├── wolfssl_%.bbappend # Configure wolfSSL for this image +├── _%.bbappend # Disable feature checks for included packages +└── (optional) test scripts # Helper scripts for testing +``` + +## Configuration Method + +These images use **Manual Configuration** (Method 3 from the main README): + +1. **Image recipes** explicitly list packages in `IMAGE_INSTALL:append` +2. **wolfssl_%.bbappend** includes the necessary `inc//wolfssl-enable-.inc` files to configure wolfSSL with required features +3. **Package bbappends** include `inc/wolfssl-manual-config.inc` to disable the automatic feature check + +This approach ensures wolfSSL is built with the correct configuration for each image's packages without requiring global `WOLFSSL_FEATURES` or `IMAGE_INSTALL` settings. + +## Building Multiple Images + +You can enable multiple demo images by space-separating them. **Remember to always include `wolfssl-image-minimal` first:** + +```bitbake +WOLFSSL_DEMOS = "wolfssl-image-minimal wolfclu-image-minimal wolfssl-py-image-minimal" +``` + +Then build each image individually: + +```bash +bitbake wolfssl-image-minimal +bitbake wolfclu-image-minimal +bitbake wolfssl-py-image-minimal +``` + +**Note:** The base `wolfssl-image-minimal` must be included in `WOLFSSL_DEMOS` for any other demo image to be parsable by BitBake. + +## Running Images + +After building, run images with QEMU using: + +```bash +runqemu +``` + +For images with special requirements (like `wolftpm-image-minimal`), use the provided test scripts in the image directory. + +## Notes + +- All images inherit from `core-image-minimal` for a minimal footprint +- wolfSSL is always built with reproducible build flags +- Images with networking include DNS configuration for internet connectivity in QEMU +- TPM images require additional DISTRO/MACHINE feature configuration +- All images include the base crypto tests (wolfcrypttest, wolfcryptbenchmark) + diff --git a/recipes-core/images/gnutls-image-minimal/README.md b/recipes-core/images/gnutls-image-minimal/README.md new file mode 100644 index 00000000..ca45c2fa --- /dev/null +++ b/recipes-core/images/gnutls-image-minimal/README.md @@ -0,0 +1,124 @@ +# gnutls-image-minimal + +Minimal demo image showcasing gnutls with wolfSSL FIPS backend. + +## Overview + +This image demonstrates gnutls configured to use wolfSSL's FIPS-validated wolfCrypt as its cryptographic backend. This allows any application using gnutls (wget, openldap etc...) to benefit from FIPS 140-3 validated cryptography. + +## What's Included + +- Everything from `wolfssl-image-minimal` +- wolfSSL FIPS (auto-configured for gnutls support) +- gnutls 3.8.9 with wolfSSL backend +- gnutls-wolfssl (test suite) + +## Configuration + +### In `build/conf/local.conf`: + +```bitbake +# Enable demo images +WOLFSSL_DEMOS = "wolfssl-image-minimal gnutls-image-minimal" + +# Configure FIPS bundle (use absolute path) +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +### Build: + +```bash +bitbake gnutls-image-minimal +``` + +### Run in QEMU: + +```bash +runqemu gnutls-image-minimal nographic +``` + +## Testing + +Inside QEMU, run the gnutls test suite: + +```bash +# Run all tests +cd /opt/wolfssl-gnutls-wrapper/tests/ +make run_fips +``` + +### Expected Output + +The gnutls test suite should pass with the wolfSSL backend, each test prints ✔️/❌ and a summary. +It also showcases all the logs of the wrapper whenever some gnutls cryptographic code +in an application is called. + +## How It Works + +### wolfssl-fips Configuration + +The `wolfssl-fips.bbappend` in this directory automatically configures wolfssl-fips with features needed by gnutls: + +```bitbake +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-enable-gnutls.inc +``` + +This adds: +- `--enable-fips=v5` +- `--enable-keygen` +- Required compile flags (`HAVE_AES_ECB`, `WC_RSA_DIRECT`, etc.) + +### gnutls Configuration + +The `gnutls_%.bbappend` conditionally switches gnutls to the wolfSSL backend when wolfssl-fips is the provider: + +```bitbake +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/gnutls/gnutls-enable-wolfssl.inc', + allowed_providers=['wolfssl-fips'] + ) +} +``` + +This: +- Switches to `github.com/wolfSSL/gnutls` source +- Configures with the configurations listed in `inc/gnutls/gnutls-enable-wolfssl.inc` +- Adds wolfSSL dependencies + +## Applications + +With this image, any application using gnutls will automatically use FIPS-validated cryptography: + +## Requirements + +- Valid wolfSSL FIPS commercial bundle +- wolfssl-fips configured as provider +- gnutls 3.8.9+ (provided by wolfSSL fork) + +## Troubleshooting + +### Test Failures + +If ptests fail, check: + +1. **FIPS hash is correct**: wolfSSL FIPS auto-hash should have generated the correct hash +2. **All features enabled**: Verify wolfssl-fips has all required flags (see `inc/wolfssl-fips/wolfssl-enable-gnutls.inc`) +3. **Dependencies**: Ensure wolfssl-fips is properly built and installed + +### Build Errors + +If build fails, ensure: + +1. **FIPS bundle is accessible**: Check `WOLFSSL_SRC_DIR` in `conf/wolfssl-fips.conf` +2. **FIPS config is included**: `require conf/wolfssl-fips.conf` in `local.conf` +3. **Demo is enabled**: `WOLFSSL_DEMOS` includes both base and gnutls images + +## More Information + +- Main README: [../../../README.md](../../../README.md) +- gnutls-wolfssl: https://github.com/wolfSSL/gnutls-wolfssl +- wolfSSL FIPS: https://www.wolfssl.com/products/wolfssl-fips/ diff --git a/recipes-core/images/gnutls-image-minimal/gnutls-image-minimal.bb b/recipes-core/images/gnutls-image-minimal/gnutls-image-minimal.bb new file mode 100644 index 00000000..10c23bee --- /dev/null +++ b/recipes-core/images/gnutls-image-minimal/gnutls-image-minimal.bb @@ -0,0 +1,24 @@ +SUMMARY = "Minimal image with gnutls-wolfssl (gnutls with wolfSSL FIPS backend)" +DESCRIPTION = "This image includes gnutls configured to use wolfSSL/wolfCrypt as the \ + crypto backend. Requires wolfssl-fips provider and demonstrates FIPS-validated \ + cryptography through gnutls." + +require recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb + +IMAGE_INSTALL += " \ + nettle \ + gnutls \ + gnutls-dev \ + gnutls-bin \ + gnutls-fips \ + wolfssl-gnutls-wrapper \ + wolfssl-gnutls-wrapper-dev \ + pkgconfig \ +" + +# This image requires wolfssl-fips +# Set in local.conf: +# WOLFSSL_DEMOS = "wolfssl-image-minimal gnutls-image-minimal" +# Absolute path to your fips configuration in meta-wolfssl +# require conf/wolfssl-fips.conf + diff --git a/recipes-core/images/gnutls-image-minimal/gnutls_%.bbappend b/recipes-core/images/gnutls-image-minimal/gnutls_%.bbappend new file mode 100644 index 00000000..16519a8b --- /dev/null +++ b/recipes-core/images/gnutls-image-minimal/gnutls_%.bbappend @@ -0,0 +1,15 @@ +# Configure gnutls for gnutls-image-minimal +# +# This bbappend directly configures gnutls to use wolfSSL backend +# when wolfssl-fips is the preferred provider. + +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/gnutls/gnutls-enable-wolfssl.inc', + allowed_providers=['wolfssl-fips'] + ) +} + diff --git a/recipes-core/images/gnutls-image-minimal/nettle_%.bbappend b/recipes-core/images/gnutls-image-minimal/nettle_%.bbappend new file mode 100644 index 00000000..fd625ee7 --- /dev/null +++ b/recipes-core/images/gnutls-image-minimal/nettle_%.bbappend @@ -0,0 +1,6 @@ +# Configure nettle for gnutls. +# nettle 3.10 in order to correctly build +# the latest release of gnutls. +# + +require ${WOLFSSL_LAYERDIR}/inc/nettle/nettle.inc diff --git a/recipes-core/images/gnutls-image-minimal/wolfssl-fips.bbappend b/recipes-core/images/gnutls-image-minimal/wolfssl-fips.bbappend new file mode 100644 index 00000000..6a6e91d2 --- /dev/null +++ b/recipes-core/images/gnutls-image-minimal/wolfssl-fips.bbappend @@ -0,0 +1,7 @@ +# Configure wolfssl-fips for gnutls-image-minimal +# +# This bbappend directly configures wolfssl-fips with features needed for gnutls support. +# Since we're already in wolfssl-fips context, just include the configuration directly. + +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-enable-gnutls.inc + diff --git a/recipes-core/images/gnutls-nonfips-image-minimal/gnutls-nonfips-image-minimal.bb b/recipes-core/images/gnutls-nonfips-image-minimal/gnutls-nonfips-image-minimal.bb new file mode 100644 index 00000000..06493e8e --- /dev/null +++ b/recipes-core/images/gnutls-nonfips-image-minimal/gnutls-nonfips-image-minimal.bb @@ -0,0 +1,15 @@ +SUMMARY = "Minimal image with gnutls-wolfssl (non-FIPS)" +DESCRIPTION = "This image includes gnutls configured to use standard wolfSSL \ +(non-FIPS) as the crypto backend." + +require recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb + +IMAGE_INSTALL += " \ + nettle \ + gnutls \ + gnutls-dev \ + gnutls-bin \ + wolfssl-gnutls-wrapper \ + wolfssl-gnutls-wrapper-dev \ + pkgconfig \ +" diff --git a/recipes-core/images/gnutls-nonfips-image-minimal/gnutls_%.bbappend b/recipes-core/images/gnutls-nonfips-image-minimal/gnutls_%.bbappend new file mode 100644 index 00000000..5d517cda --- /dev/null +++ b/recipes-core/images/gnutls-nonfips-image-minimal/gnutls_%.bbappend @@ -0,0 +1,10 @@ +# Configure gnutls for gnutls-nonfips-image-minimal +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/gnutls/gnutls-enable-wolfssl.inc', + allowed_providers=['wolfssl'] # Standard wolfSSL only + ) +} diff --git a/recipes-core/images/gnutls-nonfips-image-minimal/nettle_%.bbappend b/recipes-core/images/gnutls-nonfips-image-minimal/nettle_%.bbappend new file mode 100644 index 00000000..5ce646b3 --- /dev/null +++ b/recipes-core/images/gnutls-nonfips-image-minimal/nettle_%.bbappend @@ -0,0 +1,6 @@ +# Configure nettle for gnutls (non-FIPS). +# nettle 3.10 in order to correctly build +# the latest release of gnutls. +# + +require ${WOLFSSL_LAYERDIR}/inc/nettle/nettle.inc diff --git a/recipes-core/images/gnutls-nonfips-image-minimal/wolfssl_%.bbappend b/recipes-core/images/gnutls-nonfips-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..7ef566d6 --- /dev/null +++ b/recipes-core/images/gnutls-nonfips-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,2 @@ +# Configure wolfssl for gnutls-nonfips-image-minimal +require ${WOLFSSL_LAYERDIR}/inc/wolfssl/wolfssl-enable-gnutls.inc diff --git a/recipes-core/images/libgcrypt-image-minimal/README.md b/recipes-core/images/libgcrypt-image-minimal/README.md new file mode 100644 index 00000000..fcf3a85e --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/README.md @@ -0,0 +1,144 @@ +# libgcrypt-image-minimal + +Minimal demo image showcasing libgcrypt with wolfSSL FIPS backend. + +## Overview + +This image demonstrates libgcrypt configured to use wolfSSL's FIPS-validated wolfCrypt as its cryptographic backend. This allows any application using libgcrypt (GnuPG, systemd, etc.) to benefit from FIPS 140-3 validated cryptography. + +## What's Included + +- Everything from `wolfssl-image-minimal` +- wolfSSL FIPS (auto-configured for libgcrypt support) +- libgcrypt 1.11.0 with wolfSSL backend +- libgcrypt-ptest (test suite) +- ptest-runner (test execution tool) + +## Configuration + +### In `build/conf/local.conf`: + +```bitbake +# Enable demo images +WOLFSSL_DEMOS = "wolfssl-image-minimal libgcrypt-image-minimal" + +# Configure FIPS bundle (use absolute path) +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +### Build: + +```bash +bitbake libgcrypt-image-minimal +``` + +### Run in QEMU: + +```bash +runqemu libgcrypt-image-minimal nographic +``` + +## Testing + +Inside QEMU, run the libgcrypt test suite: + +```bash +# Run all ptests +ptest-runner + +# Run only libgcrypt tests +ptest-runner libgcrypt +``` + +### Expected Output + +The libgcrypt test suite should pass with the wolfSSL backend: + +``` +START: ptest-runner +BEGIN: /usr/lib/libgcrypt/ptest +PASS: basic +PASS: mpitests +PASS: t-mpi-bit +PASS: curves +PASS: fips186-dsa +... +END: /usr/lib/libgcrypt/ptest +STOP: ptest-runner +``` + +## How It Works + +### wolfssl-fips Configuration + +The `wolfssl-fips.bbappend` in this directory automatically configures wolfssl-fips with features needed by libgcrypt: + +```bitbake +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc +``` + +This adds: +- `--enable-fips=v5` +- `--enable-keygen` +- Required compile flags (`HAVE_AES_ECB`, `WC_RSA_DIRECT`, etc.) + +### libgcrypt Configuration + +The `libgcrypt_%.bbappend` conditionally switches libgcrypt to the wolfSSL backend when wolfssl-fips is the provider: + +```bitbake +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/libgcrypt/libgcrypt-enable-wolfssl.inc', + allowed_providers=['wolfssl-fips'] + ) +} +``` + +This: +- Switches to `github.com/wolfSSL/libgcrypt-wolfssl` source +- Configures with `--enable-wolfssl-fips` +- Adds wolfSSL dependencies + +## Applications + +With this image, any application using libgcrypt will automatically use FIPS-validated cryptography: + +- **GnuPG**: Encryption, signing, key management +- **systemd**: System services encryption +- **NetworkManager**: WPA/WPA2 authentication +- **cryptsetup**: Disk encryption (LUKS) + +## Requirements + +- Valid wolfSSL FIPS commercial bundle +- wolfssl-fips configured as provider +- libgcrypt 1.11.0+ (provided by wolfSSL fork) + +## Troubleshooting + +### Test Failures + +If ptests fail, check: + +1. **FIPS hash is correct**: wolfSSL FIPS auto-hash should have generated the correct hash +2. **All features enabled**: Verify wolfssl-fips has all required flags (see `inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc`) +3. **Dependencies**: Ensure wolfssl-fips is properly built and installed + +### Build Errors + +If build fails, ensure: + +1. **FIPS bundle is accessible**: Check `WOLFSSL_SRC_DIR` in `conf/wolfssl-fips.conf` +2. **FIPS config is included**: `require conf/wolfssl-fips.conf` in `local.conf` +3. **Demo is enabled**: `WOLFSSL_DEMOS` includes both base and libgcrypt images + +## More Information + +- OSP Integration: [../../../recipes-support/libgcrypt/README.md](../../../recipes-support/libgcrypt/README.md) +- Main README: [../../../README.md](../../../README.md) +- libgcrypt-wolfssl: https://github.com/wolfSSL/libgcrypt-wolfssl +- wolfSSL FIPS: https://www.wolfssl.com/products/wolfssl-fips/ diff --git a/recipes-core/images/libgcrypt-image-minimal/gnupg_%.bbappend b/recipes-core/images/libgcrypt-image-minimal/gnupg_%.bbappend new file mode 100644 index 00000000..815e0b81 --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/gnupg_%.bbappend @@ -0,0 +1,15 @@ +# Configure gnupg for libgcrypt-image-minimal +# +# This bbappend is needed when using gnupg with libgcrypt to use wolfSSL backend +# when wolfssl-fips is the preferred provider. + +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/gnupg/gnupg-enable-libgcrypt-wolfssl.inc', + allowed_providers=['wolfssl-fips'] + ) +} + diff --git a/recipes-core/images/libgcrypt-image-minimal/libgcrypt-image-minimal.bb b/recipes-core/images/libgcrypt-image-minimal/libgcrypt-image-minimal.bb new file mode 100644 index 00000000..fb9352ec --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/libgcrypt-image-minimal.bb @@ -0,0 +1,18 @@ +SUMMARY = "Minimal image with libgcrypt-wolfssl (libgcrypt with wolfSSL FIPS backend)" +DESCRIPTION = "This image includes libgcrypt configured to use wolfSSL/wolfCrypt as the \ + crypto backend. Requires wolfssl-fips provider and demonstrates FIPS-validated \ + cryptography through libgcrypt." + +require recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb + +IMAGE_INSTALL += " \ + libgcrypt \ + libgcrypt-ptest \ + ptest-runner \ +" + +# This image requires wolfssl-fips +# Set in local.conf: +# WOLFSSL_DEMOS = "wolfssl-image-minimal libgcrypt-image-minimal" +# require conf/wolfssl-fips.conf + diff --git a/recipes-core/images/libgcrypt-image-minimal/libgcrypt_%.bbappend b/recipes-core/images/libgcrypt-image-minimal/libgcrypt_%.bbappend new file mode 100644 index 00000000..e2045902 --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/libgcrypt_%.bbappend @@ -0,0 +1,15 @@ +# Configure libgcrypt for libgcrypt-image-minimal +# +# This bbappend directly configures libgcrypt to use wolfSSL backend +# when wolfssl-fips is the preferred provider. + +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/libgcrypt/libgcrypt-enable-wolfssl.inc', + allowed_providers=['wolfssl-fips'] + ) +} + diff --git a/recipes-core/images/libgcrypt-image-minimal/libssh_%.bbappend b/recipes-core/images/libgcrypt-image-minimal/libssh_%.bbappend new file mode 100644 index 00000000..bde255f9 --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/libssh_%.bbappend @@ -0,0 +1 @@ +require ${WOLFSSL_LAYERDIR}/inc/libssh/libssh-enable-libgcrypt-wolfssl.inc diff --git a/recipes-core/images/libgcrypt-image-minimal/rsyslog_%.bbappend b/recipes-core/images/libgcrypt-image-minimal/rsyslog_%.bbappend new file mode 100644 index 00000000..4062596b --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/rsyslog_%.bbappend @@ -0,0 +1 @@ +require ${WOLFSSL_LAYERDIR}/inc/rsyslog/rsyslog-enable-fips-crypto.inc diff --git a/recipes-core/images/libgcrypt-image-minimal/wolfssl-fips.bbappend b/recipes-core/images/libgcrypt-image-minimal/wolfssl-fips.bbappend new file mode 100644 index 00000000..31edc800 --- /dev/null +++ b/recipes-core/images/libgcrypt-image-minimal/wolfssl-fips.bbappend @@ -0,0 +1,7 @@ +# Configure wolfssl-fips for libgcrypt-image-minimal +# +# This bbappend directly configures wolfssl-fips with features needed for libgcrypt support. +# Since we're already in wolfssl-fips context, just include the configuration directly. + +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc + diff --git a/recipes-core/images/wolfclu-combined-image-minimal/wolf-py-tests_%.bbappend b/recipes-core/images/wolfclu-combined-image-minimal/wolf-py-tests_%.bbappend new file mode 100644 index 00000000..dd091d66 --- /dev/null +++ b/recipes-core/images/wolfclu-combined-image-minimal/wolf-py-tests_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolf-py-tests in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfclu-combined-image-minimal/wolfclu-combined-image-minimal.bb b/recipes-core/images/wolfclu-combined-image-minimal/wolfclu-combined-image-minimal.bb new file mode 100644 index 00000000..a2499f93 --- /dev/null +++ b/recipes-core/images/wolfclu-combined-image-minimal/wolfclu-combined-image-minimal.bb @@ -0,0 +1,51 @@ +SUMMARY = "Minimal image with wolfSSL, wolfCLU, and Python bindings" +DESCRIPTION = "A combined demonstration image including wolfclu, wolfssl-py, and wolfcrypt-py with networking support" + +require ${WOLFSSL_LAYERDIR}/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfclu wolfssl-py wolfcrypt-py wolf-py-tests python3 python3-cffi python3-pytest ca-certificates') + wolfssl_varAppendNonOverride(d, 'ROOTFS_POSTPROCESS_COMMAND', ' setup_dns_config; ') +} + +IMAGE_FEATURES += "package-management" + +# Configure DNS at boot time +setup_dns_config() { + # Create init script to configure DNS + mkdir -p ${IMAGE_ROOTFS}/etc/init.d + cat > ${IMAGE_ROOTFS}/etc/init.d/dns-config << 'EOF' +#!/bin/sh +### BEGIN INIT INFO +# Provides: dns-config +# Required-Start: $local_fs +# Required-Stop: +# Default-Start: S +# Default-Stop: +# Short-Description: Configure DNS resolvers +### END INIT INFO + +case "$1" in + start) + echo "Configuring DNS..." + cat > /etc/resolv.conf << 'RESOLV' +nameserver 8.8.8.8 +nameserver 1.1.1.1 +nameserver 8.8.4.4 +RESOLV + chmod 644 /etc/resolv.conf + chattr +i /etc/resolv.conf 2>/dev/null || true + ;; + *) + echo "Usage: $0 start" + exit 1 + ;; +esac + +exit 0 +EOF + chmod 755 ${IMAGE_ROOTFS}/etc/init.d/dns-config + ln -sf ../init.d/dns-config ${IMAGE_ROOTFS}/etc/rcS.d/S99dns-config +} diff --git a/recipes-core/images/wolfclu-combined-image-minimal/wolfclu_%.bbappend b/recipes-core/images/wolfclu-combined-image-minimal/wolfclu_%.bbappend new file mode 100644 index 00000000..53f3f50f --- /dev/null +++ b/recipes-core/images/wolfclu-combined-image-minimal/wolfclu_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolfclu in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfclu-combined-image-minimal/wolfcrypt-py_%.bbappend b/recipes-core/images/wolfclu-combined-image-minimal/wolfcrypt-py_%.bbappend new file mode 100644 index 00000000..410b0e98 --- /dev/null +++ b/recipes-core/images/wolfclu-combined-image-minimal/wolfcrypt-py_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolfcrypt-py in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfclu-combined-image-minimal/wolfssl-py_%.bbappend b/recipes-core/images/wolfclu-combined-image-minimal/wolfssl-py_%.bbappend new file mode 100644 index 00000000..1dd3c24f --- /dev/null +++ b/recipes-core/images/wolfclu-combined-image-minimal/wolfssl-py_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolfssl-py in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfclu-combined-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolfclu-combined-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..b8c38017 --- /dev/null +++ b/recipes-core/images/wolfclu-combined-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,12 @@ +# Configure wolfSSL for wolfclu and Python bindings combined image + +# Enable wolfclu +require ${WOLFSSL_LAYERDIR}/inc/wolfclu/wolfssl-enable-wolfclu.inc + +# Enable Python bindings +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-py/wolfssl-enable-wolfssl-py.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py.inc +require ${WOLFSSL_LAYERDIR}/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests.inc + +# Note: crypto tests (wolfcrypttest, wolfcryptbenchmark) are already included from wolfssl-image-minimal + diff --git a/recipes-core/images/wolfclu-image-minimal/wolfclu-image-minimal.bb b/recipes-core/images/wolfclu-image-minimal/wolfclu-image-minimal.bb new file mode 100644 index 00000000..18d6afc2 --- /dev/null +++ b/recipes-core/images/wolfclu-image-minimal/wolfclu-image-minimal.bb @@ -0,0 +1,10 @@ +SUMMARY = "Minimal image with wolfSSL, test utilities, and wolfCLU" +DESCRIPTION = "A minimal Linux image that includes wolfSSL library, test/benchmark utilities, and wolfCLU command-line utility" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfclu') +} + +require ${WOLFSSL_LAYERDIR}/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb diff --git a/recipes-core/images/wolfclu-image-minimal/wolfclu_%.bbappend b/recipes-core/images/wolfclu-image-minimal/wolfclu_%.bbappend new file mode 100644 index 00000000..9c45ee3a --- /dev/null +++ b/recipes-core/images/wolfclu-image-minimal/wolfclu_%.bbappend @@ -0,0 +1,3 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfclu-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolfclu-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..e332c3f3 --- /dev/null +++ b/recipes-core/images/wolfclu-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,5 @@ +# Manual configuration for wolfclu-image-minimal +# Enable wolfCLU support in wolfSSL + +require ${WOLFSSL_LAYERDIR}/inc/wolfclu/wolfssl-enable-wolfclu.inc + diff --git a/recipes-core/images/wolfprovider-images/README.md b/recipes-core/images/wolfprovider-images/README.md new file mode 100644 index 00000000..276ce74f --- /dev/null +++ b/recipes-core/images/wolfprovider-images/README.md @@ -0,0 +1,119 @@ +# wolfProvider Minimal Images + +Minimal demo images showcasing wolfProvider integration with OpenSSL 3.x in various configurations. + +## Overview + +These images demonstrate different wolfProvider configurations for OpenSSL 3.x integration. Each image is self-contained and requires no `local.conf` configuration (except FIPS images which require `wolfssl-fips.conf`). + +## Available Images + +### 1. wolfprovider-image-minimal +**Standalone mode, non-FIPS** + +- wolfProvider configured as an additional provider alongside OpenSSL's default +- Applications can explicitly load wolfProvider or use it alongside the default provider +- Includes test utilities and unit tests + +**Configuration:** +```bitbake +# Enable demo images +WOLFSSL_DEMOS = "wolfprovider-image-minimal" +``` + +if enabling fips add: +```bitbake +# In build/conf/local.conf: +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +**Build:** +```bash +bitbake wolfprovider-image-minimal +``` + +### 2. wolfprovider-replace-default-image-minimal +**Replace-default mode** + +- wolfProvider replaces OpenSSL's default provider +- All OpenSSL operations automatically use wolfProvider +- No code changes needed - transparent drop-in replacement + +**Configuration:** +```bitbake +# Enable demo images +WOLFSSL_DEMOS = "wolfprovider-replace-default-image-minimal" +``` + +if enabling fips add: +```bitbake +# In build/conf/local.conf: +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +**Build:** +```bash +bitbake wolfprovider-replace-default-image-minimal +``` + +## What's Included + +All images include: +- Everything from `wolfssl-image-minimal` +- wolfSSL (or wolfSSL FIPS) with wolfProvider support +- OpenSSL 3.x with wolfProvider backend +- wolfProvider environment setup tools (`wolfproviderenv`, `wolfprovidercmd`) +- Unit tests (standalone mode images only) + +## Testing + +Inside QEMU, test wolfProvider: + +```bash +# Run wolfProvider environment setup (standalone mode only) +wolfprovidertest + +# Run wolfProvider command-line tests +wolfprovidercmd + +# Run wolfProvider environment setup +wolfproviderenv + +# Verify provider configuration (replace-default images) +openssl list -providers +``` + +## How It Works + +Each image directory contains `bbappend` files that automatically configure packages: + +- **wolfssl_%.bbappend** or **wolfssl-fips_%.bbappend**: Configures wolfSSL with wolfProvider support +- **openssl_%.bbappend**: Configures OpenSSL to support wolfProvider (standalone or replace-default) +- **wolfprovider_%.bbappend**: Enables unit tests (standalone mode only) + +All configurations use conditional functions (`wolfssl_osp_include_if_provider`) that automatically detect the provider and include the appropriate configuration files. + +## Mode Comparison + +### Standalone Mode +- wolfProvider is an additional provider +- Applications must explicitly load wolfProvider +- OpenSSL's default provider remains available +- Useful for testing and selective adoption + +### Replace-Default Mode +- wolfProvider replaces OpenSSL's default provider +- All OpenSSL operations automatically use wolfProvider +- No application code changes needed +- Useful for system-wide deployment + +## Requirements + +- **FIPS images**: Valid wolfSSL FIPS commercial bundle and `wolfssl-fips.conf` configuration +- **Non-FIPS images**: No additional requirements + +## More Information + +- Main README: [../../../README.md](../../../README.md) +- wolfProvider: [../../../recipes-wolfssl/wolfprovider/README.md](../../../recipes-wolfssl/wolfprovider/README.md) +- wolfSSL FIPS: [../../../recipes-wolfssl/wolfssl/README-fips.md](../../../recipes-wolfssl/wolfssl/README-fips.md) diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/curl_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/curl_%.bbappend new file mode 100644 index 00000000..4b029867 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/curl_%.bbappend @@ -0,0 +1,14 @@ +# Configure curl with wolfprovider FIPS mode. +# +# This bbappend is needed when using curl with wolfprovider FIPS mode. + +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/curl/curl-enable-wolfprovider-fips.inc', + allowed_providers=['wolfssl-fips'] + ) +} + diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/librelp_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/librelp_%.bbappend new file mode 100644 index 00000000..afc7301a --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/librelp_%.bbappend @@ -0,0 +1 @@ +require ${WOLFSSL_LAYERDIR}/inc/librelp/librelp-ptest.inc diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/openssh_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/openssh_%.bbappend new file mode 100644 index 00000000..6f1cbb9c --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/openssh_%.bbappend @@ -0,0 +1,4 @@ +# OpenSSH ptest modifications for wolfProvider FIPS testing + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc + diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/openssl_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/openssl_%.bbappend new file mode 100644 index 00000000..e0a845b2 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/openssl_%.bbappend @@ -0,0 +1,7 @@ +# Configure OpenSSL (standalone mode) for wolfprovider-images +# +# This bbappend directly configures OpenSSL to use wolfProvider +# when wolfssl is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc + diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfprovider-image-minimal.bb b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfprovider-image-minimal.bb new file mode 100644 index 00000000..f3f2f6cc --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfprovider-image-minimal.bb @@ -0,0 +1,10 @@ +SUMMARY = "Minimal image with wolfSSL, test utilities, and wolfProvider" +DESCRIPTION = "A minimal Linux image that includes wolfSSL library, test/benchmark utilities, and wolfProvider for OpenSSL 3.x integration" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfssl wolfprovider openssl openssl-bin wolfprovidertest wolfprovidercmd wolfproviderenv bash') +} + +require recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfprovider_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfprovider_%.bbappend new file mode 100644 index 00000000..ae2cd52f --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfprovider_%.bbappend @@ -0,0 +1,12 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + +# Enable unit tests for wolfprovider +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-unittest.inc + +inherit wolfssl-compatibility + +# Enable quick test mode for standalone mode +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'CPPFLAGS', ' -DWOLFPROV_QUICKTEST') +} diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfssl-fips.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfssl-fips.bbappend new file mode 100644 index 00000000..84b72d8e --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfssl-fips.bbappend @@ -0,0 +1,15 @@ +# Configure wolfSSL (to enable FIPS standalone mode) for wolfprovider-images +# +# This bbappend directly configures wolfSSL to use FIPS wolfProvider +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc + +# Fix for commercial 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-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..bc1fbc67 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,15 @@ +# Configure wolfSSL (to enable FIPS standalone mode) for wolfprovider-images +# +# This bbappend directly configures wolfSSL to use FIPS wolfProvider +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider.inc + +# Fix for commercial 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-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/curl_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/curl_%.bbappend new file mode 100644 index 00000000..4b029867 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/curl_%.bbappend @@ -0,0 +1,14 @@ +# Configure curl with wolfprovider FIPS mode. +# +# This bbappend is needed when using curl with wolfprovider FIPS mode. + +inherit wolfssl-osp-support + +python __anonymous() { + wolfssl_osp_include_if_provider( + d, + inc_file='inc/curl/curl-enable-wolfprovider-fips.inc', + allowed_providers=['wolfssl-fips'] + ) +} + diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/librelp_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/librelp_%.bbappend new file mode 100644 index 00000000..afc7301a --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/librelp_%.bbappend @@ -0,0 +1 @@ +require ${WOLFSSL_LAYERDIR}/inc/librelp/librelp-ptest.inc diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/openssh_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/openssh_%.bbappend new file mode 100644 index 00000000..66577a18 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/openssh_%.bbappend @@ -0,0 +1,3 @@ +# OpenSSH ptest modifications for wolfProvider FIPS testing + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/openssl_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/openssl_%.bbappend new file mode 100644 index 00000000..eeb28596 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/openssl_%.bbappend @@ -0,0 +1,7 @@ +# Configure OpenSSL (replace-default mode) for wolfprovider-replace-default-image-minimal +# +# This bbappend directly configures OpenSSL to use wolfProvider in replace-default mode +# when wolfssl is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc + diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfprovider-replace-default-image-minimal.bb b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfprovider-replace-default-image-minimal.bb new file mode 100644 index 00000000..3a80ffc7 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfprovider-replace-default-image-minimal.bb @@ -0,0 +1,10 @@ +SUMMARY = "Minimal image with wolfSSL, test utilities, and wolfProvider in replace-default mode" +DESCRIPTION = "A minimal Linux image that includes wolfSSL library, and wolfProvider configured to replace OpenSSL's default provider" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfssl wolfprovider openssl openssl-bin openssl-ptest wolfprovidertest wolfprovidercmd wolfproviderenv bash librelp-ptest') +} + +require recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfprovider_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfprovider_%.bbappend new file mode 100644 index 00000000..99ab1d25 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfprovider_%.bbappend @@ -0,0 +1,8 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + +# Enable unit tests for wolfprovider replace default mode +# The inc file handles all logic including symbol checking and conditional enabling +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-replace-default-unittest.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-unittest.inc + diff --git a/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfssl-fips.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfssl-fips.bbappend new file mode 100644 index 00000000..84b72d8e --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfssl-fips.bbappend @@ -0,0 +1,15 @@ +# Configure wolfSSL (to enable FIPS standalone mode) for wolfprovider-images +# +# This bbappend directly configures wolfSSL to use FIPS wolfProvider +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc + +# Fix for commercial 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-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..bc1fbc67 --- /dev/null +++ b/recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,15 @@ +# Configure wolfSSL (to enable FIPS standalone mode) for wolfprovider-images +# +# This bbappend directly configures wolfSSL to use FIPS wolfProvider +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider.inc + +# Fix for commercial 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-core/images/wolfssl-combined-image-minimal/openssh_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/openssh_%.bbappend new file mode 100644 index 00000000..6f1cbb9c --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/openssh_%.bbappend @@ -0,0 +1,4 @@ +# OpenSSH ptest modifications for wolfProvider FIPS testing + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc + diff --git a/recipes-core/images/wolfssl-combined-image-minimal/openssl_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/openssl_%.bbappend new file mode 100644 index 00000000..b1b12138 --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/openssl_%.bbappend @@ -0,0 +1,3 @@ +# Configure OpenSSL for wolfProvider in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc + diff --git a/recipes-core/images/wolfssl-combined-image-minimal/wolfmqtt_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/wolfmqtt_%.bbappend new file mode 100644 index 00000000..d43859dc --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/wolfmqtt_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolfmqtt in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfssl-combined-image-minimal/wolfprovider_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/wolfprovider_%.bbappend new file mode 100644 index 00000000..b493414b --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/wolfprovider_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolfprovider in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfssl-combined-image-minimal/wolfssh_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/wolfssh_%.bbappend new file mode 100644 index 00000000..f8cd864e --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/wolfssh_%.bbappend @@ -0,0 +1,3 @@ +# Disable feature check for wolfssh in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfssl-combined-image-minimal/wolfssl-combined-image-minimal.bb b/recipes-core/images/wolfssl-combined-image-minimal/wolfssl-combined-image-minimal.bb new file mode 100644 index 00000000..45171ea7 --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/wolfssl-combined-image-minimal.bb @@ -0,0 +1,21 @@ +SUMMARY = "Minimal image with wolfSSL and multiple sub-packages (wolfssh, wolfmqtt, wolfprovider, wolftpm)" +DESCRIPTION = "A combined demonstration image including wolfssh, wolfmqtt, wolfprovider, and wolftpm with TPM support" + +require ${WOLFSSL_LAYERDIR}/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfssh wolfmqtt wolfprovider wolfprovidertest openssl openssl-bin wolftpm-wrap-test tpm2-tools tpm2-tss libtss2 libtss2-mu libtss2-tcti-device libtss2-tcti-mssim bash') + wolfssl_varAppendNonOverride(d, 'DISTRO_FEATURES', ' security tpm tpm2') + wolfssl_varAppendNonOverride(d, 'MACHINE_FEATURES', ' tpm tpm2') + wolfssl_varAppendNonOverride(d, 'KERNEL_FEATURES', ' features/tpm/tpm.scc') +} + +IMAGE_FEATURES += "package-management" + +# Note: TPM features are set dynamically by this recipe and the .inc file +# If building standalone without the .inc file, ensure these are set in local.conf: +# DISTRO_FEATURES += "security tpm tpm2" +# MACHINE_FEATURES += "tpm tpm2" +# KERNEL_FEATURES += "features/tpm/tpm.scc" diff --git a/recipes-core/images/wolfssl-combined-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..7d45efbc --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,13 @@ +# Configure wolfSSL for all sub-packages in combined image + +# Enable wolfssh +require ${WOLFSSL_LAYERDIR}/inc/wolfssh/wolfssl-enable-wolfssh.inc + +# Enable wolfprovider +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider.inc + +# Enable wolftpm +require ${WOLFSSL_LAYERDIR}/inc/wolftpm/wolfssl-enable-wolftpm.inc +require ${WOLFSSL_LAYERDIR}/inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test.inc + +# Note: crypto tests (wolfcrypttest, wolfcryptbenchmark) are already included from wolfssl-image-minimal diff --git a/recipes-core/images/wolfssl-combined-image-minimal/wolftpm_%.bbappend b/recipes-core/images/wolfssl-combined-image-minimal/wolftpm_%.bbappend new file mode 100644 index 00000000..e00bdcad --- /dev/null +++ b/recipes-core/images/wolfssl-combined-image-minimal/wolftpm_%.bbappend @@ -0,0 +1,5 @@ +# Disable feature check and enable devtpm for wolftpm in combined image +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + +EXTRA_OECONF += "--enable-devtpm" + diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/README.md b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/README.md new file mode 100644 index 00000000..0c6b40e0 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/README.md @@ -0,0 +1,251 @@ +# FIPS Image Minimal - Comprehensive FIPS Demonstration Image + +This image demonstrates a complete FIPS-validated Linux system using wolfSSL FIPS 140-3 certified cryptography across multiple layers: + +- **User-space libraries**: libgcrypt and gnutls backed by wolfSSL FIPS +- **OpenSSL replacement**: wolfProvider in replace-default mode +- **Kernel module**: wolfSSL FIPS kernel module loaded via initramfs (optional) + +## Features + +- wolfSSL FIPS 140-3 validated cryptography +- libgcrypt with wolfSSL backend +- GnuTLS with wolfSSL backend +- wolfProvider (OpenSSL 3.x provider) in replace-default mode +- OpenSSH, curl, and other applications using FIPS crypto +- Optional: wolfSSL FIPS kernel module loaded before rootfs mount +- Comprehensive test suite with ptest support + +## Requirements + +### Mandatory Configuration + +Add to your `local.conf`: + +```bitbake +# Enable FIPS image +WOLFSSL_DEMOS = "fips-image-minimal" + +# Include FIPS configuration +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +### Optional: Early Kernel Module Loading + +To load the wolfSSL FIPS kernel module in initramfs (before rootfs mounts), add to `local.conf`: + +```bitbake +# FIPS initramfs configuration +INITRAMFS_IMAGE = "fips-initramfs" +INITRAMFS_IMAGE_BUNDLE = "1" +``` + +**Why in local.conf?** +- The kernel must see `INITRAMFS_IMAGE` at its build time +- Setting it only in the image recipe doesn't work because the kernel builds before the image +- This ensures the kernel bundles the initramfs with the wolfSSL FIPS kernel module + +**When is this needed?** +- Systems requiring crypto operations before rootfs mount +- Early boot security requirements +- Kernel-space crypto dependencies on wolfSSL +- FIPS compliance requirements for kernel crypto + +## FIPS Configuration + +Your `wolfssl-fips.conf` should include: + +```bitbake +# wolfSSL FIPS providers (user-space) +PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips" +PREFERRED_PROVIDER_wolfssl = "wolfssl-fips" + +# wolfSSL FIPS kernel module (optional, for initramfs) +PREFERRED_PROVIDER_virtual/wolfssl-linuxkm = "wolfssl-linuxkm-fips" +PREFERRED_PROVIDER_wolfssl-linuxkm = "wolfssl-linuxkm-fips" + +# FIPS bundle details +WOLFSSL_VERSION = "x.x.x" +WOLFSSL_SRC = "wolfssl-x.x.x-commercial-fips-linux" +# ... (see conf/wolfssl-fips.conf.sample for full configuration) +``` + +## Building + +### Standard Build (No Initramfs) + +```bash +cd /path/to/poky +source oe-init-build-env +bitbake fips-image-minimal +``` + +### With Initramfs (Kernel Module in Early Boot) + +```bash +cd /path/to/poky +source oe-init-build-env + +# First build: Build initramfs and kernel with it bundled +bitbake fips-initramfs +bitbake virtual/kernel -c cleansstate +bitbake fips-image-minimal + +# Subsequent builds: Just rebuild the image +bitbake fips-image-minimal +``` + +**Note**: Only rebuild the kernel (`cleansstate`) when: +- First time enabling initramfs +- Changing `INITRAMFS_IMAGE` setting +- Updating the kernel module in `fips-initramfs` + +## Running in QEMU + +Use the provided script: + +```bash +source oe-init-build-env +./run-fips-qemu.sh [MACHINE] +``` + +Supported machines: +- `qemux86-64` (default) +- `qemuarm64` +- `qemuarm` + +## Verification + +### Check User-Space FIPS + +```bash +# On target system +openssl version +wolfssl-fips-check +libgcrypt-config --version +gnutls-cli --version +``` + +### Check Kernel Module (if using initramfs) + +```bash +# On target system +lsmod | grep wolfssl +dmesg | grep wolfssl +``` + +The kernel module should show as loaded early in `dmesg` output, before the rootfs mount message. + +### Run Test Suites + +```bash +# libgcrypt tests +ptest-runner libgcrypt + +# GnuTLS tests +ptest-runner gnutls + +# wolfProvider tests +wolfprovidertest +``` + +## Package Contents + +The image includes: + +**Core FIPS Libraries:** +- `wolfssl-fips` - FIPS 140-3 validated crypto library +- `libgcrypt` - With wolfSSL backend +- `gnutls` - With wolfSSL backend +- `wolfprovider` - OpenSSL 3.x provider (replace-default mode) + +**Applications:** +- `openssh` - SSH client/server +- `curl` - HTTP client with FIPS crypto +- `openssl-bin` - OpenSSL command-line tools + +**Testing Tools:** +- `ptest-runner` - Run package tests +- `wolfprovidercmd` - wolfProvider command-line tests +- `wolfproviderenv` - Environment setup/verification +- Various ptest packages for validation + +**Optional (with initramfs):** +- `wolfssl-linuxkm-fips` - Kernel module loaded via initramfs + +## Architecture + +### Without Initramfs +``` +┌─────────────────────────────────────┐ +│ Applications (SSH, curl, etc.) │ +├─────────────────────────────────────┤ +│ OpenSSL API (wolfProvider) │ +│ GnuTLS API │ +│ libgcrypt API │ +├─────────────────────────────────────┤ +│ wolfSSL FIPS (User-space) │ +└─────────────────────────────────────┘ +``` + +### With Initramfs +``` +Boot Sequence: + 1. Kernel starts + 2. Initramfs mounts + 3. wolfssl-linuxkm-fips loads ← FIPS module in kernel + 4. Root filesystem mounts + 5. Applications start with user-space wolfSSL FIPS + +┌─────────────────────────────────────┐ +│ Applications (SSH, curl, etc.) │ +├─────────────────────────────────────┤ +│ OpenSSL API (wolfProvider) │ +│ GnuTLS API │ +│ libgcrypt API │ +├─────────────────────────────────────┤ +│ wolfSSL FIPS (User-space) │ +└─────────────────────────────────────┘ +┌─────────────────────────────────────┐ +│ wolfSSL FIPS (Kernel-space) │ +│ libwolfssl.ko │ +└─────────────────────────────────────┘ +``` + +## Troubleshooting + +### Initramfs Not Loading + +**Symptom**: Kernel boots directly to rootfs, no initramfs messages in dmesg + +**Solution**: +1. Check `INITRAMFS_IMAGE` is set in `local.conf` (not just image recipe) +2. Rebuild kernel: `bitbake virtual/kernel -c cleansstate && bitbake fips-image-minimal` +3. Verify initramfs exists: `ls tmp/deploy/images/*/fips-initramfs*.cpio*` + +### Kernel Module Not Loading + +**Symptom**: `lsmod | grep wolfssl` shows nothing + +**Solution**: +1. Check initramfs was built: `bitbake fips-initramfs -e | grep PACKAGE_INSTALL` +2. Verify module is in initramfs: Extract and check the .cpio.gz file +3. Check kernel messages: `dmesg | grep -i wolf` + +### FIPS Validation Errors + +**Symptom**: FIPS self-tests fail or crypto operations fail + +**Solution**: +1. Verify FIPS hash is correct in `wolfssl-fips.conf` +2. Check license file matches bundle +3. Ensure `WOLFSSL_SRC_DIRECTORY` or bundle extraction is correct +4. Rebuild everything: `bitbake wolfssl-fips -c cleansstate && bitbake fips-image-minimal` + +## See Also + +- `recipes-core/images/wolfssl-linux-fips-images/fips-initramfs.bb` - Initramfs recipe +- `conf/wolfssl-fips.conf.sample` - FIPS configuration template +- `recipes-wolfssl/wolfssl/README-fips.md` - wolfSSL FIPS recipe documentation +- `recipes-wolfssl/wolfssl/README-linuxkm.md` - Kernel module documentation +- `classes/wolfssl-initramfs.bbclass` - Initramfs integration helpers diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/curl_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/curl_%.bbappend new file mode 100644 index 00000000..f78bac1a --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/curl_%.bbappend @@ -0,0 +1,3 @@ +# Conditionally configure curl with wolfProvider support + +require ${WOLFSSL_LAYERDIR}/inc/curl/curl-enable-wolfprovider-fips.inc 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 new file mode 100644 index 00000000..e58cb504 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-image-minimal.bb @@ -0,0 +1,33 @@ +SUMMARY = "Minimal FIPS image with libgcrypt, gnutls, and wolfProvider (replace-default mode)" +DESCRIPTION = "A minimal Linux image that includes libgcrypt, gnutls, and wolfProvider all configured to use wolfSSL FIPS as the crypto backend. wolfProvider is configured in replace-default mode. This image requires wolfSSL FIPS and does not require wolfssl-image-minimal." + +inherit wolfssl-compatibility + +# Validate that wolfssl-fips is the provider +# Just to be sure that the user has set the correct provider +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) + + 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) + + 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') +} + +require recipes-core/images/core-image-minimal.bb + +# This image requires wolfssl-fips +# Set in local.conf: +# WOLFSSL_DEMOS = "fips-image-minimal" +# require conf/wolfssl-fips.conf +# +# For early kernel module loading (initramfs), also add to local.conf: +# INITRAMFS_IMAGE = "fips-initramfs" +# INITRAMFS_IMAGE_BUNDLE = "1" +# +# Note: INITRAMFS_IMAGE must be set in local.conf (not here) because +# the kernel needs to see it at build time, not just the image. diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-initramfs.bb b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-initramfs.bb new file mode 100644 index 00000000..6359d245 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/fips-initramfs.bb @@ -0,0 +1,32 @@ +SUMMARY = "Minimal initramfs with wolfSSL FIPS kernel module" +DESCRIPTION = "An initramfs image that loads the wolfSSL FIPS kernel module early in the boot process, before the root filesystem is mounted." + +LICENSE = "MIT" + +# Include wolfssl-linuxkm (will use -fips version if PREFERRED_PROVIDER is set) +PACKAGE_INSTALL = "initramfs-framework-base initramfs-module-udev initramfs-module-setup-live wolfssl-linuxkm busybox udev base-passwd ${ROOTFS_BOOTSTRAP_INSTALL}" + +# Set the image fstypes to cpio.gz (required for kernel bundling) +IMAGE_FSTYPES = "${INITRAMFS_FSTYPES}" + +# Don't allow the initramfs to contain a kernel +PACKAGE_EXCLUDE = "kernel-image-*" + +IMAGE_NAME_SUFFIX ?= "" +IMAGE_LINGUAS = "" + +# Do not pollute the initrd image with rootfs features +IMAGE_FEATURES = "" + +IMAGE_ROOTFS_SIZE = "8192" +IMAGE_ROOTFS_EXTRA_SPACE = "0" + +# Inherit core-image for basic image functionality +inherit core-image + +# Inherit wolfssl-initramfs helpers +inherit wolfssl-initramfs + +# Use the bbclass methods as documented +ROOTFS_POSTPROCESS_COMMAND += "wolfssl_initramfs_run_depmod; " +ROOTFS_POSTPROCESS_COMMAND += "wolfssl_initramfs_inject_after_loadmodules; " diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/gnupg_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/gnupg_%.bbappend new file mode 100644 index 00000000..80b91deb --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/gnupg_%.bbappend @@ -0,0 +1,7 @@ +# Configure gnupg for libgcrypt-image-minimal +# +# This bbappend is needed when using gnupg with libgcrypt to use wolfSSL backend +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/gnupg/gnupg-enable-libgcrypt-wolfssl.inc + diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/gnutls_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/gnutls_%.bbappend new file mode 100644 index 00000000..3d37046e --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/gnutls_%.bbappend @@ -0,0 +1,7 @@ +# Configure gnutls for fips-image-minimal +# +# This bbappend directly configures gnutls to use wolfSSL backend +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/gnutls/gnutls-enable-wolfssl.inc + diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/libgcrypt_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/libgcrypt_%.bbappend new file mode 100644 index 00000000..8160da26 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/libgcrypt_%.bbappend @@ -0,0 +1,7 @@ +# Configure libgcrypt for fips-image-minimal +# +# This bbappend directly configures libgcrypt to use wolfSSL backend +# when wolfssl-fips is the preferred provider. + +require ${WOLFSSL_LAYERDIR}/inc/libgcrypt/libgcrypt-enable-wolfssl.inc + diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/librelp_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/librelp_%.bbappend new file mode 100644 index 00000000..afc7301a --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/librelp_%.bbappend @@ -0,0 +1 @@ +require ${WOLFSSL_LAYERDIR}/inc/librelp/librelp-ptest.inc diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/linux-yocto_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/linux-yocto_%.bbappend new file mode 100644 index 00000000..d9ed53dc --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/linux-yocto_%.bbappend @@ -0,0 +1,9 @@ +# Apply wolfSSL kernel randomness patches for FIPS DRBG integration +# This adds callback hooks to drivers/char/random.c and include/linux/random.h +# allowing the wolfSSL kernel module (libwolfssl.ko) to register its FIPS-certified +# DRBG implementation with the kernel. +# +# See: meta-wolfssl/recipes-wolfssl/wolfssl/README-linuxkm-randomness-patch.md + +inherit wolfssl-kernel-random +WOLFSSL_KERNEL_RANDOM_PATCH = "6.12" diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/nettle_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/nettle_%.bbappend new file mode 100644 index 00000000..fd625ee7 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/nettle_%.bbappend @@ -0,0 +1,6 @@ +# Configure nettle for gnutls. +# nettle 3.10 in order to correctly build +# the latest release of gnutls. +# + +require ${WOLFSSL_LAYERDIR}/inc/nettle/nettle.inc diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/openssh_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/openssh_%.bbappend new file mode 100644 index 00000000..6f1cbb9c --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/openssh_%.bbappend @@ -0,0 +1,4 @@ +# OpenSSH ptest modifications for wolfProvider FIPS testing + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssh/openssh-enable-wolfprovider.inc + diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/openssl_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/openssl_%.bbappend new file mode 100644 index 00000000..c4cf4317 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/openssl_%.bbappend @@ -0,0 +1,6 @@ +# Configure OpenSSL (replace-default mode) for fips-image-minimal +# +# This bbappend configures OpenSSL to use wolfProvider in replace-default mode + +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc + diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfprovider_%.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfprovider_%.bbappend new file mode 100644 index 00000000..a6b52a3d --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfprovider_%.bbappend @@ -0,0 +1,6 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + +# Enable unit tests for wolfprovider replace default mode since FIPS should always be using this +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-replace-default-unittest.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfprovider-enable-unittest.inc diff --git a/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips.bbappend b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips.bbappend new file mode 100644 index 00000000..e5d28d36 --- /dev/null +++ b/recipes-core/images/wolfssl-linux-fips-images/fips-image-minimal/wolfssl-fips.bbappend @@ -0,0 +1,16 @@ +# Configure wolfSSL FIPS for fips-image-minimal +# +# This bbappend configures wolfSSL FIPS with libgcrypt, gnutls, and wolfProvider support + +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-enable-gnutls.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc + +# Fix for commercial 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-core/images/wolfssl-minimal-image/wolfssl-fips.bbappend b/recipes-core/images/wolfssl-minimal-image/wolfssl-fips.bbappend new file mode 100644 index 00000000..20670366 --- /dev/null +++ b/recipes-core/images/wolfssl-minimal-image/wolfssl-fips.bbappend @@ -0,0 +1,6 @@ +# Manual configuration for wolfssl-image-minimal +# Enable features needed for test and benchmark utilities + +require ${WOLFSSL_LAYERDIR}/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc + diff --git a/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb b/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb new file mode 100644 index 00000000..c5983ab6 --- /dev/null +++ b/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb @@ -0,0 +1,10 @@ +SUMMARY = "Minimal image with wolfSSL and test utilities" +DESCRIPTION = "A minimal Linux image that includes wolfSSL library with test/benchmark utilities" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfcrypttest wolfcryptbenchmark') +} + +require recipes-core/images/core-image-minimal.bb diff --git a/recipes-core/images/wolfssl-minimal-image/wolfssl_%.bbappend b/recipes-core/images/wolfssl-minimal-image/wolfssl_%.bbappend new file mode 100644 index 00000000..20670366 --- /dev/null +++ b/recipes-core/images/wolfssl-minimal-image/wolfssl_%.bbappend @@ -0,0 +1,6 @@ +# Manual configuration for wolfssl-image-minimal +# Enable features needed for test and benchmark utilities + +require ${WOLFSSL_LAYERDIR}/inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc + diff --git a/recipes-core/images/wolfssl-py-image-minimal/wolf-py-tests_%.bbappend b/recipes-core/images/wolfssl-py-image-minimal/wolf-py-tests_%.bbappend new file mode 100644 index 00000000..9c45ee3a --- /dev/null +++ b/recipes-core/images/wolfssl-py-image-minimal/wolf-py-tests_%.bbappend @@ -0,0 +1,3 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfssl-py-image-minimal/wolfcrypt-py_%.bbappend b/recipes-core/images/wolfssl-py-image-minimal/wolfcrypt-py_%.bbappend new file mode 100644 index 00000000..9c45ee3a --- /dev/null +++ b/recipes-core/images/wolfssl-py-image-minimal/wolfcrypt-py_%.bbappend @@ -0,0 +1,3 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfssl-py-image-minimal/wolfssl-py-image-minimal.bb b/recipes-core/images/wolfssl-py-image-minimal/wolfssl-py-image-minimal.bb new file mode 100644 index 00000000..a5cf4d4e --- /dev/null +++ b/recipes-core/images/wolfssl-py-image-minimal/wolfssl-py-image-minimal.bb @@ -0,0 +1,10 @@ +SUMMARY = "Minimal image with wolfSSL, test utilities, and Python bindings" +DESCRIPTION = "A minimal Linux image that includes wolfSSL library, test/benchmark utilities, and Python bindings (wolfssl-py and wolfcrypt-py) with testing support" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolfssl wolfssl-py wolfcrypt-py wolf-py-tests python3 python3-cffi python3-pytest') +} + +require ${WOLFSSL_LAYERDIR}/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb diff --git a/recipes-core/images/wolfssl-py-image-minimal/wolfssl-py_%.bbappend b/recipes-core/images/wolfssl-py-image-minimal/wolfssl-py_%.bbappend new file mode 100644 index 00000000..9c45ee3a --- /dev/null +++ b/recipes-core/images/wolfssl-py-image-minimal/wolfssl-py_%.bbappend @@ -0,0 +1,3 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + diff --git a/recipes-core/images/wolfssl-py-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolfssl-py-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..df2827ab --- /dev/null +++ b/recipes-core/images/wolfssl-py-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,7 @@ +# Manual configuration for wolfssl-py-image-minimal +# Enable wolfSSL features for Python bindings (wolfssl-py and wolfcrypt-py) and tests + +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-py/wolfssl-enable-wolfssl-py.inc +require ${WOLFSSL_LAYERDIR}/inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py.inc +require ${WOLFSSL_LAYERDIR}/inc/wolf-py-tests/wolfssl-enable-wolf-py-tests.inc + diff --git a/recipes-core/images/wolftpm-image-minimal/test-wolftpm.sh b/recipes-core/images/wolftpm-image-minimal/test-wolftpm.sh new file mode 100755 index 00000000..420f8da5 --- /dev/null +++ b/recipes-core/images/wolftpm-image-minimal/test-wolftpm.sh @@ -0,0 +1,144 @@ +#!/bin/bash +# test-wolftpm.sh +# Script to test wolfTPM image with software TPM simulator +# +# Usage: ./test-wolftpm.sh [build-directory] +# Example: ./test-wolftpm.sh ~/wolfwork/yocto/poky/build + +set -e + +# Configuration +BUILD_DIR="${1:-$HOME/wolfwork/yocto/poky/build}" +POKY_DIR="$HOME/wolfwork/yocto/poky" +TPM_STATE_DIR="/tmp/mytpm1" +IMAGE_NAME="wolftpm-image-minimal" + +# Color output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN}wolfTPM Image Test Script${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" + +# Cleanup function +cleanup() { + echo -e "${YELLOW}Cleaning up...${NC}" + + # Kill TPM simulator + sudo killall swtpm 2>/dev/null || true + + # Remove TPM state directory + sudo rm -rf "$TPM_STATE_DIR" 2>/dev/null || true + + echo -e "${GREEN}Cleanup complete!${NC}" +} + +# Set trap to cleanup on exit +trap cleanup EXIT INT TERM + +# Check if build directory exists +if [ ! -d "$BUILD_DIR" ]; then + echo -e "${RED}Error: Build directory not found: $BUILD_DIR${NC}" + echo "Usage: $0 [build-directory]" + exit 1 +fi + +# Check if poky directory exists +if [ ! -d "$POKY_DIR" ]; then + echo -e "${RED}Error: Poky directory not found: $POKY_DIR${NC}" + exit 1 +fi + +# Check if image has been built +IMAGE_DIR="$BUILD_DIR/tmp/deploy/images/qemux86-64" +if [ ! -d "$IMAGE_DIR" ]; then + echo -e "${RED}Error: Image directory not found: $IMAGE_DIR${NC}" + echo "Please build the image first with: bitbake $IMAGE_NAME" + exit 1 +fi + +# Find the image file +IMAGE_FILE=$(find "$IMAGE_DIR" -name "${IMAGE_NAME}*.wic" -o -name "${IMAGE_NAME}*.ext4" | head -n1) +if [ -z "$IMAGE_FILE" ]; then + echo -e "${RED}Error: No image file found for $IMAGE_NAME${NC}" + echo "Please build the image first with: bitbake $IMAGE_NAME" + exit 1 +fi + +# Check if swtpm is installed +if ! command -v swtpm &> /dev/null; then + echo -e "${RED}Error: swtpm is not installed${NC}" + echo "Install with: sudo apt-get install swtpm swtpm-tools" + exit 1 +fi + +# Check if swtpm_setup is installed +if ! command -v swtpm_setup &> /dev/null; then + echo -e "${RED}Error: swtpm_setup is not installed${NC}" + echo "Install with: sudo apt-get install swtpm swtpm-tools" + exit 1 +fi + +echo -e "${YELLOW}Step 1: Cleaning up any existing TPM state...${NC}" +sudo killall swtpm 2>/dev/null || true +sudo rm -rf "$TPM_STATE_DIR" 2>/dev/null || true + +echo -e "${YELLOW}Step 2: Creating TPM state directory...${NC}" +sudo mkdir -p "$TPM_STATE_DIR" +sudo chown -R $(whoami):$(whoami) "$TPM_STATE_DIR" +chmod 755 "$TPM_STATE_DIR" + +echo -e "${YELLOW}Step 3: Starting TPM simulator in background...${NC}" +sudo swtpm socket --tpmstate dir="$TPM_STATE_DIR" \ + --ctrl type=unixio,path="$TPM_STATE_DIR/swtpm-sock" \ + --log level=20 \ + --tpm2 \ + --daemon + +# Give the simulator a moment to start +sleep 2 + +echo -e "${YELLOW}Step 4: Initializing TPM...${NC}" +sudo swtpm_setup --tpmstate "$TPM_STATE_DIR" \ + --createek \ + --create-ek-cert \ + --create-platform-cert \ + --lock-nvram \ + --tpm2 + +echo -e "${YELLOW}Step 5: Setting permissions for QEMU access...${NC}" +sudo chown -R $(whoami):$(whoami) "$TPM_STATE_DIR" +sudo chmod -R 755 "$TPM_STATE_DIR" +sudo chmod 777 "$TPM_STATE_DIR/swtpm-sock" + +echo -e "${GREEN}========================================${NC}" +echo -e "${GREEN}TPM Setup Complete!${NC}" +echo -e "${GREEN}========================================${NC}" +echo "" +echo -e "${YELLOW}Starting QEMU with $IMAGE_NAME...${NC}" +echo "" +echo -e "${GREEN}To test wolfTPM inside QEMU, run:${NC}" +echo -e " ${YELLOW}cd /usr/bin${NC}" +echo -e " ${YELLOW}./wolftpm-wrap-test${NC}" +echo "" +echo -e "${GREEN}Press Ctrl-A then X to exit QEMU${NC}" +echo "" + +# Source Yocto environment and run QEMU +cd "$POKY_DIR" +source oe-init-build-env "$BUILD_DIR" > /dev/null 2>&1 + +echo -e "${YELLOW}Found image: $(basename "$IMAGE_FILE")${NC}" +echo "" + +runqemu qemux86-64 nographic "$IMAGE_FILE" \ + qemuparams="-chardev socket,id=chrtpm,path=$TPM_STATE_DIR/swtpm-sock \ + -tpmdev emulator,id=tpm0,chardev=chrtpm \ + -device tpm-tis,tpmdev=tpm0" + +# Cleanup will be called automatically via trap + diff --git a/recipes-core/images/wolftpm-image-minimal/wolfssl_%.bbappend b/recipes-core/images/wolftpm-image-minimal/wolfssl_%.bbappend new file mode 100644 index 00000000..2bf0fd40 --- /dev/null +++ b/recipes-core/images/wolftpm-image-minimal/wolfssl_%.bbappend @@ -0,0 +1,5 @@ +# Manual configuration for wolftpm-image-minimal +# Enable wolfTPM support in wolfSSL + +require ${WOLFSSL_LAYERDIR}/inc/wolftpm/wolfssl-enable-wolftpm.inc + diff --git a/recipes-core/images/wolftpm-image-minimal/wolftpm-image-minimal.bb b/recipes-core/images/wolftpm-image-minimal/wolftpm-image-minimal.bb new file mode 100644 index 00000000..74a52c72 --- /dev/null +++ b/recipes-core/images/wolftpm-image-minimal/wolftpm-image-minimal.bb @@ -0,0 +1,44 @@ +SUMMARY = "Minimal image with wolfSSL, test utilities, and wolfTPM" +DESCRIPTION = "A minimal Linux image that includes wolfSSL library, test/benchmark utilities, and wolfTPM with TPM 2.0 support" + +inherit wolfssl-compatibility + +# Validate TPM configuration +python __anonymous() { + """ + Check that required TPM features are enabled in local.conf + """ + distro_features = d.getVar('DISTRO_FEATURES') or '' + machine_features = d.getVar('MACHINE_FEATURES') or '' + kernel_features = d.getVar('KERNEL_FEATURES') or '' + + errors = [] + + # Check DISTRO_FEATURES + if 'security' not in distro_features or 'tpm' not in distro_features or 'tpm2' not in distro_features: + errors.append("DISTRO_FEATURES must contain 'security tpm tpm2'") + errors.append(" Add to local.conf: DISTRO_FEATURES:append = \" security tpm tpm2\"") + + # Check MACHINE_FEATURES + if 'tpm' not in machine_features or 'tpm2' not in machine_features: + errors.append("MACHINE_FEATURES must contain 'tpm tpm2'") + errors.append(" Add to local.conf: MACHINE_FEATURES:append = \" tpm tpm2\"") + + # Check KERNEL_FEATURES + if 'features/tpm/tpm.scc' not in kernel_features: + errors.append("KERNEL_FEATURES must contain 'features/tpm/tpm.scc'") + errors.append(" Add to local.conf: KERNEL_FEATURES:append = \" features/tpm/tpm.scc\"") + + # Report errors + if errors: + error_msg = "\n%s requires TPM support to be properly configured in local.conf:\n\n" % d.getVar('PN') + error_msg += "\n".join([" - " + e for e in errors]) + error_msg += "\n\nThese settings MUST be in local.conf, not in the image recipe.\n" + bb.fatal(error_msg) + + wolfssl_varAppendNonOverride(d, 'IMAGE_INSTALL', ' wolftpm-wrap-test tpm2-tools tpm2-tss libtss2 libtss2-mu libtss2-tcti-device libtss2-tcti-mssim') +} + +# Enable security and TPM features + +require ${WOLFSSL_LAYERDIR}/recipes-core/images/wolfssl-minimal-image/wolfssl-image-minimal.bb diff --git a/recipes-core/images/wolftpm-image-minimal/wolftpm_%.bbappend b/recipes-core/images/wolftpm-image-minimal/wolftpm_%.bbappend new file mode 100644 index 00000000..d52e2030 --- /dev/null +++ b/recipes-core/images/wolftpm-image-minimal/wolftpm_%.bbappend @@ -0,0 +1,6 @@ +# Disable the feature check for manual image configuration +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-manual-config.inc + +# Enable software TPM support for testing with QEMU and TPM simulator +EXTRA_OECONF += "--enable-devtpm" + diff --git a/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfcryptbenchmark.bb b/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfcryptbenchmark.bb index 45ef5269..f39d1e71 100644 --- a/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfcryptbenchmark.bb +++ b/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfcryptbenchmark.bb @@ -8,7 +8,13 @@ SECTION = "x11/applications" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://benchmark.c;beginline=1;endline=20;md5=6a14f1f3bfbb40d2c3b7d0f3a1f98ffc" S = "${WORKDIR}/git/wolfcrypt/benchmark" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') +} SRC_URI = "git://github.com/wolfSSL/wolfssl.git;nobranch=1;protocol=https;rev=59f4fa568615396fbf381b073b220d1e8d61e4c2" @@ -20,26 +26,15 @@ WOLFCRYPT_BENCHMARK_INSTALL_DIR = "${D}${WOLFCRYPT_BENCHMARK_DIR}" WOLFCRYPT_BENCHMARK_README = "README.txt" WOLFCRYPT_BENCHMARK_README_DIR = "${WOLFCRYPT_BENCHMARK_INSTALL_DIR}/${WOLFCRYPT_BENCHMARK_README}" -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfcrypt_benchmark_dir = d.getVar('WOLFCRYPT_BENCHMARK_DIR', True) - wolfcrypt_benchmark_install_dir = d.getVar('WOLFCRYPT_BENCHMARK_INSTALL_DIR', True) - wolfcrypt_benchmark_readme_dir = d.getVar('WOLFCRYPT_BENCHMARK_README_DIR', True) - - bb.note("Installing dummy file for wolfCrypt benchmark example") - installDir = 'install -m 0755 -d "%s"\n' % wolfcrypt_benchmark_install_dir - makeDummy = 'echo "This is a dummy package" > "%s"\n' % wolfcrypt_benchmark_readme_dir - - d.appendVar('do_install', installDir) - d.appendVar('do_install', makeDummy) +do_install_wolfcryptbenchmark_dummy() { + bbnote "Installing dummy file for wolfCrypt benchmark example" + install -m 0755 -d "${WOLFCRYPT_BENCHMARK_INSTALL_DIR}" + echo "This is a dummy package" > "${WOLFCRYPT_BENCHMARK_README_DIR}" +} - pn = d.getVar('PN', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn +addtask do_install_wolfcryptbenchmark_dummy after do_install before do_package +do_install_wolfcryptbenchmark_dummy[fakeroot] = "1" - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfcrypt_benchmark_dir + '/*' - d.setVar(files_var_name, new_files) +python __anonymous() { + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${WOLFCRYPT_BENCHMARK_DIR}/*') } diff --git a/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl-fips.bbappend b/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl-fips.bbappend new file mode 100644 index 00000000..8a74ea7e --- /dev/null +++ b/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl-fips.bbappend @@ -0,0 +1,8 @@ +# Conditionally configure wolfssl-fips with wolfcryptbenchmark support +# Mirrors the non-FIPS helper so benchmarks ride along when enabled. + +inherit wolfssl-helper + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfcryptbenchmark', 'inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc') +} diff --git a/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl_%.bbappend b/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl_%.bbappend index b7e3821f..8649f730 100644 --- a/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl_%.bbappend +++ b/recipes-examples/wolfcrypt/wolfcryptbenchmark/wolfssl_%.bbappend @@ -1,26 +1,9 @@ -WOLFCRYPT_BENCHMARK_DIR = "${B}/wolfcrypt/benchmark/.libs" -WOLFCRYPT_BENCHMARK = "benchmark" -WOLFCRYPT_BENCHMARK_YOCTO = "wolfcryptbenchmark" -WOLFCRYPT_INSTALL_DIR = "${D}${bindir}" +# Conditionally configure wolfssl with wolfcryptbenchmark support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables -python () { - # Get the environment variables WOLFCRYPT_BENCHMARK_DIR, WOLFCRYPT_BENCHMARK, - # WOLFCRYPT_BENCHMARK_YOCTO, and WOLFCRYPT_INSTALL_DIR - wolfcrypt_benchmark_dir = d.getVar('WOLFCRYPT_BENCHMARK_DIR', True) - wolfcrypt_benchmark = d.getVar('WOLFCRYPT_BENCHMARK', True) - wolfcrypt_benchmark_yocto = d.getVar('WOLFCRYPT_BENCHMARK_YOCTO', True) - wolfcrypt_install_dir = d.getVar('WOLFCRYPT_INSTALL_DIR', True) +inherit wolfssl-helper +deltask do_wolfssl_check_package - bbnote = 'bbnote "Installing wolfCrypt Benchmarks"\n' - installDir = 'install -m 0755 -d "%s"\n' % (wolfcrypt_install_dir) - cpBenchmark = 'cp "%s/%s" "%s/%s"\n' % (wolfcrypt_benchmark_dir, wolfcrypt_benchmark, wolfcrypt_install_dir, wolfcrypt_benchmark_yocto) - - d.appendVar('do_install', bbnote) - d.appendVar('do_install', installDir) - d.appendVar('do_install', cpBenchmark) +python __anonymous() { + wolfssl_conditional_require(d, 'wolfcryptbenchmark', 'inc/wolfcryptbenchmark/wolfssl-enable-wolfcryptbenchmark.inc') } - - - -TARGET_CFLAGS += "-DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -DBENCH_EMBEDDED" - diff --git a/recipes-examples/wolfcrypt/wolfcrypttest/wolfcrypttest.bb b/recipes-examples/wolfcrypt/wolfcrypttest/wolfcrypttest.bb index 432af075..4095e386 100644 --- a/recipes-examples/wolfcrypt/wolfcrypttest/wolfcrypttest.bb +++ b/recipes-examples/wolfcrypt/wolfcrypttest/wolfcrypttest.bb @@ -8,7 +8,13 @@ SECTION = "x11/applications" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://test.c;beginline=1;endline=20;md5=928770bfaa2d2704ecffeb131cc7bfd8" S = "${WORKDIR}/git/wolfcrypt/test" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') +} SRC_URI = "git://github.com/wolfSSL/wolfssl.git;nobranch=1;protocol=https;rev=59f4fa568615396fbf381b073b220d1e8d61e4c2" @@ -21,27 +27,15 @@ WOLFCRYPT_TEST_INSTALL_DIR = "${D}${WOLFCRYPT_TEST_DIR}" WOLFCRYPT_TEST_README = "README.txt" WOLFCRYPT_TEST_README_DIR = "${WOLFCRYPT_TEST_INSTALL_DIR}/${WOLFCRYPT_TEST_README}" -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfcrypt_test_dir = d.getVar('WOLFCRYPT_TEST_DIR', True) - wolfcrypt_test_install_dir = d.getVar('WOLFCRYPT_TEST_INSTALL_DIR', True) - wolfcrypt_test_readme_dir = d.getVar('WOLFCRYPT_TEST_README_DIR', True) - - bb.note("Installing dummy file for wolfCrypt test example") - installDir = 'install -m 0755 -d "%s"\n' % wolfcrypt_test_install_dir - makeDummy = 'echo "This is a dummy package" > "%s"\n' % wolfcrypt_test_readme_dir - - d.appendVar('do_install', installDir) - d.appendVar('do_install', makeDummy) - - pn = d.getVar('PN', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn - - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfcrypt_test_dir + '/*' - d.setVar(files_var_name, new_files) +do_install_wolfcrypttest_dummy() { + bbnote "Installing dummy file for wolfCrypt test example" + install -m 0755 -d "${WOLFCRYPT_TEST_INSTALL_DIR}" + echo "This is a dummy package" > "${WOLFCRYPT_TEST_README_DIR}" } +addtask do_install_wolfcrypttest_dummy after do_install before do_package +do_install_wolfcrypttest_dummy[fakeroot] = "1" + +python __anonymous() { + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${WOLFCRYPT_TEST_DIR}/*') +} diff --git a/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl-fips.bbappend b/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl-fips.bbappend new file mode 100644 index 00000000..2f42f50a --- /dev/null +++ b/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl-fips.bbappend @@ -0,0 +1,8 @@ +# Conditionally configure wolfssl-fips with wolfcrypttest support +# Matches the wolfssl variant so FIPS builds get the same helpers. + +inherit wolfssl-helper + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfcrypttest', 'inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc') +} diff --git a/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl_%.bbappend b/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl_%.bbappend index 9420ca1f..0c089c62 100644 --- a/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl_%.bbappend +++ b/recipes-examples/wolfcrypt/wolfcrypttest/wolfssl_%.bbappend @@ -1,23 +1,9 @@ -WOLFCRYPT_TEST_DIR = "${B}/wolfcrypt/test/.libs" -WOLFCRYPT_TEST = "testwolfcrypt" -WOLFCRYPT_TEST_YOCTO = "wolfcrypttest" -WOLFCRYPT_INSTALL_DIR = "${D}${bindir}" +# Conditionally configure wolfssl with wolfcrypttest support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables -python () { - # Get the environment variables WOLFCRYPT_TEST_DIR, WOLFCRYPT_TEST, - # WOLFCRYPT_TEST_YOCTO, and WOLFCRYPT_INSTALL_DIR - wolfcrypt_test_dir = d.getVar('WOLFCRYPT_TEST_DIR', True) - wolfcrypt_test = d.getVar('WOLFCRYPT_TEST', True) - wolfcrypt_test_yocto = d.getVar('WOLFCRYPT_TEST_YOCTO', True) - wolfcrypt_install_dir = d.getVar('WOLFCRYPT_INSTALL_DIR', True) +inherit wolfssl-helper +deltask do_wolfssl_check_package - bbnote = 'bbnote "Installing wolfCrypt Tests"\n' - installDir = 'install -m 0755 -d "%s"\n' % (wolfcrypt_install_dir) - cpBenchmark = 'cp "%s/%s" "%s/%s"\n' % (wolfcrypt_test_dir, wolfcrypt_test, wolfcrypt_install_dir, wolfcrypt_test_yocto) - - d.appendVar('do_install', bbnote) - d.appendVar('do_install', installDir) - d.appendVar('do_install', cpBenchmark) +python __anonymous() { + wolfssl_conditional_require(d, 'wolfcrypttest', 'inc/wolfcrypttest/wolfssl-enable-wolfcrypttest.inc') } - -TARGET_CFLAGS += "-DUSE_CERT_BUFFERS_2048 -DUSE_CERT_BUFFERS_256 -DWOLFSSL_RSA_KEY_CHECK -DNO_WRITE_TEMP_FILES" diff --git a/recipes-examples/wolfengine/wolfenginetest/wolfengine_%.bbappend b/recipes-examples/wolfengine/wolfenginetest/wolfengine_%.bbappend index 11fb35ba..d4e4f4df 100644 --- a/recipes-examples/wolfengine/wolfenginetest/wolfengine_%.bbappend +++ b/recipes-examples/wolfengine/wolfenginetest/wolfengine_%.bbappend @@ -1 +1,16 @@ -EXTRA_OECONF += " --enable-debug " \ No newline at end of file +# Conditionally enable debug mode for wolfengine when testing +# +# This bbappend automatically enables debug configuration when: +# 1. 'wolfenginetest' is in IMAGE_INSTALL, OR +# 2. 'wolfenginetest' is in WOLFSSL_FEATURES +# +# Usage in local.conf: +# IMAGE_INSTALL:append = " wolfenginetest" +# OR +# WOLFSSL_FEATURES = "wolfenginetest" + +inherit wolfssl-helper + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfenginetest', 'inc/wolfenginetest/wolfengine-enable-test.inc') +} \ No newline at end of file diff --git a/recipes-examples/wolfengine/wolfenginetest/wolfenginetest.bb b/recipes-examples/wolfengine/wolfenginetest/wolfenginetest.bb index e28b03b0..0075470d 100644 --- a/recipes-examples/wolfengine/wolfenginetest/wolfenginetest.bb +++ b/recipes-examples/wolfengine/wolfenginetest/wolfenginetest.bb @@ -5,9 +5,11 @@ SECTION = "examples" LICENSE = "CLOSED" LIC_FILES_CHKSUM = "" -DEPENDS = "openssl pkgconfig-native wolfssl wolfengine" +DEPENDS = "openssl pkgconfig-native virtual/wolfssl wolfengine" PROVIDES += "wolfenginetest" +inherit pkgconfig wolfssl-compatibility + WOLFENGINE_TEST = "${bindir}/wolfenginetest" WOLFENGINE_ENV = "${bindir}/wolfenginetest" @@ -17,8 +19,6 @@ SRC_URI = "file://wolfenginetest.c \ S = "${WORKDIR}" -inherit pkgconfig - do_compile() { ${CC} ${WORKDIR}/wolfenginetest.c -o wolfenginetest \ ${CFLAGS} ${LDFLAGS} $(pkg-config --cflags --libs openssl) -ldl -lwolfssl -lwolfengine @@ -28,29 +28,10 @@ do_install() { install -d ${D}${bindir} install -m 0755 ${WORKDIR}/wolfenginetest ${D}${bindir}/wolfenginetest install -m 0755 ${WORKDIR}/wolfengineenv.sh ${D}${bindir}/wolfengineenv - -} - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfengine_test = d.getVar('WOLFENGINE_TEST', True) - wolfengine_env = d.getVar('WOLFENGINE_ENV', True) - pn = d.getVar('PN', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn - - - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfengine_test + ' ' + wolfengine_env - d.setVar(files_var_name, new_files) - - rdepends_var_name = 'RDEPENDS_' + pn if (distro_version.startswith('2.') or distro_version.startswith('3.')) else 'RDEPENDS:' + pn - - current_rdepends = d.getVar(rdepends_var_name, True) or "" - new_rdepends = current_rdepends + " bash" - d.setVar(rdepends_var_name, new_rdepends) +} +python __anonymous() { + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${WOLFENGINE_TEST} ${WOLFENGINE_ENV}') + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' bash') } diff --git a/recipes-examples/wolfengine/wolfenginetest/wolfssl_%.bbappend b/recipes-examples/wolfengine/wolfenginetest/wolfssl_%.bbappend new file mode 100644 index 00000000..80b89bd1 --- /dev/null +++ b/recipes-examples/wolfengine/wolfenginetest/wolfssl_%.bbappend @@ -0,0 +1,10 @@ +# Conditionally configure wolfssl with wolfenginetest support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables + +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfenginetest', 'inc/wolfenginetest/wolfssl-enable-wolfenginetest.inc') +} + diff --git a/recipes-examples/wolfprovider/wolfprovidercmd/files/wolfprovidercmd.sh b/recipes-examples/wolfprovider/wolfprovidercmd/files/wolfprovidercmd.sh new file mode 100644 index 00000000..f6627e0d --- /dev/null +++ b/recipes-examples/wolfprovider/wolfprovidercmd/files/wolfprovidercmd.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +echo "Setting up environment..." +if [ -f /usr/bin/wolfproviderenv ]; then + source /usr/bin/wolfproviderenv + if [ $? -ne 0 ]; then + echo "✗ Failed to source environment setup!" + exit 1 + fi +else + echo "✗ wolfproviderenv not found!" + exit 1 +fi + +echo "==========================================" +echo "wolfProvider Command-Line Tests" +echo "==========================================" +if [ -f /usr/share/wolfprovider-cmd-tests/scripts/cmd_test/do-cmd-tests.sh ]; then + echo "Running command-line test suite..." + echo "" + + # Set environment for cmd tests - use system-wide installations + export WOLFSSL_ISFIPS=1 # openssl built without cfb which fips also is + export OPENSSL_BIN=$(which openssl) + export WOLFPROV_PATH=/usr/lib/ssl-3/modules + export WOLFPROV_CONFIG=/opt/wolfprovider-configs/wolfprovider.conf + + # Set library paths for system-wide OpenSSL/wolfSSL + export LD_LIBRARY_PATH=/usr/lib:/lib:$LD_LIBRARY_PATH + export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/share/pkgconfig:$PKG_CONFIG_PATH + + # Prevent env-setup from trying to find build directories + export OPENSSL_DIR=/usr + export WOLFSSL_DIR=/usr + + # Change to test directory and run + ( + cd /usr/share/wolfprovider-cmd-tests/scripts/cmd_test + bash ./do-cmd-tests.sh + ) + CMD_TEST_RESULT=$? + + echo "" + echo "==========================================" + if [ $CMD_TEST_RESULT -eq 0 ]; then + echo "✓ Command-line tests PASSED!" + else + echo "✗ Command-line tests FAILED! (exit code: $CMD_TEST_RESULT)" + exit $CMD_TEST_RESULT + fi +else + echo "Command-line test suite not found at + /usr/share/wolfprovider-cmd-tests/scripts/cmd_test/do-cmd-tests.sh" + exit 1 +fi + +echo "==========================================" diff --git a/recipes-examples/wolfprovider/wolfprovidercmd/wolfprovidercmd.bb b/recipes-examples/wolfprovider/wolfprovidercmd/wolfprovidercmd.bb new file mode 100644 index 00000000..707ac300 --- /dev/null +++ b/recipes-examples/wolfprovider/wolfprovidercmd/wolfprovidercmd.bb @@ -0,0 +1,58 @@ +SUMMARY = "wolfProvider Command-Line Test Suite" +DESCRIPTION = "Command-line test scripts for wolfProvider - tests hash, AES, RSA, ECC, and certificate operations" +HOMEPAGE = "https://github.com/wolfssl/wolfProvider" +BUGTRACKER = "https://github.com/wolfssl/wolfProvider/issues" +SECTION = "examples" + +LICENSE = "GPL-3.0-only" +LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" + +DEPENDS = "openssl virtual/wolfssl wolfprovider" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varSet(d, 'RDEPENDS', '${PN}', 'bash openssl wolfprovider') +} + +SRC_URI = "git://github.com/wolfssl/wolfProvider.git;nobranch=1;protocol=https;rev=7c85aa0196ba0d3780c3e0285c61227d6c1a2892 \ + file://wolfprovidercmd.sh" + + +S = "${WORKDIR}/git" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +WOLFPROV_CMD_TEST_DIR = "${datadir}/wolfprovider-cmd-tests" +WOLFPROV_CMD_TEST_INSTALL_DIR = "${D}${WOLFPROV_CMD_TEST_DIR}" + +do_install() { + # Create directory structure that do-cmd-tests.sh expects + install -d ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test + + # Copy main cmd-test scripts to scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/do-cmd-tests.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/cmd-test-common.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/clean-cmd-test.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/hash-cmd-test.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/aes-cmd-test.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/rsa-cmd-test.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/ecc-cmd-test.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + install -m 0755 ${S}/scripts/cmd_test/req-cmd-test.sh ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/cmd_test/ + + # Copy env setup script to scripts/ + install -m 0755 ${S}/scripts/env-setup ${WOLFPROV_CMD_TEST_INSTALL_DIR}/scripts/ + + # Copy provider configuration files to root of test dir + install -m 0644 ${S}/provider.conf ${WOLFPROV_CMD_TEST_INSTALL_DIR}/ + install -m 0644 ${S}/provider-fips.conf ${WOLFPROV_CMD_TEST_INSTALL_DIR}/ || true + + # Install wrapper script to bindir + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/wolfprovidercmd.sh ${D}${bindir}/wolfprovidercmd +} + +python __anonymous() { + wolfssl_varSet(d, 'FILES', '${PN}', '${WOLFPROV_CMD_TEST_DIR}/* ${bindir}/wolfprovidercmd') +} diff --git a/recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.c b/recipes-examples/wolfprovider/wolfproviderenv/files/wolfproviderenv.c similarity index 99% rename from recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.c rename to recipes-examples/wolfprovider/wolfproviderenv/files/wolfproviderenv.c index 882f745a..2b8d182f 100644 --- a/recipes-examples/wolfprovider/wolfprovidertest/files/wolfprovidertest.c +++ b/recipes-examples/wolfprovider/wolfproviderenv/files/wolfproviderenv.c @@ -12,4 +12,4 @@ int main(void) { printf("Custom provider 'libwolfprov' loaded successfully.\n"); OSSL_PROVIDER_unload(prov); return 0; -} \ No newline at end of file +} diff --git a/recipes-examples/wolfprovider/wolfproviderenv/files/wolfproviderenv.sh b/recipes-examples/wolfprovider/wolfproviderenv/files/wolfproviderenv.sh new file mode 100644 index 00000000..0060ef7c --- /dev/null +++ b/recipes-examples/wolfprovider/wolfproviderenv/files/wolfproviderenv.sh @@ -0,0 +1,226 @@ +#!/bin/bash + +# This script can be both executed and sourced +# When sourced: Sets up environment variables for other scripts to use +# When executed: Also runs verification tests + +REPLACE_DEFAULT_MODE=0 +WOLFSSL_FIPS_MODE=0 + +# Setup for libwolfprov.so (needed before runtime detection) +mkdir -p /usr/lib/ssl-3/modules +if [ ! -L /usr/lib/ssl-3/modules/libwolfprov.so ]; then + ln -s /usr/lib/libwolfprov.so.0.0.0 /usr/lib/ssl-3/modules/libwolfprov.so +fi + +# Environment variables (needed before runtime detection) +export OPENSSL_MODULES=/usr/lib/ssl-3/modules +export LD_LIBRARY_PATH=/usr/lib:/lib:$LD_LIBRARY_PATH + +# Method 1: Check config file for replace-default mode +CONFIG_REPLACE_DEFAULT=-1 +if [ -f /etc/openssl/replace-default-enabled ]; then + MODE=$(cat /etc/openssl/replace-default-enabled) + if [ "$MODE" = "1" ]; then + CONFIG_REPLACE_DEFAULT=1 + echo "Detected replace-default mode (from config file)" + else + CONFIG_REPLACE_DEFAULT=0 + echo "Detected normal wolfprovider mode (from config file)" + fi +fi +# Method 2: Check runtime detection for replace-default mode +RUNTIME_REPLACE_DEFAULT=-1 +DEFAULT_PROVIDER_RD=$(openssl list -providers 2>/dev/null | grep -A1 "^ default$" \ +| grep "name:" | grep -i "wolfSSL Provider") +if [ -n "$DEFAULT_PROVIDER_RD" ]; then + RUNTIME_REPLACE_DEFAULT=1 + echo "Detected replace-default mode (runtime detection)" +else + RUNTIME_REPLACE_DEFAULT=0 + echo "Detected normal wolfprovider mode (runtime detection)" +fi + +# Verify both config file and runtime detection for replace-default mode +if [ "$CONFIG_REPLACE_DEFAULT" -ne -1 ] && [ "$RUNTIME_REPLACE_DEFAULT" -ne -1 ]; then + if [ "$CONFIG_REPLACE_DEFAULT" -eq "$RUNTIME_REPLACE_DEFAULT" ]; then + REPLACE_DEFAULT_MODE=$CONFIG_REPLACE_DEFAULT + if [ "$REPLACE_DEFAULT_MODE" -eq 1 ]; then + echo "Detected replace-default mode (config and runtime agree)" + else + echo "Detected normal wolfprovider mode (config and runtime agree)" + fi + else + echo "WARNING: Config file and runtime detection are inconsistent!" + echo " Config file: $([ "$CONFIG_REPLACE_DEFAULT" -eq 1 ] && echo 'replace-default' || echo 'normal')" + echo " Runtime: $([ "$RUNTIME_REPLACE_DEFAULT" -eq 1 ] && echo 'replace-default' || echo 'normal')" + echo " Using runtime detection as source of truth" + REPLACE_DEFAULT_MODE=$RUNTIME_REPLACE_DEFAULT + fi +elif [ "$CONFIG_REPLACE_DEFAULT" -ne -1 ]; then + REPLACE_DEFAULT_MODE=$CONFIG_REPLACE_DEFAULT + if [ "$REPLACE_DEFAULT_MODE" -eq 1 ]; then + echo "Detected replace-default mode (from config file only)" + else + echo "Detected normal wolfprovider mode (from config file only)" + fi +elif [ "$RUNTIME_REPLACE_DEFAULT" -ne -1 ]; then + REPLACE_DEFAULT_MODE=$RUNTIME_REPLACE_DEFAULT + if [ "$REPLACE_DEFAULT_MODE" -eq 1 ]; then + echo "Detected replace-default mode (from runtime detection only)" + else + echo "Detected normal wolfprovider mode (from runtime detection only)" + fi +fi + +# Method 1: Check config file for FIPS mode +CONFIG_FIPS=-1 +if [ -f /etc/wolfssl/fips-enabled ]; then + FIPS_VALUE=$(cat /etc/wolfssl/fips-enabled) + if [ "$FIPS_VALUE" = "1" ]; then + CONFIG_FIPS=1 + echo "Detected wolfSSL FIPS build (from config file)" + else + CONFIG_FIPS=0 + echo "Detected wolfSSL non-FIPS build (from config file)" + fi +fi +# Method 2: Check runtime detection for FIPS mode +RUNTIME_FIPS=-1 +PROVIDER_FIPS=$(openssl list -providers 2>/dev/null | grep "name:" | grep -i "wolfSSL Provider FIPS") +if [ -n "$PROVIDER_FIPS" ]; then + RUNTIME_FIPS=1 + echo "Detected wolfSSL FIPS build (runtime detection)" +else + RUNTIME_FIPS=0 + echo "Detected wolfSSL non-FIPS build (runtime detection)" +fi + +# Verify both config file and runtime detection for FIPS mode +if [ "$CONFIG_FIPS" -ne -1 ] && [ "$RUNTIME_FIPS" -ne -1 ]; then + if [ "$CONFIG_FIPS" -eq "$RUNTIME_FIPS" ]; then + WOLFSSL_FIPS_MODE=$CONFIG_FIPS + if [ "$WOLFSSL_FIPS_MODE" -eq 1 ]; then + echo "Detected wolfSSL FIPS build (config and runtime agree)" + else + echo "Detected wolfSSL non-FIPS build (config and runtime agree)" + fi + else + echo "WARNING: Config file and runtime detection are inconsistent for FIPS!" + echo " Config file: $([ "$CONFIG_FIPS" -eq 1 ] && echo 'FIPS' || echo 'non-FIPS')" + echo " Runtime: $([ "$RUNTIME_FIPS" -eq 1 ] && echo 'FIPS' || echo 'non-FIPS')" + echo " Using runtime detection as source of truth" + WOLFSSL_FIPS_MODE=$RUNTIME_FIPS + fi +elif [ "$CONFIG_FIPS" -ne -1 ]; then + WOLFSSL_FIPS_MODE=$CONFIG_FIPS + if [ "$WOLFSSL_FIPS_MODE" -eq 1 ]; then + echo "Detected wolfSSL FIPS build (from config file only)" + else + echo "Detected wolfSSL non-FIPS build (from config file only)" + fi +elif [ "$RUNTIME_FIPS" -ne -1 ]; then + WOLFSSL_FIPS_MODE=$RUNTIME_FIPS + if [ "$WOLFSSL_FIPS_MODE" -eq 1 ]; then + echo "Detected wolfSSL FIPS build (from runtime detection only)" + else + echo "Detected wolfSSL non-FIPS build (from runtime detection only)" + fi +fi + +# Determine the provider config file to use +if [ "$WOLFSSL_FIPS_MODE" -eq 1 ]; then + PROVIDER_CONF="/etc/ssl/openssl.cnf.d/wolfprovider-fips.conf" +else + PROVIDER_CONF="/etc/ssl/openssl.cnf.d/wolfprovider.conf" +fi + +# In standalone mode, we need to load the provider config +if [ "$REPLACE_DEFAULT_MODE" -eq 0 ]; then + # Determine the OpenSSL config file path + if [ -n "$OPENSSL_CONF" ]; then + OPENSSL_CNF="$OPENSSL_CONF" + elif [ -f "/etc/ssl/openssl.cnf" ]; then + OPENSSL_CNF="/etc/ssl/openssl.cnf" + elif [ -f "/usr/lib/ssl-3/openssl.cnf" ]; then + OPENSSL_CNF="/usr/lib/ssl-3/openssl.cnf" + else + OPENSSL_CNF="/etc/ssl/openssl.cnf" + fi + + # Copy provider config to openssl.cnf if both files exist and are different + if [ -f "$PROVIDER_CONF" ] && [ -f "$OPENSSL_CNF" ]; then + if ! cmp -s "$PROVIDER_CONF" "$OPENSSL_CNF"; then + cp "$PROVIDER_CONF" "$OPENSSL_CNF" + echo "Replaced $OPENSSL_CNF with wolfProvider configuration ($PROVIDER_CONF)" + fi + elif [ -f "$PROVIDER_CONF" ] && [ ! -f "$OPENSSL_CNF" ]; then + echo "Warning: $OPENSSL_CNF not found, cannot load wolfProvider configuration" + fi + + # Export OPENSSL_CONF to ensure OpenSSL uses the correct config + export OPENSSL_CONF="$OPENSSL_CNF" +fi + +echo "==========================================" +echo "wolfProvider Environment Setup" +echo "==========================================" +echo "" +if [ "$REPLACE_DEFAULT_MODE" -eq 1 ]; then + echo "Mode: Replace-Default (wolfProvider is the default provider)" +else + echo "Mode: Explicit Load (provider config included in openssl.cnf)" +fi +echo "" +if [ "$WOLFSSL_FIPS_MODE" -eq 1 ]; then + echo "FIPS Mode: Enabled (wolfSSL FIPS)" +else + echo "FIPS Mode: Disabled (wolfSSL non-FIPS)" +fi +echo "" +echo "Environment Variables:" +echo " OPENSSL_MODULES: $OPENSSL_MODULES" +echo " LD_LIBRARY_PATH: $LD_LIBRARY_PATH" +echo "" + +# Test 1: Provider Verification +echo "==========================================" +echo "Test 1: Provider Load Verification" +echo "==========================================" +if [ "$REPLACE_DEFAULT_MODE" -eq 1 ]; then + # In replace-default mode, just verify the default provider is wolfSSL + if openssl list -providers | grep -q "wolfSSL Provider"; then + echo "Default provider is wolfSSL Provider" + echo "Passed!" + else + echo "Failed - default provider is not wolfSSL Provider" + return 1 2>/dev/null || exit 1 + fi +else + # In explicit load mode, test explicit provider loading + if wolfproviderverify; then + echo "Passed!" + else + echo "Failed!" + return 1 2>/dev/null || exit 1 + fi +fi + +# Test 2: Provider List +echo "" +echo "==========================================" +echo "Test 2: OpenSSL Provider List" +echo "==========================================" +openssl list -providers -verbose + +# Test 3: OpenSSL Version +echo "" +echo "==========================================" +echo "Test 3: OpenSSL Version" +echo "==========================================" +openssl version -a + +echo "" +echo "==========================================" +echo "Environment setup completed." +echo "==========================================" diff --git a/recipes-examples/wolfprovider/wolfproviderenv/wolfproviderenv.bb b/recipes-examples/wolfprovider/wolfproviderenv/wolfproviderenv.bb new file mode 100644 index 00000000..f879c57a --- /dev/null +++ b/recipes-examples/wolfprovider/wolfproviderenv/wolfproviderenv.bb @@ -0,0 +1,45 @@ +SUMMARY = "Test suite for wolfProvider OpenSSL provider" +DESCRIPTION = "Enviroment setup for wolfProvider OpenSSL provider" +HOMEPAGE = "https://www.wolfssl.com" +SECTION = "examples" +LICENSE = "CLOSED" +LIC_FILES_CHKSUM = "" + +DEPENDS = "openssl pkgconfig-native virtual/wolfssl wolfprovider" +PROVIDES += "wolfproviderenv" + +inherit pkgconfig wolfssl-compatibility + +python __anonymous() { + wolfssl_varSet(d, 'RPROVIDES', '${PN}', 'wolfproviderenv') +} + +SRC_URI = "file://wolfproviderenv.c \ + file://wolfproviderenv.sh \ + https://raw.githubusercontent.com/wolfSSL/wolfProvider/master/provider.conf;name=provider_conf \ + https://raw.githubusercontent.com/wolfSSL/wolfProvider/master/provider-fips.conf;name=provider_fips_conf \ + " + +# SHA256 checksums for the config files +SRC_URI[provider_conf.sha256sum] = "3ad9e7cf5aefb9d36b9482232365094f42390f3ef03778fa84c3efb39d48e4c2" +SRC_URI[provider_fips_conf.sha256sum] = "0b2174ab296aefa9a3f1fe40ccf0b988b25d09188ae5abad27fb60923754e98f" + +S = "${WORKDIR}" + +inherit pkgconfig + +do_compile() { + ${CC} ${WORKDIR}/wolfproviderenv.c -o wolfproviderverify \ + ${CFLAGS} ${LDFLAGS} $(pkg-config --cflags --libs openssl) -ldl -lwolfssl -lwolfprov +} + +do_install() { + install -d ${D}${bindir} + install -m 0755 ${WORKDIR}/wolfproviderverify ${D}${bindir}/wolfproviderverify + install -m 0755 ${WORKDIR}/wolfproviderenv.sh ${D}${bindir}/wolfproviderenv +} + +python __anonymous() { + wolfssl_varSet(d, 'FILES', '${PN}', '${bindir}/wolfproviderverify ${bindir}/wolfproviderenv') + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' bash') +} diff --git a/recipes-examples/wolfprovider/wolfprovidertest/files/wolfproviderenv.sh b/recipes-examples/wolfprovider/wolfprovidertest/files/wolfproviderenv.sh deleted file mode 100644 index b0624029..00000000 --- a/recipes-examples/wolfprovider/wolfprovidertest/files/wolfproviderenv.sh +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/bash - -# Setup for libwolfprov.so -mkdir -p /usr/lib/ssl-3/modules -if [ ! -L /usr/lib/ssl-3/modules/libwolfprov.so ]; then - ln -s /usr/lib/libwolfprov.so.0.0.0 /usr/lib/ssl-3/modules/libwolfprov.so -fi - -# Environment variables -export OPENSSL_MODULES=/usr/lib/ssl-3/modules -export LD_LIBRARY_PATH=/usr/lib:/lib:$LD_LIBRARY_PATH - -# Configuration for wolfprovider -mkdir -p /opt/wolfprovider-configs -cat > /opt/wolfprovider-configs/wolfprovider.conf </dev/null || true + + # Verify certificates are installed (CERTS_DIR is compiled to point here) + echo "Verifying test certificates..." + if [ -d /usr/share/wolfprovider-test/certs ]; then + echo "Certificates found at /usr/share/wolfprovider-test/certs:" + ls -la /usr/share/wolfprovider-test/certs/ + else + echo "Warning: Certificate directory not found at /usr/share/wolfprovider-test/certs" + fi + echo "" + + # Run the test from /tmp where .libs is available + # CERTS_DIR is compiled to point to /usr/share/wolfprovider-test/certs + ( + cd /tmp + echo "Running unit tests from: $(pwd)" + echo "Checking for .libs directory:" + ls -la .libs/ 2>/dev/null || echo "ERROR: .libs directory not found!" + echo "" + unit.test + ) + TEST_RESULT=$? + + echo "" + echo "==========================================" + if [ $TEST_RESULT -eq 0 ]; then + echo "✓ Unit tests PASSED!" + else + echo "✗ Unit tests FAILED! (exit code: $TEST_RESULT)" + exit $TEST_RESULT + fi +else + echo "Unit test binary not found at /usr/bin/unit.test" + exit 1 +fi + +echo "==========================================" diff --git a/recipes-examples/wolfprovider/wolfprovidertest/wolfprovider_%.bbappend b/recipes-examples/wolfprovider/wolfprovidertest/wolfprovider_%.bbappend new file mode 100644 index 00000000..c73dd811 --- /dev/null +++ b/recipes-examples/wolfprovider/wolfprovidertest/wolfprovider_%.bbappend @@ -0,0 +1,14 @@ +# Conditionally configure wolfProvider with unit tests +# +# This bbappend automatically enables wolfProvider unit tests when +# wolfprovidertest is in IMAGE_INSTALL or WOLFSSL_FEATURES + +inherit wolfssl-helper + +python __anonymous() { + wolfssl_conditional_require( + d, + package_name='wolfprovidertest', + inc_path='inc/wolfprovider/wolfprovider-enable-unittest.inc' + ) +} diff --git a/recipes-examples/wolfprovider/wolfprovidertest/wolfprovidertest.bb b/recipes-examples/wolfprovider/wolfprovidertest/wolfprovidertest.bb index 76fd6789..ed17f9e3 100644 --- a/recipes-examples/wolfprovider/wolfprovidertest/wolfprovidertest.bb +++ b/recipes-examples/wolfprovider/wolfprovidertest/wolfprovidertest.bb @@ -1,46 +1,32 @@ -SUMMARY = "Test program for custom OpenSSL provider 'libwolfprov'" -DESCRIPTION = "Compiles and runs a test program to verify the functionality of the custom OpenSSL provider libwolfprov." +SUMMARY = "wolfProvider Unit Test Application" +DESCRIPTION = "wolfProvider unit test application used to test provider functionality" HOMEPAGE = "https://www.wolfssl.com" -SECTION = "examples" -LICENSE = "CLOSED" -LIC_FILES_CHKSUM = "" +BUGTRACKER = "https://github.com/wolfssl/wolfprovider/issues" +SECTION = "x11/applications" -DEPENDS = "openssl pkgconfig-native wolfssl wolfprovider" -PROVIDES += "wolfprovidertest" -RPROVIDES_${PN} = "wolfprovidertest" +LICENSE = "GPL-3.0-only" +LIC_FILES_CHKSUM = "file://${COREBASE}/meta/files/common-licenses/GPL-3.0-only;md5=c79ff39f19dfec6d293b95dea7b07891" +DEPENDS += "wolfprovider" +inherit wolfssl-compatibility -SRC_URI = "file://wolfprovidertest.c \ - file://wolfproviderenv.sh \ - " +do_configure[noexec] = "1" +do_compile[noexec] = "1" -S = "${WORKDIR}" +WOLFPROVIDER_TEST_DIR = "${datadir}/wolfprovider-test" +WOLFPROVIDER_TEST_INSTALL_DIR = "${D}${WOLFPROVIDER_TEST_DIR}" +WOLFPROVIDER_TEST_README = "README.txt" +WOLFPROVIDER_TEST_README_DIR = "${WOLFPROVIDER_TEST_INSTALL_DIR}/${WOLFPROVIDER_TEST_README}" -inherit pkgconfig - -do_compile() { - ${CC} ${WORKDIR}/wolfprovidertest.c -o wolfprovidertest \ - ${CFLAGS} ${LDFLAGS} $(pkg-config --cflags --libs openssl) -ldl -lwolfssl -lwolfprov -} - -do_install() { - install -d ${D}${bindir} - install -m 0755 ${WORKDIR}/wolfprovidertest ${D}${bindir}/wolfprovidertest - install -m 0755 ${WORKDIR}/wolfproviderenv.sh ${D}${bindir}/wolfproviderenv +do_install_wolfprovidertest_dummy() { + bbnote "Installing dummy file for wolfProvider test example" + install -m 0755 -d "${WOLFPROVIDER_TEST_INSTALL_DIR}" + echo "This is a dummy package" > "${WOLFPROVIDER_TEST_README_DIR}" } -FILES_${PN} += "${bindir}/wolfprovidertest \ - ${bindir}/wolfproviderenv \ - " - -# Dynamic RDEPENDS adjustment for bash -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - pn = d.getVar('PN', True) - - rdepends_var_name = 'RDEPENDS_' + pn if (distro_version.startswith('2.') or distro_version.startswith('3.')) else 'RDEPENDS:' + pn +addtask do_install_wolfprovidertest_dummy after do_install before do_package +do_install_wolfprovidertest_dummy[fakeroot] = "1" - current_rdepends = d.getVar(rdepends_var_name, True) or "" - new_rdepends = current_rdepends + " bash" - d.setVar(rdepends_var_name, new_rdepends) +python __anonymous() { + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${WOLFPROVIDER_TEST_DIR}/*') } diff --git a/recipes-examples/wolfssl-py/wolf-py-tests/wolf-py-tests_5.6.0.bb b/recipes-examples/wolfssl-py/wolf-py-tests/wolf-py-tests_5.6.0.bb index 79c2ee1b..58a2d460 100644 --- a/recipes-examples/wolfssl-py/wolf-py-tests/wolf-py-tests_5.6.0.bb +++ b/recipes-examples/wolfssl-py/wolf-py-tests/wolf-py-tests_5.6.0.bb @@ -15,7 +15,9 @@ SRC_URI = "git://github.com/wolfSSL/wolfssl-py.git;nobranch=1;protocol=https;rev DEPENDS += " wolfssl-py \ wolfcrypt-py \ - " + " + +inherit wolfssl-compatibility S = "${WORKDIR}/git" @@ -27,26 +29,15 @@ WOLFCRYPT_TEST_PY_INSTALL_DIR = "${D}${WOLFCRYPT_TEST_PY_DIR}" WOLFCRYPT_TEST_PY_README = "README.txt" WOLFCRYPT_TEST_PY_README_DIR = "${WOLFCRYPT_TEST_PY_INSTALL_DIR}/${WOLFCRYPT_TEST_PY_README}" -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfcrypt_test_py_dir = d.getVar('WOLFCRYPT_TEST_PY_DIR', True) - wolfcrypt_test_py_install_dir = d.getVar('WOLFCRYPT_TEST_PY_INSTALL_DIR', True) - wolfcrypt_test_py_readme_dir = d.getVar('WOLFCRYPT_TEST_PY_README_DIR', True) - - bb.note("Installing dummy file for wolfCrypt test example") - installDir = 'install -m 0755 -d "%s"\n' % wolfcrypt_test_py_install_dir - makeDummy = 'echo "This is a dummy package" > "%s"\n' % wolfcrypt_test_py_readme_dir - - d.appendVar('do_install', installDir) - d.appendVar('do_install', makeDummy) - - pn = d.getVar('PN', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn - - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfcrypt_test_py_dir + '/*' - d.setVar(files_var_name, new_files) +do_install_wolf_py_tests_dummy() { + bbnote "Installing dummy file for wolfCrypt test example" + install -m 0755 -d "${WOLFCRYPT_TEST_PY_INSTALL_DIR}" + echo "This is a dummy package" > "${WOLFCRYPT_TEST_PY_README_DIR}" +} + +addtask do_install_wolf_py_tests_dummy after do_install before do_package +do_install_wolf_py_tests_dummy[fakeroot] = "1" + +python __anonymous() { + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${WOLFCRYPT_TEST_PY_DIR}/*') } diff --git a/recipes-examples/wolfssl-py/wolf-py-tests/wolfcrypt-py_%.bbappend b/recipes-examples/wolfssl-py/wolf-py-tests/wolfcrypt-py_%.bbappend index c1bf0150..988ace66 100644 --- a/recipes-examples/wolfssl-py/wolf-py-tests/wolfcrypt-py_%.bbappend +++ b/recipes-examples/wolfssl-py/wolf-py-tests/wolfcrypt-py_%.bbappend @@ -1,32 +1,17 @@ -WOLFCRYPT_PY_TEST_DIR = "${S}" -WOLFCRYPT_PY_DIR = "/home/root/wolf-py-tests/wolfcrypt-py-test" -WOLFCRYPT_PY_TEST_TARGET_DIR = "${D}${WOLFCRYPT_PY_DIR}" +# Conditionally enable test directory installation for wolfcrypt-py +# +# This bbappend automatically enables test installation when: +# 1. 'wolf-py-tests' is in IMAGE_INSTALL, OR +# 2. 'wolf-py-tests' is in WOLFSSL_FEATURES +# +# Usage in local.conf: +# IMAGE_INSTALL:append = " wolf-py-tests" +# OR +# WOLFSSL_FEATURES = "wolf-py-tests" -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfcrypt_py_test_dir = d.getVar('WOLFCRYPT_PY_TEST_DIR', True) - wolfcrypt_py_test_target_dir = d.getVar('WOLFCRYPT_PY_TEST_TARGET_DIR', True) +inherit wolfssl-helper - bb.note("Installing Certs Directory for wolf-py Tests") - installDirCmd = 'install -m 0755 -d "%s"\n' % wolfcrypt_py_test_target_dir - cpWolfcryptPyTestCmd = 'cp -r %s/* %s\n' % (wolfcrypt_py_test_dir, wolfcrypt_py_test_target_dir) - - d.appendVar('do_install', installDirCmd) - d.appendVar('do_install', cpWolfcryptPyTestCmd) - - - pn = d.getVar('PN', True) - wolfcrypt_py_dir = d.getVar('WOLFCRYPT_PY_DIR', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn - - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfcrypt_py_dir + '/*' - d.setVar(files_var_name, new_files) +python __anonymous() { + wolfssl_conditional_require(d, 'wolf-py-tests', 'inc/wolf-py-tests/wolfcrypt-py-enable-tests.inc') } -# Python Specific option -export PYTHONDONTWRITEBYTECODE = "1" - diff --git a/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl-py_%.bbappend b/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl-py_%.bbappend index 1ac4fb77..d3071a29 100644 --- a/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl-py_%.bbappend +++ b/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl-py_%.bbappend @@ -1,34 +1,16 @@ -WOLFSSL_PY_TEST_DIR = "${S}" -WOLFSSL_PY_DIR = "/home/root/wolf-py-tests/wolfssl-py-test" -WOLFSSL_PY_TEST_TARGET_DIR = "${D}${WOLFSSL_PY_DIR}" +# Conditionally enable test directory installation for wolfssl-py +# +# This bbappend automatically enables test installation when: +# 1. 'wolf-py-tests' is in IMAGE_INSTALL, OR +# 2. 'wolf-py-tests' is in WOLFSSL_FEATURES +# +# Usage in local.conf: +# IMAGE_INSTALL:append = " wolf-py-tests" +# OR +# WOLFSSL_FEATURES = "wolf-py-tests" -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfssl_py_test_dir = d.getVar('WOLFSSL_PY_TEST_DIR', True) - wolfssl_py_test_target_dir = d.getVar('WOLFSSL_PY_TEST_TARGET_DIR', True) +inherit wolfssl-helper - bb.note("Installing Certs Directory for wolf-py Tests") - installDir = 'install -m 0755 -d "%s"\n' % (wolfssl_py_test_target_dir) - cpWolfsslPyTest = 'cp -r %s/* %s\n' % (wolfssl_py_test_dir, wolfssl_py_test_target_dir) - - d.appendVar('do_install', installDir) - d.appendVar('do_install', cpWolfsslPyTest) - - # Append to FILES:${PN} within the Python function - files_var = 'FILES:' + d.getVar('PN', True) - wolfssl_py_test_files = wolfssl_py_test_target_dir + '/*' - - pn = d.getVar('PN', True) - wolfssl_py_dir = d.getVar('WOLFSSL_PY_DIR', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn - - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfssl_py_dir + '/*' - d.setVar(files_var_name, new_files) -} - -# Python Specific option -export PYTHONDONTWRITEBYTECODE = "1" +python __anonymous() { + wolfssl_conditional_require(d, 'wolf-py-tests', 'inc/wolf-py-tests/wolfssl-py-enable-tests.inc') +} diff --git a/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl_%.bbappend b/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl_%.bbappend index 8b18e5e8..7ebb7a01 100644 --- a/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl_%.bbappend +++ b/recipes-examples/wolfssl-py/wolf-py-tests/wolfssl_%.bbappend @@ -1,32 +1,9 @@ -WOLFSSL_PY_TEST_CERTS_DIR = "/home/root/wolf-py-tests/certs" -WOLFSSL_PY_CERTS_DIR = "/certs" -WOLFSSL_PY_CERTS_INSTALL_DIR = "${D}${WOLFSSL_PY_TEST_CERTS_DIR}" -WOLFSSL_PY_CERTS_SOURCE_DIR = "${S}${WOLFSSL_PY_CERTS_DIR}" +# Conditionally configure wolfssl with wolf-py-tests support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wolfssl_py_certs_install_dir = d.getVar('WOLFSSL_PY_CERTS_INSTALL_DIR', True) - wolfssl_py_certs_source_dir = d.getVar('WOLFSSL_PY_CERTS_SOURCE_DIR', True) +inherit wolfssl-helper +deltask do_wolfssl_check_package - bbnote = 'bbnote "Installing Certs Directory for wolf-py Tests"\n' - installDir = 'install -m 0755 -d "%s"\n' % (wolfssl_py_certs_install_dir) - cpDer = 'cp -r %s/*.der %s\n' % (wolfssl_py_certs_source_dir, wolfssl_py_certs_install_dir) - cpPem = 'cp -r %s/*.pem %s\n' % (wolfssl_py_certs_source_dir, wolfssl_py_certs_install_dir) - - d.appendVar('do_install', bbnote) - d.appendVar('do_install', installDir) - d.appendVar('do_install', cpDer) - d.appendVar('do_install', cpPem) - - - pn = d.getVar('PN', True) - wolfssl_py_test_certs_dir = d.getVar('WOLFSSL_PY_TEST_CERTS_DIR', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn - - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wolfssl_py_test_certs_dir + '/*' - d.setVar(files_var_name, new_files) +python __anonymous() { + wolfssl_conditional_require(d, 'wolf-py-tests', 'inc/wolf-py-tests/wolfssl-enable-wolf-py-tests.inc') } diff --git a/recipes-examples/wolftpm/wolfssl_%.bbappend b/recipes-examples/wolftpm/wolfssl_%.bbappend index 7562ce5d..2da39827 100644 --- a/recipes-examples/wolftpm/wolfssl_%.bbappend +++ b/recipes-examples/wolftpm/wolfssl_%.bbappend @@ -1,4 +1,9 @@ -# wolfssl_%.bbappend +# Conditionally configure wolfssl with wolftpm-wrap-test support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables -# Enables wolfTPM support in wolfSSL -EXTRA_OECONF += "--enable-wolftpm" +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolftpm-wrap-test', 'inc/wolftpm-tests/wolfssl-enable-wolftpm-wrap-test.inc') +} diff --git a/recipes-examples/wolftpm/wolftpm-wrap-test.bb b/recipes-examples/wolftpm/wolftpm-wrap-test.bb index 0b58dc34..b9ca98fd 100644 --- a/recipes-examples/wolftpm/wolftpm-wrap-test.bb +++ b/recipes-examples/wolftpm/wolftpm-wrap-test.bb @@ -9,7 +9,13 @@ SECTION = "libs" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263" S = "${WORKDIR}/git" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" + +inherit wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolftpm wolfssl') +} SRC_URI = "git://github.com/wolfssl/wolfTPM.git;nobranch=1;protocol=https;rev=bcf2647ebcf76e76a75cefc46f7187d213eb1fcd" @@ -21,26 +27,15 @@ WOLFTPM_EXAMPLES_INSTALL_DIR = "${D}${WOLFTPM_EXAMPLES_DIR}" WOLFTPM_EXAMPLES_README = "README.txt" WOLFTPM_EXAMPLES_README_DIR = "${WOLFTPM_EXAMPLES_INSTALL_DIR}/${WOLFTPM_EXAMPLES_README}" -python () { - distro_version = d.getVar('DISTRO_VERSION', True) - wofltpm_examples_dir = d.getVar('WOLFTPM_EXAMPLES_DIR', True) - wolftpm_examples_install_dir = d.getVar('WOLFTPM_EXAMPLES_INSTALL_DIR', True) - wolftpm_examples_readme_dir = d.getVar('WOLFTPM_EXAMPLES_README_DIR', True) - - bb.note("Installing dummy file for wolfTPM test example") - installDir = 'install -m 0755 -d "%s"\n' % wolftpm_examples_install_dir - makeDummy = 'echo "This is a dummy package" > "%s"\n' % wolftpm_examples_readme_dir - - d.appendVar('do_install', installDir) - d.appendVar('do_install', makeDummy) +do_install_wolftpm_dummy() { + bbnote "Installing dummy file for wolfTPM test example" + install -m 0755 -d "${WOLFTPM_EXAMPLES_INSTALL_DIR}" + echo "This is a dummy package" > "${WOLFTPM_EXAMPLES_README_DIR}" +} - pn = d.getVar('PN', True) - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - files_var_name = 'FILES_' + pn - else: - files_var_name = 'FILES:' + pn +addtask do_install_wolftpm_dummy after do_install before do_package +do_install_wolftpm_dummy[fakeroot] = "1" - current_files = d.getVar(files_var_name, True) or "" - new_files = current_files + ' ' + wofltpm_examples_dir + '/*' - d.setVar(files_var_name, new_files) +python __anonymous() { + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${WOLFTPM_EXAMPLES_DIR}/*') } diff --git a/recipes-examples/wolftpm/wolftpm_%.bbappend b/recipes-examples/wolftpm/wolftpm_%.bbappend index 114596e5..5d69bd12 100644 --- a/recipes-examples/wolftpm/wolftpm_%.bbappend +++ b/recipes-examples/wolftpm/wolftpm_%.bbappend @@ -1,26 +1,16 @@ -#wolftpm_%.bbappend -WOLFTPM_TEST_DIR = "${B}/examples/wrap/.libs" -WOLFTPM_TEST = "wrap_test" -WOLFTPM_TEST_YOCTO = "wolftpm-wrap-test" -WOLFTPM_INSTALL_DIR = "${D}${bindir}" +# Conditionally enable wrap_test installation for wolfTPM +# +# This bbappend automatically enables wrap_test when: +# 1. 'wolftpm-wrap-test' is in IMAGE_INSTALL, OR +# 2. 'wolftpm-wrap-test' is in WOLFSSL_FEATURES +# +# Usage in local.conf: +# IMAGE_INSTALL:append = " wolftpm-wrap-test" +# OR +# WOLFSSL_FEATURES = "wolftpm-wrap-test" -# Configurations (--enable-devtpm is required for the TPM simulator to work) -EXTRA_OECONF += "--enable-devtpm" +inherit wolfssl-helper -python () { - # Get the environment variables WOLFTPM_TEST_DIR, WOLFTPM_TEST, - # WOLFTPM_TEST_YOCTO, and WOLFTPM_INSTALL_DIR - wolftpm_test_dir = d.getVar('WOLFTPM_TEST_DIR', True) - wolftpm_test = d.getVar('WOLFTPM_TEST', True) - wolftpm_test_yocto = d.getVar('WOLFTPM_TEST_YOCTO', True) - wolftpm_install_dir = d.getVar('WOLFTPM_INSTALL_DIR', True) - - bbnote = 'bbnote "Installing wolfTPM wrap_test"\n' - installDir = 'install -m 0755 -d "%s"\n' % (wolftpm_install_dir) - cpWrapTest = 'cp "%s/%s" "%s/%s"\n' % (wolftpm_test_dir, wolftpm_test, - wolftpm_install_dir, wolftpm_test_yocto) - - d.appendVar('do_install', bbnote) - d.appendVar('do_install', installDir) - d.appendVar('do_install', cpWrapTest) +python __anonymous() { + wolfssl_conditional_require(d, 'wolftpm-wrap-test', 'inc/wolftpm-tests/wolftpm-enable-wrap-test.inc') } diff --git a/recipes-extended/rsyslog/files/rsyslog-fips-crypto.conf b/recipes-extended/rsyslog/files/rsyslog-fips-crypto.conf new file mode 100644 index 00000000..e69de29b diff --git a/recipes-extended/rsyslog/rsyslog_8.2106.0.bbappend b/recipes-extended/rsyslog/rsyslog_8.2106.0.bbappend index 2afd89ae..9d22f914 100644 --- a/recipes-extended/rsyslog/rsyslog_8.2106.0.bbappend +++ b/recipes-extended/rsyslog/rsyslog_8.2106.0.bbappend @@ -1,5 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://rsyslog-8.2106.0.patch" PACKAGECONFIG_remove = "gnutls libgcrypt" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-protocols/net-snmp/net-snmp_5.9.bbappend b/recipes-protocols/net-snmp/net-snmp_5.9.bbappend index 41744f1b..0b7691d8 100644 --- a/recipes-protocols/net-snmp/net-snmp_5.9.bbappend +++ b/recipes-protocols/net-snmp/net-snmp_5.9.bbappend @@ -1,5 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://net-snmp-5.9.patch" DEPENDS_remove = "openssl" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-support/curl/curl_7.82.0.bbappend b/recipes-support/curl/curl_7.82.0.bbappend index 61f8ee5b..46be3e7d 100644 --- a/recipes-support/curl/curl_7.82.0.bbappend +++ b/recipes-support/curl/curl_7.82.0.bbappend @@ -1,5 +1,5 @@ PACKAGECONFIG_remove = "openssl" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_DIR_HOST}${prefix}" CPPFLAGS += "-I${STAGING_DIR_HOST}${prefix}/include/wolfssl" diff --git a/recipes-support/curl/kirkstone/curl_7.82.0.bbappend b/recipes-support/curl/kirkstone/curl_7.82.0.bbappend index 954b793e..aab81635 100644 --- a/recipes-support/curl/kirkstone/curl_7.82.0.bbappend +++ b/recipes-support/curl/kirkstone/curl_7.82.0.bbappend @@ -1,15 +1,19 @@ -PACKAGECONFIG:remove:class-target = "openssl" -DEPENDS:class-target += "wolfssl" -EXTRA_OECONF:class-target += "--with-wolfssl=${STAGING_DIR_HOST}${prefix} \ +inherit wolfssl-compatibility + +PACKAGECONFIG_remove_class-target = "openssl" +DEPENDS_class-target += "virtual/wolfssl" +EXTRA_OECONF_class-target += "--with-wolfssl=${STAGING_DIR_HOST}${prefix} \ --with-ca-bundle=${sysconfdir}/ssl/certs/ca-certificates.crt \ " -CPPFLAGS:class-target += "-I${STAGING_DIR_HOST}${prefix}/include/wolfssl" +CPPFLAGS_class-target += "-I${STAGING_DIR_HOST}${prefix}/include/wolfssl" # Uncomment the line below if you're targeting FIPS compliance. NTLM uses MD5, # which isn't a FIPS-approved algorithm. -# EXTRA_OECONF:class-target += "--disable-ntlm" - -# Add the directory where the patch is located to the search path -FILESEXTRAPATHS:prepend := "${THISDIR}/../patches:" +# EXTRA_OECONF_class-target += "--disable-ntlm" -SRC_URI += "file://wolfssl-m4-options-fix.patch" \ No newline at end of file +python __anonymous() { + if bb.data.inherits_class('target', d): + # Add the directory where the patch is located to the search path + wolfssl_varPrepend(d, 'FILESEXTRAPATHS', '${THISDIR}/../patches:') + wolfssl_varAppendNonOverride(d, 'SRC_URI', ' file://wolfssl-m4-options-fix.patch') +} diff --git a/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb b/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb new file mode 100644 index 00000000..34c72679 --- /dev/null +++ b/recipes-support/gnutls/wolfssl-gnutls-wrapper_git.bb @@ -0,0 +1,161 @@ +SUMMARY = "wolfSSL GnuTLS Crypto Wrapper Library" +DESCRIPTION = "Cryptography wrapper library that registers as a GnuTLS crypto \ +provider and delegates cryptographic operations to wolfSSL." +HOMEPAGE = "https://github.com/wolfssl/gnutls-wolfssl" +SECTION = "libs" +LICENSE = "GPL-3.0-only" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6" + +PV = "1.0+git${SRCPV}" + +DEPENDS = "virtual/wolfssl gnutls" + +inherit pkgconfig wolfssl-compatibility + +python __anonymous() { + wolfssl_varSet(d, 'RDEPENDS', '${PN}', 'wolfssl gnutls bash') +} + +SRC_URI = "git://github.com/wolfssl/gnutls-wolfssl.git;protocol=https;branch=main;destsuffix=git" +SRCREV = "${AUTOREV}" + +S = "${WORKDIR}/git/wolfssl-gnutls-wrapper" + +# Custom installation prefix +WOLFSSL_GNUTLS_PREFIX = "/opt/wolfssl-gnutls-wrapper" + +inherit pkgconfig + +EXTRA_OEMAKE = " \ + 'CC=${CC}' \ + 'GNUTLS_INSTALL=${STAGING_DIR_TARGET}${prefix}' \ + 'WOLFSSL_INSTALL=${STAGING_DIR_TARGET}${prefix}' \ +" + +python __anonymous() { + wolfssl_varAppendNonOverride(d, 'CFLAGS', ' -I${STAGING_INCDIR} -DENABLE_WOLFSSL -fPIC') + wolfssl_varAppendNonOverride(d, 'LDFLAGS', ' -L${STAGING_LIBDIR} -Wl,-rpath,${libdir} -Wl,-rpath,${WOLFSSL_GNUTLS_PREFIX}/lib -Wl,--no-as-needed -Wl,-z,now') +} + +do_compile() { + bbnote "Building wolfSSL-GnuTLS wrapper..." + + # Compiling the wrapper + oe_runmake \ + CC="${CC}" \ + CFLAGS="${CFLAGS}" \ + LDFLAGS="${LDFLAGS}" \ + GNUTLS_INSTALL="${STAGING_DIR_TARGET}${prefix}" \ + WOLFSSL_INSTALL="${STAGING_DIR_TARGET}${prefix}" \ + all + + bbnote "Building GnuTLS-wolfSSL tests..." + + # Compiling tests + cd ${S}/tests + oe_runmake \ + CC="${CC}" \ + CFLAGS="${CFLAGS}" \ + LDFLAGS="${LDFLAGS}" \ + GNUTLS_INSTALL="${STAGING_DIR_TARGET}${prefix}" \ + WOLFSSL_INSTALL="${STAGING_DIR_TARGET}${prefix}" \ + PROVIDER_PATH="${WOLFSSL_GNUTLS_PREFIX}" \ + all +} + +do_install() { + # Install to /usr/lib/gnutls + install -d ${D}${libdir} + if [ -f ${S}/libgnutls-wolfssl-wrapper.so ]; then + install -m 0755 ${S}/libgnutls-wolfssl-wrapper.so ${D}${libdir} + bbnote "Installed wrapper to ${D}${libdir}" + else + bbwarn "Wrapper library not found" + ls -la ${S}/ || true + fi + + # Install headers if they exist + if [ -d ${S}/include ]; then + install -d ${D}${includedir}/gnutls-wolfssl-wrapper + install -m 0644 ${S}/include/*.h ${D}${includedir}/gnutls-wolfssl-wrapper/ || true + fi + + # Install pkg-config file if it exists + if [ -f ${S}/gnutls-wolfssl-wrapper.pc ]; then + install -d ${D}${libdir}/pkgconfig + install -m 0644 ${S}/gnutls-wolfssl-wrapper.pc ${D}${libdir}/pkgconfig/ + fi + + # Create compatibility symlinks for hardcoded /opt paths + install -d ${D}/opt/wolfssl-gnutls-wrapper/lib + ln -sf ${libdir}/libgnutls-wolfssl-wrapper.so \ + ${D}/opt/wolfssl-gnutls-wrapper/lib/libgnutls-wolfssl-wrapper.so + + # Install tests to /opt/wolfssl-gnutls-wrapper/tests + bbnote "Installing GnuTLS-wolfSSL tests..." + install -d ${D}${WOLFSSL_GNUTLS_PREFIX}/tests + + # Install Makefile + install -m 0644 ${S}/tests/Makefile ${D}${WOLFSSL_GNUTLS_PREFIX}/tests/ + + # Install test utility header + if [ -f ${S}/tests/test_util.h ]; then + install -m 0644 ${S}/tests/test_util.h ${D}${WOLFSSL_GNUTLS_PREFIX}/tests/ + fi + + # Install all test executables + for test in ${S}/tests/test_*; do + if [ -f "$test" ] && [ -x "$test" ]; then + install -m 0755 "$test" ${D}${WOLFSSL_GNUTLS_PREFIX}/tests/ + fi + done + + # Install any additional test files + if [ -f ${S}/tests/run ]; then + install -m 0755 ${S}/tests/run ${D}${WOLFSSL_GNUTLS_PREFIX}/tests/ + fi + + # Create a helper script to run tests with proper environment + cat > ${D}${WOLFSSL_GNUTLS_PREFIX}/tests/run-tests.sh << 'EOF' +#!/bin/bash +# Helper script to run GnuTLS-wolfSSL tests with proper environment + +export LD_LIBRARY_PATH=/usr/lib:/opt/wolfssl-gnutls-wrapper/lib:$LD_LIBRARY_PATH +export LD_PRELOAD=/opt/wolfssl-gnutls-wrapper/lib/libgnutls-wolfssl-wrapper.so +export GNUTLS_DEBUG_LEVEL=3 + +# Optional: Enable FIPS mode +# export GNUTLS_FORCE_FIPS_MODE=1 + +echo "=== GnuTLS-wolfSSL Test Environment ===" +echo "LD_LIBRARY_PATH: $LD_LIBRARY_PATH" +echo "LD_PRELOAD: $LD_PRELOAD" +echo "Test directory: /opt/wolfssl-gnutls-wrapper/tests" +echo "" + +cd /opt/wolfssl-gnutls-wrapper/tests + +if [ $# -eq 0 ]; then + echo "Running all tests..." + make run +else + echo "Running specific test: $1" + ./"$1" +fi +EOF + + chmod 755 ${D}${WOLFSSL_GNUTLS_PREFIX}/tests/run-tests.sh + + # Create a convenience symlink in /usr/bin + install -d ${D}${bindir} + ln -sf ${WOLFSSL_GNUTLS_PREFIX}/tests/run-tests.sh ${D}${bindir}/gnutls-wolfssl-tests +} + +python __anonymous() { + wolfssl_varSet(d, 'FILES', '${PN}', '${libdir}/*.so /opt/wolfssl-gnutls-wrapper/lib/*.so ${WOLFSSL_GNUTLS_PREFIX}/tests/* ${bindir}/gnutls-wolfssl-tests') + wolfssl_varSet(d, 'FILES', '${PN}-dev', '${includedir}/* ${libdir}/pkgconfig/*') + wolfssl_varAppend(d, 'INSANE_SKIP', '${PN}', ' dev-so ldflags') +} + +SOLIBS = ".so" +FILES_SOLIBSDEV = "" diff --git a/recipes-support/libgcrypt/README.md b/recipes-support/libgcrypt/README.md new file mode 100644 index 00000000..ec8292cc --- /dev/null +++ b/recipes-support/libgcrypt/README.md @@ -0,0 +1,99 @@ +# libgcrypt with wolfSSL Backend + +This directory provides integration for running libgcrypt with wolfSSL/wolfCrypt as the cryptographic backend, enabling FIPS-validated cryptography through libgcrypt's standard API. + +## Overview + +libgcrypt is a general-purpose cryptographic library used by many Linux applications (GnuPG, systemd, etc.). By configuring it to use wolfSSL's FIPS-validated wolfCrypt as the backend, you can provide FIPS 140-3 validated cryptography to all applications using libgcrypt. + +## Files + +### `libgcrypt_%.bbappend` +Conditionally enables wolfSSL backend when: +- `libgcrypt` is in `WOLFSSL_FEATURES`, AND +- `wolfssl-fips` is the `PREFERRED_PROVIDER` + +Uses the `wolfssl-osp-support` class for conditional configuration. + +### `wolfssl-fips.bbappend` +Configures wolfssl-fips with additional features needed by libgcrypt when `libgcrypt` is in `WOLFSSL_FEATURES`. + +## Configuration Files + +### `inc/libgcrypt/libgcrypt-enable-wolfssl.inc` +Configures libgcrypt to use the wolfSSL-enabled fork: +- Changes source to `github.com/wolfSSL/libgcrypt-wolfssl` +- Updates to version 1.11.0 +- Adds wolfSSL dependencies +- Configures with `--enable-wolfssl-fips` + +### `inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc` +Configures wolfssl-fips with features required by libgcrypt: +- `--enable-fips=v5` - FIPS 140-3 validation +- `--enable-keygen` - Key generation support +- Additional compile flags for libgcrypt compatibility + +## Usage + +### Method 1: Using WOLFSSL_FEATURES (Recommended) + +```bitbake +# In build/conf/local.conf +WOLFSSL_FEATURES = "libgcrypt" +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf + +# Add to your image +IMAGE_INSTALL:append = " libgcrypt" +``` + +### Method 2: Using Demo Image + +```bitbake +# In build/conf/local.conf +WOLFSSL_DEMOS = "wolfssl-image-minimal libgcrypt-image-minimal" +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf + +# Build the demo image +bitbake libgcrypt-image-minimal +``` + +## Testing + +The demo image includes ptest support: + +```bash +# In QEMU +ptest-runner libgcrypt +``` + +This runs the libgcrypt test suite to verify the wolfSSL backend is working correctly. + +## Requirements + +- **wolfssl-fips**: This integration only works with wolfSSL FIPS builds +- **FIPS Bundle**: You must have a valid wolfSSL FIPS commercial bundle +- **libgcrypt 1.11.0+**: The wolfSSL fork is based on libgcrypt 1.11.0 + +## Architecture + +``` +┌─────────────────────────────────┐ +│ Applications (GnuPG, systemd) │ +└───────────────┬─────────────────┘ + │ libgcrypt API +┌───────────────▼─────────────────┐ +│ libgcrypt 1.11.0 │ +│ (wolfSSL-enabled fork) │ +└───────────────┬─────────────────┘ + │ wolfCrypt API +┌───────────────▼─────────────────┐ +│ wolfSSL FIPS (wolfCrypt Core) │ +│ FIPS 140-3 Validated │ +└─────────────────────────────────┘ +``` + +## More Information + +- Demo Image: [recipes-core/images/libgcrypt-image-minimal/README.md](../../recipes-core/images/libgcrypt-image-minimal/README.md) +- Main Layer README: [../../README.md](../../README.md) +- libgcrypt-wolfssl: https://github.com/wolfSSL/libgcrypt-wolfssl diff --git a/recipes-support/libgcrypt/libgcrypt_%.bbappend b/recipes-support/libgcrypt/libgcrypt_%.bbappend new file mode 100644 index 00000000..7c7b53ff --- /dev/null +++ b/recipes-support/libgcrypt/libgcrypt_%.bbappend @@ -0,0 +1,23 @@ +# Conditionally enable wolfSSL backend for libgcrypt +# +# This bbappend automatically enables wolfSSL backend when: +# 1. 'libgcrypt' is in WOLFSSL_FEATURES (explicit intent) +# 2. AND PREFERRED_PROVIDER_virtual/wolfssl is in the allowed list +# +# Usage in local.conf: +# WOLFSSL_FEATURES = "libgcrypt" +# require conf/wolfssl-fips.conf + +inherit wolfssl-osp-support + +python __anonymous() { + # libgcrypt-wolfssl currently only supports wolfssl-fips + # In the future, it may support regular wolfssl as well + wolfssl_osp_conditional_include( + d, + feature_name='libgcrypt', + inc_file='inc/libgcrypt/libgcrypt-enable-wolfssl.inc', + allowed_providers=['wolfssl-fips'] # Only FIPS supported for now + ) +} + diff --git a/recipes-support/libgcrypt/wolfssl-fips.bbappend b/recipes-support/libgcrypt/wolfssl-fips.bbappend new file mode 100644 index 00000000..945c57a1 --- /dev/null +++ b/recipes-support/libgcrypt/wolfssl-fips.bbappend @@ -0,0 +1,24 @@ +# Configure wolfssl-fips for libgcrypt integration +# +# This bbappend automatically configures wolfssl-fips with the features +# needed by libgcrypt-wolfssl when 'libgcrypt' is in WOLFSSL_FEATURES +# +# Usage in local.conf: +# WOLFSSL_FEATURES = "libgcrypt" +# require conf/wolfssl-fips.conf + +inherit wolfssl-helper + +python __anonymous() { + # Check if libgcrypt is in WOLFSSL_FEATURES + wolfssl_features = d.getVar('WOLFSSL_FEATURES') or '' + + if 'libgcrypt' in wolfssl_features.split(): + bb.note("libgcrypt in WOLFSSL_FEATURES - configuring wolfssl-fips for libgcrypt support") + # Use the helper to include the configuration + wolfssl_conditional_require(d, 'libgcrypt', 'inc/wolfssl-fips/wolfssl-enable-libgcrypt.inc') +} + +# Disable package check since this is configuration for wolfssl-fips itself +deltask do_wolfssl_check_package + diff --git a/recipes-support/libssh2/libssh2_1.9.0.bbappend b/recipes-support/libssh2/libssh2_1.9.0.bbappend index 9a77ab06..6dc3a081 100644 --- a/recipes-support/libssh2/libssh2_1.9.0.bbappend +++ b/recipes-support/libssh2/libssh2_1.9.0.bbappend @@ -1,5 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://libssh2-1.9.0.patch" PACKAGECONFIG_remove = "openssl" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-support/tcpdump/tcpdump_4.9.3.bbappend b/recipes-support/tcpdump/tcpdump_4.9.3.bbappend index a980cf3f..1bfee18c 100644 --- a/recipes-support/tcpdump/tcpdump_4.9.3.bbappend +++ b/recipes-support/tcpdump/tcpdump_4.9.3.bbappend @@ -1,5 +1,5 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://tcpdump-4.9.3.patch" PACKAGECONFIG_remove = "openssl" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" EXTRA_OECONF += "--with-wolfssl=${STAGING_EXECPREFIXDIR}" diff --git a/recipes-wolfssl/wolfclu/commercial/commercial-details/wolfclu_%.bbappend b/recipes-wolfssl/wolfclu/commercial/commercial-details/wolfclu_%.bbappend index dcabc1e8..7e0a365d 100644 --- a/recipes-wolfssl/wolfclu/commercial/commercial-details/wolfclu_%.bbappend +++ b/recipes-wolfssl/wolfclu/commercial/commercial-details/wolfclu_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFCLU_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFCLU_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFCLU_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFCLU_SRC ?= "" WOLFCLU_SRC_SHA ?= "" WOLFCLU_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfclu/commercial/wolfclu_%.bbappend b/recipes-wolfssl/wolfclu/commercial/wolfclu_%.bbappend index 0e88a178..b7191051 100644 --- a/recipes-wolfssl/wolfclu/commercial/wolfclu_%.bbappend +++ b/recipes-wolfssl/wolfclu/commercial/wolfclu_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFCLU_LICENSE};md5=${WOLFCLU_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFCLU_SRC}.7z" SRC_URI[sha256sum]="${WOLFCLU_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFCLU_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFCLU_SRC}.7z" -p"${WOLFCLU_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfclu/wolfclu_0.1.8.bb b/recipes-wolfssl/wolfclu/wolfclu_0.1.8.bb index 7c9d46b7..077f13f0 100644 --- a/recipes-wolfssl/wolfclu/wolfclu_0.1.8.bb +++ b/recipes-wolfssl/wolfclu/wolfclu_0.1.8.bb @@ -10,28 +10,21 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=b234ee4d69f5fce4486a80fdaf4a4263" PROVIDES += "wolfclu" RPROVIDES_${PN} = "wolfclu" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" SRC_URI = "git://github.com/wolfssl/wolfclu.git;nobranch=1;protocol=https;rev=439a801afb3b9050af7906479300afb29f7b72ff" S = "${WORKDIR}/git" -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility -EXTRA_OECONF = "--with-wolfssl=${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') +} -BBCLASSEXTEND += "native nativesdk" +EXTRA_OECONF = "--with-wolfssl=${STAGING_EXECPREFIXDIR}" -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = 'cd ${S}; ./autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) -} +BBCLASSEXTEND += "native nativesdk" # Add reproducible build flags export CFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' diff --git a/recipes-wolfssl/wolfclu/wolfssl_%.bbappend b/recipes-wolfssl/wolfclu/wolfssl_%.bbappend index 9aa33fb1..6d0d6a3d 100644 --- a/recipes-wolfssl/wolfclu/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfclu/wolfssl_%.bbappend @@ -1,2 +1,11 @@ -EXTRA_OECONF += "--enable-wolfclu" +# Conditionally configure wolfssl with wolfclu support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables +# Set WOLFSSL_FEATURES:append = " wolfclu" in your image recipe to enable + +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfclu', 'inc/wolfclu/wolfssl-enable-wolfclu.inc') +} diff --git a/recipes-wolfssl/wolfcrypt-py/wolfcrypt-py_5.8.2.bb b/recipes-wolfssl/wolfcrypt-py/wolfcrypt-py_5.8.2.bb index 99237f23..3ec5ded7 100644 --- a/recipes-wolfssl/wolfcrypt-py/wolfcrypt-py_5.8.2.bb +++ b/recipes-wolfssl/wolfcrypt-py/wolfcrypt-py_5.8.2.bb @@ -1,6 +1,6 @@ SUMMARY = "wolfCrypt Python, a.k.a. wolfcrypt is a Python module that \ encapsulates wolfSSL's wolfCrypt API." - + DESCRIPTION = "wolfCrypt is a lightweight, portable, C-language-based crypto \ library targeted at IoT, embedded, and RTOS environments \ primarily because of its size, speed, and feature set. It works \ @@ -21,7 +21,7 @@ SRC_URI[mlkem.sha256sum] = "eb4bc00b66d4844b6c3f3314fe1da657e232e377486ef23c9642 -DEPENDS += " wolfssl \ +DEPENDS += " virtual/wolfssl \ python3-pip-native \ python3-cffi-native \ python3-cffi \ @@ -29,14 +29,15 @@ DEPENDS += " wolfssl \ python3 \ " -inherit setuptools3 - -S = "${WORKDIR}/git" +inherit setuptools3 wolfssl-compatibility -WOLFSSL_YOCTO_DIR = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl python3 python3-cffi') +} +S = "${WORKDIR}/git" -export USE_LOCAL_WOLFSSL="${WOLFSSL_YOCTO_DIR}" +export USE_LOCAL_WOLFSSL="${STAGING_EXECPREFIXDIR}" # Add reproducible build flags CFLAGS += " -g0 -O2 -ffile-prefix-map=${WORKDIR}=." CXXFLAGS += " -g0 -O2 -ffile-prefix-map=${WORKDIR}=." @@ -45,3 +46,4 @@ LDFLAGS += " -Wl,--build-id=none" # Ensure consistent locale for build reproducibility export LC_ALL = "C" + diff --git a/recipes-wolfssl/wolfcrypt-py/wolfssl_%.bbappend b/recipes-wolfssl/wolfcrypt-py/wolfssl_%.bbappend index a87c468a..7263a7d3 100644 --- a/recipes-wolfssl/wolfcrypt-py/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfcrypt-py/wolfssl_%.bbappend @@ -1,2 +1,9 @@ -EXTRA_OECONF += " --enable-aes --enable-aesctr --enable-des3 --enable-chacha --enable-aesgcm-stream --enable-aesgcm --enable-sha --enable-sha384 --enable-sha512 --enable-sha3 --enable-hkdf --enable-rsa --enable-rsapss --enable-ecc --enable-ed25519 --enable-ed448 --enable-curve25519 --enable-keygen --enable-pwdbased --enable-pkcs7 --enable-dtls --enable-tls13 --enable-tlsx" +# Conditionally configure wolfssl with wolfcrypt-py support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfcrypt-py', 'inc/wolfcrypt-py/wolfssl-enable-wolfcrypt-py.inc') +} diff --git a/recipes-wolfssl/wolfengine/README.md b/recipes-wolfssl/wolfengine/README.md index 5e722e8a..c0ab193e 100644 --- a/recipes-wolfssl/wolfengine/README.md +++ b/recipes-wolfssl/wolfengine/README.md @@ -2,7 +2,7 @@ The `wolfengine` recipe enables the integration of wolfSSL's cryptographic functionalities into OpenSSL through a custom engine mechanism. This integration allows applications using OpenSSL to leverage wolfSSL's advanced cryptographic algorithms, combining wolfSSL's lightweight and performance-optimized cryptography with OpenSSL's extensive API and capabilities. `wolfengine` is designed for easy integration into Yocto-based systems, ensuring a seamless blend of security and performance ideal for embedded and constrained environments. -The `wolfenginetest` yocto package will provide two apps, `wolfengineenv` and `wolfenginetest`. Running `wolfengineenv` will start up a child shell and run `wolfenginetest`. Use `wolfengineenv` to test that the `wolfengine` package is succesfully installed. If you want to run `wolfenginetest` directly you will need to directly source `wolfengineenv` via `source /usr/bin/wolfengineenv` or setup the env on your own, because `wolfenginetest` will fail otherwise. Use `wolfenginetest` to check that your shell env is correctly setup. +The `wolfenginetest` yocto package will provide two apps, `wolfengineenv` and `wolfenginetest`. Running `wolfengineenv` will start up a child shell and run `wolfenginetest`. Use `wolfengineenv` to test that the `wolfengine` package is successfully installed. If you want to run `wolfenginetest` directly you will need to directly source `wolfengineenv` via `source /usr/bin/wolfengineenv` or setup the env on your own, because `wolfenginetest` will fail otherwise. Use `wolfenginetest` to check that your shell env is correctly setup. ## Getting Started diff --git a/recipes-wolfssl/wolfengine/commercial/commercial-details/wolfengine_%.bbappend b/recipes-wolfssl/wolfengine/commercial/commercial-details/wolfengine_%.bbappend index 4677e830..f19618c5 100644 --- a/recipes-wolfssl/wolfengine/commercial/commercial-details/wolfengine_%.bbappend +++ b/recipes-wolfssl/wolfengine/commercial/commercial-details/wolfengine_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFENGINE_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFENGINE_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFENGINE_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFENGINE_SRC ?= "" WOLFENGINE_SRC_SHA ?= "" WOLFENGINE_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfengine/commercial/wolfengine_%.bbappend b/recipes-wolfssl/wolfengine/commercial/wolfengine_%.bbappend index 5060dd7e..52a4905f 100644 --- a/recipes-wolfssl/wolfengine/commercial/wolfengine_%.bbappend +++ b/recipes-wolfssl/wolfengine/commercial/wolfengine_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFENGINE_LICENSE};md5=${WOLFENGINE_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFENGINE_SRC}.7z" SRC_URI[sha256sum]="${WOLFENGINE_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFENGINE_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFENGINE_SRC}.7z" -p"${WOLFENGINE_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfengine/openssl_1.%.bbappend b/recipes-wolfssl/wolfengine/openssl_1.%.bbappend index aee27f8b..ee0ed320 100644 --- a/recipes-wolfssl/wolfengine/openssl_1.%.bbappend +++ b/recipes-wolfssl/wolfengine/openssl_1.%.bbappend @@ -1 +1,9 @@ -EXTRA_OECONF += " shared " \ No newline at end of file +inherit wolfssl-helper + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfengine', 'inc/wolfengine/openssl/openssl-enable-wolfengine.inc') +} + +# OpenSSL is a dependency of wolfengine, not a direct image package +# The check above already validates wolfengine is in IMAGE_INSTALL +deltask do_wolfssl_check_package \ No newline at end of file diff --git a/recipes-wolfssl/wolfengine/wolfengine_1.4.0.bb b/recipes-wolfssl/wolfengine/wolfengine_1.4.0.bb index a55b5b2b..18cfd353 100644 --- a/recipes-wolfssl/wolfengine/wolfengine_1.4.0.bb +++ b/recipes-wolfssl/wolfengine/wolfengine_1.4.0.bb @@ -14,29 +14,17 @@ SRC_URI = "git://github.com/wolfssl/wolfengine.git;nobranch=1;protocol=https;rev S = "${WORKDIR}/git" -DEPENDS += " wolfssl \ +DEPENDS += " virtual/wolfssl \ openssl \ " -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility -OPENSSL_YOCTO_DIR = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/openssl/usr" -WOLFSSL_YOCTO_DIR = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" - - -# Approach: Use Python to dynamically set function content based on Yocto version -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = "cd ${S}; ./autogen.sh" - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl openssl') } CFLAGS += " -I${S}/include -g0 -O2 -ffile-prefix-map=${WORKDIR}=." CXXFLAGS += " -I${S}/include -g0 -O2 -ffile-prefix-map=${WORKDIR}=." LDFLAGS += " -Wl,--build-id=none" -EXTRA_OECONF += " --with-openssl=${OPENSSL_YOCTO_DIR} --with-wolfssl=${WOLFSSL_YOCTO_DIR} " \ No newline at end of file +EXTRA_OECONF += " --with-openssl=${STAGING_EXECPREFIXDIR} --with-wolfssl=${STAGING_EXECPREFIXDIR} " \ No newline at end of file diff --git a/recipes-wolfssl/wolfengine/wolfssl_%.bbappend b/recipes-wolfssl/wolfengine/wolfssl_%.bbappend index e53d1051..a22c2b73 100644 --- a/recipes-wolfssl/wolfengine/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfengine/wolfssl_%.bbappend @@ -1,13 +1,9 @@ +# Conditionally configure wolfssl with wolfengine support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables -python() { - # Get the package revision (PR) for wolfssl - wolfssl_pr = d.getVar('PR', True) +inherit wolfssl-helper +deltask do_wolfssl_check_package - # Based on the revision, conditionally append to EXTRA_OECONF - if wolfssl_pr == 'commerical.fips': - d.appendVar('EXTRA_OECONF', ' --enable-engine=fips-v5') - elif wolfssl_pr == 'fipsReady': - d.appendVar('EXTRA_OECONF', ' --enable-engine=fips-ready') - else: - d.appendVar('EXTRA_OECONF', ' --enable-engine=no-fips') +python __anonymous() { + wolfssl_conditional_require(d, 'wolfengine', 'inc/wolfengine/wolfssl-enable-wolfengine.inc') } diff --git a/recipes-wolfssl/wolfmqtt/commercial/commercial-details/wolfmqtt_%.bbappend b/recipes-wolfssl/wolfmqtt/commercial/commercial-details/wolfmqtt_%.bbappend index 86819565..8423fd71 100644 --- a/recipes-wolfssl/wolfmqtt/commercial/commercial-details/wolfmqtt_%.bbappend +++ b/recipes-wolfssl/wolfmqtt/commercial/commercial-details/wolfmqtt_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFMQTT_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFMQTT_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFMQTT_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFMQTT_SRC ?= "" WOLFMQTT_SRC_SHA ?= "" WOLFMQTT_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfmqtt/commercial/wolfmqtt_%.bbappend b/recipes-wolfssl/wolfmqtt/commercial/wolfmqtt_%.bbappend index 0366eabb..6ef8f98a 100644 --- a/recipes-wolfssl/wolfmqtt/commercial/wolfmqtt_%.bbappend +++ b/recipes-wolfssl/wolfmqtt/commercial/wolfmqtt_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFMQTT_LICENSE};md5=${WOLFMQTT_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFMQTT_SRC}.7z" SRC_URI[sha256sum]="${WOLFMQTT_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFMQTT_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFMQTT_SRC}.7z" -p"${WOLFMQTT_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfmqtt/wolfmqtt_1.20.0.bb b/recipes-wolfssl/wolfmqtt/wolfmqtt_1.20.0.bb index 684a9f2f..2bbc88cc 100644 --- a/recipes-wolfssl/wolfmqtt/wolfmqtt_1.20.0.bb +++ b/recipes-wolfssl/wolfmqtt/wolfmqtt_1.20.0.bb @@ -10,32 +10,25 @@ SECTION = "libs" LICENSE = "GPL-2.0-only" LIC_FILES_CHKSUM = "file://LICENSE;md5=2c1c00f9d3ed9e24fa69b932b7e7aff2" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" SRC_URI = "git://github.com/wolfssl/wolfMQTT.git;nobranch=1;protocol=https;rev=320ed37633f896cf2485c9c5f8bed3400ae8b4d5" S = "${WORKDIR}/git" -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility -EXTRA_OECONF = "--with-libwolfssl-prefix=${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = 'cd ${S}; ./autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') } +EXTRA_OECONF = "--with-libwolfssl-prefix=${STAGING_EXECPREFIXDIR}" + # Add reproducible build flags export CFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export CXXFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export LDFLAGS += ' -Wl,--build-id=none' -# Ensure consistent locale -export LC_ALL = "C" +# Ensure consistent locale +export LC_ALL = "C" \ No newline at end of file diff --git a/recipes-wolfssl/wolfpkcs11/commercial/commercial-details/wolfpkcs11_%.bbappend b/recipes-wolfssl/wolfpkcs11/commercial/commercial-details/wolfpkcs11_%.bbappend index 71eed664..4758f5cd 100644 --- a/recipes-wolfssl/wolfpkcs11/commercial/commercial-details/wolfpkcs11_%.bbappend +++ b/recipes-wolfssl/wolfpkcs11/commercial/commercial-details/wolfpkcs11_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFPKCS11_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFPKCS11_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFPKCS11_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFPKCS11_SRC ?= "" WOLFPKCS11_SRC_SHA ?= "" WOLFPKCS11_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfpkcs11/commercial/wolfpkcs11_%.bbappend b/recipes-wolfssl/wolfpkcs11/commercial/wolfpkcs11_%.bbappend index ef252b91..407e7e3c 100644 --- a/recipes-wolfssl/wolfpkcs11/commercial/wolfpkcs11_%.bbappend +++ b/recipes-wolfssl/wolfpkcs11/commercial/wolfpkcs11_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFPKCS11_LICENSE};md5=${WOLFPKCS11_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFPKCS11_SRC}.7z" SRC_URI[sha256sum]="${WOLFPKCS11_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFPKCS11_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFPKCS11_SRC}.7z" -p"${WOLFPKCS11_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfpkcs11/wolfpkcs11_2.0.0.bb b/recipes-wolfssl/wolfpkcs11/wolfpkcs11_2.0.0.bb index 2384079e..96a8dc0e 100644 --- a/recipes-wolfssl/wolfpkcs11/wolfpkcs11_2.0.0.bb +++ b/recipes-wolfssl/wolfpkcs11/wolfpkcs11_2.0.0.bb @@ -6,27 +6,20 @@ SECTION = "libs" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://gpl-3.0.txt;md5=d32239bcb673463ab874e80d47fae504" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" SRC_URI = "git://github.com/wolfSSL/wolfPKCS11.git;nobranch=1;protocol=https;rev=6b76537e4cc5bea0358b7059fda26d1872584be4" S = "${WORKDIR}/git" -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility -export CFLAGS += ' -I${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr/include -L${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr/lib' - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = 'cd ${S}; ./autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') } +export CFLAGS += ' -I${STAGING_INCDIR} -L${STAGING_LIBDIR}' + # Add reproducible build flags export CFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export CXXFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' diff --git a/recipes-wolfssl/wolfpkcs11/wolfssl_%.bbappend b/recipes-wolfssl/wolfpkcs11/wolfssl_%.bbappend index 007b5734..e284a82e 100644 --- a/recipes-wolfssl/wolfpkcs11/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfpkcs11/wolfssl_%.bbappend @@ -1,2 +1,6 @@ -EXTRA_OECONF += "--enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt" -TARGET_CFLAGS += "-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP" +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfpkcs11', 'inc/wolfpkcs11/wolfssl-enable-wolfpkcs11.inc') +} diff --git a/recipes-wolfssl/wolfprovider/README.md b/recipes-wolfssl/wolfprovider/README.md index 28528dbd..8340cb58 100644 --- a/recipes-wolfssl/wolfprovider/README.md +++ b/recipes-wolfssl/wolfprovider/README.md @@ -2,7 +2,7 @@ The `wolfprovider` recipe enables the integration of wolfSSL's cryptographic functionalities into OpenSSL through a custom provider mechanism. This integration allows applications using OpenSSL to leverage wolfSSL's advanced cryptographic algorithms, combining wolfSSL's lightweight and performance-optimized cryptography with OpenSSL's extensive API and capabilities. `wolfprovider` is designed for easy integration into Yocto-based systems, ensuring a seamless blend of security and performance ideal for embedded and constrained environments. -The `wolfprovidertest` yocto package will provide two apps, `wolfproviderenv` and `wolfprovidertest`. Running `wolfproviderenv` will start up a child shell and run `wolfprovidertest`. Use `wolfproviderenv` to test that the `wolfprovider` package is succesfully installed. If you want to run `wolfprovidertest` directly you will need to directly source `wolfproviderenv` via `source /usr/bin/wolfproviderenv` or setup the env on your own, because `wolfprovidertest` will fail otherwise. Use `wolfprovidertest` to check that your shell env is correctly setup. +The `wolfprovidertest` yocto package will provide two apps, `wolfproviderenv` and `wolfprovidertest`. Running `wolfproviderenv` will start up a child shell and run `wolfprovidertest`. Use `wolfproviderenv` to test that the `wolfprovider` package is successfully installed. If you want to run `wolfprovidertest` directly you will need to directly source `wolfproviderenv` via `source /usr/bin/wolfproviderenv` or setup the env on your own, because `wolfprovidertest` will fail otherwise. Use `wolfprovidertest` to check that your shell env is correctly setup. ## Getting Started @@ -36,45 +36,202 @@ The `wolfprovidertest` yocto package will provide two apps, `wolfproviderenv` an 3. **Add wolfprovider to your image**: - Modify your image recipe or `local.conf` file to include `wolfprovider`, `wolfssl`, `openssl`, `openssl-bin`, and `wolfprovidertest`. You will only need `openssl-bin` and `wolfprovidertest` if you want to use and test with our included example and conf file. + Enable the wolfprovider demo image in your `local.conf` file: + ```bitbake + WOLFSSL_DEMOS = "wolfprovider-image-minimal" + ``` +4. **Configure wolfProvider Mode (Optional)**: - For yocto kirkstone or newer: - ``` - IMAGE_INSTALL:append = "wolfprovider wolfssl openssl openssl-bin wolfprovidertest" - ``` + wolfProvider can operate in two modes: - For yocto dunfell or earlier: - ``` - IMAGE_INSTALL_append = "wolfprovider wolfssl openssl openssl-bin wolfprovidertest" + **Normal Mode (Default)**: wolfProvider acts as a supplementary provider alongside OpenSSL's default provider. No configuration needed. + + **Replace-Default Mode**: wolfProvider replaces OpenSSL's default provider by patching OpenSSL, making wolfSSL the primary crypto backend. + + To enable and disable modes like FIPS, replace default, etc. for testing you can use these files: + `layers/meta-wolfssl/recipes-core/images/wolfprovider-images/wolfssl_%.bbappend` + `layers/meta-wolfssl/recipes-core/images/wolfprovider-images/openssl_%.bbappend` + + to rebuild with replace default we need to run a clean on the wolfprovider and openssl then rebuild: + + ```sh + bitbake -c cleanall openssl wolfprovider + bitbake wolfprovider-image-minimal ``` -4. **Build Your Image**: +5. **Build Your Image**: With the `meta-wolfssl` layer added and the necessary packages included in your image configuration, proceed to build your Yocto image as usual. ```sh - bitbake + bitbake wolfprovider-image-minimal ``` -### Testing wolfprovider - -After building and deploying your image to the target device, you can test `wolfprovider` functionality through the `wolfproviderenv` script. +## Testing wolfProvider -1. **Execute the wolfproviderenv Script**: +After building and deploying your image to the target device, you can test `wolfprovider` functionality with three test suites: - `wolfproviderenv` is located in `/usr/bin`, so just execute the script upon entering into your terminal. +1. **Environment Setup and Verification**: ```sh wolfproviderenv ``` - The script performs necessary setup actions, executes `wolfprovidertest` to validate the integration, and lists available OpenSSL providers to confirm `wolfprovider` is active and correctly configured. + This sets up the environment and verifies wolfProvider is correctly installed and loaded. It automatically detects the mode you are in and does the necessary things to prepare the env for testing. + +2. **Unit Tests**: + + ```sh + wolfprovidertest + ``` + + Runs the comprehensive wolfProvider unit test suite from the upstream wolfProvider repository. Tests cover all cryptographic operations. + +3. **Command-Line Tests**: + + ```sh + wolfprovidercmd + ``` + + Runs OpenSSL command-line tests including: + - Hash operations (SHA, MD5, etc.) + - AES encryption/decryption + - RSA operations + - ECC operations + - Certificate operations + +## Demo Image + +See `recipes-core/images/wolfprovider-images/` for complete working examples of all configurations. +Refer to the [recipes-core/images/wolfprovider-images/README.md](recipes-core/images/wolfprovider-images/README.md) file for more information. + +### Integrating wolfProvider with Custom Image + +To integrate wolfProvider into your own image recipe (not using the demo images), directly require the appropriate `.inc` files in `bbappend` files. + +#### Direct Include in bbappend Files + +Create `bbappend` files in your custom layer that directly require the `.inc` files you need. + +**1. Create `recipes-wolfssl/wolfssl/wolfssl_%.bbappend` in your layer:** + +For non-FIPS: +```bitbake +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider.inc +``` + +For FIPS: +```bitbake +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc +``` + +**2. Create `recipes-connectivity/openssl/openssl_%.bbappend` in your layer:** + +For standalone mode: +```bitbake +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc +``` + +For replace-default mode: +```bitbake +require ${WOLFSSL_LAYERDIR}/inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc +``` + +**3. Add packages to your image recipe:** + +```bitbake +# In your-image.bb +IMAGE_INSTALL:append = " \ + wolfprovider \ + openssl \ + openssl-bin \ + wolfproviderenv \ + wolfprovidercmd \ +" + +**3. For FIPS mode, configure in `local.conf`:** + +```bitbake +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +**See working examples:** +- `recipes-core/images/wolfprovider-images/wolfprovider-image-minimal/` (standalone, non-FIPS) +- `recipes-core/images/wolfprovider-images/wolfprovider-fips-image-minimal/` (standalone, FIPS) +- `recipes-core/images/wolfprovider-images/wolfprovider-replace-default-image-minimal/` (replace-default, non-FIPS) +- `recipes-core/images/wolfprovider-images/wolfprovider-replace-default-fips-image-minimal/` (replace-default, FIPS) + +#### Using WOLFSSL_FEATURES (For Testing/Development) + +If you want conditional configuration based on variables, you can use the existing `bbappend` files in `recipes-wolfssl/wolfprovider/`: + +Add to your `local.conf`: + +```bitbake +# Enable wolfProvider feature +WOLFSSL_FEATURES = "wolfprovider" + +# For replace-default mode (optional) +WOLFPROVIDER_MODE = "replace-default" + +# For FIPS mode (optional) +require /path/to/meta-wolfssl/conf/wolfssl-fips.conf +``` + +Then add packages to your image recipe: + +```bitbake +# In your-image.bb +IMAGE_INSTALL:append = " \ + wolfprovider \ + openssl \ + openssl-bin \ + wolfproviderenv \ + wolfprovidercmd \ +" +``` + +The following existing files will automatically handle configuration: +- `recipes-wolfssl/wolfprovider/wolfssl_%.bbappend` - Configures wolfSSL with wolfProvider support +- `recipes-wolfssl/wolfprovider/openssl_3.%.bbappend` - Configures OpenSSL for wolfProvider + +#### Available Reusable Files + +**`.inc` files in `inc/wolfprovider/`:** +- `wolfssl-enable-wolfprovider.inc` - Configure wolfSSL for wolfProvider (non-FIPS) +- `wolfssl-enable-wolfprovider-fips.inc` - Configure wolfSSL for wolfProvider (FIPS) +- `openssl/openssl-enable-wolfprovider.inc` - Configure OpenSSL for standalone mode +- `openssl/openssl-enable-wolfprovider-replace-default.inc` - Configure OpenSSL for replace-default mode +- `wolfprovider-enable-unittest.inc` - Enable unit tests (optional only for standalone mode) + +**Existing `bbappend` files in `recipes-wolfssl/wolfprovider/`:** +- `wolfssl_%.bbappend` - Automatically configures wolfSSL based on `WOLFSSL_FEATURES` +- `openssl_3.%.bbappend` - Automatically configures OpenSSL based on `WOLFPROVIDER_MODE` + +**Demo implementations:** +See `recipes-core/images/wolfprovider-images/` for complete working examples of all configurations. + +#### Building Your Image + +After setting up your configuration: + +```bash +# Clean state if switching modes or providers +bitbake -c cleanall openssl wolfprovider + +# Build your image +bitbake your-image +``` + +#### Verifying Integration -2. **Expected Output**: +On your target device: - Look for messages indicating a successful environment setup, execution of `wolfprovidertest` with a custom provider loaded successfully, and `libwolfprovider` listed among active OpenSSL providers. +```bash +wolfproviderenv +``` -### Documentation and Support +## Documentation and Support For further information about `wolfprovider` and `wolfssl`, visit the [wolfSSL Documentation](https://www.wolfssl.com/docs/) and the [wolfProvider Github](https://www.github.com/wolfSSL/wolfprovider). If you encounter issues or require support regarding the integration of `wolfprovider` with Yocto, feel free to reach out through [wolfSSL Support](support@wolfssl.com). diff --git a/recipes-wolfssl/wolfprovider/commercial/commercial-details/wolfprovider_%.bbappend b/recipes-wolfssl/wolfprovider/commercial/commercial-details/wolfprovider_%.bbappend index de917930..1505a171 100644 --- a/recipes-wolfssl/wolfprovider/commercial/commercial-details/wolfprovider_%.bbappend +++ b/recipes-wolfssl/wolfprovider/commercial/commercial-details/wolfprovider_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFPROVIDER_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFPROVIDER_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFPROVIDER_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFPROVIDER_SRC ?= "" WOLFPROVIDER_SRC_SHA ?= "" diff --git a/recipes-wolfssl/wolfprovider/commercial/wolfprovider_%.bbappend b/recipes-wolfssl/wolfprovider/commercial/wolfprovider_%.bbappend index c5ffc303..ee2be3e9 100644 --- a/recipes-wolfssl/wolfprovider/commercial/wolfprovider_%.bbappend +++ b/recipes-wolfssl/wolfprovider/commercial/wolfprovider_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFPROVIDER_LICENSE};md5=${WOLFPROVIDER_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFPROVIDER_SRC}.7z" SRC_URI[sha256sum]="${WOLFPROVIDER_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFPROVIDER_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFPROVIDER_SRC}.7z" -p"${WOLFPROVIDER_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfprovider/openssl_3.%.bbappend b/recipes-wolfssl/wolfprovider/openssl_3.%.bbappend index 0e0c9e10..0b45d327 100644 --- a/recipes-wolfssl/wolfprovider/openssl_3.%.bbappend +++ b/recipes-wolfssl/wolfprovider/openssl_3.%.bbappend @@ -1,2 +1,27 @@ -EXTRA_OECONF += " no-fips shared " +# Conditionally configure openssl with wolfProvider support +# +# This bbappend automatically enables wolfProvider backend when: +# 1. 'wolfprovider' is in WOLFSSL_FEATURES (explicit intent) +# 2. AND WOLFPROVIDER_MODE specifies the desired mode +# +# Usage in local.conf: +# WOLFSSL_FEATURES = "wolfprovider" +# WOLFPROVIDER_MODE = "standalone" # or "replace-default" + +inherit wolfssl-helper + +python __anonymous() { + wolfssl_conditional_require_mode( + d, + package_name='wolfprovider', + mode={ + 'standalone': 'inc/wolfprovider/openssl/openssl-enable-wolfprovider.inc', + 'replace-default': 'inc/wolfprovider/openssl/openssl-enable-wolfprovider-replace-default.inc', + }, + ) +} + +# OpenSSL is a dependency of wolfprovider, not a direct image package +# The check above already validates wolfprovider is in IMAGE_INSTALL +deltask do_wolfssl_check_package diff --git a/recipes-wolfssl/wolfprovider/wolfprovider_1.1.0.bb b/recipes-wolfssl/wolfprovider/wolfprovider_1.1.0.bb index 7fabce65..353bca56 100644 --- a/recipes-wolfssl/wolfprovider/wolfprovider_1.1.0.bb +++ b/recipes-wolfssl/wolfprovider/wolfprovider_1.1.0.bb @@ -1,5 +1,5 @@ -SUMMARY = "wolfProvider is a Proivder designed for Openssl 3.X.X" -DESCRIPTION = "wolfProvider is a library that can be used as an Provider in OpenSSL" +SUMMARY = "wolfProvider is a Provider designed for Openssl 3.X.X" +DESCRIPTION = "wolfProvider is a crypto backend interface for use as an OpenSSL Provider" HOMEPAGE = "https://github.com/wolfSSL/wolfProvider" BUGTRACKER = "https://github.com/wolfSSL/wolfProvider/issues" SECTION = "libs" @@ -10,30 +10,58 @@ DEPENDS += "util-linux-native" PROVIDES += "wolfprovider" RPROVIDES_${PN} = "wolfprovider" -SRC_URI = "git://github.com/wolfssl/wolfProvider.git;nobranch=1;protocol=https;rev=f8f432408f2c6f446a9e5bd9330577d2c2e1ed4f" +SRC_URI = "git://github.com/wolfssl/wolfProvider.git;nobranch=1;protocol=https;rev=7c85aa0196ba0d3780c3e0285c61227d6c1a2892" -DEPENDS += " wolfssl \ +DEPENDS += " virtual/wolfssl \ openssl \ " -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility + +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl openssl') + wolfssl_varSet(d, 'FILES', '${PN}-dev', '${includedir} ${libdir}/pkgconfig/*.pc') + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${libdir}/libwolfprov.so ${libdir}/ssl-3/modules/libwolfprov.so ${libdir}/ossl-modules/libwolfprov.so') + wolfssl_varAppend(d, 'FILES', '${PN}', ' ${sysconfdir}/ssl/openssl.cnf.d/wolfprovider*.conf') + wolfssl_varAppend(d, 'INSANE_SKIP', '${PN}', ' dev-so') +} S = "${WORKDIR}/git" -OPENSSL_YOCTO_DIR = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/openssl/usr" - -# Approach: Use Python to dynamically set function content based on Yocto version -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = "cd ${S}; ./autogen.sh" - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) + +# Install provider module symlink (autotools already creates libwolfprov.so symlinks) +install_provider_module() { + # Ensure target library exists + if [ ! -f ${D}${libdir}/libwolfprov.so.0.0.0 ]; then + echo "libwolfprov.so.0.0.0 not found in ${D}${libdir}/" >&2 + exit 1 + fi + + # Create the OpenSSL module directory symlink + install -d ${D}${libdir}/ssl-3/modules + if [ ! -e ${D}${libdir}/ssl-3/modules/libwolfprov.so ]; then + ln -sf ${libdir}/libwolfprov.so.0.0.0 ${D}${libdir}/ssl-3/modules/libwolfprov.so + fi + + # Create symlink in the ossl-modules directory + install -d ${D}${libdir}/ossl-modules + if [ ! -e ${D}${libdir}/ossl-modules/libwolfprov.so ]; then + ln -sf ${libdir}/libwolfprov.so.0.0.0 ${D}${libdir}/ossl-modules/libwolfprov.so + fi + + # Install config files to openssl.cnf.d/ (following Debian convention) + install -d ${D}${sysconfdir}/ssl/openssl.cnf.d + install -m 0644 ${S}/provider.conf ${D}${sysconfdir}/ssl/openssl.cnf.d/wolfprovider.conf + install -m 0644 ${S}/provider-fips.conf ${D}${sysconfdir}/ssl/openssl.cnf.d/wolfprovider-fips.conf } -CFLAGS += " -I${S}/include -g0 -O2 -ffile-prefix-map=${WORKDIR}=." -CXXFLAGS += " -I${S}/include -g0 -O2 -ffile-prefix-map=${WORKDIR}=." -LDFLAGS += " -Wl,--build-id=none" -EXTRA_OECONF += " --with-openssl=${OPENSSL_YOCTO_DIR}" +do_install[postfuncs] += "install_provider_module" + +CFLAGS += " -I${S}/include" +CXXFLAGS += " -I${S}/include" +CPPFLAGS += " -I${S}/include" + +EXTRA_OECONF += " --with-openssl=${STAGING_EXECPREFIXDIR}" + +# Keep unversioned .so in the runtime package +FILES_SOLIBSDEV = "" + diff --git a/recipes-wolfssl/wolfprovider/wolfssl-fips.bbappend b/recipes-wolfssl/wolfprovider/wolfssl-fips.bbappend new file mode 100644 index 00000000..103b7576 --- /dev/null +++ b/recipes-wolfssl/wolfprovider/wolfssl-fips.bbappend @@ -0,0 +1,25 @@ +# Configure wolfSSL to support wolfProvider FIPS mode +# +# This bbappend automatically configures wolfssl or wolfssl-fips with the features +# needed by wolfprovider when 'wolfprovider' is in WOLFSSL_FEATURES or IMAGE_INSTALL +# +# Usage in local.conf: +# require conf/wolfssl-fips.conf # If FIPS mode is enabled +# IMAGE_INSTALL += "wolfprovider" + +inherit wolfssl-osp-support + +python __anonymous() { + # wolfProvider FIPS mode + wolfssl_conditional_include_ext( + d, + enable_for='wolfprovider', + inc_file='inc/wolfprovider/wolfssl-enable-wolfprovider-fips.inc', + allowed_providers=['wolfssl-fips'] + ) +} + +# Disable package check since this is configuration for wolfssl itself +deltask do_wolfssl_check_package + + diff --git a/recipes-wolfssl/wolfprovider/wolfssl_%.bbappend b/recipes-wolfssl/wolfprovider/wolfssl_%.bbappend index 0d599c9f..bcecd0d2 100644 --- a/recipes-wolfssl/wolfprovider/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfprovider/wolfssl_%.bbappend @@ -1,3 +1,25 @@ -EXTRA_OECONF += " --enable-opensslcoexist --enable-cmac --enable-keygen --enable-sha --enable-des3 --enable-aesctr --enable-aesccm --enable-x963kdf --enable-compkey --enable-certgen --enable-aeskeywrap --enable-enckeys --enable-base16 " -CPPFLAGS += " -DHAVE_AES_ECB -DWOLFSSL_AES_DIRECT -DWC_RSA_NO_PADDING -DWOLFSSL_PUBLIC_MP -DECC_MIN_KEY_SZ=192 -DHAVE_PUBLIC_FFDHE -DWOLFSSL_DH_EXTRA -DRSA_MIN_SIZE=1024" -CPPFLAGS += " ${@'-DWOLFSSL_PSS_LONG_SALT -DWOLFSSL_PSS_SALT_LEN_DISCOVER' if d.getVar('WOLFSSL_TYPE') not in ("fips", "fips-ready") else ''}" \ No newline at end of file +# Configure wolfSSL to support wolfProvider +# +# This bbappend automatically configures wolfssl or wolfssl-fips with the features +# needed by wolfprovider when 'wolfprovider' is in WOLFSSL_FEATURES or IMAGE_INSTALL +# +# Usage in local.conf: +# require conf/wolfssl-fips.conf # If FIPS mode is enabled +# IMAGE_INSTALL += "wolfprovider" + +inherit wolfssl-osp-support + +python __anonymous() { + # wolfProvider non-FIPS mode + wolfssl_conditional_include_ext( + d, + enable_for='wolfprovider', + inc_file='inc/wolfprovider/wolfssl-enable-wolfprovider.inc', + allowed_providers=['wolfssl'] + ) +} + +# Disable package check since this is configuration for wolfssl itself +deltask do_wolfssl_check_package + + diff --git a/recipes-wolfssl/wolfssh/commercial/commercial-details/wolfssh_%.bbappend b/recipes-wolfssl/wolfssh/commercial/commercial-details/wolfssh_%.bbappend index 8fbc9d04..8f19d34a 100644 --- a/recipes-wolfssl/wolfssh/commercial/commercial-details/wolfssh_%.bbappend +++ b/recipes-wolfssl/wolfssh/commercial/commercial-details/wolfssh_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFSSH_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFSSH_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFSSH_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFSSH_SRC ?= "" WOLFSSH_SRC_SHA ?= "" WOLFSSH_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfssh/commercial/wolfssh_%.bbappend b/recipes-wolfssl/wolfssh/commercial/wolfssh_%.bbappend index 6a4628b0..df2084fd 100644 --- a/recipes-wolfssl/wolfssh/commercial/wolfssh_%.bbappend +++ b/recipes-wolfssl/wolfssh/commercial/wolfssh_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFSSH_LICENSE};md5=${WOLFSSH_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFSSH_SRC}.7z" SRC_URI[sha256sum]="${WOLFSSH_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFSSH_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFSSH_SRC}.7z" -p"${WOLFSSH_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfssh/wolfssh_1.4.21.bb b/recipes-wolfssl/wolfssh/wolfssh_1.4.21.bb index e4b7261b..e1ba1eac 100644 --- a/recipes-wolfssl/wolfssh/wolfssh_1.4.21.bb +++ b/recipes-wolfssl/wolfssh/wolfssh_1.4.21.bb @@ -9,31 +9,24 @@ SECTION = "libs" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://LICENSING;md5=2c2d0ee3db6ceba278dd43212ed03733" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" SRC_URI = "git://github.com/wolfssl/wolfssh.git;nobranch=1;protocol=https;rev=c10896cae99ecf2b5c1ae170d0eb001f18008809" S = "${WORKDIR}/git" -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility -EXTRA_OECONF = "--with-wolfssl=${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = 'cd ${S}; ./autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') } +EXTRA_OECONF = "--with-wolfssl=${STAGING_EXECPREFIXDIR}" + # Add reproducible build flags export CFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export CXXFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export LDFLAGS += ' -Wl,--build-id=none' -# Ensure consistent locale -export LC_ALL = "C" +# Ensure consistent locale +export LC_ALL = "C" \ No newline at end of file diff --git a/recipes-wolfssl/wolfssh/wolfssl_%.bbappend b/recipes-wolfssl/wolfssh/wolfssl_%.bbappend index 20725f9d..b8ebda32 100644 --- a/recipes-wolfssl/wolfssh/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfssh/wolfssl_%.bbappend @@ -1,2 +1,9 @@ -EXTRA_OECONF += "--enable-ssh" +# Conditionally configure wolfssl with wolfssh support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfssh', 'inc/wolfssh/wolfssl-enable-wolfssh.inc') +} diff --git a/recipes-wolfssl/wolfssl-py/wolfssl-py_5.8.2.bb b/recipes-wolfssl/wolfssl-py/wolfssl-py_5.8.2.bb index e18faa5b..6e381e37 100644 --- a/recipes-wolfssl/wolfssl-py/wolfssl-py_5.8.2.bb +++ b/recipes-wolfssl/wolfssl-py/wolfssl-py_5.8.2.bb @@ -14,7 +14,7 @@ LIC_FILES_CHKSUM = "file://LICENSING.rst;md5=e4abd0c56c3f6dc95a7a7eed4c77414b" SRC_URI = "git://github.com/wolfSSL/wolfssl-py.git;nobranch=1;protocol=https;rev=3e4ec8484403ea16db79cf4ebde10b5b36d944b3" -DEPENDS += " wolfssl \ +DEPENDS += " virtual/wolfssl \ python3-pip-native \ python3-cffi-native \ python3-cffi \ @@ -22,7 +22,8 @@ DEPENDS += " wolfssl \ python3 \ " -RDEPENDS_${PN} += " python3 \ +RDEPENDS_${PN} += " wolfssl \ + python3 \ python3-cffi \ " @@ -30,9 +31,7 @@ inherit setuptools3 S = "${WORKDIR}/git" -WOLFSSL_YOCTO_DIR = "${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" - -export USE_LOCAL_WOLFSSL="${WOLFSSL_YOCTO_DIR}" +export USE_LOCAL_WOLFSSL="${STAGING_EXECPREFIXDIR}" # Add reproducible build flags CFLAGS += " -g0 -O2 -ffile-prefix-map=${WORKDIR}=." @@ -41,3 +40,4 @@ LDFLAGS += " -Wl,--build-id=none" # Ensure consistent locale for build reproducibility export LC_ALL = "C" + diff --git a/recipes-wolfssl/wolfssl-py/wolfssl_%.bbappend b/recipes-wolfssl/wolfssl-py/wolfssl_%.bbappend index e623c7c3..585f3787 100644 --- a/recipes-wolfssl/wolfssl-py/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfssl-py/wolfssl_%.bbappend @@ -1,3 +1,9 @@ -EXTRA_OECONF += "--enable-sni --enable-opensslextra --enable-opensslall --enable-dtls13 --enable-dtls --enable-crl --enable-tlsx --enable-secure-renegotiation" +# Conditionally configure wolfssl with wolfssl-py support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables -TARGET_CFLAGS += "-DKEEP_PEER_CERT -DFP_MAX_BITS=8192 -DHAVE_EX_DATA -DOPENSSL_COMPATIBLE_DEFAULTS" +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolfssl-py', 'inc/wolfssl-py/wolfssl-enable-wolfssl-py.inc') +} diff --git a/recipes-wolfssl/wolfssl/README-fips.md b/recipes-wolfssl/wolfssl/README-fips.md new file mode 100644 index 00000000..1684c600 --- /dev/null +++ b/recipes-wolfssl/wolfssl/README-fips.md @@ -0,0 +1,38 @@ +# wolfSSL FIPS Recipe + +This directory contains the `wolfssl-fips` recipe for building FIPS 140-3 validated wolfSSL. + +## Requirements + +### Layer Dependencies + +The `wolfssl-fips` recipe requires the following layers **only when actively building FIPS**: + +1. **meta-openembedded/meta-oe** - Provides `p7zip-native` for extracting commercial bundles +2. **BitBake GCS fetch dependencies (only when using `WOLFSSL_BUNDLE_GCS_URI`)** - Install the Google Cloud SDK (which includes the required GCS client libraries) by following https://docs.cloud.google.com/sdk/docs/install, and ensure the Python `google` namespace is available (RPM users need `python3-google-cloud-core` in addition to `google-cloud-cli`). For private buckets, run `gcloud auth application-default login` or export `GOOGLE_APPLICATION_CREDENTIALS` to a service-account JSON before invoking BitBake. + +**Note**: If you're not using FIPS (i.e., `WOLFSSL_SRC` is not configured), the `p7zip-native` dependency is automatically skipped, so you don't need meta-oe. This allows CI environments to parse the layer without requiring additional dependencies. + +When building with FIPS, add to your `bblayers.conf`: +``` +BBLAYERS ?= " \ + /path/to/poky/meta \ + /path/to/poky/meta-poky \ + /path/to/poky/meta-yocto-bsp \ + /path/to/meta-openembedded/meta-oe \ + /path/to/meta-wolfssl \ +" +``` + +### Configuration + +See the main README.md for detailed FIPS configuration instructions, including: +- Creating `conf/wolfssl-fips.conf` from the `.sample` template +- Setting `PREFERRED_PROVIDER_virtual/wolfssl = "wolfssl-fips"` +- Configuring FIPS hash modes (manual vs auto) + +## Note + +The `wolfssl-fips` recipe is disabled by default (`DEFAULT_PREFERENCE = "-1"`). It will only be built when explicitly selected as the provider for `virtual/wolfssl` in your configuration. + +If you're not using FIPS, you can ignore this recipe - it won't affect your builds. diff --git a/recipes-wolfssl/wolfssl/README-linuxkm-randomness-patch.md b/recipes-wolfssl/wolfssl/README-linuxkm-randomness-patch.md new file mode 100644 index 00000000..1db3b969 --- /dev/null +++ b/recipes-wolfssl/wolfssl/README-linuxkm-randomness-patch.md @@ -0,0 +1,166 @@ +# wolfSSL Kernel Randomness Patch + +This bbclass allows you to apply wolfSSL random callback patches to the Linux kernel, enabling wolfSSL's DRBG to integrate with the kernel's random subsystem. + +## Overview + +The patches add callback hooks to `drivers/char/random.c` and `include/linux/random.h`, allowing the wolfSSL kernel module (`libwolfssl.ko`) to register its DRBG implementation with the kernel. + +This is useful for: +- FIPS 140-2/140-3 compliance requiring certified DRBG +- Hardware security module (HSM) integration +- Custom entropy sources + +## Available Patches + +See all available patches at: +**https://github.com/wolfSSL/wolfssl/tree/master/linuxkm/patches** + +Common patch directories: + +| Patch Directory | Target Kernel | +|-----------------------------|--------------------------------------| +| `5.10.17` | Linux 5.10.17 | +| `5.10.236` | Linux 5.10.236 LTS | +| `5.15` | Linux 5.15.x (vanilla) | +| `5.17` | Linux 5.17.x (vanilla) | +| `5.17-ubuntu-jammy-tegra` | NVIDIA Tegra L4T (Jetson platforms) | +| `6.1.73` | Linux 6.1.73 LTS | +| `6.12` | Linux 6.12.x | +| `6.15` | Linux 6.15.x | + +## Usage + +### 1. Create a kernel bbappend + +Create a bbappend for your kernel recipe in your layer: + +``` +meta-mylayer/ +└── recipes-kernel/ + └── linux/ + └── linux-jammy-nvidia-tegra.bbappend # or your kernel recipe name +``` + +### 2. Inherit the bbclass and set the patch + +```bitbake +inherit wolfssl-kernel-random +WOLFSSL_KERNEL_RANDOM_PATCH = "5.17-ubuntu-jammy-tegra" +``` + +### 3. Build the kernel + +```bash +bitbake virtual/kernel +``` + +The patches will be automatically fetched from the wolfSSL GitHub repository and applied during the kernel build. + +## Examples + +### NVIDIA Tegra (Jetson Orin, Xavier, AGX, Nano) + +```bitbake +# linux-jammy-nvidia-tegra.bbappend +inherit wolfssl-kernel-random +WOLFSSL_KERNEL_RANDOM_PATCH = "5.17-ubuntu-jammy-tegra" +``` + +### Standard Yocto linux-yocto 6.12 + +```bitbake +# linux-yocto_%.bbappend +inherit wolfssl-kernel-random +WOLFSSL_KERNEL_RANDOM_PATCH = "6.12" +``` + +### Older LTS Kernel 5.10 + +```bitbake +# linux-yocto_5.10.bbappend +inherit wolfssl-kernel-random +WOLFSSL_KERNEL_RANDOM_PATCH = "5.10.236" +``` + +## Configuration Options + +| Variable | Description | Default | +|------------------------------|--------------------------------------------------|--------------| +| `WOLFSSL_KERNEL_RANDOM_PATCH`| Patch directory name from wolfSSL repo | `""` (none) | +| `WOLFSSL_PATCHES_REPO` | wolfSSL Git repository URL | GitHub master| +| `WOLFSSL_PATCHES_SRCREV` | Git revision to fetch patches from | `AUTOREV` | + +### Pin to a specific wolfSSL release + +```bitbake +inherit wolfssl-kernel-random +WOLFSSL_KERNEL_RANDOM_PATCH = "6.12" +WOLFSSL_PATCHES_SRCREV = "v5.7.0-stable" +``` + +## How It Works + +1. The bbclass adds wolfSSL Git repo to `SRC_URI` +2. During `do_patch`, it locates the specified patch directory +3. All `.patch` files in that directory are applied to the kernel source +4. If a patch is already applied, it is skipped + +## Verifying the Patch + +After building, verify the patch was applied: + +```bash +grep -r "WOLFSSL_LINUXKM" /path/to/kernel-source/drivers/char/random.c +grep -r "WOLFSSL_LINUXKM" /path/to/kernel-source/include/linux/random.h +``` + +You should see `WOLFSSL_LINUXKM_HAVE_GET_RANDOM_CALLBACKS` definitions. + +## Using with wolfSSL Kernel Module + +After patching the kernel, build the wolfSSL kernel module: + +```bash +bitbake wolfssl-linuxkm +``` + +Or for FIPS: + +```bash +bitbake wolfssl-linuxkm-fips +``` + +The module will automatically use the callback hooks if the kernel was patched. + +## Troubleshooting + +### Patch fails to apply + +``` +wolfSSL: Failed to apply patch: ... +``` + +The patch may not be compatible with your kernel version. Check: +1. Your kernel version matches the patch directory +2. Available patches at https://github.com/wolfSSL/wolfssl/tree/master/linuxkm/patches + +### Patch directory not found + +``` +wolfSSL: Patch directory not found: ... +``` + +Verify `WOLFSSL_KERNEL_RANDOM_PATCH` matches a directory name in the wolfSSL repo. + +### Patch already applied + +``` +wolfSSL: Patch already applied, skipping: ... +``` + +This is normal - the bbclass detects previously applied patches and skips them. + +## Security Note + +Enabling these patches allows wolfSSL to provide cryptographic random numbers to the kernel. Ensure your wolfSSL configuration meets your security requirements, especially for FIPS compliance. \ No newline at end of file diff --git a/recipes-wolfssl/wolfssl/README-linuxkm.md b/recipes-wolfssl/wolfssl/README-linuxkm.md new file mode 100644 index 00000000..9d388654 --- /dev/null +++ b/recipes-wolfssl/wolfssl/README-linuxkm.md @@ -0,0 +1,201 @@ +# 📘 **wolfSSL LinuxKM Integration Guide (Updated for New Initramfs API)** + +This document describes how to build and integrate the wolfSSL Linux Kernel Module (LinuxKM) into standard Yocto images and initramfs images, including a complete example for **NVIDIA Tegra-based systems**. + +--- + +# 🧩 1. Building the wolfSSL Linux Kernel Module + +Build the non-FIPS kernel module: + +```sh +bitbake wolfssl-linuxkm +``` + +This produces: + +``` +libwolfssl.ko → /lib/modules//extra/ +``` + +and installs an autoload entry: + +``` +/etc/modules-load.d/wolfssl.conf +``` + +This ensures wolfSSL loads automatically during systemd boot on standard rootfs images — even without an initramfs. + +--- + +# 🧩 2. Adding wolfSSL LinuxKM to an Initramfs Image + +Some systems require wolfSSL to be available **before** the root filesystem is mounted. +For that purpose, this layer provides: + +``` +classes/wolfssl-initramfs.bbclass +``` + +Unlike earlier versions, this class **does not automatically install wolfssl-linuxkm** or modify `/init`. +Instead, it provides **a set of opt-in helper functions** that the initramfs recipe can call explicitly. + +--- + +## **2.1. Include wolfSSL LinuxKM (or FIPS) in the initramfs** + +In your initramfs recipe or `.bbappend`: + +```bitbake +inherit wolfssl-initramfs +PACKAGE_INSTALL:append = " wolfssl-linuxkm" +``` + +**Automatic FIPS Selection:** + +If you have configured `wolfssl-fips.conf` with: +```bitbake +# Use wolfSSL FIPS Linux kernel module (FIPS-validated kernel module) +PREFERRED_PROVIDER_virtual/wolfssl-linuxkm = "wolfssl-linuxkm-fips" +PREFERRED_PROVIDER_wolfssl-linuxkm = "wolfssl-linuxkm-fips" +``` + +**Note:** Both lines are required: +- `virtual/wolfssl-linuxkm` - Controls build-time dependencies +- `wolfssl-linuxkm` - Controls runtime package installation + +Then `wolfssl-linuxkm` will automatically resolve to the FIPS-validated version (`wolfssl-linuxkm-fips`). +No code changes needed - the virtual provider system handles the switch automatically. + +**Manual FIPS Selection (alternative):** + +You can also explicitly specify the FIPS version: +```bitbake +PACKAGE_INSTALL:append = " wolfssl-linuxkm-fips" +``` + +This ensures the selected kernel module is included inside the initramfs filesystem. + +--- + +## **2.2. Optional: Generate module dependencies inside the initramfs** + +If your initramfs uses `modprobe`, you should generate dependency metadata: + +```bitbake +ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_run_depmod; " +``` + +--- + +## **2.3. Optional: Auto-load wolfSSL during initramfs boot** + +The class exposes the following injection methods, letting you choose how `/init` gets modified: + +| Function | Injection Point | +| -------------------------------------------- | --------------------------------------------- | +| `wolfssl_initramfs_inject_after_modalias` | After modalias scan loop | +| `wolfssl_initramfs_inject_after_loadmodules` | After the “Load and run modules” section | +| `wolfssl_initramfs_inject_after_kmsg` | Early injection after `/dev/kmsg` redirection | + +Example (recommended for Tegra): + +```bitbake +ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_run_depmod; " +ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_inject_after_modalias; " +``` + +Fallback for simpler initramfs layouts: + +```bitbake +ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_inject_after_kmsg; " +``` + +--- + +# 🐧 **3. Example: Integrating wolfSSL LinuxKM into Tegra Initramfs** + +NVIDIA Tegra boards (Jetson Orin, Xavier, Nano, AGX, etc.) commonly use: + +``` +tegra-minimal-initramfs +``` + +To integrate wolfSSL LinuxKM into the Tegra initramfs, create this file: + +``` +meta--overrides/recipes-core/images/tegra-minimal-initramfs.bbappend +``` + +Contents: + +```bitbake +inherit wolfssl-initramfs + +PACKAGE_INSTALL:append = " wolfssl-linuxkm" + +ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_run_depmod; " +ROOTFS_POSTPROCESS_COMMAND += " wolfssl_initramfs_inject_after_modalias; " +``` + +### After building: + +```sh +bitbake tegra-minimal-initramfs +``` + +Inside the generated rootfs you will find: + +``` +lib/modules//extra/libwolfssl.ko +etc/modules-load.d/wolfssl.conf +init (modified to auto-load wolfSSL) +``` + +wolfSSL now loads **before** the root filesystem is mounted — required for early-boot crypto or dependencies in Tegra BSPs. + +--- + +# ✨ 4. How LinuxKM behaves on Tegra (with and without initramfs) + +### ✔ Case A — *Without* initramfs integration + +* wolfssl-linuxkm is installed into the main rootfs +* systemd loads it automatically +* Suitable for most Linux systems + +--- + +### ✔ Case B — *With* `wolfssl-initramfs` + +* libwolfssl.ko included inside initramfs +* `modprobe libwolfssl` runs before mount of rootfs +* Required if: + + * Early boot crypto operations need wolfSSL + * Kernel services in initramfs depend on wolfSSL + * Tegra BSP loads cryptography-related modules early + * FIPS-certified environments require early module availability + +--- + +### 💡 Why this matters on Tegra + +Tegra platforms (especially industrial/robotics/ADAS) rely heavily on initramfs-stage drivers and may need wolfSSL *before userspace starts*. +Placing wolfSSL in initramfs avoids failures due to: + +* module load ordering +* missing crypto backends +* delayed rootfs mounts + +--- + +# 🚀 **5. Summary** + +| Use Case | Recommended Method | +| ---------------------------------------------- | ----------------------------------------------------------------- | +| Normal Linux systems | Include `wolfssl-linuxkm` in `IMAGE_INSTALL` | +| Early-boot crypto or initramfs crypto services | Use `wolfssl-initramfs` helpers | +| Tegra or meta-tegra BSP | Add `inherit wolfssl-initramfs` and explicit postprocess commands | + +`wolfssl-initramfs.bbclass` now acts as a **modular, opt-in integration toolkit**, supporting both standard and FIPS kernel modules cleanly. \ No newline at end of file diff --git a/recipes-wolfssl/wolfssl/commercial/README.md b/recipes-wolfssl/wolfssl/commercial/README.md index 2e7a2af4..e5fc5496 100644 --- a/recipes-wolfssl/wolfssl/commercial/README.md +++ b/recipes-wolfssl/wolfssl/commercial/README.md @@ -39,10 +39,12 @@ WOLFCLU_TYPE = "commercial" ``` -4. **Move the Downloaded FIPS/Commerical Bundle** +4. **Move the Downloaded FIPS/Commercial Bundle** - Move or copy the downloaded `wolfssl-x.x.x-*.7z` file to the appropriate directory within the meta-wolfssl repository: + Move or copy the downloaded `wolfssl-x.x.x-*.(7z|tar.gz)` file to the appropriate directory within the meta-wolfssl repository: ``` + cp /path/to/wolfssl-x.x.x-*.tar.gz /path/to/meta-wolfssl/recipes-wolfssl/wolfssl/commerical/files + # or cp /path/to/wolfssl-x.x.x-*.7z /path/to/meta-wolfssl/recipes-wolfssl/wolfssl/commerical/files ``` @@ -53,8 +55,9 @@ Update/Add the variables in your project's `poky/build/conf/local.conf`: `WOLFSSL_VERSION = "x.x.x"`: x.x.x should be the version of the fips/commercial bundle you downloaded. `WOLFSSL_SRC_SHA = ""`: `` This is the sha hash given when you received the bundle. - `WOLFSSL_SRC_PASS = ""`: `` This is the password given to unarchive the bundle. - `WOLFSSL_SRC = ""`: `` This is the name of the bundle you wish to use without the .7z extension. + `WOLFSSL_SRC_PASS = ""`: `` This is the password given to unarchive the bundle (leave empty for `.tar.gz` archives). + `WOLFSSL_SRC = ""`: `` This is the logical name of the bundle without the extension. + `WOLFSSL_BUNDLE_FILE = ""`: Optional override when the archive uses `.tar.gz` (for `.7z`, omit and it will default to `.7z`). 6. **Clean and Build wolfssl and wolfcrypttest** @@ -101,4 +104,3 @@ 10. **Rebuild and Test** Perform bitbake on wolfssl and wolfcrypttest again to ensure they compile correctly. Rebuild your image and test with QEMU as before. The command `wolfcrypttest` should result in no errors. - diff --git a/recipes-wolfssl/wolfssl/commercial/commercial-details/wolfssl_%.bbappend b/recipes-wolfssl/wolfssl/commercial/commercial-details/wolfssl_%.bbappend index 2ba35bb0..0134ac90 100644 --- a/recipes-wolfssl/wolfssl/commercial/commercial-details/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfssl/commercial/commercial-details/wolfssl_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFSSL_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFSSL_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFSSL_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFSSL_SRC ?= "" WOLFSSL_SRC_SHA ?= "" WOLFSSL_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfssl/commercial/fips-details/wolfssl_%.bbappend b/recipes-wolfssl/wolfssl/commercial/fips-details/wolfssl_%.bbappend index e089efcd..599cfbdd 100644 --- a/recipes-wolfssl/wolfssl/commercial/fips-details/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfssl/commercial/fips-details/wolfssl_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFSSL_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFSSL_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFSSL_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFSSL_SRC ?= "" WOLFSSL_SRC_SHA ?= "" WOLFSSL_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolfssl/commercial/wolfssl_%.bbappend b/recipes-wolfssl/wolfssl/commercial/wolfssl_%.bbappend index eb750a90..6243be1d 100644 --- a/recipes-wolfssl/wolfssl/commercial/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfssl/commercial/wolfssl_%.bbappend @@ -1,30 +1,33 @@ -BBFILE_PRIORITY='2' +BBFILE_PRIORITY = "2" + COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +WOLFSSL_SRC_DIR ?= "${COMMERCIAL_CONFIG_DIR}/files" +WOLFSSL_BUNDLE_FILE ?= "" +WOLFSSL_BUNDLE_GCS_URI ?= "" +WOLFSSL_BUNDLE_GCS_TOOL ?= "" -SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFSSL_SRC}.7z" -SRC_URI[sha256sum]="${WOLFSSL_SRC_SHA}" +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://${WOLFSSL_LICENSE};md5=${WOLFSSL_LICENSE_MD5}" -DEPENDS += "p7zip-native" +COMMERCIAL_BUNDLE_ENABLED = "1" +COMMERCIAL_BUNDLE_DIR = "${WOLFSSL_SRC_DIR}" +COMMERCIAL_BUNDLE_NAME = "${WOLFSSL_SRC}" +COMMERCIAL_BUNDLE_FILE = "${WOLFSSL_BUNDLE_FILE}" +COMMERCIAL_BUNDLE_PASS = "${WOLFSSL_SRC_PASS}" +COMMERCIAL_BUNDLE_SHA = "${WOLFSSL_SRC_SHA}" +COMMERCIAL_BUNDLE_TARGET = "${WORKDIR}" +COMMERCIAL_BUNDLE_GCS_URI = "${WOLFSSL_BUNDLE_GCS_URI}" +COMMERCIAL_BUNDLE_GCS_TOOL = "${@d.getVar('WOLFSSL_BUNDLE_GCS_TOOL') or 'auto'}" -S = "${WORKDIR}/${WOLFSSL_SRC}" +SRC_URI = "${@get_commercial_src_uri(d)}" +S = "${@get_commercial_source_dir(d)}" -do_unpack[depends] += "p7zip-native:do_populate_sysroot" +inherit wolfssl-commercial wolfssl-compatibility -do_unpack() { - cp -f "${COMMERCIAL_CONFIG_DIR}/files/${WOLFSSL_SRC}.7z" "${WORKDIR}" - 7za x "${WORKDIR}/${WOLFSSL_SRC}.7z" -p"${WOLFSSL_SRC_PASS}" -o"${WORKDIR}" -aoa +# Ensure autogen.sh never runs for commercial bundles +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) -} +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolfssl/fips-ready/wolfssl_%.bbappend b/recipes-wolfssl/wolfssl/fips-ready/wolfssl_%.bbappend index 1c7f1a43..5417944a 100644 --- a/recipes-wolfssl/wolfssl/fips-ready/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolfssl/fips-ready/wolfssl_%.bbappend @@ -6,18 +6,16 @@ FIPSREADY_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" SRC_URI = "file://${FIPSREADY_CONFIG_DIR}/files/${WOLFSSL_SRC}.zip" SRC_URI[sha256sum] = "${WOLFSSL_SRC_SHA}" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFSSL_SRC}" -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } +addtask do_configure_disable_autogen after do_unpack before do_configure + TARGET_CFLAGS += "-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=${FIPS_HASH} -DFP_MAX_BITS=16384" EXTRA_OECONF += "--enable-fips=ready " diff --git a/recipes-wolfssl/wolfssl/wolfssl-fips.bb b/recipes-wolfssl/wolfssl/wolfssl-fips.bb new file mode 100644 index 00000000..1118d237 --- /dev/null +++ b/recipes-wolfssl/wolfssl/wolfssl-fips.bb @@ -0,0 +1,82 @@ +SUMMARY = "wolfSSL FIPS 140-3 Validated Cryptography" +DESCRIPTION = "wolfSSL is a lightweight SSL/TLS library with FIPS 140-3 validated cryptography module. This recipe provides the FIPS-validated 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" + +# Commercial/FIPS license - Update when using commercial bundle +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://${WOLFSSL_LICENSE};md5=${WOLFSSL_LICENSE_MD5}" + +DEPENDS += "util-linux-native" + +# This recipe provides: +# - wolfssl-fips (automatic from recipe name) +# - virtual/wolfssl (build-time interface for switching implementations) +# At runtime, the wolfssl-fips package provides wolfssl to satisfy package dependencies +PROVIDES += "wolfssl-fips 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" +DEFAULT_PREFERENCE = "-1" + +# FIPS bundle source - expects commercial bundle in files/ directory +# User must set these in local.conf: +# WOLFSSL_VERSION = "x.x.x" +# WOLFSSL_SRC = "wolfssl-x.x.x-commercial-fips-linux" +# WOLFSSL_SRC_SHA = "sha256sum of bundle" +# WOLFSSL_SRC_PASS = "password for bundle" +# WOLFSSL_LICENSE = "${S}/LICENSING" (or path to license file relative to source code) +# WOLFSSL_LICENSE_MD5 = "md5sum of license" +# FIPS_HASH = "hash value after first build" (for FIPS validation) + +# Commercial bundle configuration +# Users can set WOLFSSL_SRC_DIR in local.conf to specify bundle location +# Users can set WOLFSSL_SRC_DIRECTORY in local.conf to point directly to extracted source +WOLFSSL_SRC_DIR ?= "${@os.path.dirname(d.getVar('FILE', True))}/commercial/files" +WOLFSSL_SRC_DIRECTORY ?= "" +WOLFSSL_BUNDLE_FILE ?= "" +WOLFSSL_BUNDLE_GCS_URI ?= "" +WOLFSSL_BUNDLE_GCS_TOOL ?= "" + +# 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 = "${WOLFSSL_SRC_PASS}" +COMMERCIAL_BUNDLE_SHA = "${WOLFSSL_SRC_SHA}" +COMMERCIAL_BUNDLE_TARGET = "${WORKDIR}" +COMMERCIAL_BUNDLE_GCS_URI = "${WOLFSSL_BUNDLE_GCS_URI}" +COMMERCIAL_BUNDLE_GCS_TOOL = "${@d.getVar('WOLFSSL_BUNDLE_GCS_TOOL') or 'auto'}" +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)}" + +# Optional: switch to GCS/tarball flow (gs:// URI) when set +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-commercial-gcs.inc + +# Skip the package check for wolfssl-fips itself (it's the base library) +deltask do_wolfssl_check_package + +# Enable native/nativesdk variants when FIPS is configured +BBCLASSEXTEND = "${@'native nativesdk' if (d.getVar('WOLFSSL_SRC') or '').strip() else ''}" + +# FIPS-specific configuration +# Note: FIPS hash is handled by wolfssl-fips-helper.bbclass +TARGET_CFLAGS += "-DFP_MAX_BITS=16384" +EXTRA_OECONF += " \ + --enable-fips=v5 \ + --enable-reproducible-build \ +" diff --git a/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips.bb b/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips.bb new file mode 100644 index 00000000..9c9d77a4 --- /dev/null +++ b/recipes-wolfssl/wolfssl/wolfssl-linuxkm-fips.bb @@ -0,0 +1,120 @@ +SUMMARY = "wolfSSL FIPS Linux kernel module (libwolfssl.ko)" +DESCRIPTION = "Out-of-tree Linux kernel module for wolfSSL/wolfCrypt with FIPS 140-3 validation" +LICENSE = "CLOSED" +WOLFSSL_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" +WOLFSSL_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +LIC_FILES_CHKSUM = "file://${WOLFSSL_LICENSE};md5=${WOLFSSL_LICENSE_MD5}" +DEPENDS += "virtual/kernel openssl-native" + +# This recipe provides: +# - wolfssl-linuxkm-fips (automatic from recipe name) +# - virtual/wolfssl-linuxkm (build-time interface for switching implementations) +# At runtime, the wolfssl-linuxkm-fips package provides wolfssl-linuxkm to satisfy package dependencies +PROVIDES += "wolfssl-linuxkm-fips 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" +DEFAULT_PREFERENCE = "-1" + +# Use the same commercial FIPS bundle as user-mode wolfssl +# These come from wolfssl-fips.conf (WOLFSSL_SRC, WOLFSSL_SRC_PASS, WOLFSSL_SRC_SHA) +# Users can set WOLFSSL_SRC_DIR in local.conf to specify bundle location +# Users can set WOLFSSL_SRC_DIRECTORY in local.conf to point directly to extracted source +WOLFSSL_SRC_DIR ?= "${@os.path.dirname(d.getVar('FILE', True))}/commercial/files" +WOLFSSL_SRC_DIRECTORY ?= "" +WOLFSSL_BUNDLE_FILE ?= "" +WOLFSSL_BUNDLE_GCS_URI ?= "" +WOLFSSL_BUNDLE_GCS_TOOL ?= "" +COMMERCIAL_BUNDLE_DIR = "${WOLFSSL_SRC_DIR}" +COMMERCIAL_BUNDLE_NAME = "${WOLFSSL_SRC}" +COMMERCIAL_BUNDLE_FILE = "${WOLFSSL_BUNDLE_FILE}" +COMMERCIAL_BUNDLE_PASS = "${WOLFSSL_SRC_PASS}" +COMMERCIAL_BUNDLE_SHA = "${WOLFSSL_SRC_SHA}" +COMMERCIAL_BUNDLE_TARGET = "${WORKDIR}" +COMMERCIAL_BUNDLE_GCS_URI = "${WOLFSSL_BUNDLE_GCS_URI}" +COMMERCIAL_BUNDLE_GCS_TOOL = "${@d.getVar('WOLFSSL_BUNDLE_GCS_TOOL') or 'auto'}" +COMMERCIAL_BUNDLE_SRC_DIR = "${WOLFSSL_SRC_DIRECTORY}" + +# Kernel module FIPS hash configuration +# WOLFSSL_FIPS_HASH_MODE_LINUXKM controls whether to use manual hash or kernel's 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 .7z bundle (or README placeholder if not configured) +SRC_URI = "${@ get_commercial_src_uri(d) }" + +# Use helper functions from wolfssl-commercial.bbclass for conditional configuration +# After extraction, S points to the top directory of the bundle: +# ${WORKDIR}/${WOLFSSL_SRC} +S = "${@ get_commercial_source_dir(d) }" +B = "${S}" + +# Optional: switch to GCS/tarball flow (gs:// URI) when set +require ${WOLFSSL_LAYERDIR}/inc/wolfssl-fips/wolfssl-commercial-gcs.inc + +# 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 +EXTRA_OECONF = " \ + --enable-linuxkm \ + --enable-fips=v5.2.4 \ + --with-linux-source=${STAGING_KERNEL_BUILDDIR} \ + --enable-all-crypto \ + --enable-crypttests \ +" + +python __anonymous() { + # Pass FIPS hash as compile-time define (same approach as userspace wolfssl-fips) + 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 - hash will be determined by build" + fi +} + +addtask do_configure_fips_hash_check after do_patch before do_configure + +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/ +} diff --git a/recipes-wolfssl/wolfssl/wolfssl-linuxkm.bb b/recipes-wolfssl/wolfssl/wolfssl-linuxkm.bb new file mode 100644 index 00000000..140a06d1 --- /dev/null +++ b/recipes-wolfssl/wolfssl/wolfssl-linuxkm.bb @@ -0,0 +1,67 @@ +SUMMARY = "wolfSSL Linux kernel module (libwolfssl.ko)" +DESCRIPTION = "Out-of-tree Linux kernel module for wolfSSL/wolfCrypt" +LICENSE = "GPL-3.0-only" +DEPENDS += "virtual/kernel openssl-native" +LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" + +# This recipe provides: +# - wolfssl-linuxkm (automatic from recipe name) +# - virtual/wolfssl-linuxkm (build-time interface for switching implementations) +PROVIDES += "wolfssl-linuxkm virtual/wolfssl-linuxkm" + +# Build for target kernel +inherit module-base autotools wolfssl-helper wolfssl-compatibility + +python __anonymous() { + wolfssl_varSet(d, 'RDEPENDS', '${PN}', '') + wolfssl_varSet(d, 'FILES', '${PN}', '${nonarch_base_libdir}/modules ${sysconfdir}/modules-load.d') + wolfssl_varAppend(d, 'INSANE_SKIP', '${PN}', ' buildpaths debug-files') +} + +# Skip the package check for wolfssl itself (it's the base library) +deltask do_wolfssl_check_package + +# Fetch wolfSSL from upstream GitHub +SRC_URI = "git://github.com/wolfSSL/wolfssl.git;protocol=https;branch=master" +SRCREV = "569a5e03882c4cdef9e99f3a4cfcee96bc25c2cb" + +# After git fetch, S is the git checkout +S = "${WORKDIR}/git" + +# Build in-tree; wolfSSL's configure expects linuxkm/ under the build dir +B = "${S}" + +EXTRA_OECONF = " \ + --enable-linuxkm \ + --host=${HOST_SYS} \ + --build=${BUILD_SYS} \ + --with-linux-source=${STAGING_KERNEL_BUILDDIR} \ + --enable-all-crypto \ + --enable-crypttests \ +" + +# We use the in-tree linuxkm Kbuild rather than the standalone Makefile +do_compile() { + # Avoid host CFLAGS interfering with kernel build + unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS + + # build user mode build first + oe_runmake +} + +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/ +} + +# Remove debug directory if present +do_install_linuxkm_autoload() { + install -d ${D}/etc/modules-load.d + echo "libwolfssl" > ${D}/etc/modules-load.d/wolfssl.conf +} + +addtask do_install_linuxkm_autoload after do_install before do_package +do_install_linuxkm_autoload[fakeroot] = "1" + +INHIBIT_PACKAGE_DEBUG_SPLIT = "1" diff --git a/recipes-wolfssl/wolfssl/wolfssl_5.8.4.bb b/recipes-wolfssl/wolfssl/wolfssl_5.8.4.bb index fdb6c4d3..d6ffc372 100644 --- a/recipes-wolfssl/wolfssl/wolfssl_5.8.4.bb +++ b/recipes-wolfssl/wolfssl/wolfssl_5.8.4.bb @@ -7,28 +7,17 @@ LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://COPYING;md5=d32239bcb673463ab874e80d47fae504" DEPENDS += "util-linux-native" -PROVIDES += "wolfssl" +PROVIDES += "wolfssl virtual/wolfssl" RPROVIDES_${PN} = "wolfssl" SRC_URI = "git://github.com/wolfssl/wolfssl.git;nobranch=1;protocol=https;rev=59f4fa568615396fbf381b073b220d1e8d61e4c2" S = "${WORKDIR}/git" +inherit autotools pkgconfig wolfssl-helper -inherit autotools pkgconfig - -# Approach: Use Python to dynamically set function content based on Yocto version -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = 'cd ${S}; ./autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) -} - +# Skip the package check for wolfssl itself (it's the base library) +deltask do_wolfssl_check_package BBCLASSEXTEND = "native nativesdk" EXTRA_OECONF += "--enable-reproducible-build" diff --git a/recipes-wolfssl/wolftpm/commercial/commercial-details/wolftpm_%.bbappend b/recipes-wolfssl/wolftpm/commercial/commercial-details/wolftpm_%.bbappend index 0cdb7661..76be9fc7 100644 --- a/recipes-wolfssl/wolftpm/commercial/commercial-details/wolftpm_%.bbappend +++ b/recipes-wolfssl/wolftpm/commercial/commercial-details/wolftpm_%.bbappend @@ -1,8 +1,8 @@ #Adjust these as needed WOLFTPM_VERSION ?= "" -WOLF_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2024.pdf" -WOLF_LICENSE_MD5 ?= "9b56a02d020e92a4bd49d0914e7d7db8" +WOLFTPM_LICENSE ?= "WolfSSL_LicenseAgmt_JAN-2022.pdf" +WOLFTPM_LICENSE_MD5 ?= "be28609dc681e98236c52428fadf04dd" WOLFTPM_SRC ?= "" WOLFTPM_SRC_SHA ?= "" WOLFTPM_SRC_PASS ?= "" diff --git a/recipes-wolfssl/wolftpm/commercial/wolftpm_%.bbappend b/recipes-wolfssl/wolftpm/commercial/wolftpm_%.bbappend index 19065c8d..9e696ff3 100644 --- a/recipes-wolfssl/wolftpm/commercial/wolftpm_%.bbappend +++ b/recipes-wolfssl/wolftpm/commercial/wolftpm_%.bbappend @@ -1,13 +1,15 @@ BBFILE_PRIORITY='2' COMMERCIAL_CONFIG_DIR := "${@os.path.dirname(d.getVar('FILE', True))}" -LICENSE="Proprietary" -LIC_FILES_CHKSUM="file://${WOLF_LICENSE};md5=${WOLF_LICENSE_MD5}" +LICENSE="Proprietary" +LIC_FILES_CHKSUM="file://${WOLFTPM_LICENSE};md5=${WOLFTPM_LICENSE_MD5}" SRC_URI="file://${COMMERCIAL_CONFIG_DIR}/files/${WOLFTPM_SRC}.7z" SRC_URI[sha256sum]="${WOLFTPM_SRC_SHA}" DEPENDS += "p7zip-native" +inherit wolfssl-compatibility + S = "${WORKDIR}/${WOLFTPM_SRC}" do_unpack[depends] += "p7zip-native:do_populate_sysroot" @@ -17,14 +19,9 @@ do_unpack() { 7za x "${WORKDIR}/${WOLFTPM_SRC}.7z" -p"${WOLFTPM_SRC_PASS}" -o"${WORKDIR}" -aoa } - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_create = 'echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh && chmod +x ${S}/autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_create) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_create) +do_configure_disable_autogen() { + echo -e "#!/bin/sh\nexit 0" > ${S}/autogen.sh + chmod +x ${S}/autogen.sh } + +addtask do_configure_disable_autogen after do_unpack before do_configure diff --git a/recipes-wolfssl/wolftpm/wolfssl_%.bbappend b/recipes-wolfssl/wolftpm/wolfssl_%.bbappend index 3bf38de3..8a1269e3 100644 --- a/recipes-wolfssl/wolftpm/wolfssl_%.bbappend +++ b/recipes-wolfssl/wolftpm/wolfssl_%.bbappend @@ -1,2 +1,9 @@ -EXTRA_OECONF += "--enable-certgen --enable-certreq --enable-certext --enable-pkcs7 --enable-cryptocb" +# Conditionally configure wolfssl with wolftpm support +# This bbappend checks the WOLFSSL_FEATURES and IMAGE_INSTALL variables +inherit wolfssl-helper +deltask do_wolfssl_check_package + +python __anonymous() { + wolfssl_conditional_require(d, 'wolftpm', 'inc/wolftpm/wolfssl-enable-wolftpm.inc') +} diff --git a/recipes-wolfssl/wolftpm/wolftpm_3.9.2.bb b/recipes-wolfssl/wolftpm/wolftpm_3.9.2.bb index 10d86f04..e34cf3fa 100644 --- a/recipes-wolfssl/wolftpm/wolftpm_3.9.2.bb +++ b/recipes-wolfssl/wolftpm/wolftpm_3.9.2.bb @@ -10,31 +10,24 @@ SECTION = "libs" LICENSE = "GPL-3.0-only" LIC_FILES_CHKSUM = "file://LICENSE;md5=d32239bcb673463ab874e80d47fae504" -DEPENDS += "wolfssl" +DEPENDS += "virtual/wolfssl" SRC_URI = "git://github.com/wolfssl/wolfTPM.git;nobranch=1;protocol=https;rev=75938ca2b0810aba6ed21c5184e7a45d28003522" S = "${WORKDIR}/git" -inherit autotools pkgconfig +inherit autotools pkgconfig wolfssl-helper wolfssl-compatibility -EXTRA_OECONF = "--with-wolfcrypt=${COMPONENTS_DIR}/${PACKAGE_ARCH}/wolfssl/usr" - -python() { - distro_version = d.getVar('DISTRO_VERSION', True) - autogen_command = 'cd ${S}; ./autogen.sh' - if distro_version and (distro_version.startswith('2.') or distro_version.startswith('3.')): - # For Dunfell and earlier - d.appendVar('do_configure_prepend', autogen_command) - else: - # For Kirkstone and later - d.appendVar('do_configure:prepend', autogen_command) +python __anonymous() { + wolfssl_varAppend(d, 'RDEPENDS', '${PN}', ' wolfssl') } +EXTRA_OECONF = "--with-wolfcrypt=${STAGING_EXECPREFIXDIR}" + # Add reproducible build flags export CFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export CXXFLAGS += ' -g0 -O2 -ffile-prefix-map=${WORKDIR}=.' export LDFLAGS += ' -Wl,--build-id=none' -# Ensure consistent locale -export LC_ALL = "C" +# Ensure consistent locale +export LC_ALL = "C" \ No newline at end of file