remove outdated documentation

This commit is contained in:
Michele Balistreri 2019-02-11 16:58:34 +03:00
parent fe8ecb2b03
commit ca65db5c71
4 changed files with 0 additions and 855 deletions

View File

@ -1,448 +0,0 @@
# Status Keycard Application
## Version
Version numbers are in the form major.minor. An major revision increment indicates the presence of breaking changes as
compared to the previous released version. This is version 2.0 of the specs.
### Changes since 1.2
* **BREAKING** Changed application AID
* **BREAKING** Completely redefined the EXPORT KEY command
* **BREAKING** Removed assisted key derivation
* **BREAKING** Removed plain data signing, now only 32-byte long hashes can be signed
* Added internal key generation (GENERATE KEY)
* Added the ability to customize the NDEF response (SET NDEF)
* Added DUPLICATE KEY command
## Overview
This application allows signing of transactions using ECDSA with a keyset stored on card. The keys are defined on the
SECP256k1 curve. Signing is available only after PIN authentication.
The keyset used for signing is generated externally and loaded on card. This is also only available after PIN
authentication.
Before any application command is processed, a Secure Channel session must be established as specified in the
[SECURE_CHANNEL.MD](SECURE_CHANNEL.MD) document.
## INITIALIZATION
After installation, the applet is not ready to operate and is in a pre-initializaed state. In this state the applet can
only process the SELECT and INIT command. The INIT command is used to personalize the PIN, PUK and pairing secret, which
must be generated off-card.
## PIN
The PIN length is fixed at 6 digits. After 3 failed authentication attempts the PIN is blocked and authentication is not
possible anymore. A blocked PIN can be replaced and unblocked using a PUK. The PUK is a 12-digit number. After 5 failed
attempts to unblock the applet using the PUK, the PUK is blocked, meaning the wallet is lost.
After authentication, the user remains authenticated until the application is either deselected or the card is reset.
Authentication with PIN is a requirement for most commands to succeed.
The PIN and PUK can be changed by the user after authentication.
## Keys & Signature
The application allows loading and replacing of a single EC keyset, defined on the SECP256k1 curve. The keyset can contain
a 32-byte chain code to further derive keys according to the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
specifications. This keyset is used to sign transactions. When the applet is first installed, no keyset is available so
signing will fail. It is necessary to first load the keyset in order for the application to be fully operational.
Signing of transactions is done by uploading the data in blocks no larger than 255 bytes (including the overhead caused
by the Secure Channel). Segmentation must be handled at the application protocol. Another option is to sign the hash
of the transaction, with the hash being calculated off-card. Signing generally requires the PIN to be authenticated,
however the user can set a special key path which requires no authentication.
## APDUs
These are the commands supported by the application. When a command has a precondition clause and these are not met the
SW 0x6985 is returned. All tagged data structures are encoded in the [BER-TLV format](http://www.cardwerk.com/smartcards/smartcard_standard_ISO7816-4_annex-d.aspx)
### SELECT
* CLA = 0x00
* INS = 0xA4
* P1 = 0x04
* P2 = 0x00
* Data = the instance AID
* Response = Application Info Template or ECC public key.
Response Data format:
- Tag 0xA4 = Application Info Template
- Tag 0x8F = Instance UID (16 bytes)
- Tag 0x80 = ECC public Key
- Tag 0x02 = Application Version (2 bytes)
- Tag 0x02 = Number of remaining pairing slots (1 byte)
- Tag 0x8E = Key UID (0 or 32 bytes)
The SELECT command is documented in the ISO 7816-4 specifications and is used to select the application on the card,
making it the active one. The data field is the AID of the application. The response is the Application Info template
which contains the instance UID (which can be used by the client to keep track of multiple cards) and the public key
which must be used by the client to establish the Secure Channel. Additionally it contains the version number of the
application, formatted on two bytes. The first byte is the major version and the second is the minor version
(e.g: version 1.1 is formatted as 0x0101). The number of remaining pairing slots is also included in the response.
The Key UID can be either empty (when no key is loaded on card) or the SHA-256 hash of the master public key.
When the applet is in pre-initializated state, it only returns the ECC public key, BER-TLV encoded with tag 0x80.
### INIT
* CLA = 0x80
* INS = 0xFE
* P1 = 0x00
* P2 = 0x00
* Data = EC public key (LV encoded) | IV | encrypted payload
* Response SW = 0x9000 on success, 0x6D00 if the applet is already initialized, 0x6A80 if the data is invalid
This command is only available when the applet is in pre-initialized state and successful execution brings the applet in
the initialized state. This command is needed to allow securely storing secrets on the applet at a different moment and
place than installation is taking place. Currently these are the PIN, PUK and pairing password.
The client must take the public key received after the SELECT command, generate a random keypair and perform EC-DH to
generate an AES key. It must then generate a random IV and encrypt the payload using AES-CBC with ISO/IEC 9797-1 Method
2 padding.
They payload is the concatenation of the PIN (6 digits/bytes), PUK (12 digits/bytes) and pairing secret (32 bytes).
This scheme guarantees protection against passive MITM attacks. Since the applet has no "owner" before the execution of
this command, protection against active MITM cannot be provided at this stage. However since the communication happens
locally (either through NFC or contacted interface) the realization of such an attack at this point is unrealistic.
After successful execution, this command cannot be executed anymore. The regular SecureChannel (with pairing) is active
and PIN and PUK are initialized.
### OPEN SECURE CHANNEL
The OPEN SECURE CHANNEL command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD).
### MUTUALLY AUTHENTICATE
The MUTUALLY AUTHENTICATE command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD).
### PAIR
The PAIR command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD). The shared secret is 32 bytes long. The
way the secret is generated is not within the scope of this document because the applet accepts the already generated
secret as an installation parameter. However the card issuer and clients must agree on the way it is generated for
interoperability reasons.
If the code is meant to be input manually, a random, variable length alphanumeric password to be used in conjuction with
an algorithm such as scrypt or PBKDF2 is suggested. If another input mechanism is foreseen (such as QR-code scanning),
then the sequence should be composed of random bytes from a secure source of randomness.
### UNPAIR
The UNPAIR command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD). The user PIN must be verified for the
command to work.
### GET STATUS
* CLA = 0x80
* INS = 0xF2
* P1 = 0x00 for application status, 0x01 for key path status
* P2 = 0x00
* Response SW = 0x9000 on success, 0x6A86 on undefined P1
* Response Data = Application Status Template or Key Path
* Preconditions: Secure Channel must be opened
Response Data format:
if P1 = 0x00:
- Tag 0xA3 = Application Status Template
- Tag 0x02 = PIN retry count (1 byte)
- Tag 0x02 = PUK retry count (1 byte)
- Tag 0x01 = 0xff if key is initialized, 0 otherwise
if P1 = 0x01
- a sequence of 32-bit numbers indicating the current key path. Empty if master key is selected.
### SET NDEF
* CLA = 0x80
* INS = 0xF3
* P1 = 0x00
* P2 = 0x00
* Data = the data to store
* Response SW = 0x9000 on success, 0x6A80 on invalid data
* Preconditions: Secure Channel must be opened, PIN must be verified
Used to set the content of the data file owned by the NDEF applet. This allows changing the behavior of Android and other
clients when tapping the card with no open client. As an example, it could be used to launch a specific wallet software.
The data is stored as is. A check is made that the first 2 bytes, read as a MSB first short, are equal to the Lc field
minus 2 (the length of the field itself). This does not ensure that the NDEF record is valid, but ensures that no out
of bound access happens.
### VERIFY PIN
* CLA = 0x80
* INS = 0x20
* P1 = 0x00
* P2 = 0x00
* Data = the PIN to be verified
* Response SW = 0x9000 on success, 0x63CX on failure, where X is the number of attempt remaining
* Preconditions: Secure Channel must be opened
Used to verify the user PIN. On correct PIN entry the card returns 0x9000, the retry counter is reset and the PIN is
marked as authenticated for the entire session (until the application is deselected or the card reset/teared). On
error, the number of remaining retries is decreased and the SW 0x63CX, where X is the number of available retries is
returned. When the number of remaining retries reaches 0 the PIN is blocked. When the PIN is blocked this command
always returns 0x63C0, even if the PIN is inserted correctly.
### CHANGE PIN
* CLA = 0x80
* INS = 0x21
* P1 = PIN identifier
* P2 = 0x00
* Data = the new PIN
* Response SW = 0x9000 on success, 0x6A80 if the PIN format is invalid, 0x6A86 if P1 is invalid
* Preconditions: Secure Channel must be opened, user PIN must be verified
Used to change a PIN or secret. In case of invalid format, the code 0x6A80 is returned. If the conditions match, the PIN
or secret is updated. The no-error SW 0x9000 is returned.
P1:
* 0x00: User PIN. Must be 6-digits. The updated PIN is authenticated for the rest of the session.
* 0x01: Applet PUK. Must be 12-digits.
* 0x02: Pairing secret. Must be 32-bytes long. Existing pairings are not broken, but new pairings will need to use the
new secret.
### UNBLOCK PIN
* CLA = 0x80
* INS = 0x22
* P1 = 0x00
* P2 = 0x00
* Data = the PUK followed by the new PIN
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid
* Preconditions: Secure Channel must be opened, user PIN must be blocked
Used to unblock the user PIN. The data field must contain exactly 18 numeric digits, otherwise SW 0x6A80 is returned.
The first 12 digits are the PUK and the last 6 are the new PIN. If the PUK is correct the PIN is changed to the supplied
one, it is unblocked and authenticated for the rest of the session. The status code 0x9000 is returned. When the PUK is
wrong, the number of remaining retries is decreased and the SW 0x63CX, where X is the number of available retries is
returned. When the number of remaining retries reaches 0 the PUK is blocked. When the PUK is blocked this command
always returns 0x63C0, even if the PUK is inserted correctly. In this case the wallet is effectively lost.
### LOAD KEY
* CLA = 0x80
* INS = 0xD0
* P1 = key type
* P2 = 0x00
* Data = the key data
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6A86 if P1 is invalid
* Response Data = the key UID, defined as the SHA-256 of the public key
* Preconditions: Secure Channel must be opened, user PIN must be verified
P1:
* 0x01 = ECC SECP256k1 keypair
* 0x02 = ECC SECP256k1 extended keypair
* 0x03 = Binary seed as defined in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
Data:
If P1 is 0x01 or 0x02
- Tag 0xA1 = keypair template
- Tag 0x80 = ECC public key component (can be omitted)
- Tag 0x81 = ECC private key component
- Tag 0x82 = chain code (if P1=0x02)
If P1 is 0x03 a 64 byte sequence generated according to the BIP39 specifications is expected. The master key will be
generated according to the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) specifications. This
is only supported if the hardware supports public key derivation.
This command is used to load or replace the keypair used for signing on the card. This command always aborts open
signing sessions, if any. Unless a DERIVE KEY is sent, a subsequent SIGN command will use this keypair for signature.
### DERIVE KEY
* CLA = 0x80
* INS = 0xD1
* P1 = derivation options
* P2 = 0x00
* Data = a sequence of 32-bit integers (most significant byte first). Empty if the master key must be used.
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6984 if one of the components in the path
generates an invalid key, 0x6B00 if derivation from parent keys is selected but no valid parent key is cached.
* Preconditions: Secure Channel must be opened, user PIN must be verified (if no PIN-less key is defined), an extended
keyset must be loaded
This command is used before a signing session to generate a private key according to the [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
specifications. This command always aborts open signing sessions, if any. The generated key is used for all subsequent
SIGN sessions. The maximum depth of derivation from the master key is 10. Any attempt to get deeper results in 0x6A80
being returned. The BIP32 specifications define a few checks which must be performed on the derived keys. If these fail,
the 0x6984 is returned and the invalid key is discarded. A client should perform a GET STATUS command to get the actual
current key path and resume derivation using a different path.
The ability to start derivation from the parent keys allows to more efficiently switch between children of the same key.
Note however that only the immediate parent of the current key is cached so you cannot use this to go back in the
hierarchy. If no valid parent key is available the status code 0x6B00 will be returned.
P1:
* bit 0-5 = reserved
* bit 7-6:
- 00 derive from master keys
- 01 derive from parent keys
- 10 derive from current keys
- 11 reserved
### GENERATE MNEMONIC
* CLA = 0x80
* INS = 0xD2
* P1 = checksum size (between 4 and 8)
* P2 = 0x00
* Response SW = 0x9000 on success. 0x6A86 if P1 is invalid.
* Response Data = a sequence of 16-bit integers (most significant byte first).
* Preconditions: Secure Channel must be opened
Used to generate a mnemonic according to the algorithm specified in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
The returned data is a list of 16-byte integers which should be used as indexes in a wordlist to generate the
human-readable mnemonic. Each integer can have a value from 0 to 2047.
### REMOVE KEY
* CLA = 0x80
* INS = 0xD3
* P1 = 0x00
* P2 = 0x00
* Response SW = 0x9000 on success.
* Preconditions: Secure Channel must be opened, user PIN must be verified
Removes the key from the card, bringing it back to an uninitialized state. No signing operation is possible after this
command until a new LOAD KEY command is performed.
### GENERATE KEY
* CLA = 0x80
* INS = 0xD4
* P1 = 0x00
* P2 = 0x00
* Response SW = 0x9000 on success.
* Response Data = the key UID, defined as the SHA-256 of the public key
* Preconditions: Secure Channel must be opened, user PIN must be verified
Generates and stores keys completely on card. The state of the card after execution is the same as if a LOAD KEY command
had been performed.
### DUPLICATE KEY
* CLA = 0x80
* INS = 0xD5
* P1 = subcommand
* P2 = depends on subcommand
* Data = depends on phase
* Response SW = 0x9000 on success.
* Response Data = depends on subcommand
* Preconditions: depends on subcommand
P1:
* 0x00: START DUPLICATE
* 0x01: ADD ENTROPY
* 0x02: EXPORT DUPLICATE
* 0x03: IMPORT DUPLICATE
#### START DUPLICATE
This is the first step to start duplication. Requires an open secure channel and user PIN must be verified. Aborts any
on-going duplication session. P2 is the number of entropy pieces to expect in total (including this command). The data
contain the first piece of entropy. Returns no data. Must be performed with exactly the same parameters and data on all
cards taking part in the duplication.
#### ADD ENTROPY
This command uses the same one-shot secure channel scheme as defined in the INIT command. P2 is 00. Requires an ongoing
duplicate session started with the START DUPLICATE subcommand. Must be performed once per device taking part in the
duplication process, for a total number of devices equaling the P2 parameter of the START DUPLICATE subcommand (counting
the device which sent the START DUPLICATE command as the first device). The data is a random 256-bit number. The same
data must be sent to all the cards taking part in the duplication process.
#### EXPORT DUPLICATE
This command must be sent to the card which you wish to duplicate. Requires an open secure channel and authenticated
PIN. Works only if a duplication session is active and ADD ENTROPY has been performed the required number of times.
Returns the encrypted duplicate of the master key and terminates the duplication session for this card. The format is
exactly the same as the one defined in the LOAD KEY (TLV) command with omitted public key. It is however prepended by a
16-bytes IV and the entire TLV structure is encrypted.
#### IMPORT DUPLICATE
This command must be sent to all the cards which are a target for duplication. The Data field must contain the output
from the EXPORT DUPLICATE command performed on the source card. Returns the key UID. It follows exactly the same rules
as the EXPORT DUPLICATE subcommand.
### SIGN
* CLA = 0x80
* INS = 0xC0
* P1 = 0x00
* P2 = 0x00
* Data = the hash to sign
* Response = public key and the signature
* Response SW = 0x9000 on success, 0x6A80 if the data is not 32-byte long
* Preconditions: Secure Channel must be opened, user PIN must be verified (or a PIN-less key must be active), a valid
keypair must be loaded
Response Data format:
- Tag 0xA0 = signature template
- Tag 0x80 = ECC public key component
- Tag 0x30 = ECDSA Signature
- Tag 0x02 = R value
- Tag 0x02 = S value
Returns the ECDSA signature of the hash. The hash can be calculated using any algorithm, but must be 32-bytes long. The
signature is returned in a signature template, containing the public key associated to the signature and the signature
itself. For usage on the blockchain, you will need to calculate the recovery ID in addition to extracting R and S.
To calculate the recovery ID you need to apply the same algorithm used for public key recovery from a transaction starting
with a recovery ID of 0. If the public key matches the one returned in the template, then you have found the recovery ID,
otherwise you try again by incrementing the recovery ID.
### SET PINLESS PATH
* CLA = 0x80
* INS = 0xC1
* P1 = 0x00
* P2 = 0x00
* Data = a sequence of 32-bit integers
* Response SW = 0x9000 on success, 0x6A80 if data is invalid
* Preconditions: Secure Channel must be opened, user PIN must be verified
Sets the given sequence of 32-bit integers as a PIN-less path. When the current derived key matches this path, SIGN
will work even if no PIN authentication has been performed. An empty sequence means that no PIN-less path is defined.
### EXPORT KEY
* CLA = 0x80
* INS = 0xC2
* P1 = derivation options
* P2 = export options
* Response SW = 0x9000 on success, 0x6A86 if P1 or P2 are wrong
* Data = a sequence of 32-bit integers (empty if P1=0x00)
* Response Data = key pair template
* Response SW = 0x9000 on success, 0x6985 if the private key cannot be exported, 0x6A80 if the path is malformed
* Preconditions: Secure Channel must be opened, user PIN must be verified
P1:
0x00 = Current key
0x01 = Derive
0x02 = Derive and make current
P2:
0x00 = private and public key
0x01 = public key only
Response Data format:
- Tag 0xA1 = keypair template
- Tag 0x80 = ECC public key component (could be omitted)
- Tag 0x81 = ECC private key component (if P2=0x00)
This command exports the requested public and private key. The public key can be always exported (P2=0x01), but the
private key (P2=0x00) can be exported if and only if the requested key path is in the
[EIP-1581](https://eips.ethereum.org/EIPS/eip-1581) subtree.
The P1 parameter indicates how to the derive the desired key. P1 = 0x00 indicates that the current key must be exported,
and no derivation will be performed. P1 = 0x01 derives the path given in the data field without changing the current
path of the card. P1 = 0x02 derives the path but also changes the current path of the card. The source for derivation
can be set by OR'ing P1 with the constants defined in the DERIVE KEY command. This allows deriving from master, parent
or current.
If the private key is being exported, the card could omit exporting the public key for performance reason. The public
key can then be calculate off-card if needed.

View File

@ -1,139 +0,0 @@
# Notes for client implementation
This document should help client application developers to integrate support for the Status Keycard in their applications.
## Low-level communication
The Status Keycard is a JavaCard application and as such is deployed on ISO7816 compatible SmartCards. Communication
will happen exchanging APDUs using either the T=0 or preferably the T=1 protocol. Most operating systems use an
implementation of [this Microsoft API](https://msdn.microsoft.com/en-us/library/windows/desktop/aa374731(v=vs.85).aspx#smart_card_functions)
like [PCSC lite](http://pcsclite.alioth.debian.org/pcsclite.html). Your language of choice might provide bindings for
this library or an higher-level API built on top of it.
A few things to keep in mind when communicating with SmartCards
1. The card can never initiate communication. The card only responds to commands sent from the client.
2. When connecting to the card using SCardConnect, always use the SCARD_SHARE_EXCLUSIVE mode to avoid OS services
messing with the card while you are using it.
3. A SmartCard can have multiple applications installed. If using only the basic channel (recommended for our use-case)
only a single application can be selected at the time. This must be done explicitly on each reset by issuing the
SELECT command with the AID of the keycard application.
4. Since we are not using extended APDUs, the maximum size of the data field of the APDU is 255 bytes.
## Wallet management and security
Before thinking about the application-specific communication (i.e: actually using the Keycard applet to derive keys and
sign transactions) the client must be able to actually talk with the card using its [Secure Channel protocol](SECURE_CHANNEL.MD).
The first step, after an APDU channel is available is to [SELECT](APPLICATION.MD) the Keycard application on the card.
The Keycard will return its Instance UID and public key for Secure Channel establishment. Although both values are unique,
only use the Instance UID to identify the Keycard since only this value is guaranteed not to change over the lifetime of
the card. If your application has already performed pairing with the Keycard with this Instance UID, you can establish
a Secure Channel session (described later). Otherwise you should proceed with pairing.
For pairing, the client must show that it knows the pairing code. For this reason the user must be prompted
to insert said code. The result of pairing is a secret value shared by both parties which is used during the session key
generation on establishment of a Secure Channel. The client must permanently store the association of the Instance UID,
the secret generated during pairing and the index which the card assigned to this client. Said index must be provided
when opening a Secure Channel so that the card knows with which client it is speaking. Since the pairing secret is
sensitive data, it should be stored as securely as possible, eventually with password protection. Losing this secret
allows an attacker to pose either as the client to the card or as the card to the client. It does not allow however
decrypting older communication and perform passive attacks.
Note that the card can only pair with a limited number of clients (currently 5). Unpairing allows to replace old clients
with new ones.
When a card and a client are paired, they can establish a Secure Channel session. The Secure Channel provides the
authentication, confidentiality and integrity guarantees which the plain APDU channel does not provide. This phase is
divided in 2 steps:
1. Sending an OPEN SECURE CHANNEL APDU to generate session keys
2. Sending a MUTUALLY AUTHENTICATE command to verify that both parties have the same keys.
After this happens, all further communication will be encrypted and with a MAC providing integrity and authentication
for each APDU.
The card and client must abort the Secure Channel session at any time if MAC verification fails, since this means that
the APDU has been corrupted, possibly as a result of an attack attempt. The card also resets the session when the
application is (re-)selected or the card is reset (or on power loss).
Note that while pairing requires user input, opening a secure channel session does not.
## User authentication
Aside from the Secure Channel-related APDUs, the application also provides commands to authenticate the user (as opposed
as authenticating the client) and to manage the user's authentication credentials. These are the VERIFY PIN, CHANGE PIN
and UNBLOCK PIN commands. The client is not supposed to store the PIN and verification should always require user input.
After verifying the PIN the card considers to the user to be authenticated for the entire application session. The
application session ends on card reset, power loss or application re-selection. The client should keep track of whether
the user has been authenticated or not in order to avoid repeatedly asking for the PIN. The card will respond with an
error to any APDU requiring user authentication if the user has not been authenticated in the current application
session.
## Keycard features and workflow
Now that the client can finally talk with the applet and provide user authentication facilities, it is time to look on
how to actually use the Keycard. The Keycard applet allows management of a single HD wallet as described in the
[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) specifications. It provides the following features
1. Source of entropy to generate master seeds (GENERATE MNEMONIC). No PIN required (has no effect on card state).
2. Loading of master key (LOAD KEY). PIN required. The same command can be used to replace the loaded master key.
3. Set the key to be used for signing by deriving from the master key (DERIVE KEY). PIN required unless a PIN-less path
is set.
4. Sign hashes (SIGN). PIN required unless the current key path is set as PIN-less. Note that the Keccak-256 hash of the
transaction is signed and must be generate off-card. The actual transaction data are not sent to the card.
5. Setting/Unsetting a PIN-less path (SET PINLESS PATH). PIN required. It allows disabling PIN authentication for a
specific key path.
6. Exporting keys (EXPORT KEY). PIN required. Exporting the private key is only allowed for specific keys.
Additionally the GET STATUS command (no PIN required) allows retrieving information about the card status and the
current key path.
The card is shipped with no keys on-board. In this state the SIGN and DERIVE KEY commands will not work. The client can
detect when a card has no keys by issuing a GET STATUS command. In this case it could prompt the user to either enter a
mnemonic passphrase or allow the card to generate a new one (GENERATE MNEMONIC is issued). In both cases, the mnemonic
must be converted to a master key from the client and loaded to the card using the LOAD KEY command.
The card stores the master key permanently, until replaced. Additionally the card has the concept of current key and
current key path. The current key is the one used during the SIGN command. The current key equals the master key when
new keys are loaded and the current key path is empty. Using the DERIVE KEY command however, the client can move through
the tree of the HD wallet. This command derives the key as described in BIP32 and sets both the current key and current
key path according to its arguments and the results of key derivation. Using the GET STATUS command the client can
always know the current key path and thus decide if further derivation is needed or not before issuing a SIGN command.
The current key persists across application sessions (including in case of power loss). A flag in the DERIVE KEY command
decides whether derivations restarts from the master key or is performed on the current key, extending the current path.
The current maximum key path depth is 10 levels under the master key.
The SIGN command signs the Keccak-256 hash provided in the APDU's data field using the current key. The client must
calculate the hash of the transaction off-card. The signature (r,s) and the public key used to verify it are both
returned. The client must use this to calculate 'v' and format the signature as required by Ethereum (v,r,s) if it
wishes to submit the transaction to the network.
Another feature is the ability to define a key path which requires no PIN authentication for signing. When a PIN-less
path is set the DERIVE KEY command never requires a PIN (because there must be a PIN-less way to reach that path). Note
that setting the PIN-less key path does not automatically set the current key path to the PIN-less one. You still need
to use DERIVE KEY to get there. Only when the current key path matches the PIN-less one the SIGN command will not require
PIN authentication. The master key can never be used without PIN.
Finally, some keys can be exported (after PIN authentication). The public key can be exported for any key, while the
private one only for specific keys. The EXPORT KEY command does not automatically do key derivation. This means that you
must use DERIVE KEY before exporting the desired key.
## Additional notes
1. The SIGN command also allows signing data directly instead of a precomputed hash (if P1 is 0x00 instead of 0x01),
transmitted over several blocks if needed. This feature is never used because this signature uses SHA-256 instead of
Keccak-256 (which is not available) making it useless. This mode of operation has been implemented before the current
one with precomputed hashes. It remains because if we get hold of a hardware platform implementing Keccak-256, or we
decide to implement it in software, we might want to operate this way.
2. Communication has less overhead when using the T=1 protocol. However the card/reader/os combination I have seems to
only work with T=0 (although all claim to support T=1). Contactless readers always emulate T=1 when operated through
the PC/SC interface.
3. You can refer to the tests for examples of communication with the card. The manual-only signTransactionTest test in
particular generates a real transaction, signs it and submits it to the network.
4. If you test your client against our fork of jCardSim instead of a real card, keep in mind that it supports unassisted
key derivation, but you shouldn't use it because, as explained above, it wouldn't work on the card.
5. If using jCardSim, only use our fork, since some of the needed algorithms are unsupported in the upstream version.
6. The pairing code is a randomly generated password (using whatever password generation algorithm is desired). This
password must be converted to a 256-bit key using PBKDF2 with the salt "Keycard Pairing Password Salt" and 50000 iterations.

View File

@ -1,168 +0,0 @@
# Secure Channel
## Overview
A Secure Channel must be established to allow communication between the applet and the client. This secure channel has
the concept of pairing with multiple devices (how many clients can be paired at the same time is defined by the applet).
The SecureChannel guarantees protection from snooping, MITM, replay attacks and provides message integrity and
authentication for each APDU.
A short description of establishing a session is as follows
1. The client selects the application on card. The application responds with a public EC key.
2. The client sends an OPEN SECURE CHANNEL command with its public key and pairing index. The EC-DH algorithm is used by
both parties to generate a shared 256-bit secret (more details below).
3. The generated secret is concatenated with the pairing key and random data and hashed with SHA-512.
4. The first half of the generated value is used as an AES key to encrypt all further communication. CBC mode is used
with a random IV generated for each APDU and prepended to the APDU payload. The second half is used to MAC generation
and verification. Both command and responses are encrypted.
5. The client sends a MUTUALLY AUTHENTICATE command to verify that the keys are matching and thus the secure channel is
successfully established.
The EC keyset used by the card for the EC-DH algorithm is generated on-card on applet installation and is not used
for anything else. The EC keyset used by the client is generated every time a new secure channel session must be
opened.
## APDU format
### OPEN SECURE CHANNEL
* CLA = 0x80
* INS = 0x10
* P1 = the pairing index
* P2 = 0x00
* Data = An EC-256 public key on the SECP256k1 curve encoded as an uncompressed point.
* Response Data = A 256-bit salt and a 128-bit seed IV
* Response SW = 0x9000 on success, 0x6A86 if P1 is invalid, 0x6A80 if the data is not a public key
This APDU is the first step to establish a Secure Channel session. A session is aborted when the application is
deselected, either directly or because of a card reset/tear.
The card generates a random 256-bit salt which is sent to the client. Both the client and the card do the following
for key derivation
1. Use their private key and the counterpart public key to generate a secret using the EC-DH algorithm.
2. The generated secret, the pairing key and the salt are concatenated and the SHA-512 of the concatenated value is
calculated.
3. The output of the SHA-512 algorithm is split in two parts of 256-bit. The first part is used as the encryption key
and the second part is used as the MAC key for further communication.
The seed IV is used by the client as the IV for the next encrypted APDU.
### MUTUALLY AUTHENTICATE
* CLA = 0x80
* INS = 0x11
* P1 = 0x00
* P2 = 0x00
* Data = 256-bit random number
* Response Data = 256-bit random number
* Response SW = 0x9000 on success, 0x6985 if the previous successfully executed APDU was not OPEN SECURE CHANNEL, 0x6982
if authentication failed or the data is not 256-bit long
This APDU allows both parties to verify that the keys generated in the OPEN SECURE CHANNEL step are matching and thus
guarantee authentication of the counterpart. The data sent by both parties is a 256-bit random number The APDU data is
sent encrypted with the keys generated in the OPEN SECURE CHANNEL step. Each party must verify the MAC of the received
APDU. If the MAC can be verified, it means that both parties are using the same keys. Only after this step has been
executed the secure channel can be considered to be open and other commands can be sent. If the authentication fails
the card must respond with 0x6982. In this case the OPEN SECURE CHANNEL command must be repeated to generate new keys.
### PAIR
* CLA = 0x80
* INS = 0x12
* P1 = pairing phase
* P2 = 0x00
* Data = see below
* Response Data = see below
* Response SW = 0x9000 on success, 0x6A80 if the data is in the wrong format, 0x6982 if client cryptogram verification
fails, 0x6A84 if all available pairing slot are taken, 0x6A86 if P1 is invalid or is 0x01 but the first phase was not
completed, 0x6985 if a secure channel is open
P1:
* 0x00: First step
* 0x01: Final step
Data:
* On first step: a 256-bit random client challenge
* On second step: the client cryptogram as SHA-256(shared secret, card challenge)
Response Data:
* On first step: the card cryptogram as SHA-256(shared secret, client challenge) followed by a 256-bit card challenge
* On second step: the pairing index followed by a 256-bit salt
This APDU is sent to pair a client. Pairing is performed with two commands which must be sent immediately one after the
other.
In the first phase the client sends a random challenge to the card. The card replies with the SHA-256 hash of the
challenge and the shared secret followed by its random challenge. The client is thus able to authenticate the card by
verifying the card cryptogram (since the client can generate the same and verify that it matches).
In the second phase the client sends the client cryptogram which is the SHA-256 hash of the shared secret and the card
challenge. The card verifies the cryptogram and thus authenticates the client. On success the card generates a random
256-bit salt which is appended to the shared secret. The SHA-256 hash of the concatenated value is stored in the fist
available pairing slot and will be further used to derive session keys. The card responds with the pairing index (which
the client must send in all OPEN SECURE CHANNEL commands) and the salt used to generate the key, so that the client can
generate and store the same key.
The shared secret is a 256-bit value which must be be known to both parts being paired. The exact means of how this
happens depend on the specific applet.
### UNPAIR
* CLA = 0x80
* INS = 0x13
* P1 = the index to unpair
* P2 = 0x00
* Response SW = 0x9000 on success, 0x6985 if security conditions are not met, 0x6A86 if the index is higher than the
highest possible pairing index.
This APDU is sent to unpair a client. An existing secure channel session must be open. The application implementing this
protocol may apply additional restrictions, such as the verification of a user PIN. On success the pairing slot at the
given index will be freed and will be made available to pair other clients. If the index is already free nothing will
happen.
### Encrypted APDUs
After a successful OPEN SECURE CHANNEL command all communication between card and client is encrypted. Note that only
the data fields of C-APDU are encrypted, which means that CLA, INS, P1, P2 for C-APDU are plaintext. This means no
sensitive data should be sent in these parameters. Additionally a MAC is calculated for the entire APDU, including
the unencrypted fields.
Because R-APDU can only contain data if their SW is a success or warning status word (0x9000, 0x62XX, 0x63XX), when the
secure channel is open all responses will have SW 0x9000. The actual SW is always appended at the end of the response
data before encryption, which means the client must interpret the last two bytes of the plaintext response as the SW.
An exception to this is SW 0x6982, which indicates that the SecureChannel has been aborted and as such is returned
without any MAC.
To encrypt the data both the card and the client do the following:
1. The data is padded using the ISO/IEC 9797-1 Method 2 algorithm.
2. The data is encrypted using AES in CBC mode using the session key.
3. An AES CBC-MAC is calculated over the entire APDU data
4. The data field of the APDU is set to the MAC followed by the encrypted data.
To decrypt the data both the card and the client do the following:
1. The first 16 bytes of the APDU data are the MAC to be verified
2. The remaining data is decrypted using AES in CBC mode using the session key.
3. The padding is removed.
The IV used for the encryption is the last seen MAC from the counterpart. This optimizes the number
of transmitted bytes and guarantees protection from replay attacks. For the MAC generation, a zero IV is always used.
MAC generation for C-APDUs is calculated on the concatenation of CLA INS P1 P2 LC 00 00 00 00 00 00 00 00 00 00 00 and
the encrypted data field. The 11-byte long padding does not become part of the data field and does not affect LC
MAC generation fo R-APDUs is calculated on the concatenation of Lr 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 and
the encrypted data field. The 15-byte long padding does not become part of the response field. Lr is the length of the
encrypted response data field and is not transmitted.
Because AES in CBC mode requires the data field length in bytes to be a multiple of 16, the maximum effective APDU
size becomes 240 bytes. Of these 16 bytes are used for the MAC and minimum of 1 byte for padding, making the maximum
payload size in a single APDU 223 bytes, meaning about a 13,5% overhead.
### Error conditions
1. If a sensitive command is received without an active Secure Channel, the card shall respond with SW 0x6985 (
SW_CONDITIONS_NOT_SATISFIED)
2. If a MAC cannot be verified the card shall respond 0x6982 and the Secure Channel must be closed

View File

@ -1,100 +0,0 @@
# Status Keycard UX guidelines
The scope of this document is to describe the interactions between the keycard, the user and client applications.
Technical details about the commands mentioned here are to be found in the [APPLICATION.MD](APPLICATION.MD) file.
## Physical interaction
The applet is installed on a regular Smart Card (plastic card) with contacted and/or contactless interface. Since the
card does not have any user input or output devices, all input and output happens through the host device. The host
device needs a card reader to interface with the card.
Each card will have a uniquely generated 12-digits PUK code (used to unblock the PIN) and a unique pairing code. The
pairing code is a password which must be converted to a 256-bit secret as defined in [CLIENT_NOTES.md](CLIENT_NOTES.md).
The initial PIN of the card can be set to "000000" or can be chosen by the user. The length is always 6 digits. The user
has 3 attempts to insert the correct PIN, after which it is blocked. The PIN can be reset by using the PUK. The user has
5 attempts to insert the correct PUK.
PIN, PUK and pairing password can be changed at any time by the user, after authenticating with the current PIN.
## Application selection
When the client detects a SmartCard, it should try to select the Status Keycard application by sending a selection command.
The applet will respond providing details useful for the next steps.
## PIN sessions
Many operations require the PIN to be authenticated. PIN entry scheme is the same as the one used for SIM-cards and follows
the rules described above. Once a PIN is authenticated, it remains authenticated until the card is reset, loses powers or
the application is re-selected. Since the card does not have a clock, if the client wants to reset PIN verification status
after a specific time/inactivity interval, it should keep track of the time itself and reset the session as described above.
## Pairing
A card can pair with up to 5 devices. The number of remaining pairing slot is given as a response to application selection.
The client will also receive an identifier, so it can recognize if it already paired with this card. Pairing must only
be done once and requires user interaction in form of pairing code entry. Keeping the generated pairing key secret is
critical to guarantee secure communication between card and client. However pairing alone does not give any access to the
keys stored on card or any other sensitive functionality, so the pairing code itself is not as sensitive.
## Unpairing
Unpairing allows to recover a pairing slot. An authenticated device can unpair itself or any other paired device. This
step requires PIN authorization. Since the card does not provide a list of paired devices, from a UI perspective the only
two options that make sense are "Unpair this device" and "Unpair all others".
## Initialization
When the card is delivered, it does not contain any secret so it is not able to operate properly. In this state only the
INIT command will work, which allows setting the initial PIN, PUK and pairing password using a temporary secure channel.
After this first initialization, a master key must be stored on the card. It can be recovered from a mnemonic phrase,
generated ex-novo using BIP39 or internally on the card.
The GET STATUS command can be used to determine if the card is ready to be used for signing or not.
The card is able to generate the mnemonic phrase internally and send it to the client as a sequence of 16-bit numbers which
are the indexes in the word dictionary. The actual key generation must happen off-card however, because the applet does not
implement PBKDF-2 to convert the phrase in a BIP-39 binary seed. The applet supports loading either the full master keypair
(private and public) or the binary seed. However the second option only works if the card supports public key derivation and
these are hard to get, since this function has been added to the JavaCard standard only in revision 3.0.5. It is critical
that the client destroys all copies of the key immediately after loading them to the card by explicitly clearing the memory
areas used to store them.
Initialization requires the PIN to be authenticated so it would be better if, upon detecting a new card, the client would
first prompt to change PIN (a step which includes PIN verification) and only after this step generates key.
The process of generating and loading new keys can also be repeated on an already initialized card. This step does not
reset the PIN to factory condition but permanently destroys the currently stored keys, so a fat huge warning must be
issued.
As with all HD-wallets, the client should show the mnemonic phrase to the user and prompt them to write down the words.
This will allow recovering the keys in case the card is lost, permanently blocked or re-initialized. Although the mnemonic
phrase could be generated by the client itself, it is safer to use the card facilities since their RNG is certified.
## Signing transactions
The main function of the card is indeed signing transactions (thus authorizing them). Signing requires the PIN to be
authenticated (except in a case mentioned below). All transaction details will be shown on the client, because of the
physical limitations of the card. The card support BIP32 HD wallets, but the key derivation (used to navigate the wallet
hierarchy) and sign steps are separate from each other. The key derivation step also requires PIN authentication
(except in a case mentioned below) but since both steps are likely to happen in the same session, this only needs to be
done once. The user does not need to interact in this key derivation step, but depending on the depth of the selected
wallet it might take a while (up to 2 seconds). Signing itself can also take a while, so it is a good idea to show a waiting
indicator during this step.
The card signs the hash of the transaction provided by client, so it can actually be used to sign any 256-bit value, making
it flexible to eventually use it contexts other than Ethereum transactions.
The card also support defining a wallet path which is PIN-less. This path can be changed but can only be one at a given time
and cannot be the master wallet. Transactions using this wallet will not require PIN entry. Setting a PIN-less path requires
PIN authorization, but the setting is retained across sessions.
The GET STATUS command can be used to query the currently selected wallet. This allows skipping the key derivation step
if the needed wallet is selected already. The selected wallet is also retained across sessions.
## Exporting keys
Exporting the private key is not allowed, except for specific key paths. This step requires PIN authorization. Public
keys can be exported for any path.