SE050Sim: support direct ECDH variant, never export HMACKey objects - #12
Merged
Merged
Conversation
Real SE051 applet 7.2.0 hardware settled two behaviors the simulator modeled wrongly: ReadObject on an HMACKey object fails with SW 0x6986 even when the object's attributes confirm an attached POLICY_OBJ_ALLOW_READ, so the read-policy exception honored since the strict-mode enforcement landed does not exist on silicon. Refuse HMACKey reads unconditionally; the policy recorded at WriteSymmKey stays as attribute bookkeeping. The Tag7-less ECDHGenerateSharedSecret form is how a host obtains an ECDH secret on applet >= 7.2: the applet returns it in the response (big endian for Montgomery curves, byte swapped by the SDK around the call) and touches no object. The simulator rejected Tag7-less requests with SW_WRONG_DATA; accept them in strict and lenient mode alike, with the strict InObject target contract unchanged for Tag7 requests. Rewrite the sdk-test P-256 and X25519 ECDH tests to the direct variant, since the derive-into-object-and-read-back flow they encoded is impossible on real parts, and drop their derive-target policy globals. Verified: 52 cargo tests; wolfCrypt-vs-simulator docker run against the wolfSSL direct-APDU port passes in strict and lenient modes; sdk-test 31/31; hardware cross-check on SE051 applet 7.2.0 (direct ECDH passes, policy-attached HMACKey read denied 0x6986).
There was a problem hiding this comment.
Pull request overview
This PR updates the SE050 simulator to match observed SE05x hardware behavior around ECDH shared-secret derivation and symmetric key export restrictions, and aligns the SDK test suite accordingly so CI can exercise the real-world host flows.
Changes:
- Add support for Tag7-less (“direct”) ECDH in
handle_ecdh, returning the shared secret in the APDU response (including big-endian Montgomery behavior). - Make
ReadObjectonHMACKeyobjects always fail withSW_COMMAND_NOT_ALLOWED (0x6986), regardless of attached policy. - Update
sdk-testECDH tests to use the direct ECDH API flow instead of derive-into-object-and-read-back.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| SE050Sim/se050-sim/src/object_store/types.rs | Clarifies HMACKey policy is retained as attributes but does not allow export. |
| SE050Sim/se050-sim/src/handlers/object_mgmt.rs | Enforces “never export HMACKey via ReadObject” behavior and updates related tests. |
| SE050Sim/se050-sim/src/handlers/ec.rs | Implements optional Tag7 to support direct ECDH response behavior; adds direct-variant tests. |
| SE050Sim/se050-sim/src/handlers/aes.rs | Updates HMAC write documentation to reflect non-exportability regardless of policy. |
| SE050Sim/sdk-test/test_se050.c | Switches ECDH tests to the direct APDU variant and adjusts Montgomery byte-order handling. |
Suppressed comments (5)
SE050Sim/sdk-test/test_se050.c:379
TEST_FAILFalready returns from the current test function; the extrareturn;is unreachable. Removing it avoids dead code.
if (sm != SM_OK) {
TEST_FAILF("direct ECDH failed: 0x%04x", (unsigned)sm);
return;
}
SE050Sim/sdk-test/test_se050.c:1431
TEST_FAILalready returns; the trailingreturn;is unreachable. Dropping it avoids dead code and keeps the error path consistent with the rest of the test helpers.
if (pub_len < 32) { TEST_FAIL("key_b public too short"); return; }
SE050Sim/sdk-test/test_se050.c:1441
TEST_FAILFalready returns; the extrareturn;is unreachable and can be removed.
if (sm != SM_OK) {
TEST_FAILF("direct ECDH a failed: 0x%04x", (unsigned)sm);
return;
}
SE050Sim/sdk-test/test_se050.c:1453
TEST_FAILalready returns; the trailingreturn;is unreachable. Dropping it avoids dead code.
if (pub_len < 32) { TEST_FAIL("key_a public too short"); return; }
SE050Sim/sdk-test/test_se050.c:1463
TEST_FAILFalready returns; the extrareturn;is unreachable and can be removed.
if (sm != SM_OK) {
TEST_FAILF("direct ECDH b failed: 0x%04x", (unsigned)sm);
return;
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Zero-init the sss_key_store_get_key bit-length out-parameters for consistency with the rest of the file, drop the unreachable returns after TEST_FAIL/TEST_FAILF (the macros return), and extract the peer public key in the Tag7-less unit test by TLV parsing instead of fixed offsets.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
Testing on real SE051 applet 7.2.0 hardware settled the ECDH derive-target question with two facts the simulator (and PR #10/#11) got wrong:
POLICY_OBJ_ALLOW_READ(and addingALLOW_IMPORT_EXPORTchanges nothing). The read-policy exception the simulator honored does not exist on silicon; the SE050C (applet 3.1.1) behaves identically.Se05x_API_ECDHGenerateSharedSecret(no Tag7) returns the shared secret in the APDU response on the same applet, and is whatsss_se05x_derive_key_dhitself uses whenever the derived key object lives in a host keystore. The simulator rejected Tag7-less requests with SW_WRONG_DATA.wolfSSL's
se050_applet72_ecdhbranch now uses the direct variant on applet >= 7.2 (verified on the SE051: ECC P-256, X25519, and the wolfCrypt suite pass), so the simulator must support it for CI to run at all.Changes
handle_ecdh: Tag7 is now optional. Without it (direct variant) the shared secret is returned in response Tag1 and no object is touched, in strict and lenient mode alike; Montgomery secrets are returned big endian, as on hardware (the SDK swaps around the call). With Tag7 the InObject behavior and the strict target contract are unchanged.ReadObjecton HMACKey objects is now always refused with SW 0x6986, regardless of any attached policy, matching hardware. The policy recorded at WriteSymmKey is kept as object-attribute bookkeeping.Validation
cargo test: 52 tests pass (2 new direct-variant tests, including a big-endian X25519 response check; the with-read-policy read test is inverted to match hardware).The wolfSSL branch CI pin (
SIMULATORS_REF) should be bumped to this PR's head once merged.