Skip to content

SE050Sim: applet 3.1.1/7.2.0 personalities and hardware-verified gap fixes - #13

Merged
LinuxJedi merged 2 commits into
wolfSSL:mainfrom
LinuxJedi:se050-applet-personalities
Aug 3, 2026
Merged

SE050Sim: applet 3.1.1/7.2.0 personalities and hardware-verified gap fixes#13
LinuxJedi merged 2 commits into
wolfSSL:mainfrom
LinuxJedi:se050-applet-personalities

Conversation

@LinuxJedi

Copy link
Copy Markdown
Member

Summary

Follow-up to the August 2026 bench sessions that cross-checked the simulator against real silicon: an SE051 (applet 7.2.0) and an SE050C (applet 3.1.1), probed with raw Se05x_API_* APDUs and NIST/RFC test vectors. Every behavior change below is traceable to a hardware run on one or both parts.

Applet personality (new)

SE050_SIM_APPLET selects the presented part at runtime: unset/7.2.0 = SE051 (default, matching what the simulator always advertised), 3/3.1.1 = SE050C. Modelled differences:

Behavior 3.1.1 7.2.0
SELECT / GetVersion blob 03 01 01 6f ff 01 0b 07 02 00 3f ff ff ff
GetFreeMemory reply U16, 31304/575/560 U32, 21000/605/592
GetRandom cap 880 bytes 1018 bytes
ReadType for EC keys generic 0x01/0x03 curve-specific (P-256 pair 0x29, P-521 0x31)
Duplicate CreateECCurve 0x9000 + params silently wiped 0x6985, curve intact

Fixes verified identical on both generations

  • MAC surface added: HMAC-SHA1/256/384/512 + AES-CMAC, one-shot and multi-step, generate and validate (previously unrouted, 0x6A86). Vectors: RFC 4231 / SP800-38B as returned by both chips.
  • AESKey objects are never exportable: ReadObject now 0x6986 like HMACKey, including with POLICY_OBJ_ALLOW_READ attached.
  • Cipher mode byte honored: ECB_NOPAD / CBC_NOPAD / CTR verified against SP800-38A vectors; unaligned NOPAD input 0x6985. Previously every mode silently ran CBC.
  • Streaming cipher emits output per CipherUpdate (with CBC chaining / CTR counters across calls); Final returns only the remainder.
  • Crypto-object lifecycle enforced: Init on a never-created crypto object 0x6985; duplicate CreateCryptoObject 0x6986. DigestInit now accepts the real wire format (TAG_2 only; algo from the CreateCryptoObject subtype) - the old handler required a TAG_1 the SDK never sends.
  • EC curves are stateful objects: create / set-param / delete / list (SET=0x02 / NOT_SET=0x01), keygen and import require a fully parameterized curve (0x6985 otherwise), state persists. The simulator pre-provisions P-192..P-521 so hosts that never create curves keep working; DeleteAll re-provisions.
  • P-521 and P-192 support end to end (keygen/import/sign/verify/ECDH). p192 0.13 only ships the verify primitive, so signing is implemented over its arithmetic and tested against the crate's own VerifyingKey.
  • ECDSA algo/length contract: input must equal the algo digest length (bench: SHA256+20B and SHA512+32B fail 0x6985; SHA1+20B and SHA512+64B pass; leftmost-truncation host-verified on both parts).
  • Status words: missing objects and delete-nonexistent are 0x6985 (not 0x6A82 / 0x9000); binary bounds enforced (read past end 0x6985, write past end 0x6A80, size immutable); ReadSize reports EC scalar sizes (32 for P-256, 66 for P-521); counters keep their creation-time size with Set/Inc semantics; ReadIDList emits TAG_1 more-indicator + TAG_2 ID array with type filtering; GetRandom(0) refused; DigestOneShot hashes the empty message; WriteUserID refused 0x6985 in plain sessions (verified via raw APDU and the sss layer on both parts).

Store schema

Persisted JSON is now {"objects": {...}, "ec_curves": {...}} with a fallback loader for legacy flat-map store files (covered by tests).

