Skip to content

Add AES-CCM#883

Open
mhochsto wants to merge 3 commits into
softhsm:mainfrom
evva-sfw:main
Open

Add AES-CCM#883
mhochsto wants to merge 3 commits into
softhsm:mainfrom
evva-sfw:main

Conversation

@mhochsto

@mhochsto mhochsto commented Jun 11, 2026

Copy link
Copy Markdown

Cherry Picked AES-CCM Implementation from #798

Summary by CodeRabbit

  • New Features

    • Added support for AES-CCM authenticated encryption/decryption across implementations.
  • Documentation

    • Updated installation notes to require OpenSSL 3.6+ for AES-CCM.
  • Tests

    • Added unit tests validating AES-CCM against NIST vectors to ensure interoperability and correct behavior.

mhochsto added 2 commits June 10, 2026 07:28
…-kem/586adccc85646fd59a8da225db489547a53a563b ml-kem/86bfed65ccdc8503f106c99950c1649b3eae294f
@mhochsto mhochsto requested a review from a team as a code owner June 11, 2026 13:36
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds PKCS#11 AES-CCM support: enum, mechanism registration and parameter parsing, Botan and OpenSSL backend AEAD implementations, AEAD buffering updates, unit tests, and documentation noting OpenSSL 3.6+ requirement.

Changes

AES-CCM Cipher Mode Support

Layer / File(s) Summary
Cipher mode enumeration
src/lib/crypto/SymmetricAlgorithm.h
SymMode::Type now includes CCM.
PKCS#11 mechanism registration
src/lib/SoftHSM.cpp
Adds CKM_AES_CCM to mechanism mappings, includes it in C_GetMechanismInfo, and marks it symmetric in isSymMechanism.
PKCS#11 parameter parsing
src/lib/SoftHSM.cpp
SymEncryptInit/SymDecryptInit parse CK_CCM_PARAMS, validate struct presence/size, map nonce→iv, aad→aad, ulMACLen→tagBytes, ulDataLen→counterBits, enforce nonce length (7–13) and MAC-length whitelist {16,14,12,10,8}.
Botan backend support
src/lib/crypto/BotanAES.cpp, src/lib/crypto/BotanSymmetricAlgorithm.cpp
BotanAES::getCipher() builds CCM cipher descriptor (tagBytes,L); BotanSymmetricAlgorithm treats CCM like GCM for IV validation and AEAD path, adds CCM AEAD setup with optional AAD, and defers plaintext until finalization.
OpenSSL backend support
src/lib/crypto/OSSLAES.cpp, src/lib/crypto/OSSLEVPSymmetricAlgorithm.cpp
OSSLAES::getCipher() selects EVP AES-CCM by key size; OSSLEVPSymmetricAlgorithm sets IV/tag/L, initializes key/nonce, handles AAD, appends/get/sets CCM tag on encrypt/decrypt finalization, and buffers AEAD ciphertext until final.
Base class AEAD logic
src/lib/crypto/SymmetricAlgorithm.cpp
decryptUpdate now buffers AEAD data for both GCM and CCM.
Tests and documentation
src/lib/crypto/test/AESTests.cpp, src/lib/crypto/test/AESTests.h, src/lib/crypto/test/DESTests.h, README.md, OSX-NOTES.md
Adds AESTests::testCCM() with vectors, conditionally registers testECB when WITH_BOTAN is unset, updates test declarations, and documents OpenSSL 3.6+ requirement.

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly Related PRs

Suggested Reviewers

  • kalvdans
  • bjosv
  • jschlyter

Poem

🐰 In code and carrots I did roam,

I stitched a CCM into home,
Botan, OpenSSL, both now sing,
Authenticated tags take wing,
Hoppity tests make sure it's known.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'Add AES-CCM' is clear, concise, and directly summarizes the main change—adding AES-CCM cipher mode support across the codebase.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@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: 2

🧹 Nitpick comments (1)
src/lib/crypto/test/AESTests.cpp (1)

1257-1257: 💤 Low value

Avoid recalculating the subtraction.

The expression shsmCipherText.size() - tagBits is evaluated twice. Consider comparing sizes first to avoid redundant arithmetic.

♻️ Proposed refactor
-		int dataSize = shsmCipherText.size() - tagBits > 0 ? shsmCipherText.size() - tagBits : 0;
+		size_t dataSize = (shsmCipherText.size() > tagBits) ? (shsmCipherText.size() - tagBits) : 0;
🤖 Prompt for 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.

