Files
app-ethereum/doc/ethapp.asc

409 lines
20 KiB
Plaintext
Raw Normal View History

2016-06-01 21:41:29 +02:00
Ethereum application : Common Technical Specifications
=======================================================
Ledger Firmware Team <hello@ledger.fr>
2020-09-26 15:49:36 +02:00
Application version 1.5.0 - 25th of September 2020
2016-06-01 21:41:29 +02:00
2018-02-23 10:28:45 +02:00
## 1.0
2016-06-01 21:41:29 +02:00
- Initial release
2018-02-23 10:28:45 +02:00
## 1.1
2016-10-18 00:05:56 +02:00
- Add GET APP CONFIGURATION
- Add an option to return the chain code in GET ETH PUBLIC ADDRESS
2018-02-23 10:28:45 +02:00
## 1.2
- Add SIGN ETH PERSONAL MESSAGE
2019-02-05 14:50:36 +01:00
## 1.1.10
- Add PROVIDE ERC 20 TOKEN INFORMATION
2020-09-26 15:49:36 +02:00
## 1.5.0
- Add SIGN ETH EIP 712
2018-02-23 10:28:45 +02:00
## About
2016-06-01 21:41:29 +02:00
This application describes the APDU messages interface to communicate with the Ethereum application.
The application covers the following functionalities :
- Retrieve a public Ethereum address given a BIP 32 path
- Sign a basic Ethereum transaction given a BIP 32 path
- Provide callbacks to validate the data associated to an Ethereum transaction
The application interface can be accessed over HID or BLE
2018-02-23 10:28:45 +02:00
## General purpose APDUs
2016-06-01 21:41:29 +02:00
2018-02-23 10:28:45 +02:00
### GET ETH PUBLIC ADDRESS
2016-06-01 21:41:29 +02:00
2018-02-23 10:28:45 +02:00
#### Description
2016-06-01 21:41:29 +02:00
This command returns the public key and Ethereum address for the given BIP 32 path.
The address can be optionally checked on the device before being returned.
2018-02-23 10:28:45 +02:00
#### Coding
2016-06-01 21:41:29 +02:00
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
| E0 | 02 | 00 : return address
01 : display address and confirm before returning
2016-10-18 00:05:56 +02:00
| 00 : do not return the chain code
01 : return the chain code | variable | variable
2016-06-01 21:41:29 +02:00
|==============================================================================================================================
'Input data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Number of BIP 32 derivations to perform (max 10) | 1
| First derivation index (big endian) | 4
| ... | 4
| Last derivation index (big endian) | 4
|==============================================================================================================================
'Output data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Public Key length | 1
| Uncompressed Public Key | var
| Ethereum address length | 1
| Ethereum address | var
2016-10-18 00:05:56 +02:00
| Chain code if requested | 32
2016-06-01 21:41:29 +02:00
|==============================================================================================================================
2018-02-23 10:28:45 +02:00
### SIGN ETH TRANSACTION
2016-06-01 21:41:29 +02:00
2018-02-23 10:28:45 +02:00
#### Description
2016-06-01 21:41:29 +02:00
This command signs an Ethereum transaction after having the user validate the following parameters
- Gas price
- Gas limit
- Recipient address
- Value
The input data is the RLP encoded transaction (as per https://github.com/ethereum/pyethereum/blob/develop/ethereum/transactions.py#L22), without v/r/s present, streamed to the device in 255 bytes maximum data chunks.
2018-02-23 10:28:45 +02:00
#### Coding
2016-06-01 21:41:29 +02:00
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
| E0 | 04 | 00 : first transaction data block
80 : subsequent transaction data block
| 00 | variable | variable
|==============================================================================================================================
'Input data (first transaction data block)'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Number of BIP 32 derivations to perform (max 10) | 1
| First derivation index (big endian) | 4
| ... | 4
| Last derivation index (big endian) | 4
| RLP transaction chunk | variable
|==============================================================================================================================
'Input data (other transaction data block)'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| RLP transaction chunk | variable
|==============================================================================================================================
'Output data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| v | 1
| r | 32
| s | 32
2018-02-23 10:28:45 +02:00
|==============================================================================================================================
2016-06-01 23:09:02 +02:00
2018-02-23 10:28:45 +02:00
### SIGN ETH PERSONAL MESSAGE
#### Description
This command signs an Ethereum message following the personal_sign specification (https://github.com/ethereum/go-ethereum/pull/2940) after having the user validate the SHA-256 hash of the message being signed.
This command has been supported since firmware version 1.0.8
The input data is the message to sign, streamed to the device in 255 bytes maximum data chunks
2018-02-23 10:28:45 +02:00
#### Coding
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
| E0 | 08 | 00 : first message data block
80 : subsequent message data block
2018-02-23 10:28:45 +02:00
| 00 | variable | variable
|==============================================================================================================================
'Input data (first message data block)'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Number of BIP 32 derivations to perform (max 10) | 1
| First derivation index (big endian) | 4
| ... | 4
| Last derivation index (big endian) | 4
| Message length | 4
| Message chunk | variable
|==============================================================================================================================
'Input data (other transaction data block)'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Message chunk | variable
|==============================================================================================================================
'Output data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| v | 1
| r | 32
| s | 32
2018-02-23 10:28:45 +02:00
|==============================================================================================================================
2019-02-05 14:50:36 +01:00
### PROVIDE ERC 20 TOKEN INFORMATION
#### Description
This commands provides a trusted description of an ERC 20 token to associate a contract address with a ticker and number of decimals.
It shall be run immediately before performing a transaction involving a contract calling this contract address to display the proper token information to the user if necessary, as marked in GET APP CONFIGURATION flags.
The signature is computed on
ticker || address || number of decimals (uint4be) || chainId (uint4be)
signed by the following secp256k1 public key 0482bbf2f34f367b2e5bc21847b6566f21f0976b22d3388a9a5e446ac62d25cf725b62a2555b2dd464a4da0ab2f4d506820543af1d242470b1b1a969a27578f353
#### Coding
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
| E0 | 0A | 00 | 00 | variable | 00
|==============================================================================================================================
'Input data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Length of ERC 20 ticker | 1
| ERC 20 ticker | variable
| ERC 20 contract address | 20
| Number of decimals (big endian encoded) | 4
| Chain ID (big endian encoded) | 4
| Token information signature | variable
|==============================================================================================================================
'Output data'
None
2018-02-23 10:28:45 +02:00
### GET APP CONFIGURATION
2016-10-18 00:05:56 +02:00
2018-02-23 10:28:45 +02:00
#### Description
2016-10-18 00:05:56 +02:00
This command returns specific application configuration
2018-02-23 10:28:45 +02:00
#### Coding
2016-10-18 00:05:56 +02:00
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
2018-02-23 10:28:45 +02:00
| E0 | 06 | 00 | 00 | 00 | 04
2016-10-18 00:05:56 +02:00
|==============================================================================================================================
'Input data'
None
'Output data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Flags
0x01 : arbitrary data signature enabled by user
2019-02-05 14:50:36 +01:00
0x02 : ERC 20 Token information needs to be provided externally
2016-10-18 00:05:56 +02:00
| 01
| Application major version | 01
| Application minor version | 01
| Application patch version | 01
|==============================================================================================================================
2020-09-26 15:49:36 +02:00
### SIGN ETH EIP 712
#### Description
This command signs an Ethereum message following the EIP 712 specification (https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md)
For implementation version 0, the domain hash and message hash are provided to the device, which displays them and returns the signature
This command has been supported since firmware version 1.5.0
#### Coding
'Command'
[width="80%"]
|==============================================================================================================================
| *CLA* | *INS* | *P1* | *P2* | *Lc* | *Le*
| E0 | 0C | 00
| implementation version : 00 | variable | variable
|==============================================================================================================================
'Input data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Number of BIP 32 derivations to perform (max 10) | 1
| First derivation index (big endian) | 4
| ... | 4
| Last derivation index (big endian) | 4
| Domain hash | 32
| Message hash | 32
|==============================================================================================================================
'Output data'
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| v | 1
| r | 32
| s | 32
|==============================================================================================================================
2016-06-01 21:41:29 +02:00
2018-02-23 10:28:45 +02:00
## Transport protocol
2016-06-01 21:41:29 +02:00
2018-02-23 10:28:45 +02:00
### General transport description
2016-06-01 21:41:29 +02:00
Ledger APDUs requests and responses are encapsulated using a flexible protocol allowing to fragment large payloads over different underlying transport mechanisms.
The common transport header is defined as follows :
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| Communication channel ID (big endian) | 2
| Command tag | 1
| Packet sequence index (big endian) | 2
| Payload | var
|==============================================================================================================================
The Communication channel ID allows commands multiplexing over the same physical link. It is not used for the time being, and should be set to 0101 to avoid compatibility issues with implementations ignoring a leading 00 byte.
The Command tag describes the message content. Use TAG_APDU (0x05) for standard APDU payloads, or TAG_PING (0x02) for a simple link test.
The Packet sequence index describes the current sequence for fragmented payloads. The first fragment index is 0x00.
2018-02-23 10:28:45 +02:00
### APDU Command payload encoding
2016-06-01 21:41:29 +02:00
APDU Command payloads are encoded as follows :
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| APDU length (big endian) | 2
| APDU CLA | 1
| APDU INS | 1
| APDU P1 | 1
| APDU P2 | 1
| APDU length | 1
| Optional APDU data | var
|==============================================================================================================================
APDU payload is encoded according to the APDU case
[width="80%"]
|=======================================================================================
| Case Number | *Lc* | *Le* | Case description
| 1 | 0 | 0 | No data in either direction - L is set to 00
| 2 | 0 | !0 | Input Data present, no Output Data - L is set to Lc
| 3 | !0 | 0 | Output Data present, no Input Data - L is set to Le
| 4 | !0 | !0 | Both Input and Output Data are present - L is set to Lc
|=======================================================================================
2018-02-23 10:28:45 +02:00
### APDU Response payload encoding
2016-06-01 21:41:29 +02:00
APDU Response payloads are encoded as follows :
[width="80%"]
|==============================================================================================================================
| *Description* | *Length*
| APDU response length (big endian) | 2
| APDU response data and Status Word | var
|==============================================================================================================================
2018-02-23 10:28:45 +02:00
### USB mapping
2016-06-01 21:41:29 +02:00
Messages are exchanged with the dongle over HID endpoints over interrupt transfers, with each chunk being 64 bytes long. The HID Report ID is ignored.
2018-02-23 10:28:45 +02:00
### BLE mapping
2016-06-01 21:41:29 +02:00
A similar encoding is used over BLE, without the Communication channel ID.
The application acts as a GATT server defining service UUID D973F2E0-B19E-11E2-9E96-0800200C9A66
When using this service, the client sends requests to the characteristic D973F2E2-B19E-11E2-9E96-0800200C9A66, and gets notified on the characteristic D973F2E1-B19E-11E2-9E96-0800200C9A66 after registering for it.
Requests are encoded using the standard BLE 20 bytes MTU size
2018-02-23 10:28:45 +02:00
## Status Words
2016-06-01 21:41:29 +02:00
The following standard Status Words are returned for all APDUs - some specific Status Words can be used for specific commands and are mentioned in the command description.
'Status Words'
[width="80%"]
|===============================================================================================
| *SW* | *Description*
| 6700 | Incorrect length
| 6982 | Security status not satisfied (Canceled by user)
| 6A80 | Invalid data
| 6B00 | Incorrect parameter P1 or P2
| 6Fxx | Technical problem (Internal error, please report)
| 9000 | Normal ending of the command
2018-02-23 10:28:45 +02:00
|===============================================================================================