Test plan

  • cargo test -- --test-threads=1: 72 lib + 14 driver integration tests pass, including under SE050_SIM_APPLET=3.1.1.
  • New unit tests pin each hardware-verified behavior with the exact SWs/vectors captured on the bench.
  • Docker tiers exercise strictly more surface than before (MAC, cipher modes, curve flows); the sdk-test and wolfcrypt tiers should be watched on CI.

…ed gaps

Every behavior below was cross-checked against real silicon in the
August 2026 bench sessions: an SE051 (applet 7.2.0) and an SE050C
(applet 3.1.1) driven over raw Se05x_API_* APDUs on the Raspberry Pi
bench, with NIST/RFC vectors where applicable.

SE050_SIM_APPLET selects the personality at runtime (default 7.2.0;
3/3.1.1 for the SE050C). Modelled differences: SELECT/GetVersion
blobs, GetFreeMemory width (U16 vs U32) and values, GetRandom cap
(880 vs 1018 bytes), EC ReadType codes (generic vs curve-specific),
and duplicate CreateECCurve (7.2 refuses 0x6985; 3.x accepts and
silently wipes the curve params).

Fixes applying to both generations:
- MAC surface: HMAC-SHA1/256/384/512 + AES-CMAC, one-shot and
  multi-step, generate and validate (was entirely missing, 0x6A86).
- ReadObject on AESKey objects now refused 0x6986 like HMACKey,
  regardless of an attached ALLOW_READ policy.
- Cipher mode byte honored: ECB_NOPAD/CBC_NOPAD/CTR implemented and
  verified against SP800-38A vectors; unaligned NOPAD input 0x6985.
- Streaming cipher emits output per CipherUpdate with proper chaining
  and returns only the remainder at Final.
- Crypto-object lifecycle enforced: CreateCryptoObject required before
  Init (0x6985), duplicate create 0x6986; DigestInit now takes the
  real wire format (TAG_2 only, algo from the create subtype).
- EC Weierstrass curves are stateful objects: create/set-param/delete/
  list with SET=0x02 semantics, keygen requires a fully parameterized
  curve. The sim pre-provisions P-192..P-521 so existing hosts keep
  working; DeleteAll re-provisions.
- P-521 and P-192 supported end to end (keygen/import/sign/verify/
  ECDH); p192 0.13 lacks a sign primitive so signing is implemented
  over its arithmetic and tested against its VerifyingKey.
- ECDSA sign/verify enforce input length == algo digest length.
- Missing-object and delete-nonexistent SWs corrected to 0x6985;
  binary file bounds enforced (read past end 0x6985, write past end
  0x6A80, size immutable); ReadSize reports EC scalar sizes; counter
  size fixed at creation with Set/Inc semantics; ReadIDList emits the
  TAG_1 more-indicator + TAG_2 ID-list format with type filtering;
  GetRandom(0) refused; DigestOneShot hashes the empty message;
  WriteUserID refused 0x6985 in plain sessions.

Object store schema extended to {objects, ec_curves} with a fallback
loader for legacy flat-map files.
Copilot AI review requested due to automatic review settings August 3, 2026 15:47

Copilot AI 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.

Pull request overview

This PR updates the SE050 simulator to match hardware-verified behavior observed on SE050C (applet 3.1.1) and SE051 (applet 7.2.0), including a runtime “applet personality” switch and numerous correctness fixes across object management and crypto operations.

Changes:

  • Add applet personality selection (SE050_SIM_APPLET) to model 3.1.1 vs 7.2.0 deltas (version blobs, GetRandom cap, GetFreeMemory width, EC ReadType codes, CreateECCurve duplicate behavior).
  • Implement/repair hardware-aligned crypto and object behaviors (MAC surface, AES cipher modes + streaming semantics, curve object lifecycle/state, corrected status words and bounds rules).
  • Update persistence schema to include EC curve state with a legacy loader + tests.

Reviewed changes

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

Show a summary per file
File Description
SE050Sim/se050-sim/src/object_store/types.rs Extend curve/type modeling (P-192/P-521, scalar sizing, EC ReadType version dependence, counter size persistence).
SE050Sim/se050-sim/src/object_store/mod.rs Add persistent EC-curve state, new JSON schema + legacy fallback loader, and tests.
SE050Sim/se050-sim/src/lib.rs Export new applet module.
SE050Sim/se050-sim/src/handlers/session.rs Make SELECT response version-dependent via AppletVersion.
SE050Sim/se050-sim/src/handlers/rsa.rs Align missing-object status word handling with hardware behavior.
SE050Sim/se050-sim/src/handlers/object_mgmt.rs Enforce hardware bounds/semantics for Binary/Counter/UserID/AESKey exports; version-dependent ReadType/ReadIDList.
SE050Sim/se050-sim/src/handlers/mod.rs Register new curve and mac handlers.
SE050Sim/se050-sim/src/handlers/management.rs Implement version-dependent GetVersion/GetFreeMemory/GetRandom behavior + tests.
SE050Sim/se050-sim/src/handlers/mac.rs Add HMAC/CMAC one-shot and streaming MAC operations + tests.
SE050Sim/se050-sim/src/handlers/ec.rs Add P-192/P-521 support, enforce ECDSA algo/length contract, and integrate curve-object readiness checks.
SE050Sim/se050-sim/src/handlers/digest.rs Make DigestOneShot accept empty input; make DigestInit use crypto-object subtype wire format.
SE050Sim/se050-sim/src/handlers/curve.rs Implement Create/Param/Delete/List EC curve object lifecycle with version-dependent duplicate-create behavior + tests.
SE050Sim/se050-sim/src/handlers/crypto_obj.rs Enforce duplicate CreateCryptoObject as 0x6986.
SE050Sim/se050-sim/src/handlers/aes.rs Honor cipher mode byte, implement ECB/CBC/CTR + streaming output semantics, and add NIST-vector tests.
SE050Sim/se050-sim/src/dispatch.rs Thread applet personality/version flag through dispatch; route curve + MAC commands.
SE050Sim/se050-sim/src/applet.rs Add AppletVersion personality selection and version-specific constants/encodings.
SE050Sim/se050-sim/src/apdu.rs Add new P2 constants for curve param + MAC operations.
SE050Sim/se050-sim/Cargo.toml Add crypto dependencies needed for new curve/MAC functionality.
Suppressed comments (2)

SE050Sim/se050-sim/src/handlers/ec.rs:38

  • The pad_hash doc comment says it "right-pad[s] with zeros", but the implementation truncates longer inputs and left-pads shorter inputs (which matches the inline comment in the body). Please update the comment to match the actual behavior to avoid confusion when reasoning about ECDSA prehash handling.
/// Pad a hash to the curve's scalar size (right-pad with zeros).
/// ECDSA requires the hash to be at least as long as the curve order.
/// When the hash is shorter (e.g., SHA-1 on P-384), it must be padded.

SE050Sim/se050-sim/src/object_store/mod.rs:290

  • This test also uses a fixed temp filename (se050_sim_curve_store_test.json), which can collide when tests run in parallel or when multiple test processes run on the same machine. Make the temp path unique per test run to avoid flakes.
        let dir = std::env::temp_dir();
        let path = dir.join("se050_sim_curve_store_test.json");

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

Comment thread SE050Sim/se050-sim/src/handlers/mac.rs
Comment thread SE050Sim/se050-sim/src/object_store/mod.rs Outdated
…paths

MACInit now requires the crypto object to have been created with the
SIGNATURE context (0x03), matching how the SDK creates MAC contexts
and how the digest (0x01) and cipher (0x02) handlers already validate
theirs. The persistence tests write to per-invocation store paths
(pid + nanos) so concurrent cargo test processes cannot interfere
through a shared temp file.
@LinuxJedi
LinuxJedi merged commit 07a8dcf into wolfSSL:main Aug 3, 2026
21 checks passed
@LinuxJedi
LinuxJedi deleted the se050-applet-personalities branch August 3, 2026 16:18
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