In `@src/lib/crypto/test/AESTests.cpp` at line 1257, Compute the subtraction once
and reuse it: cache shsmCipherText.size() into a local variable (or compute diff
into a temp) and then set dataSize using that cached value (reference
shsmCipherText, tagBits, and dataSize) so you avoid evaluating
shsmCipherText.size() - tagBits twice; replace the ternary that repeats the
subtraction with a single comparison against the cached size and one subtraction
if needed.
🤖 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 `@src/lib/crypto/test/AESTests.cpp`:
- Line 1219: The loop currently iterating over the AES128 test vectors uses `for
(int i = 0; i < 12; i++)` and therefore skips the final entry in the `test128`
array (index 12); update the loop condition to `i < 13` so the iteration covers
all 13 vectors, ensuring the test loop that references `test128` validates the
last test vector as well.

In `@src/lib/SoftHSM.cpp`:
- Around line 2471-2477: The CCM parameter validation must accept ulMACLen
values 4,6,8,10,12,14,16 and must enforce ulDataLen < 2^(8*L) where L = 15 -
ulNonceLen before passing parameters to encryptInit/decryptInit; update the
validation around CK_CCM_PARAMS_PTR(pMechanism->pParameter) (variables tagBytes
and counterBits) to allow 4 and 6, fix the DEBUG_MSG to list 4 and 6, compute L
from CK_CCM_PARAMS_PTR(...)->ulNonceLen and check counterBits (ulDataLen) is
less than (1ULL << (8 * L)) and return CKR_ARGUMENTS_BAD on violation, and
ensure this same logic is applied at both occurrences (around the blocks
handling encryptInit/decryptInit).

---

Nitpick comments:
In `@src/lib/crypto/test/AESTests.cpp`:
- Line 1257: Compute the subtraction once and reuse it: cache
shsmCipherText.size() into a local variable (or compute diff into a temp) and
then set dataSize using that cached value (reference shsmCipherText, tagBits,
and dataSize) so you avoid evaluating shsmCipherText.size() - tagBits twice;
replace the ternary that repeats the subtraction with a single comparison
against the cached size and one subtraction if needed.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3748017a-fae0-4bda-8b73-a1787ec4d724

📥 Commits

Reviewing files that changed from the base of the PR and between de25233 and 0523073.

📒 Files selected for processing (11)
  • README.md
  • src/lib/SoftHSM.cpp
  • src/lib/crypto/BotanAES.cpp
  • src/lib/crypto/BotanSymmetricAlgorithm.cpp
  • src/lib/crypto/OSSLAES.cpp
  • src/lib/crypto/OSSLEVPSymmetricAlgorithm.cpp
  • src/lib/crypto/SymmetricAlgorithm.cpp
  • src/lib/crypto/SymmetricAlgorithm.h
  • src/lib/crypto/test/AESTests.cpp
  • src/lib/crypto/test/AESTests.h
  • src/lib/crypto/test/DESTests.h

};


for (int i = 0; i < 12; i++)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Loop bound excludes the last test vector.

The test128 array defines 13 test vectors (indices 0–12), but the loop only iterates to i < 12, skipping the vector at index 12 (lines 1208–1215). Change the loop condition to i < 13 to test all vectors.

🔧 Proposed fix
-	for (int i = 0; i < 12; i++)
+	for (int i = 0; i < 13; i++)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
for (int i = 0; i < 12; i++)
for (int i = 0; i < 13; i++)
🤖 Prompt for 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.

In `@src/lib/crypto/test/AESTests.cpp` at line 1219, The loop currently iterating
over the AES128 test vectors uses `for (int i = 0; i < 12; i++)` and therefore
skips the final entry in the `test128` array (index 12); update the loop
condition to `i < 13` so the iteration covers all 13 vectors, ensuring the test
loop that references `test128` validates the last test vector as well.

