Skip to content

Conversation

@keldonin
Copy link
Collaborator

Hello team!

this PR is all about optimizing calls when fetching attributes from a (potentially network-based, slow) token. The design goal is to minimize the number of calls to the PKCS#11 layer, using the following strategies:

  • regroup all attributes within one template instead of making individual calls to C_GetAttributeValue
  • for those attributes with a known size, pre-allocate buffer
  • for the others, and only if needed, regroup them in a secondary template, and fetch them all at once
  • Once done, build up resulting array.

I have tried this patch on a PKCS#11 scanning utility. In some cases, the number of invocations to PKCS#11 APIs is an order of magnitude below the original version, I found it a massive improvement in terms of performance and execution time.

A small benchmarking tool has been added to this PR - the intent is to give the ability to test it against different tokens and see how it goes. It will be removed at a later stage. The former get_attributes() has been temporarily renamed get_attributes_old() to allow for the benchmarking.

Results with SoftHSM

Note: SoftHSM is likely to be a worst-case scenario, as fetching attributes is extremely fast on a software-based token. Playing the benchmarking tool against other equipments (smart cards, HSMs) will yield better results.

Different situations have been tested below:

  • multiple: several, mixed attributes are requested
  • single-fixed: a single attribute which size is well known ( e.g. CKA_ENCRYPT)
  • single-variable: a single attribute with a variable size (e.g. CKA_MODULUS)
  • single-nonexist: a single attribute that does not exists for the object

The single-variable case is typically on parity ( the stats varies from run to run between 0.95 and 1.05, which range is within standard deviation). All other cases provide better performance.

╔═══════════════════════════════════════════════════════════════════════════════════════════════════╗
║                                  BENCHMARK SUMMARY TABLE                                          ║
╠═══════════════════╦═════════════╦═════════════╦═════════════╦═════════════╦═══════╦═══════════════╣
║     Test Case     ║   Orig Mean ║    Orig p95 ║    Opt Mean ║     Opt p95 ║ Unit  ║    Speedup    ║
╠═══════════════════╬═════════════╬═════════════╬═════════════╬═════════════╬═══════╬═══════════════╣
║ Multiple          ║     1585.61 ║     2867.11 ║      257.49 ║      409.27 ║    µs ║        x 6.16 ║
║ Single-fixed      ║      281.74 ║      800.74 ║      123.31 ║      160.49 ║    µs ║        x 2.28 ║
║ Single-variable   ║      243.94 ║      308.98 ║      245.94 ║      358.56 ║    µs ║        x 0.99 ║
║ Single-nonexist   ║      279.43 ║      762.66 ║      128.42 ║      159.12 ║    µs ║        x 2.18 ║
╚═══════════════════╩═════════════╩═════════════╩═════════════╩═════════════╩═══════╩═══════════════╝

details (generated by Copilot)

Benchmarking and Developer Tooling

  • Added a new example file benchmark_attributes.rs that benchmarks and compares the performance and correctness of the original (get_attributes_old) and optimized (get_attributes) attribute retrieval implementations. It reports statistics and speedups for various attribute types and scenarios.

Attribute Retrieval Optimization

  • Implemented a new Session::get_attributes method that optimizes attribute retrieval by pre-allocating buffers for attributes with known fixed sizes and minimizing the number of PKCS#11 calls, while maintaining correctness and filtering out unavailable attributes.
  • Renamed the old attribute retrieval method to get_attributes_old for benchmarking and comparison purposes.

Utility and Type Improvements

  • Added the AttributeType::fixed_size method to determine if an attribute type has a known fixed size, supporting buffer pre-allocation and optimization in the new retrieval method.
  • Minor code improvements such as consistent use of c_void and import adjustments to support the new implementation. [1] [2]

Signed-off-by: Eric Devolder <eric.devolder@gmail.com>
…rtcard token when benchmarking

Signed-off-by: Eric Devolder <eric.devolder@gmail.com>
Copilot AI review requested due to automatic review settings November 15, 2025 13:49
Copilot finished reviewing on behalf of keldonin November 15, 2025 13:51
@keldonin keldonin added the enhancement New feature or request label Nov 15, 2025
Copy link

Copilot AI left a comment

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 optimizes PKCS#11 attribute retrieval by reducing the number of API calls through intelligent batching and pre-allocation. The optimization pre-allocates buffers for fixed-size attributes and batches variable-size queries to minimize round-trips to potentially slow network-based tokens.

Key changes:

  • Implemented a new optimized get_attributes() method that uses 1-2 PKCS#11 calls instead of one per attribute
  • Added AttributeType::fixed_size() to identify attributes with known sizes for pre-allocation
  • Renamed the original implementation to get_attributes_old() for benchmarking comparison

Reviewed Changes

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

Show a summary per file
File Description
cryptoki/src/object.rs Adds AttributeType::fixed_size() method to identify fixed-size attributes for optimization (contains critical bug with CK_BBOOL size)
cryptoki/src/session/object_management.rs Implements new optimized get_attributes() and renames old version to get_attributes_old() for comparison
cryptoki/tests/basic.rs Adds comprehensive test coverage for the new get_attributes() implementation
cryptoki/tests/common/mod.rs Adds test utility function get_pretend_library() to simulate different library behaviors
cryptoki/examples/benchmark_attributes.rs Adds benchmarking tool to compare performance between old and new implementations

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

Signed-off-by: Eric Devolder <eric.devolder@gmail.com>
@keldonin keldonin force-pushed the accelerate_fetching_attributes branch from caa0629 to 2375a05 Compare November 17, 2025 21:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant