Skip to content

feat(crypto): support OpenSSL 1.1.x with per-version backend files#500

Open
walterchris wants to merge 7 commits into
mainfrom
engine/crypto-ossl11-compat
Open

feat(crypto): support OpenSSL 1.1.x with per-version backend files#500
walterchris wants to merge 7 commits into
mainfrom
engine/crypto-ossl11-compat

Conversation

@walterchris

@walterchris walterchris commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Problem

azihsm_crypto is OpenSSL-3.x-only — it uses EVP_MAC, OSSL_PARAM, library
contexts, and provider fetch. That blocks the OpenSSL 1.1.x engine, which
depends on the crate transitively via azihsm_api. The engine targets the
legacy 1.1 ABI; the provider serves 3.x.

Change

Add a 1.1.x backend for each algorithm alongside the existing 3.x one,
selected at build time:

  • build.rs emits cfg(ossl300) from the OpenSSL version openssl-sys
    exposes (DEP_OPENSSL_VERSION_NUMBER).
  • Each algorithm gains a *_ossl11.rs compiled under cfg(not(ossl300)).
    The existing *_ossl.rs stays unchanged as the cfg(ossl300) backend
    (no rename, no diff).
  • libctx.rs (private OSSL_LIB_CTX isolation) is gated to 3.x; 1.1 has no
    library contexts or providers.

Covers aes (cbc/ecb/gcm/xts), ecc/ecdh, hash, hmac, kdf/hkdf, and rsa
(enc/sign/hash-sign). The version-agnostic code (key, kbkdf, hpke,
aead_envelope, der, x509, secret) is unchanged.

The 1.1.x backends match the implementation used before the crate's 3.x-only
rewrite (commit 8277a01e).

1.1 correctness notes

Two behaviors where 1.1 is stricter than 3.x, handled in the 1.1 backends:

  • AES-ECB: set_padding(false) is called after EVP_*Init (which resets
    padding to on). On 1.1 a pre-init call is silently dropped, which would add a
    spurious padding block to block-aligned input — this also covers AES-KW/KWP
    and RSA-AES-KW, which build on ECB.
  • HKDF: zero-length output (invalid per RFC 5869) and a mismatched
    Extract-mode length are rejected, matching the 3.x / CNG backends; the 1.1
    EVP_PKEY HKDF path otherwise accepts both silently.

Validation

  • 3.x: build, clippy -D warnings, 477 tests — all pass, unchanged.
  • 1.1.x (OpenSSL 1.1.1w): 477/477 tests pass, clippy clean.
  • Engine matrix (Ubuntu 20.04 / OpenSSL 1.1.1f): the cdylib builds with
    --features engine, passes clippy -D warnings, loads via
    openssl engine -t[ available ], and now runs the azihsm_crypto
    test suite against real 1.1.

Copilot AI review requested due to automatic review settings June 30, 2026 06:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds dual-build support for azihsm_crypto so it can compile against both OpenSSL 3.x (full functionality with private libctx/provider isolation) and OpenSSL 1.1.x (interim runtime-error stubs to unblock downstream OpenSSL 1.1 engine builds).

Changes:

  • Adds crates/crypto/build.rs to emit cfg(ossl300) when building against OpenSSL ≥ 3.0.
  • Refactors libctx plumbing to support OpenSSL 3.x private-libctx isolation while providing a default-context PkeyCtx on OpenSSL 1.1.x.
  • Gates 3.x-only backends (AES/HMAC/HKDF/RSA/hash) behind cfg(ossl300) and adds Ossl11Unsupported stubs for not(ossl300).

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
crates/crypto/build.rs Detects OpenSSL version and emits cfg(ossl300) for conditional compilation.
crates/crypto/src/lib.rs Introduces an OpenSSL 1.1.x “unsupported” error and relaxes dead-code linting for interim stubs.
crates/crypto/src/libctx.rs Splits libctx handling: private libctx for 3.x, default-context PkeyCtx for 1.1.x.
crates/crypto/src/hash/hash_ossl.rs Gates 3.x hash implementation; adds 1.1.x runtime-error stub.
crates/crypto/src/hmac/hmac_ossl.rs Gates EVP_MAC-based HMAC to 3.x; adds 1.1.x runtime-error stubs.
crates/crypto/src/kdf/hkdf_ossl.rs Gates HKDF derive to 3.x; adds 1.1.x runtime-error stub.
crates/crypto/src/rsa/rsa_enc_ossl.rs Gates 3.x RSA encrypt/decrypt implementation; adds 1.1.x runtime-error stubs.
crates/crypto/src/rsa/rsa_sign_ossl.rs Gates 3.x RSA pre-hash sign/verify/recover; adds 1.1.x runtime-error stubs.
crates/crypto/src/rsa/rsa_hash_sign_ossl.rs Gates 3.x digest-sign/digest-verify isolation; adds 1.1.x runtime-error stubs.
crates/crypto/src/aes/cbc_ossl.rs Gates 3.x AES-CBC OpenSSL backend; adds 1.1.x runtime-error stubs.
crates/crypto/src/aes/ecb_ossl.rs Gates 3.x AES-ECB OpenSSL backend; adds 1.1.x runtime-error stubs.
crates/crypto/src/aes/gcm_ossl.rs Gates 3.x AES-GCM OpenSSL backend; adds 1.1.x runtime-error stubs.
crates/crypto/src/aes/xts_ossl.rs Gates 3.x AES-XTS internals; adds 1.1.x runtime-error stub path.

