Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs #51

Merged
merged 5 commits into from
Dec 17, 2024
Merged

Docs #51

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,38 @@
# DISCLAIMER

:warning: | THIS IS AN EXPERIMENTAL PROJECT. IT IS INSECURE AT THIS STAGE<br/>Please don't start depending on it, and do not use it in production. Large parts of this project are subject to change. | :warning:
:---: | :--- | :---

---

# Vanadium

Vanadium is a Risc-V VM that runs in an embedded Secure Element.
Vanadium is a Risc-V Virtual Machine that runs in an embedded Secure Element.

<img align="right" src="docs/assets/vanadium_logo.png" alt="Vanadium Logo" style="width: 50%; min-width: 200px; max-width: 280px"/>

By outsourcing encrypted, authenticated pages to an untrusted client, it allows to run applications (V-Apps) in the element without worrying about the limitations of the embedded platform. You can write V-Apps without worrying about binary size and memory usage: only the code actually used at runtime will be sent to the device for execution, and page swapping with the client happens transparently between the VM and the VM client.
By outsourcing encrypted, authenticated pages to an untrusted client, it allows to run applications (V-Apps) in the secure element without worrying about the limitations of the embedded platform.

You can write V-Apps without worrying about binary size and memory usage: only the code actually used at runtime will be sent to the device for execution, and page swapping with the client happens transparently between the VM and the VM client.

# Repository
During development, you will write and test code natively, without relying on an external emulator. This simplifies writing, testing and deploying your code while keeping the majority of it generic, and not tied to a specific platform.

# Repository structure

This repository is organized in a monorepo structure.

* [docs](docs) - Architecture and technical documentation
* [VM](vm) - The Vanadium Ledger app
* [app-sdk](app-sdk) - Vanadium V-App SDK
* [client-sdk](client-sdk) - Vanadium V-App client SDK
* [VM](vm) <small>[<tt>arm</tt>], no-std</small> - The Vanadium Ledger app. It contains the actual Virtual Machine.
* [app-sdk](app-sdk) <small>[<tt>riscv</tt>], no_std</small> - Vanadium V-App SDK. It is used by V-Apps to access all the system services.
* [client-sdk](client-sdk) <small>[<tt>native</tt>]</small> - Vanadium V-App client SDK. V-App Clients use it as a base for their own client crates.
* [common](common) <small>[<tt>arm|riscv|native</tt>], no_std</small> - Any code that is shared among two or more of the above crates.
* [apps](apps) - Complete V-Apps, and their clients
* [test](apps/test) - Simple V-App to test the Vanadium.
* [sadik](apps/sadik) - A V-App specifically designed to test the various functionality of the Vanadium V-App SDK, and particularly the ECALLs.
* [bitcoin](apps/bitcoin) - Grandiose things will happen here, but it's mostly empty at this stage.

In VSCode, opening the [vanadium.code-workspace](vanadium.code-workspace) is the most convenient way to work with this repository.

## License

A [test](apps/test) V-App and client is also available.
This project is licensed under the [Apache Licence v2.0](LICENSE).
12 changes: 12 additions & 0 deletions app-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,15 @@
The `vanadium-app-sdk` crate is the V-app SDK. V-app are built using it.

It provides abstractions to the services provided via calls to the OS in the target platform (ECALLs).

Functionalities include:
- Communication primitives;
- BIP32 derivations, and the master key fingerprint;
- Big integers;
- Elliptic Curve points, private keys and pubkeys;
- Hash functions;
- UX functionality (TODO)

# Design principles

The public exports of this library try to keep an interface that is not directly tied to the underlying ecalls. This allows to abstract differences between targets, where some ECALLs might be unavailable or different, or simply unstable and subject to change.
14 changes: 14 additions & 0 deletions app-sdk/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# build for both native and riscv targets
build:
cargo build --release --target=x86_64-unknown-linux-gnu
cargo build --release --target=riscv32i-unknown-none-elf

# build for native target
build-native:
cargo build --release --target=x86_64-unknown-linux-gnu

# build for riscv target
build-riscv:
cargo build --release --target=riscv32i-unknown-none-elf

23 changes: 23 additions & 0 deletions apps/bitcoin/app/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
run:
cargo run

# build for both native and riscv targets
build:
cargo build --release --target=x86_64-unknown-linux-gnu
cargo build --release --target=riscv32i-unknown-none-elf

# build for native target
build-native:
cargo build --release --target=x86_64-unknown-linux-gnu

# build for riscv target
build-riscv:
cargo build --release --target=riscv32i-unknown-none-elf

# disassembles the riscv binary
disassemble:
riscv64-linux-gnu-objdump -d target/riscv32i-unknown-none-elf/release/vnd-bitcoin

# show the sections of the riscv binary
show-sections:
readelf -S target/riscv32i-unknown-none-elf/release/vnd-bitcoin
23 changes: 23 additions & 0 deletions apps/sadik/app/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
run:
cargo run

# build for both native and riscv targets
build:
cargo build --release --target=x86_64-unknown-linux-gnu
cargo build --release --target=riscv32i-unknown-none-elf

# build for native target
build-native:
cargo build --release --target=x86_64-unknown-linux-gnu

# build for riscv target
build-riscv:
cargo build --release --target=riscv32i-unknown-none-elf

# disassembles the riscv binary
disassemble:
riscv64-linux-gnu-objdump -d target/riscv32i-unknown-none-elf/release/vnd-test

# show the sections of the riscv binary
show-sections:
readelf -S target/riscv32i-unknown-none-elf/release/vnd-test
5 changes: 5 additions & 0 deletions apps/sadik/client/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# build for both native and riscv targets
integration-tests:
cargo test --features speculos-tests

23 changes: 23 additions & 0 deletions apps/test/app/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
run:
cargo run

# build for both native and riscv targets
build:
cargo build --release --target=x86_64-unknown-linux-gnu
cargo build --release --target=riscv32i-unknown-none-elf

# build for native target
build-native:
cargo build --release --target=x86_64-unknown-linux-gnu

# build for riscv target
build-riscv:
cargo build --release --target=riscv32i-unknown-none-elf

# disassembles the riscv binary
disassemble:
riscv64-linux-gnu-objdump -d target/riscv32i-unknown-none-elf/release/vnd-test

# show the sections of the riscv binary
show-sections:
readelf -S target/riscv32i-unknown-none-elf/release/vnd-test
35 changes: 35 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Compilation targets

With the exception of the Vanadium app itself, which is an embedded Ledger app on the `ARM` target, all the other crates target either the `native` or the `riscv` targets.

- The `native` target is currently `x86_64-unknown-linux-gnu`, but more native targets might be added in the future. It has `riscv` and `native` targets, in `no_std` mode.
- The `riscv` target is currently `riscv32i-unknown-none`.

> **⚠️ WARNING: The native target is insecure.**<br> While it is possible to compile and run the V-Apps on native targets, this is only intended for development and testing purposes. The cryptographic primitives are not hardened against side channels, or other kinds of attacks.

# Architecture

![Vanadium architecture chart](assets/architecture.svg)

## System crates

In the above chart, all the crates outside *USERLAND* are developed as part of the Vanadium project.

