2017-09-22 09:14:15 +00:00
# Status Wallet Application
## 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.
## PIN
During installation the user's PIN is set to 000000 (six times zero). 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, unique for each installation and is generated off-card
and passed as an installation parameter to the applet according to the JavaCard specifications. After 5 failed attempts
to unblock the applet using the PUK, the PUK is blocked, meaning the the wallet is lost.
After authentication, the user remains authenticated until the application is either deselected or the card is reset.
2017-10-26 09:11:49 +00:00
Authentication with PIN is a requirement for most commands to succeed.
2017-09-22 09:14:15 +00:00
The PIN can be changed by the user after authentication.
## Keys & Signature
2017-10-19 13:37:14 +00:00
The application allows loading a 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.
2017-09-22 09:14:15 +00:00
Signing of transactions is done by uploading the data in blocks no larger than 255 bytes (including the overhead caused
2017-10-26 09:11:49 +00:00
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.
2017-09-22 09:14:15 +00:00
2017-10-09 12:06:59 +00:00
## APDUs
2017-09-22 09:14:15 +00:00
These are the commands supported by the application. When a command has a precondition clause and these are not met the
2017-10-09 12:06:59 +00:00
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)
2017-09-22 09:14:15 +00:00
### SELECT
* CLA = 0x00
* INS = 0xA4
* P1 = 0x04
* P2 = 0x00
* Data = 53746174757357616C6C6574417070 (hex)
2017-11-15 09:55:41 +00:00
* Response = Application Info Template
Response Data format:
- Tag 0xA4 = Application Info Template
2018-01-05 13:11:00 +00:00
- Tag 0x4F = Instance UID (16 bytes)
2017-11-15 09:55:41 +00:00
- Tag 0x80 = ECC public Key
2017-09-22 09:14:15 +00:00
The SELECT command is documented in the ISO 7816-4 specifications and is used to select the application on the card,
2017-11-15 09:55:41 +00:00
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.
2017-09-22 09:14:15 +00:00
### OPEN SECURE CHANNEL
The OPEN SECURE CHANNEL command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD).
2017-11-17 13:12:28 +00:00
### MUTUALLY AUTHENTICATE
The MUTUALLY AUTHENTICATE command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD).
2017-11-14 12:50:07 +00:00
### PAIR
The PAIR command is as specified in the [SECURE_CHANNEL.MD](SECURE_CHANNEL.MD). The shared secret is the SHA-256 of the
PUK.
### 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.
2017-10-09 14:12:21 +00:00
### GET STATUS
2017-10-26 09:11:49 +00:00
2017-10-09 14:12:21 +00:00
* CLA = 0x80
* INS = 0xF2
2017-10-25 11:29:13 +00:00
* P1 = 0x00 for application status, 0x01 for key path status
2017-10-09 14:12:21 +00:00
* P2 = 0x00
2017-10-25 11:29:13 +00:00
* Response SW = 0x9000 on success, 0x6A86 on undefined P1
* Response Data = Application Status Template or Key Path
2017-11-20 14:42:12 +00:00
* Preconditions: Secure Channel must be opened, if Key Path is required then the card must not be in the middle of a
derivation session
2017-10-09 14:12:21 +00:00
Response Data format:
2017-10-25 11:29:13 +00:00
if P1 = 0x00:
2017-10-09 14:12:21 +00:00
- Tag 0xA3 = Application Status Template
2018-01-17 13:29:38 +00:00
- Tag 0x02 = PIN retry count (1 byte)
- Tag 0x02 = PUK retry count (1 byte)
- Tag 0x01 = 0 if key is not initialized, 1 otherwise
- Tag 0x01 = 1 if public key derivation is supported, 0 otherwise
2017-10-09 14:12:21 +00:00
2017-10-25 11:29:13 +00:00
if P1 = 0x01
- a sequence of 32-bit numbers indicating the current key path. Empty if master key is selected.
2017-09-22 09:14:15 +00:00
### 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 = 0x00
* P2 = 0x00
* Data = the new PIN
* Response SW = 0x9000 on success, 0x6A80 if the PIN format is invalid
* Preconditions: Secure Channel must be opened, user PIN must be verified
Used to change the user PIN. The new PIN must be composed of exactly 6 numeric digits. Should this be not the case,
the code 0x6A80 is returned. If the conditions matches the user PIN is updated and authenticated for the rest of
the session. The no-error SW 0x9000 is returned.
### 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
2017-10-09 12:06:59 +00:00
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
2017-09-22 09:14:15 +00:00
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.
2017-09-22 09:41:43 +00:00
2017-09-25 08:27:55 +00:00
### LOAD KEY
2017-09-22 09:41:43 +00:00
* CLA = 0x80
* INS = 0xD0
2017-10-09 12:06:59 +00:00
* P1 = key type
2017-09-25 08:27:55 +00:00
* P2 = 0x00
2017-09-22 09:41:43 +00:00
* Data = the key data
2017-10-19 13:37:14 +00:00
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6A86 if P1 is invalid, 0x6A81 if public key
derivation is not supported and the public key is omitted
2017-09-22 09:41:43 +00:00
* Preconditions: Secure Channel must be opened, user PIN must be verified
2017-10-09 12:06:59 +00:00
P1:
* 0x01 = ECC SECP256k1 keypair
* 0x02 = ECC SECP256k1 extended keypair
2017-10-11 07:55:04 +00:00
* 0x03 = Binary seed as defined in [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
2017-09-25 07:53:20 +00:00
2017-10-09 12:06:59 +00:00
Data:
If P1 is 0x01 or 0x02
2017-09-25 08:27:55 +00:00
- Tag 0xA1 = keypair template
2017-10-19 13:37:14 +00:00
- Tag 0x80 = ECC public key component (can be omitted if public key derivation is supported)
2017-10-06 12:08:07 +00:00
- Tag 0x81 = ECC private key component
2017-10-09 12:06:59 +00:00
- 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
2017-10-19 13:37:14 +00:00
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.
2017-09-25 07:53:20 +00:00
This command is used to load or replace the keypair used for signing on the card. This command always aborts open
2017-10-09 12:06:59 +00:00
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
2017-10-19 13:37:14 +00:00
* P1 = derivation options
* P2 = assisted derivation phase
* Data = a sequence of 32-bit integers (most significant byte first). Empty if the master key must be used. On assisted
derivation contains a public key when P2 = 0x02.
* Response SW = 0x9000 on success, 0x6A80 if the format is invalid, 0x6A81 if public key derivation is not supported and
2017-10-28 16:43:07 +00:00
bit 0 of P1 is set, 0x6A86 if P2 = 0x01 and bit 0 of P1 is not set, 0x6984 if one of the components in the path
generates an invalid key.
2017-10-19 13:37:14 +00:00
* Response Data = On assisted derivation and P2 = 0x01 the key derivation template. Empty otherwise.
2017-11-20 14:42:12 +00:00
* Preconditions: Secure Channel must be opened, user PIN must be verified (if no PIN-less key is defined), an extended
keyset must be loaded
2017-10-09 12:06:59 +00:00
2017-10-18 11:30:56 +00:00
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)
2017-10-19 13:37:14 +00:00
specifications. This command always aborts open signing sessions, if any. The generated key is used for all subsequent
SIGN sessions. Because JavaCard does not offer native EC point multiplication before version 3.0.5, there is an
alternative mode of operation where the public key is partially derived off-card and loaded back on card. In this mode
of operation only 1 derivation step at the time can be completed and as such during assisted derivation the data can
2017-10-25 11:29:13 +00:00
contain a single 32-bit integer, instead of a sequence. The maximum depth of derivation from the master key is 10. Any
2017-10-28 16:43:07 +00:00
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.
2017-10-19 13:37:14 +00:00
P1:
* bit 0 = if 0 derive autonomously (only works if public key derivation is supported), if 1 do assisted derivation
* bit 1-6 = reserved
* bit 7 = if 0 derive from master keys, if 1 derive from current keys
P2:
2017-10-26 09:11:49 +00:00
* 0x00 = data is a sequence of 32-bit integers
2017-10-19 13:37:14 +00:00
* 0x01 = data is a public key
Response Data format:
2017-10-24 08:45:05 +00:00
The signature is calculated over the SHA-256 hash of the message "STATUS KEY DERIVATION"
- Tag 0xA2 = key derivation template
2017-10-19 13:37:14 +00:00
- Tag 0x83 = ECC Public Key X component
- Tag 0x30 = ECDSA Signature
- Tag 0x02 = R value
- Tag 0x02 = S value
2017-10-09 12:06:59 +00:00
### 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.
2017-09-25 07:53:20 +00:00
### SIGN
* CLA = 0x80
* INS = 0xC0
2017-10-04 12:10:59 +00:00
* P1 = data type
2017-09-25 07:53:20 +00:00
* P2 = segment flag
* Data = the data to sign
2017-10-06 12:08:07 +00:00
* Response = if P2 indicates last segment, the public key and the signature are returned
2017-09-25 07:53:20 +00:00
* Response SW = 0x9000 on success, 0x6A86 if P2 is invalid
2017-11-20 14:42:12 +00:00
* 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
2017-09-25 07:53:20 +00:00
2017-10-04 12:10:59 +00:00
P1:
* 0x00 = transaction data
* 0x01 = precomputed hash
2017-09-25 07:53:20 +00:00
P2:
* bit 0 = if 1 first block, if 0 other block
* bit 1-6 = reserved
* bit 7 = if 0 more blocks, if 1 last block
2017-10-06 12:08:07 +00:00
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
2017-09-25 07:53:20 +00:00
Used to sign transactions. Since the maximum short APDU size is 255 bytes the transaction must be segmented before
being sent if it is larger than that. The overhead from the Secure Channel must be also accounted for. When the last
2017-09-30 14:26:06 +00:00
segment is sent, the card returns the calculated signature. The signature is an ECDSA signature calculated over the
2017-10-06 12:08:07 +00:00
SHA-256 hash of the sent data or directly over the provided hash if P1 = 0x01.
2017-09-25 07:53:20 +00:00
The P2 parameter is used to manage the signing session and is treated as a bitmask. The rightmost bit indicates whether
this block is the first one (1) or not (0). On the first block the card resets the signature state. The leftmost bit
indicates whether this is the last block (1) or not (0). On the last block, the card generates and sends the signatures
to the client.
For example, if a signing session spans over 3 segments, the value of P2 will be respectively 0x01, 0x00, 0x80. If
the signing session is composed of a single session P2 will have the value of 0x81.
After a signature is generated, the next SIGN command must have the rightmost bit of P2 set, otherwise 0x6A86 will
be returned.
2017-09-30 14:26:06 +00:00
This segmentation scheme allows resuming signature sessions if other commands must be sent in between and at
the same time avoid generating signatures over partial data, since both the first and the last block are marked.
2017-10-26 09:11:49 +00:00
On applet selection any pending signing session is aborted.
### 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
2017-10-26 11:15:40 +00:00
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 = 0x01 (Whisper key)
* P2 = 0x00
* Response SW = 0x9000 on success, 0x6A86 if P1 is wrong
* Response Data = key pair template
* Preconditions: Secure Channel must be opened, user PIN must be verified, the current key path must match the one of
the key selected through P1
Response Data format:
- Tag 0xA1 = keypair template
- Tag 0x80 = ECC public key component
- Tag 0x81 = ECC private key component
This command exports the current public and private key if and only if the current key path matches the one of the key
selected by P1. P1 is only an index, the actual key path is stored immutably in the applet itself. At the moment only
the Whisper key (P1=0x01) can be exported and its key path is m/1/1. Other key paths could be added in the future, but
the last should remain as short as possible because of the security implications of revealing private keys to a possibly
2018-01-17 13:29:38 +00:00
compromised device. The current chain code is never exported to make it impossible to further derive keys off-card.