Comment thread crates/crypto/src/lib.rs Outdated
Comment thread crates/crypto/build.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_sign_ossl.rs Outdated
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch 2 times, most recently from bf8fbdc to df79b29 Compare June 30, 2026 07:49
Copilot AI review requested due to automatic review settings July 1, 2026 12:23
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch from df79b29 to 32017ca Compare July 1, 2026 12:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 32 changed files in this pull request and generated 5 comments.

Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_sign_ossl11.rs
Comment thread crates/crypto/src/rsa/rsa_hash_sign_ossl11.rs
Comment thread crates/crypto/src/rsa/rsa_sign_ossl11.rs
@walterchris walterchris changed the title feat(crypto): build azihsm_crypto against OpenSSL 1.1.x (interim 1.1 stubs) feat(crypto): support OpenSSL 1.1.x with per-version backend files Jul 1, 2026
Copilot AI review requested due to automatic review settings July 1, 2026 12:36
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch from 1ca3ac3 to 271afec Compare July 1, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 33 changed files in this pull request and generated 5 comments.

Comment thread crates/crypto/src/rsa/rsa_sign_ossl11.rs
Comment thread crates/crypto/src/rsa/rsa_hash_sign_ossl11.rs
Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/ecc/ecdh_ossl11.rs
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch from 271afec to a2c974b Compare July 1, 2026 16:00
Copilot AI review requested due to automatic review settings July 1, 2026 19:29
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch from a2c974b to 949bfdd Compare July 1, 2026 19:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 4 comments.

Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/aes/cbc_ossl11.rs Outdated
Comment thread crates/crypto/src/aes/cbc_ossl11.rs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Comment thread crates/crypto/src/kdf/hkdf_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_enc_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_hash_sign_ossl11.rs Outdated
Copilot AI review requested due to automatic review settings July 2, 2026 18:22
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch from fead37c to 23be5d9 Compare July 2, 2026 18:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 7 comments.

Comment thread .github/workflows/engine-matrix.yml Outdated
Comment thread crates/crypto/src/kdf/hkdf_ossl11.rs Outdated
Comment thread crates/crypto/src/hmac/hmac_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_sign_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_sign_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_hash_sign_ossl11.rs Outdated
Comment thread crates/crypto/src/rsa/rsa_hash_sign_ossl11.rs Outdated
azihsm_crypto is OpenSSL-3.x-only (EVP_MAC, OSSL_PARAM, library contexts,
provider fetch), which blocks the OpenSSL 1.1.x engine that depends on it
transitively via azihsm_api.

Add a 1.1.x backend for each algorithm alongside the existing 3.x one,
selected at build time:
- build.rs emits cfg(ossl300) from the OpenSSL version openssl-sys exposes
  (DEP_OPENSSL_VERSION_NUMBER).
- Each algorithm gains a *_ossl11.rs compiled under cfg(not(ossl300)); the
  existing *_ossl.rs stays unchanged as the cfg(ossl300) backend.
- libctx (private OSSL_LIB_CTX isolation) is gated to 3.x; 1.1 has no
  library contexts or providers.

Covers aes (cbc/ecb/gcm/xts), ecc/ecdh, hash, hmac, kdf/hkdf, and rsa
(enc/sign/hash-sign). 3.x is unchanged.