* `vanadium`: This is a Ledger application, targeting the ARM embedded platform that is used by Ledger devices. It contains the VM, code to register and run V-Apps, and provides the implementation of all the system services (via Risc-V ECALLs) to V-Apps. It interacts with the operating system ([BOLOS](https://www.ledger.com/academy/security/our-custom-operating-system-bolos)) in order to provide access to low level primitives, like communication and the cryptographic accelerator.
* `vanadium-app-sdk`: The SDK used for developing V-Apps. It has `riscv` and `native` targets, in `no_std` mode.
* `vanadium-client-sdk`: The SDK used for developing the client of V-Apps. It contains the client code common to all V-Apps; in particular, it manages the outsourced memory of the V-App, providing the content of memory pages (and proofs of correctness) when requested by the VM. It only has the `native` target.

## V-App structure

Currently, all existing V-Apps are in this repository, with a monorepo structure.

In the architecture chart above, each V-App will implement the crates in *USERLAND*: particularly, the V-App itself, the V-App client crate, and any external software using the V-App.

A V-App called `foo` should contain three crates:
* `vnd-foo`: the code of the app. It has `riscv` and `native` targets, in `no_std` mode.
* `vnd-foo-client`: contains the client code of the V-App, built using the `vanadium-app-client-sdk` crate. It only has the `native` target.
* `vnd-foo-common`: any shared code between the app and client crates. It has `riscv` and `native`, in `no_std` mode.

# Other documentation

* [ECALLs](ecalls.md)
2 changes: 0 additions & 2 deletions docs/architecture.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/assets/architecture.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/vanadium_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 20 additions & 2 deletions docs/ecalls.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
ECALLs allow Risc-V code to call system services, that are provided by the environment. The Vanadium VM defines ECALLs for low level primitives (communication, screen management, etc.) and access to the implementation cryptographic accelerator, or other functionalities the VM provides for performance reasons.

# Risc-V calling conventions for ECALLs

ECALLs use the following calling convention:

- ECALL code in `t0`
- Up to 8 ECALL arguments in `a0`, `a1`, ..., `a8`, in this order.
- Up to 8 ECALL arguments in `a0`, `a1`, ..., `a7`, in this order.
- Return value (if any) is in `a0`.

No ECALLs with more than 8 argments (using the stack) are currently defined.

# Currently defined ECALLs

See [ecalls.rs](../app-sdk/src/ecalls.rs).
See [ecalls.rs](../app-sdk/src/ecalls.rs) for the interface and documentation of the currently defined ECALLs.

# Implementation of ECALLs

Each new ECALL requires:
- adding the appropriate constants in [`common/src/ecall_constants.rs`](../common/src/ecall_constants.rs);
- add the prototype of the ECALL to the <code>EcallsInterface</code> in [`app-sdk/src/ecalls.rs`](../app-sdk/src/ecalls.rs);
- implementing the ECALL for native compilation in [`app-sdk/src/ecalls_native.rs`](../app-sdk/src/ecalls_native.rs);
- implementing the ECALL code generation via the macros in [`app-sdk/src/ecalls_riscv.rs`](../app-sdk/src/ecalls_riscv.rs);
- implementing the ECALL handler in the Vanadium VM in [`vm/src/handlers/lib/ecall.rs`](../vm/src/handlers/lib/ecall.rs);
- expose the functionality of the ECALL via the appropriate abstraction in the app-sdk;
- add code to the [sadik V-App](../apps/sadik/) in order to test the new ECALLs.

ECALLs are not exported directly in the `vanadium-app-sdk`. Rather, clean Rust abstractions are implemented. Apart from providing a cleaner interface, the goal of the abstraction is to avoid that the application code depends on the low-level details of ECALLs. This allows breaking changes in the ECALLs, or even target-specific ECALLs, without impacting the users of the crate.

Eventually, the goal is to stabilize a set of ECALLs that constitutes the core of Vanadium, in order to simplify adding new targets.
28 changes: 28 additions & 0 deletions vm/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
run:
speculos build/nanos2/bin/app.elf

run-nanox:
speculos build/nanox/bin/app.elf

run-nanosplus:
speculos build/nanos2/bin/app.elf

run-flex:
speculos build/flex/bin/app.elf

run-stax:
speculos build/stax/bin/app.elf


load-nanosplus:
python3 -m ledgerblue.runScript --scp --fileName build/nanos2/bin/app.apdu --elfFile build/nanos2/bin/app.elf

load-nanox:
python3 -m ledgerblue.runScript --scp --fileName build/nanox/bin/app.apdu --elfFile build/nanox/bin/app.elf

load-flex:
python3 -m ledgerblue.runScript --scp --fileName build/flex/bin/app.apdu --elfFile build/flex/bin/app.elf

load-stax:
python3 -m ledgerblue.runScript --scp --fileName build/stax/bin/app.apdu --elfFile build/stax/bin/app.elf

Loading