Skip to content

fix: use runtime OpenSSL algorithm detection to handle missing SM3 support#1259

Open
ansasaki wants to merge 1 commit into
keylime:masterfrom
ansasaki:fix-sm3-openssl-no-sm3
Open

fix: use runtime OpenSSL algorithm detection to handle missing SM3 support#1259
ansasaki wants to merge 1 commit into
keylime:masterfrom
ansasaki:fix-sm3-openssl-no-sm3

Conversation

@ansasaki

@ansasaki ansasaki commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactor (no functional changes)
  • Tests
  • CI/CD
  • Other

Related Issues

See also: Fedora COPR build failure — openssl::hash::MessageDigest::sm3() not found when building against Fedora's OpenSSL (compiled with OPENSSL_NO_SM3).

Change Description

Concise Summary

Replace all MessageDigest::sha*() / MessageDigest::sm3() associated function calls with MessageDigest::from_name() runtime lookups, making the code resilient to any hash algorithm being removed from OpenSSL without requiring code changes.

Technical Details

Fedora's OpenSSL is now built with OPENSSL_NO_SM3, which removes MessageDigest::sm3() from the openssl crate at compile time. This caused two build errors in algorithms.rs and tpm.rs.

Rather than using compile-time cfg gates (which don't propagate transitively from the openssl crate), the fix uses MessageDigest::from_name() — a runtime lookup via EVP_get_digestbyname — for all hash algorithms. This is future-proof: if OpenSSL drops another algorithm, the code handles it gracefully without any changes.

Changes:

  • algorithms.rs: From<HashAlgorithm> for MessageDigest becomes TryFrom, using from_name() for all algorithms. Adds digest_size() (compile-time constant sizes), openssl_name(), and is_supported() methods to HashAlgorithm.
  • tpm.rs: hash_alg_to_message_digest now delegates to the TryFrom impl instead of duplicating the conversion logic. get_supported_hash_algorithms filters out algorithms unavailable in the current OpenSSL build, preventing the agent from advertising capabilities it cannot fulfill.
  • entry.rs: Digest::start() and Digest::ff() use digest_size() instead of going through OpenSSL — they only need byte lengths, not digest objects. Digest::new() also uses digest_size() for validation. This removes the OpenSSL dependency from entry.rs entirely.
  • context_info.rs, keylime-ima-emulator/main.rs: Call sites updated from infallible .into() to TryFrom/try_from.

What is NOT changed

  • No Cargo.toml changes (no new dependencies, no lint configs)
  • No RPM spec or packit changes
  • No cfg gates or build.rs files
  • HashAlgorithm::Sm3_256 enum variant remains (TPM protocol compatibility)
  • PcrBanks.sm3_256 field remains (wire format / deserialization compatibility)
  • capabilities_negotiation.rs and struct_filler.rs are unchanged — they are pure data structures that don't use OpenSSL

Alternatives Considered

  1. Compile-time cfg(osslconf = "OPENSSL_NO_SM3"): The openssl crate's osslconf cfg doesn't propagate to downstream crates, requiring build.rs + openssl-sys dependency additions — more complex for no benefit.
  2. Cargo feature flag: Would require manual coordination between spec files, packit, and Cargo.toml on every platform.

Documentation Updates Required

  • README
  • Configuration documentation
  • API documentation
  • None required

Verification Process

  1. Build on Fedora (OpenSSL with OPENSSL_NO_SM3): cargo build — compiles cleanly
  2. Build on systems with SM3 support: cargo build — compiles cleanly
  3. Run test suite: bash tests/run.sh — all tests pass
  4. Verify no MessageDigest::sm3() references remain: grep -r "MessageDigest::sm3" --include="*.rs" | grep -v target/

Checklist

  • Code follows the project style guidelines
  • Tests have been added/updated
  • Documentation has been updated
  • Commit messages follow the project conventions
  • CHANGELOG has been updated
  • All tests pass locally

Additional Context

Note: This PR was developed with AI assistance (Claude).

Summary by CodeRabbit

  • New Features
    • Added hash-algorithm availability checks so only algorithms supported by the current OpenSSL build are used.
  • Bug Fixes
    • Digest creation now returns errors when an algorithm isn’t supported, eliminating implicit conversion/silent fallback behavior.
    • Improved IMA digest initialization and validation; start/ff now return Result to reflect potential failures.
    • Updated TPM and context initialization to surface unsupported-algorithm errors consistently.
  • Tests
    • Updated hashing-to-digest tests to reflect the new supported/unsupported behavior (including SM3).

@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0c535500-eed1-40d4-a8ee-753c5923e43e

📥 Commits

Reviewing files that changed from the base of the PR and between 865e1ca and e9fa193.

📒 Files selected for processing (5)
  • keylime-ima-emulator/src/main.rs
  • keylime/src/algorithms.rs
  • keylime/src/context_info.rs
  • keylime/src/ima/entry.rs
  • keylime/src/tpm.rs

📝 Walkthrough

Walkthrough

MessageDigest construction now uses fallible conversion from HashAlgorithm, with unsupported digests returning errors. TPM filtering, IMA digest construction, and emulator/context call sites were updated to propagate those failures.

Changes

Fallible digest conversion

Layer / File(s) Summary
Fallible TryFrom conversion and support probe
keylime/src/algorithms.rs
Adds a digest-name mapping, HashAlgorithm::is_supported(), and replaces infallible From<HashAlgorithm> for MessageDigest with fallible TryFrom, with tests updated for the new behavior.
TPM algorithm filtering and conversion
keylime/src/tpm.rs
Filters supported algorithms with is_supported() and converts hash algorithms to MessageDigest through fallible conversion, returning TpmError::UnsupportedHashingAlgorithm on failure.
IMA digest construction
keylime/src/ima/entry.rs
Makes Digest::new, Digest::start, and Digest::ff construct digests through MessageDigest::try_from(...) and return errors when conversion fails.
Consumer call sites
keylime/src/context_info.rs, keylime-ima-emulator/src/main.rs
Updates hash-algorithm validation and digest setup to use fallible MessageDigest construction with propagated errors.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: sarroutbi, sergio-correia

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: switching to runtime OpenSSL algorithm detection to handle missing SM3 support.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ansasaki ansasaki marked this pull request as draft July 3, 2026 13:44
@ansasaki ansasaki force-pushed the fix-sm3-openssl-no-sm3 branch from 2e0c8cf to fe96e1b Compare July 3, 2026 13:50
@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 60.31746% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.67%. Comparing base (28a2e1d) to head (e9fa193).

Files with missing lines Patch % Lines
keylime/src/context_info.rs 18.18% 9 Missing ⚠️
keylime/src/tpm.rs 40.00% 9 Missing ⚠️
keylime/src/algorithms.rs 72.22% 5 Missing ⚠️
keylime/src/ima/entry.rs 83.33% 2 Missing ⚠️
Additional details and impacted files
Flag Coverage Δ
e2e-testsuite 39.06% <44.44%> (+0.01%) ⬆️
upstream-unit-tests 65.65% <48.78%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
keylime-ima-emulator/src/main.rs 66.18% <100.00%> (+0.24%) ⬆️
keylime/src/ima/entry.rs 76.15% <83.33%> (-0.13%) ⬇️
keylime/src/algorithms.rs 78.26% <72.22%> (+1.09%) ⬆️
keylime/src/context_info.rs 45.05% <18.18%> (-0.73%) ⬇️
keylime/src/tpm.rs 64.52% <40.00%> (-0.07%) ⬇️

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ansasaki ansasaki marked this pull request as ready for review July 6, 2026 08:04

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@keylime/src/algorithms.rs`:
- Around line 116-135: The SM3 fallback in TryFrom<HashAlgorithm> for
MessageDigest is gated on a cfg that is only checked, not emitted, so the
unsupported path never becomes active in this crate. Add a crate-local
build-time cfg emission so #[cfg(osslconf = "OPENSSL_NO_SM3")] can actually
fire, and keep the HashAlgorithm::Sm3_256 match arm in algorithms.rs split
between the supported and unsupported OpenSSL cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: cbe8ad81-157e-4b18-bc1b-7750daac9567

📥 Commits

Reviewing files that changed from the base of the PR and between 2e0c8cf and fe96e1b.

📒 Files selected for processing (12)
  • keylime-ima-emulator/Cargo.toml
  • keylime-ima-emulator/src/main.rs
  • keylime-push-model-agent/Cargo.toml
  • keylime-push-model-agent/src/struct_filler.rs
  • keylime/Cargo.toml
  • keylime/src/algorithms.rs
  • keylime/src/context_info.rs
  • keylime/src/ima/entry.rs
  • keylime/src/structures/capabilities_negotiation.rs
  • keylime/src/tpm.rs
  • rpm/centos/rust-keylime-metadata.patch
  • rpm/fedora/rust-keylime-metadata.patch

Comment thread keylime/src/algorithms.rs

@sergio-correia sergio-correia 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.

A few issues to address, mostly around completeness of the SM3 gating.

Not in this diff, but related: get_supported_hash_algorithms() in keylime/src/tpm.rs:1768-1822 returns SM3 from the TPM unfiltered. The PCR banks in available_subjects are correctly filtered (the new cfg guard in struct_filler.rs), and PcrBanks::to_map() also drops SM3. But the hash_algorithms field at struct_filler.rs:249 calls get_supported_hash_algorithms() with no SM3 filtering. If a verifier selects SM3 from the advertised list, the agent fails at hash_alg_to_message_digest().

The simplest fix would be to filter SM3 from the returned list in get_supported_hash_algorithms():

// After building usable_algs, before returning:
#[cfg(osslconf = "OPENSSL_NO_SM3")]
usable_algs.retain(|alg| !matches!(alg, KeylimeInternalHashAlgorithm::Sm3_256));

Comment thread keylime/src/ima/entry.rs Outdated
Comment thread keylime/src/tpm.rs Outdated
Comment thread keylime/src/structures/capabilities_negotiation.rs Outdated
@ansasaki ansasaki force-pushed the fix-sm3-openssl-no-sm3 branch from fe96e1b to 607647b Compare July 6, 2026 12:59
@ansasaki ansasaki changed the title fix: conditionally disable SM3 when OpenSSL is built without support fix: use runtime OpenSSL algorithm detection to handle missing SM3 support Jul 6, 2026
@ansasaki ansasaki force-pushed the fix-sm3-openssl-no-sm3 branch from 607647b to 865e1ca Compare July 7, 2026 11:17

@sergio-correia sergio-correia 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.

A few things to address, mostly around diagnostic logging and fail-fast behavior.

Not in this diff, but related: ContextInfo::new() in keylime/src/context_info.rs:160 accepts the configured tpm_hash_alg and immediately proceeds to create EK/AK objects in the TPM without checking is_supported(). OpenSSL support is only validated much later when get_ak_local_identifier_str() or quote operations invoke MessageDigest::try_from().

If an operator configures tpm_hash_alg = "sm3_256" on a system where OpenSSL lacks SM3, the agent starts, creates EK/AK handles, registers with the verifier, then fails at the first attestation attempt. Would it make sense to add an early is_supported() check before the TPM operations?

let tpm_hash_alg = config.tpm_hash_alg;
if !tpm_hash_alg.is_supported() {
    return Err(ContextInfoError::InvalidAlgorithm(
        AlgorithmError::UnsupportedHashingAlgorithm(format!(
            "{tpm_hash_alg} (not supported by this OpenSSL build)"
        ))
    ));
}

Comment thread keylime/src/tpm.rs Outdated
Comment thread keylime/src/tpm.rs Outdated
…ime symbols

Fedora's OpenSSL is now built with OPENSSL_NO_SM3, which removes
MessageDigest::sm3() from the openssl crate, causing build failures.

Replace all MessageDigest::sha*() and MessageDigest::sm3() associated
function calls with MessageDigest::from_name() runtime lookups via
EVP_get_digestbyname. This makes the code resilient to any algorithm
being removed from OpenSSL without requiring code changes.

Changes:
- algorithms.rs: change From<HashAlgorithm> for MessageDigest to TryFrom
  using from_name() for all algorithms; add is_supported() method and
  openssl_name() mapping to HashAlgorithm
- tpm.rs: hash_alg_to_message_digest delegates to TryFrom instead of
  duplicating the conversion; get_supported_hash_algorithms filters out
  algorithms unavailable in the OpenSSL build with a warning log for
  each dropped algorithm
- entry.rs: Digest::start() and Digest::ff() return Result, using
  MessageDigest::try_from() for digest size; Digest::new() does the same
  for validation
- context_info.rs: early is_supported() check in ContextInfo::new() to
  fail fast if the configured hash algorithm is not available in the
  OpenSSL build
- keylime-ima-emulator/main.rs: update call sites from infallible
  .into() to TryFrom

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
@ansasaki ansasaki force-pushed the fix-sm3-openssl-no-sm3 branch from 865e1ca to e9fa193 Compare July 7, 2026 13:59
@ansasaki ansasaki requested a review from sergio-correia July 8, 2026 07:54

@sergio-correia sergio-correia 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.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants