/ TECH

Developing Nano apps in Rust

Bringing a modern language and memory safety into our applications.

We are open-sourcing an application demo in Rust that uses our C SDK. In this short post, we will explain our choices and why we wanted Rust to be an option for Ledger Nano developers.

What is Rust?

Not everyone might know the language so here is a short introduction. Rust is a language that was developed at Mozilla as essentially a memory-safe replacement to C/C++. It prevents lots of known bugs at compile-time, and achieves this without using a garbage collector. A good list of reasons to use the language can be found on the blog of Microsoft Security Response Center. One of their studies showed that 70% of CVEs they assign are due to memory safety bugs. Using Rust would eliminate this class of bugs entirely.

Why on Nano?

Bringing compile-time safety guarantees is an obvious plus for the Ledger Nano ecosystem. Also we have taken upon ourselves to perform security reviews of apps before they land on Ledger Live and check whether the app isolation can be broken or not. Having those static guarantees means we also save time on the review and can focus on more complex bugs.

Another very important aspect is the ergonomics of the language. Rust offers a lot more constructs than plain C, which is the default language Nano apps have to be developed in.

This was already noticed by developers, who put it a little more bluntly :)

Ledger apps require going back in time and leaving the nice advantages of Rust.

How to use it

Head over to https://github.com/LedgerHQ/rust-app-demo, everything is explained there!

This app serves as a very basic boilerplate and shows how to interface with:

  • a hash function syscall
  • receiving/sending APDUs
  • setting up a menu with a ‘quit’ callback

There are necessarily lots of unsafe{ } in the code due to the nature of the project, however some safe wrapping can be done and will improve the safety of a function although it is marked as an unsafe call.

Limitations

This project is so far only a demonstration of a hybrid C/Rust setup. Your whole app code can be written in Rust, but the code related to the SDK is still in C. For example, that means that non null-terminated strings that you usually declare in Rust will be considered to end farther away in memory once it is sent into the C code.

Some basic functions and macros were set-up so you do not have to worry about this for this basic app.

Will it be improved?

Yes! We plan to actively develop it so as to replace as much of the SDK C code as we can in order to get the most out of the safety guarantees. Ideally, we would reach a full Rust SDK much like the one from github user roosma (which sadly is not maintained anymore).

Having a C/Rust hybrid setup allows to replace the C code incrementally, which will help us spot bugs on the way and not lock this SDK to a particular SDK version. Our goal is not to replace the initial Nano SDK with the Rust one, but rather have both coexist.

We also hope open-sourcing this basic setup will give ideas to the community. Any new feature that helps developing apps will be welcome!