feat(crypto): support OpenSSL 1.1.x with per-version backend files#500
Open
walterchris wants to merge 7 commits into
Open
feat(crypto): support OpenSSL 1.1.x with per-version backend files#500walterchris wants to merge 7 commits into
walterchris wants to merge 7 commits into
Conversation
Contributor
There was a problem hiding this comment.
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.rsto emitcfg(ossl300)when building against OpenSSL ≥ 3.0. - Refactors
libctxplumbing to support OpenSSL 3.x private-libctx isolation while providing a default-contextPkeyCtxon OpenSSL 1.1.x. - Gates 3.x-only backends (AES/HMAC/HKDF/RSA/hash) behind
cfg(ossl300)and addsOssl11Unsupportedstubs fornot(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. |
bf8fbdc to
df79b29
Compare
df79b29 to
32017ca
Compare
1ca3ac3 to
271afec
Compare
271afec to
a2c974b
Compare
a2c974b to
949bfdd
Compare
bd166ed to
8658717
Compare
fead37c to
23be5d9
Compare
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>
4433b5c to
2c2ee14
Compare
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" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
azihsm_cryptois OpenSSL-3.x-only — it uses EVP_MAC, OSSL_PARAM, librarycontexts, and provider fetch. That blocks the OpenSSL 1.1.x engine, which
depends on the crate transitively via
azihsm_api. The engine targets thelegacy 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.rsemitscfg(ossl300)from the OpenSSL versionopenssl-sysexposes (
DEP_OPENSSL_VERSION_NUMBER).*_ossl11.rscompiled undercfg(not(ossl300)).The existing
*_ossl.rsstays unchanged as thecfg(ossl300)backend(no rename, no diff).
libctx.rs(privateOSSL_LIB_CTXisolation) is gated to 3.x; 1.1 has nolibrary 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:
set_padding(false)is called afterEVP_*Init(which resetspadding 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.
Extract-mode length are rejected, matching the 3.x / CNG backends; the 1.1
EVP_PKEYHKDF path otherwise accepts both silently.Validation
clippy -D warnings, 477 tests — all pass, unchanged.--features engine, passesclippy -D warnings, loads viaopenssl engine -t→[ available ], and now runs theazihsm_cryptotest suite against real 1.1.