Signed-off-by: Christian Walter <christian.walter@9elements.com>
- AES-ECB: move set_padding(false) after encrypt_init. EVP_*Init resets
  padding to its default (on); OpenSSL 1.1 honors that reset, so the
  pre-init call was discarded and a block-aligned input got a spurious
  PKCS#7 block (wrong, over-long ciphertext). Also fixes the AES-KW/KWP
  and RSA-AES-KW paths, which build on ECB.
- HKDF: reject a zero-length output (HkdfDeriveError) and a mismatched
  Extract-mode length (HmacInvalidDerivedKeyLength), matching the 3.x /
  CNG backends; the 1.1 EVP_PKEY_HKDF path accepted both silently.

The 1.1.x crypto test suite now passes 477/477 (was 458/19); 3.x is
unchanged (477/477).

Signed-off-by: Christian Walter <christian.walter@9elements.com>
The engine build only compile-checks the crate's 1.1.x crypto backends; run
its test suite in the 1.1.1f cell so the 1.1 paths are exercised at runtime,
not just compiled.

Signed-off-by: Christian Walter <christian.walter@9elements.com>
The restored 1.1.x backends predate three defensive checks the 3.x
backends already carry:

- HMAC verify: compare with openssl::memcmp::eq after a length check
  instead of `==`, so verification is constant-time (the module docs
  already promise this).
- AES-CBC: only advance the chaining IV when a full block was produced;
  an empty input with padding disabled yields count == 0 (encrypt) or a
  short input (decrypt), which would underflow the slice index and panic.
- RSA-PSS: convert the salt length with i32::try_from and error on
  overflow instead of truncating with `as`.

3.x is unchanged.

Signed-off-by: Christian Walter <christian.walter@9elements.com>
Install cargo-nextest from its prebuilt binary (building it from source
is unreliable in the 20.04 cell) and run the openssl-engine and
azihsm_crypto suites through `cargo nextest run`, matching the runner the
3.x CI already uses. nextest skips doctests, so run azihsm_crypto's
doctests in a separate step.

Signed-off-by: Christian Walter <christian.walter@9elements.com>
- HKDF: error if OpenSSL returns fewer bytes than requested instead of
  returning a silently truncated key; the 3.x backend already yields the
  full requested length.
- RSA-OAEP decrypt: map set_rsa_mgf1_md failure to RsaSetPropertyError to
  match the surrounding OAEP setup calls and the documented error.
- Fix a with_pss_padding doc comment that named the parameter hash_algo
  instead of hash.

Signed-off-by: Christian Walter <christian.walter@9elements.com>
- Correct doc comments naming renamed types: OsslRsaSigning ->
  OsslRsaSignAlgo / OsslRsaHashSignAlgo, OsslHkdf -> OsslHkdfAlgo, and an
  HMAC module doc describing an OsslHmacKey wrapper / OsslHmacAlgo trait the
  backend doesn't use (it drives an OpenSSL Signer).
- Drop the nonexistent `derived_length` argument from the HKDF new() docs
  and order the argument list to match the signature.
- Pin the engine-matrix cargo-nextest download to 0.9.132 (the version
  xtask installs) rather than `latest`, for a deterministic install.

Signed-off-by: Christian Walter <christian.walter@9elements.com>
Copilot AI review requested due to automatic review settings July 2, 2026 20:43
@walterchris walterchris force-pushed the engine/crypto-ossl11-compat branch from 4433b5c to 2c2ee14 Compare July 2, 2026 20:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.

Comment on lines +309 to +313
/// # Errors
///
/// Returns an error if:
/// - `CryptoError::RsaSetPropertyError` - Setting padding, OAEP hash algorithm, or label fails
/// - `CryptoError::RsaError` - Setting MGF1 hash algorithm fails
Comment on lines +657 to +658
// Note: IV is updated in the context but not propagated back to the caller
// For proper IV chaining in streaming mode, the IV should be the last block of ciphertext
Comment on lines +105 to +109
# cargo-nextest isn't in the base image and building it from source is
# unreliable here; fetch the prebuilt binary, pinned to the version xtask
# installs elsewhere (xtask/src/setup.rs CARGO_NEXTEST_VERSION).
- name: Install cargo-nextest
run: curl -LsSf https://get.nexte.st/0.9.132/linux | tar zxf - -C "${CARGO_HOME:-$HOME/.cargo}/bin"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants