feat: add Secure Enclave key type and Swift shim#363
Conversation
Add initial plumbing for Apple Secure Enclave P-256 key support: - Add KeyType::SecureEnclave variant (P-256 backed by SE hardware) - Add KeyError::SecureEnclave error variant - Add secure_enclave module (shells out to tempo-se Swift binary) - Add tools/tempo-se Swift Package (generate, sign, pubkey, delete) The Swift shim uses Security.framework to create non-exportable P-256 keys in the Secure Enclave and sign prehashed digests. Keychain queries are scoped to kSecAttrTokenIDSecureEnclave + kSecAttrKeyClassPrivate to prevent cross-key confusion. This is foundational plumbing — end-to-end signer integration (wiring SE keys into the Signer/Keystore selection path) and a `tempo wallet` subcommand for SE key management will follow in subsequent PRs. Co-Authored-By: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
|
Tempo Lint ResultsSummaryFound 338 issue(s) across 32 file(s)
Issues by Rule Type
|
Wire Secure Enclave keys into the keystore model and add CLI commands: - Add `se_label` field to KeyEntry for SE-backed key identification - Add `has_signing_capability()` / `is_secure_enclave()` to KeyEntry - Update key selection: passkey > SE > inline key > first entry - Update readiness checks to recognize SE keys (has_wallet, whoami) - Add `Keystore::delete_se_label()` for SE key removal - Export `KeyType` from tempo_common::keys CLI commands (`tempo wallet se`): - `generate [--label]` — create SE key, derive address, save to keystore - `list` — show all SE keys with label/address/wallet - `pubkey [--label]` — print uncompressed P-256 public key hex - `delete [--label] [--yes]` — delete from both SE and keystore Note: end-to-end signing (SE → mpp::TempoProvider) requires mpp crate changes and will follow in a separate PR. Co-Authored-By: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com>
Build the Swift shim alongside tempo-wallet on macOS targets: - Build tempo-se with `swift build` on darwin-amd64 and darwin-arm64 - Upload tempo-se binaries as separate artifacts - Ship to GitHub Release and R2 alongside tempo-wallet binaries Co-Authored-By: Alexey Shekhirin <5773434+shekhirin@users.noreply.github.com> Co-Authored-By: Georgios Konstantopoulos <17802178+gakonst@users.noreply.github.com>
- Add WalletSigner enum supporting both PrivateKey and SecureEnclave variants - P-256 transaction signing with SHA-256 prehash, DER parsing, low-s normalization - P-256 voucher signing for sessions and cooperative channel close - Pass keyType=p256 hint to Tempo node for correct gas estimation - SE key generate creates a direct wallet (no browser login required) - Refuse to overwrite existing SE keys to prevent fund loss - Xcode project for tempo-se with provisioning profile and entitlements - Add biometry flag to SE key access control - Add duplicate key guard in Swift shim - Add sign_for_key() to authorization for P-256 key type support
Summary
Add Secure Enclave P-256 key support to the wallet CLI — Swift shim, Rust integration, keystore model, and
tempo wallet sesubcommand.Motivation
Secure Enclave provides hardware-bound, non-exportable P-256 keys — ideal for CLI/programmatic signing without browser WebAuthn ceremonies. Tempo supports P-256 on-chain verification via the RIP-7212 precompile, so SE keys work as a new signer type alongside passkeys.
Changes
Swift shim (
tools/tempo-se/)generate --tag <tag>— create SE-backed P-256 key, print uncompressed pubkey hexsign --tag <tag> --hash <hex>— sign prehashed digest (.ecdsaSignatureDigestX962SHA256)pubkey --tag <tag>— retrieve existing key's public keydelete --tag <tag>— remove key from KeychainkSecAttrTokenIDSecureEnclave+kSecAttrKeyClassPrivateRust integration (
tempo-common)KeyType::SecureEnclavevariant (P-256 on-chain, SE-backed storage)KeyError::SecureEnclaveerror variantsecure_enclavemodule — Rust shim that locates + shells out totempo-sese_labelfield onKeyEntryfor SE key identificationhas_signing_capability()/is_secure_enclave()methodshas_wallet,whoami) recognize SE keysKeystore::delete_se_label()for key removalCLI (
tempo wallet se)generate [--label]— create SE key, derive EVM address, save to keystorelist— show all SE keys with label/address/walletpubkey [--label]— print uncompressed P-256 public key hexdelete [--label] [--yes]— delete from both SE and keystoreNot in this PR
End-to-end signing (SE →
mpp::TempoProviderpipeline) requires mpp crate changes and will follow separately.Testing
make check # clippy + fmt + tests passCo-Authored-By: Alexey Shekhirin 5773434+shekhirin@users.noreply.github.com
Prompted by: alexey