Skip to content

Commit

Permalink
Merge pull request #115 from LedgerHQ/embedded/restructure
Browse files Browse the repository at this point in the history
Embedded doc proposal
  • Loading branch information
cfranceschi-ledger authored Jan 26, 2024
2 parents 08263bd + 448ff9a commit 87666e8
Show file tree
Hide file tree
Showing 162 changed files with 2,115 additions and 2,698 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules
.DS_Store
public/.DS_Store

.*
376 changes: 321 additions & 55 deletions next.config.js

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions pages/docs/_meta.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
{
"sections": "All the sections",
"device-app": "Device App",
"plugin": "Plugin",
"device-app": "Device app",
"connectivity": "Connectivity",
"nft-display": "NFT Display",
"discover": "Discover",
Expand Down
25 changes: 15 additions & 10 deletions pages/docs/device-app.mdx
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
---
title: What is an Device App?
Description: "There are three types of embedded apps: Classical embedded apps, DApp plugins, and utility applications."
title: What is a Device App?
Description: "There are three types of device apps: Classical device apps, DApp plugins, and utility applications."
---

# What is an Device App?
# What is a Device App?

<img style={{width: "250px", float:"right"}} src="/device-app/nanosplus.png"/>

There are three types of embedded apps: Classical embedded apps, DApp plugins, and utility applications.
There are three types of device apps: Classical device apps, DApp plugins, and utility applications.

### Classical device apps (or embedded apps)
This is the application that allows the users to manage their crypto-assets with their Ledger devices. It is the first step to an integration of your coin or token to the Ledger environment and to an integration of your blockchain to Ledger Live. The following sections will help you develop this type of application. For more information about the role of the Ledger embedded app, read [this Academy article](https://www.ledger.com/academy/hardwarewallet/what-are-ledger-applications-and-why-do-i-need-them).
## Classical device apps (or device apps)

This is the application that allows the users to manage their crypto-assets with their Ledger devices. It is the first step to an integration of your coin or token to the Ledger environment and to an integration of your blockchain to Ledger Live. The following sections will help you develop this type of application. For more information about the role of the Ledger device app, read [this Academy article](https://www.ledger.com/academy/hardwarewallet/what-are-ledger-applications-and-why-do-i-need-them).

## DApp plugins

### DApp plugins
DApp Plugins are developed to integrate an Ethereum DApp to Ledger live. Ledger Live has a DApp browser where your DApp will be visible and usable through an iframe. Ethereum DApps can be developed for example to lend or borrow, swap, trade, pay with cryptoassets or manage your portfolio. The documentation for DApp plugins is in the [Live App section](../../../docs/discover).

### Utility applications
These applications leverage Ledger technology but are not involved in managing crypto assets. They can be, for example, a password manager application, or a two-factor authentication application.
For a DApp Plugins to be able to sign transactions on a Ledger Device, one needs to develop a small, specific application relying on the Ethereum application environment. This type of application is called a **plugin**.

## Utility applications

These applications leverage Ledger technology but are not involved in managing crypto assets. They can be, for example, a password manager application, or a two-factor authentication application.

**You are developing a classical embedded App or a utility application, you are in the right section!**
**You are developing a classical device App, a utility application or a plugin, you are in the right section!**
27 changes: 6 additions & 21 deletions pages/docs/device-app/_meta.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
{
"getting-started": "Getting started",
"submission": "Submission Requirements",
"quickstart": "Quickstart",
"separator1": {
"title": "",
"type": "separator"
},
"coding-guidelines": "Coding guidelines",
"deliverables": "Deliverables",
"clones": "Ethereum Clones",
"separator2": {
"title": "",
"type": "separator"
},
"cryptography-lib": "Cryptoraphy Library and syscalls",
"psd": "Personal security devices",
"bolos": "The BOLOS Platform",
"tools": "Tools",
"faq": "Frequently Asked Questions"
}
{
"introduction": "Introduction",
"develop": "Develop & Test",
"deliver": "Deliver",
"architecture": "References"
}
29 changes: 29 additions & 0 deletions pages/docs/device-app/architecture.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Cards, Card } from 'nextra/components'

#

This chapter talks about key concept of what a Personnal Security Device (PSD) is and why it is needed, the design of
such a device, and more specific high-level consideration on the Ledger PSDs: UI, BOLOS and such.

<Cards num={2}>
<Card
title="Personal Security Device"
href="./architecture/psd"
/>
<Card
title="Application architecture"
href="./architecture/app-architecture"
/>
<Card
title="BOLOS"
href="./architecture/bolos"
/>
<Card
title="UI examples and good practices"
href="./architecture/ui"
/>
<Card
title="Tips"
href="./architecture/tips"
/>
</Cards>
7 changes: 7 additions & 0 deletions pages/docs/device-app/architecture/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"psd": "Personal Security Device",
"bolos": "BOLOS",
"security": "Security concerns",
"crypto": "Cryptography",
"ui": "UI good practices"
}
File renamed without changes.
5 changes: 5 additions & 0 deletions pages/docs/device-app/architecture/bolos/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"features": "BOLOS features",
"hardware-architecture": "Hardware architecture",
"application-environment": "Application environment"
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Callout } from 'nextra/components'

## Introduction

In this article, we'll discuss some of the features that are built into BOLOS. These features are available through the [dashboard app](./#the-dashboard) and / or can be used by userspace applications.
In this article, we'll discuss some of the features that are built into BOLOS. These features are available through the [dashboard app](../bolos#the-dashboard) and / or can be used by userspace applications.

## Management of Cryptographic Secrets

Expand All @@ -21,7 +21,7 @@ Both of these secrets are stored by BOLOS and are not directly accessible to app

### Passphrases in BOLOS

Since firmware version 1.3 on the Ledger Nano S, BOLOS allows users to load multiple [BIP 39 passphrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki/#from-mnemonic-to-seed) onto the device at once. As described in [the previous chapter](../psd/masterseed/), passphrases are a method to add additional entropy to the BIP 39 master seed in order to completely change the [HD tree](../psd/keys/). Users can set a temporary passphrase which is activated until the device is disconnected, or store a passphrase on the device by attaching it to a PIN. When a passphrase is attached to a PIN, it is only activated when the user unlocks the device using the PIN corresponding to that passphrase. See our [Help Center article on the advanced passphrase options](https://support.ledger.com/hc/en-us/articles/115005214529-Advanced-passphrase-security) for more information about using passphrases.
Since firmware version 1.3 on the Ledger Nano S, BOLOS allows users to load multiple [BIP 39 passphrases](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki/#from-mnemonic-to-seed) onto the device at once. As described in [the previous chapter](../psd), passphrases are a method to add additional entropy to the BIP 39 master seed in order to completely change the [HD tree](../psd/keys/). Users can set a temporary passphrase which is activated until the device is disconnected, or store a passphrase on the device by attaching it to a PIN. When a passphrase is attached to a PIN, it is only activated when the user unlocks the device using the PIN corresponding to that passphrase. See our [Help Center article on the advanced passphrase options](https://support.ledger.com/hc/en-us/articles/115005214529-Advanced-passphrase-security) for more information about using passphrases.

When a passphrase is activated, the binary seed derived according to BIP 39 is changed and consequently the entire HD tree is changed. This means that using a different passphrase causes applications that derive information from the HD tree (like cryptocurrency wallet applications) to derive entirely different information (different cryptocurrency addresses will be generated).

Expand Down Expand Up @@ -78,7 +78,7 @@ This diagram shows the chain of trust of our attestation model. All data signed

Throughout the standard device lifecycle, it is possible for a host computer to establish a Secure Channel with a device to verify its authenticity and to securely exchange secrets with it.

As discussed in `anti-tampering`, the authenticity of a Ledger device can be verified when it connects to a host computer by requesting the device's `Issuer Certificate`, which is signed by Ledger. This is done when establishing a Secure Channel with the device. However, the Secure Channel is not only a means to verify the authenticity of a Ledger device, it also allows the host computer to establish an encrypted communication channel with the device. Only the [dashboard application](./#dashboard) is able to establish a Secure Channel with the host computer, as doing so requires access to the `Device` private key.
As discussed in `anti-tampering`, the authenticity of a Ledger device can be verified when it connects to a host computer by requesting the device's `Issuer Certificate`, which is signed by Ledger. This is done when establishing a Secure Channel with the device. However, the Secure Channel is not only a means to verify the authenticity of a Ledger device, it also allows the host computer to establish an encrypted communication channel with the device. Only the [dashboard application](../bolos/#dashboard) is able to establish a Secure Channel with the host computer, as doing so requires access to the `Device` private key.

The Secure Channel protocol is built on top of the APDU (Application Protocol Data Unit) protocol used to communicate with the device over USB. As such, the protocol consists of a series of Command APDUs being sent from the host computer, and then associated Response APDUs being sent back from the device, with a one-to-one correspondence. The Secure Channel exists between two parties: the Signer and the Device. The Signer is the remote host connecting to the device. This may be the Issuer (Ledger) connecting to the device through our APIs, a [Custom Certificate Authority](#custom-ca) connecting to the device using a previously [enrolled Custom CA public key](#custom-ca-public-key-enrollment), or another end-user using a randomly generated keypair.

Expand Down Expand Up @@ -126,4 +126,3 @@ Below is a definition of all of the parties involved in our public key cryptogra
<Callout>
A Custom CA may be a BOLOS application developer or a third party company that would like to give their application manager special administration permissions with a BOLOS device.
</Callout>

File renamed without changes.
98 changes: 98 additions & 0 deletions pages/docs/device-app/architecture/crypto.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Callout } from 'nextra/components'


## Cryptography

This section presents general concepts about cryptography development, but also guidelines specific to the security model of the Ledger devices. It gives guidelines to:

- Ensure a potential vulnerability in one application will not cause damages to other apps.
- Make sure all the operations that manipulate secrets are approved by the user.
- Restrict the use of these secrets by apps.


### Never store or export secrets derived from seed

The seed allows the user to derive any key from a given path at will. The user can reconstruct this secret from a new device by reentering its seed if he were to lose the original device.

Generating secrets must be done on demand. An application **must not** store a secret derived from the seed, and should regenerate it instead then erased when it is not used anymore.

Even in encrypted form, those secrets **must not** not be stored outside of the device. They can be regenerated instead.


### Avoid blindly signing data

**You should never allow signing of any attacker-controlled message unless it has been verified for structural validity. Importantly, you should never sign a message that might be a hash of transaction.**

Rationale: If you allow an attacker to blindly sign a message, it can easily supply a hash of a valid transaction. Your signature could then be used to send an unauthorized transaction.

If you want to sign user-supplied "personal" messages, prefix them with a fixed string (which shouldn't be a valid transaction prefix). It is also a good practice to include message length in the text to be signed. Ledger-app-eth has a good example in function `handleSignPersonalMessage`. Note that sometimes cryptocurrencies have a standardized way of signing such personal messages and in that case you should use the approved scheme.

Warning: If you allow signing untrusted hashes (while displaying a prompt to the user), be aware that

1. Some users are not familiar with security and could be easily tricked. They can click through your prompt without properly checking unless you give them explicit "Warning: this is a very unusual operation. Do not continue unless you know what you are doing" warning. They might not see the message even then.
2. A compromised host might both change hash on the screen and also data sent to device. This opens the possibility of users signing something they didn't want to.


### Signing/disclosing keys

<Callout type="warning" emoji="⚠️">
You must always require user approval for signing transactions/messages.
</Callout>

Rationale: If you do not require user consent for signing important data, an attacker can use your device as a signing black box and sign whatever they want.

<Callout type="info" emoji="👉">
You might also consider approvals for extracting public keys, as some users might want extended privacy.
</Callout>

1. They might not want to reveal their *root/account* public key, only address keys
2. They might not want to reveal address public key until it is required. (Some cryptocurrencies use addresses that are hash of public keys. It is therefore enough to send the address to the host).

<Callout type="info" emoji="👉">
There is a trade-off between privacy and usability here. If you want privacy, it would require a user interaction every time they want to use Ledger device, as opposed to only interaction while signing transactions. The behaviour could also be manually set in the application options.
</Callout>


### Don't roll your own crypto primitives

**You should never roll your own crypto primitives** (including encryption/derivation schemes, hashing functions, HMAC, etc.)

Rationale: It is a purpose of BOLOS operating system to perform these in a secure manner. Importantly, writing your own crypto primitives is likely to open you to side-channel attacks or other problems. If your primitive is not supported by BOLOS (e.g., some very new cryptography), consult with Ledger developers the possibility of including it in the OS.

### Avoid Exceptions for Cryptographic Code

From the 2.0 version of the SDK every cryptographic function has a version that returns an error code instead of raising an exception. As an example `cx_ecdsa_sign_no_throw` performs the same computation as `cx_ecdsa_sign` but does not raise any exception and returns CX_OK if everything went fine.

We enforce using all `_no_throw` equivalents when available, as the ones raising exceptions are deprecated in a future SDK release.

Rationale: the exception mechanism is not standard C, and is difficult to use, particularly for error management. There were errors related to this exception model in every single app we reviewed in 2020.

### Private Key Management

**You should minimize the code that works with private (ECDSA, RSA, etc.) or secret (HMAC, AES, etc.) keys.** Importantly, you should always **clear the memory** after you use these keys. That includes key data and key objects.

Leaving parts of private or secret keys lying around in memory is not a security issue on its own because there is no easy way to extract the RAM content on the chip. If a key is left in RAM by an app, another app will not be able to access it.

However, if the key has not properly been erased, a security issue could lead to the leak of this key, even if it is not used anymore. An attacker able to read arbitrary memory from the app, or execute arbitrary code, will be able to read the content of the stack segment, hence the parts of the key which have not been erased.

Here is an example of a common and **wrong way** of doing this:

``` c copy
uint8_t privateKeyData[64];
cx_ecfp_private_key_t privateKey;

os_perso_derive_node_bip32(
tmpCtx.transactionContext.curve, tmpCtx.transactionContext.bip32Path,
tmpCtx.transactionContext.pathLength, privateKeyData,
NULL);
cx_ecfp_init_private_key(tmpCtx.transactionContext.curve, privateKeyData,
32, &privateKey);
explicit_bzero(privateKeyData, sizeof(privateKeyData));

// (later, after privateKey is not needed)
explicit_bzero(&privateKey, sizeof(privateKey));
```
In the happy path, the previous code will correctly clean the memory once the private key is initialized. Note, however, that this code **fails to protect private keys in case some system call throws (for example cx\_ecfp\_init\_private\_key)**. Correct code should wrap the clearing in `BEGIN_TRY { TRY { ... } FINALLY { explicit_bzero() } END_TRY;`.
Applications where such issues were fixed include [the ARK app](https://github.com/LedgerHQ/app-ark/commit/e84a4dc0c422f7ade586c831cbab56cb15c64df1) and [the Solana app](https://github.com/LedgerHQ/app-solana/pull/5/files).
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 87666e8

Please sign in to comment.