Comment thread src/lib/SoftHSM.cpp
Comment on lines +2471 to +2477
tagBytes = CK_CCM_PARAMS_PTR(pMechanism->pParameter)->ulMACLen;
counterBits = CK_CCM_PARAMS_PTR(pMechanism->pParameter)->ulDataLen;
if (tagBytes != 16 && tagBytes != 14 && tagBytes != 12 && tagBytes != 10 && tagBytes != 8)
{
DEBUG_MSG("Invalid ulMACLen value, is %#5d should be 16, 14, 12, 10 or 8", tagBytes);
return CKR_ARGUMENTS_BAD;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix CCM parameter validation (CK_CCM_PARAMS) for ulMACLen and ulDataLen.

ulMACLen must allow 4, 6, 8, 10, 12, 14, 16, but the current check rejects 4 and 6 (and the DEBUG_MSG text also omits them). Also add the spec-required bound ulDataLen < 2^(8L) with L = 15 - ulNonceLen before forwarding parameters into encryptInit / decryptInit.

File: src/lib/SoftHSM.cpp (also applies to 3255-3261)

Suggested fix
-			if (tagBytes != 16 &amp;&amp; tagBytes != 14 &amp;&amp; tagBytes != 12 &amp;&amp; tagBytes != 10 &amp;&amp; tagBytes != 8)
+			if (tagBytes != 16 &amp;&amp; tagBytes != 14 &amp;&amp; tagBytes != 12 &amp;&amp;
+			    tagBytes != 10 &amp;&amp; tagBytes != 8 &amp;&amp; tagBytes != 6 &amp;&amp; tagBytes != 4)
 			{
 				DEBUG_MSG("Invalid ulMACLen value, is %#5d should be 16, 14, 12, 10 or 8", tagBytes);
 				return CKR_ARGUMENTS_BAD;
 			}
+			size_t L = 15 - CK_CCM_PARAMS_PTR(pMechanism-&gt;pParameter)-&gt;ulNonceLen;
+			if (L &lt; sizeof(CK_ULONG) &amp;&amp;
+			    CK_CCM_PARAMS_PTR(pMechanism-&gt;pParameter)-&gt;ulDataLen &gt;= (CK_ULONG(1) &lt;&lt; (8 * L)))
+			{
+				return CKR_MECHANISM_PARAM_INVALID;
+			}

Update the DEBUG_MSG text to include 4 and 6 as well.

🤖 Prompt for 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.

In `@src/lib/SoftHSM.cpp` around lines 2471 - 2477, The CCM parameter validation
must accept ulMACLen values 4,6,8,10,12,14,16 and must enforce ulDataLen <
2^(8*L) where L = 15 - ulNonceLen before passing parameters to
encryptInit/decryptInit; update the validation around
CK_CCM_PARAMS_PTR(pMechanism->pParameter) (variables tagBytes and counterBits)
to allow 4 and 6, fix the DEBUG_MSG to list 4 and 6, compute L from
CK_CCM_PARAMS_PTR(...)->ulNonceLen and check counterBits (ulDataLen) is less
than (1ULL << (8 * L)) and return CKR_ARGUMENTS_BAD on violation, and ensure
this same logic is applied at both occurrences (around the blocks handling
encryptInit/decryptInit).

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
OSX-NOTES.md (1)

91-91: ⚠️ Potential issue | 🟠 Major

Fix --with-openssl path mismatch in OSX-NOTES.md

OSX-NOTES.md installs [email protected] (line 46), but the ./configure commands hardcode --with-openssl=/usr/local/opt/openssl (lines 91 and 101). Update these to use the [email protected] prefix so the configure step finds the correct OpenSSL.

💡 Suggested update for both occurrences
 	$ ./configure --with-objectstore-backend-db \
-		--with-openssl=/usr/local/opt/openssl \
+		--with-openssl=/usr/local/opt/[email protected] \
 		--with-sqlite3=/usr/local/opt/sqlite

 	$ ./configure --with-objectstore-backend-db \
-		--with-openssl=/usr/local/opt/openssl \
+		--with-openssl=/usr/local/opt/[email protected] \
 		--with-sqlite3=/usr/local/opt/sqlite
🤖 Prompt for 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.

In `@OSX-NOTES.md` at line 91, The configure commands currently hardcode
--with-openssl=/usr/local/opt/openssl which mismatches the installed formula
[email protected]; update both occurrences of the --with-openssl flag in the configure
command examples to point to the [email protected] prefix (e.g.
/usr/local/opt/[email protected]) or use the Brew prefix command substitution (brew
--prefix [email protected]) so the configure step finds the correct OpenSSL.
🧹 Nitpick comments (1)
OSX-NOTES.md (1)

51-52: ⚡ Quick win

Clarify the issue reference for better documentation.

The reference "issue #22773" is ambiguous without specifying which repository or system it refers to. Consider using "OpenSSL issue #22773" or providing a full URL for clarity.

📝 Suggested clarification
-OpenSSL 3.6+ required for AES-CCM ref issue `#22773`
+OpenSSL 3.6+ required for AES-CCM (see OpenSSL issue `#22773` or https://github.com/openssl/openssl/issues/22773)
🤖 Prompt for 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.

In `@OSX-NOTES.md` around lines 51 - 52, The note "OpenSSL 3.6+ required for
AES-CCM ref issue `#22773`" is ambiguous; update that line (the "OpenSSL 3.6+
required for AES-CCM ref issue `#22773`" entry) to explicitly reference the
repository or include a full URL—e.g., "OpenSSL 3.6+ required for AES-CCM
(OpenSSL issue `#22773`: https://github.com/openssl/openssl/issues/22773)"—so
readers can locate the referenced issue unambiguously.
🤖 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 `@OSX-NOTES.md`:
- Line 46: Update the OpenSSL path used in the configure flags to match the
installed Homebrew formula by replacing the hardcoded
"--with-openssl=/usr/local/opt/openssl" with the versioned path for the
installed formula (e.g., "--with-openssl=/usr/local/opt/[email protected]" or the
Homebrew symlink target) so the build links against [email protected] that you
installed with "brew install [email protected]"; also replace the ambiguous "ref issue
`#22773`" note with a full repository/URL reference (e.g.,
https://github.com/ORG/REPO/issues/22773) so readers can find the issue context.

---

Outside diff comments:
In `@OSX-NOTES.md`:
- Line 91: The configure commands currently hardcode
--with-openssl=/usr/local/opt/openssl which mismatches the installed formula
[email protected]; update both occurrences of the --with-openssl flag in the configure
command examples to point to the [email protected] prefix (e.g.
/usr/local/opt/[email protected]) or use the Brew prefix command substitution (brew
--prefix [email protected]) so the configure step finds the correct OpenSSL.

---

Nitpick comments:
In `@OSX-NOTES.md`:
- Around line 51-52: The note "OpenSSL 3.6+ required for AES-CCM ref issue
`#22773`" is ambiguous; update that line (the "OpenSSL 3.6+ required for AES-CCM
ref issue `#22773`" entry) to explicitly reference the repository or include a
full URL—e.g., "OpenSSL 3.6+ required for AES-CCM (OpenSSL issue `#22773`:
https://github.com/openssl/openssl/issues/22773)"—so readers can locate the
referenced issue unambiguously.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba0da6d5-a7c0-4873-8ecc-6e87b1de5aae

📥 Commits

Reviewing files that changed from the base of the PR and between 0523073 and 45066d6.

📒 Files selected for processing (1)
  • OSX-NOTES.md

Comment thread OSX-NOTES.md
$ brew install automake
$ brew install pkg-config
$ brew install openssl
$ brew install openssl@3.6

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Verify the availability of [email protected] in Homebrew

# Check if the formula exists
brew info [email protected] 2>&1 | head -20

Repository: softhsm/SoftHSMv2

Length of output: 104


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant sections around the referenced line numbers
echo "---- OSX-NOTES.md: around line 35-70 ----"
nl -ba OSX-NOTES.md | sed -n '35,75p'

echo "---- OSX-NOTES.md: around line 80-115 ----"
nl -ba OSX-NOTES.md | sed -n '80,115p'

Repository: softhsm/SoftHSMv2

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "---- OSX-NOTES.md: around line 35-75 ----"
awk 'NR>=35 && NR<=75 { printf "%d:%s\n", NR, $0 }' OSX-NOTES.md

echo "---- OSX-NOTES.md: around line 80-115 ----"
awk 'NR>=80 && NR<=115 { printf "%d:%s\n", NR, $0 }' OSX-NOTES.md

Repository: softhsm/SoftHSMv2

Length of output: 2744


Align --with-openssl path with [email protected]

  • brew install [email protected] but ./configure uses --with-openssl=/usr/local/opt/openssl (lines 91-92, 101-102); update to the versioned OpenSSL path (e.g., /usr/local/opt/[email protected], or whatever Homebrew symlink targets) to ensure the build links against the intended OpenSSL 3.6+.
  • “ref issue #22773” needs clearer context (repo/URL) for readers (lines 51-52).
🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 46-46: Dollar signs used before commands without showing output

(MD014, commands-show-output)

🤖 Prompt for 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.

In `@OSX-NOTES.md` at line 46, Update the OpenSSL path used in the configure flags
to match the installed Homebrew formula by replacing the hardcoded
"--with-openssl=/usr/local/opt/openssl" with the versioned path for the
installed formula (e.g., "--with-openssl=/usr/local/opt/[email protected]" or the
Homebrew symlink target) so the build links against [email protected] that you
installed with "brew install [email protected]"; also replace the ambiguous "ref issue
`#22773`" note with a full repository/URL reference (e.g.,
https://github.com/ORG/REPO/issues/22773) so readers can find the issue context.

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.

1 participant