Skip to content

Implement jwe enc - #26

Open
keldonin wants to merge 2 commits into
Mastercard:mainfrom
keldonin:implement_jwe_enc
Open

Implement jwe enc#26
keldonin wants to merge 2 commits into
Mastercard:mainfrom
keldonin:implement_jwe_enc

Conversation

@keldonin

Copy link
Copy Markdown
Contributor

This pull request adds support for JWE-like encryption test cases to the PKCS#11 performance test suite. The new tests benchmark the process of generating an AES session key, wrapping it with RSA OAEP, encrypting content with AES GCM, and destroying the session key—all performed on a PKCS#11 token. The changes include new test case implementations, updates to test selection and coverage, and documentation.

New JWE-like encryption test support:

  • Added a new benchmark class P11JWEEncryptBenchmark in p11jweenc.cpp/p11jweenc.hpp to perform JWE-like encryption (RSA OAEP key wrapping + AES GCM content encryption), supporting SHA1/SHA256 for OAEP and AES GCM with 128/192/256-bit keys. [1] [2]
  • Integrated the new test into the test runner: updated p11perftest.cpp to recognize jweenc, jweencoaepsha1, and jweencoaepsha256 as valid test cases, including them in the default test set and help text, and instantiating the new benchmarks for all supported RSA/AES key size combinations. [1] [2] [3] [4] [5]
  • Updated the build system to compile the new source files by adding them to src/Makefile.am.

Test coverage and documentation:

  • Extended the test coverage tracking in testcoverage.cpp/testcoverage.hpp to include the new JWE-like encryption cases and their variants (jweenc, jweencoaepsha1, jweencoaepsha256). [1] [2] [3]
  • Documented the addition of JWE-like encryption test cases in the CHANGELOG.md.

Copilot AI review requested due to automatic review settings March 25, 2026 15:33

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 a new “JWE-like encryption” benchmark to the PKCS#11 performance test suite, covering the workflow of generating an AES session key on-token, wrapping it with RSA-OAEP, encrypting payload data with AES-GCM, and destroying the session key.

Changes:

  • Added P11JWEEncryptBenchmark (p11jweenc.cpp/.hpp) implementing RSA-OAEP key wrap + AES-GCM content encryption variants (SHA1/SHA256 OAEP; AES-128/192/256 GCM).
  • Integrated the new jweenc/jweencoaepsha1/jweencoaepsha256 coverage into the CLI runner and default test set.
  • Extended test coverage tracking, build sources, and changelog documentation for the new benchmark.

Reviewed changes

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

Show a summary per file
File Description
src/p11jweenc.hpp Declares the new JWE-like encryption benchmark class and its variants.
src/p11jweenc.cpp Implements the benchmark: AES keygen, RSA-OAEP wrap, AES-GCM encrypt, key destroy.
src/p11perftest.cpp Registers new test names, updates defaults/help text, and instantiates benchmarks across key sizes.
src/testcoverage.hpp Adds new coverage enum values for jweenc and OAEP hash subsets.
src/testcoverage.cpp Maps new CLI tokens/aliases to coverage enum values and contains() checks.
src/Makefile.am Adds the new source/header to the build.
CHANGELOG.md Documents the new JWE-like encryption benchmark under Unreleased.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/p11jweenc.cpp
Comment on lines +88 to +91
// shuffle IV to avoid reusing values between iterations
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(m_iv.begin(), m_iv.end(), g);

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

In the generic flavour, m_iv is resized but never populated with non-zero data before std::shuffle(). Shuffling a freshly resized vector (all zeros) does not produce a random IV, so the IV ends up constant across iterations despite the comment. Populate the IV with random bytes (or another deterministic-but-unique strategy) before use.

Suggested change
// shuffle IV to avoid reusing values between iterations
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(m_iv.begin(), m_iv.end(), g);
// populate IV with random bytes to avoid reusing values between iterations
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<unsigned int> dist(0, 255);
for (auto &b : m_iv) {
b = static_cast<decltype(b)>(dist(gen));
}

Copilot uses AI. Check for mistakes.
Comment thread src/p11jweenc.cpp
Comment on lines +214 to +217
Ulong returned_len = m_encrypted.size();
session.module()->C_EncryptInit(session.handle(), &m_mech_aes_gcm, symkey_handle);
session.module()->C_Encrypt(session.handle(), m_payload.data(), m_payload.size(), m_encrypted.data(), &returned_len);
m_encrypted.resize(returned_len);

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

m_encrypted.resize(returned_len) shrinks the output buffer on every iteration. Because the next iteration re-expands the buffer (see the size check just above), this can introduce repeated reallocations inside the timed region and skew benchmark results. Consider keeping the buffer at a fixed max size and tracking returned_len separately (or avoid shrinking the vector in the hot path).

Copilot uses AI. Check for mistakes.
Comment thread src/p11perftest.cpp
@@ -149,7 +150,8 @@ int main(int argc, char **argv)
" - oaep = oaepsha1 + oaepsha256\n"
" - oaepuwn = oaepunwsha1 + oaepunwsha256\n"

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

The help text lists the compound test case as oaepuwn, but the actual test name elsewhere is oaepunw (unwrap). This typo makes the CLI help misleading; please change it to oaepunw.

Suggested change
" - oaepuwn = oaepunwsha1 + oaepunwsha256\n"
" - oaepunw = oaepunwsha1 + oaepunwsha256\n"

Copilot uses AI. Check for mistakes.
Comment thread src/p11perftest.cpp
@@ -113,7 +114,7 @@ int main(int argc, char **argv)
po::options_description envvars("environment variables");

// default coverage: RSA, ECDSA, HMAC, DES and AES

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

The comment says the default coverage is "RSA, ECDSA, HMAC, DES and AES", but default_tests now also includes ECDH, xorder, rand, find, JWE, JWE encryption, and OAEP-related tests. Please update the comment (or remove it) so it matches the actual default set.

Suggested change
// default coverage: RSA, ECDSA, HMAC, DES and AES
// default coverage: RSA (incl. PSS), ECDSA, ECDH, HMAC, DES, AES, xorder, rand, find, JWE (incl. encryption), and OAEP (incl. wrap/unwrap)

Copilot uses AI. Check for mistakes.
Comment thread src/p11perftest.cpp

// default coverage: RSA, ECDSA, HMAC, DES and AES
const auto default_tests {"rsa,rsapss,ecdsa,ecdh,hmac,des,aes,xorder,rand,find,jwe,oaep,oaepenc,oaepunw"};
const auto default_tests {"rsa,rsapss,ecdsa,ecdh,hmac,des,aes,xorder,rand,find,jwe,jweenc,oaep,oaepenc,oaepunw"};

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.

I believe this got converted to tab, convert back to spaces.

Comment thread src/p11jweenc.cpp
session.module()->C_Encrypt(session.handle(), m_payload.data(), m_payload.size(), m_encrypted.data(), &returned_len);
m_encrypted.resize(returned_len);

session.module()->C_DestroyObject(session.handle(), symkey_handle);

@covertmatthew covertmatthew Apr 1, 2026

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.

I noticed that in p11jwe.cpp the timer is suspended at various points before destroying the test object and returning, e.g.

suspend_timer();

As noted in P11JWEBenchmark::crashtestdummy, there are some housekeeping steps that should not be timed. Should there be a similar consideration here for P11JWEEncryptBenchmark::crashtestdummy? Maybe before the resizing calls?

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.

3 participants