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

Wip c sdk bindings #108

Merged
merged 5 commits into from
Dec 19, 2023
Merged
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
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v4
- name: Cargo update
uses: actions-rs/cargo@v1
with:
command: update
args: -p [email protected] --precise 0.5.5
- name: Cargo clippy
uses: actions-rs/cargo@v1
with:
Expand Down Expand Up @@ -72,6 +77,11 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v4
- name: Cargo update
uses: actions-rs/cargo@v1
with:
command: update
args: -p [email protected] --precise 0.5.5
- name: Cargo build
uses: actions-rs/cargo@v1
with:
Expand All @@ -86,6 +96,11 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v4
- name: Cargo update
uses: actions-rs/cargo@v1
with:
command: update
args: -p [email protected] --precise 0.5.5
- name: Cargo build
uses: actions-rs/cargo@v1
with:
Expand All @@ -104,6 +119,11 @@ jobs:
steps:
- name: Clone
uses: actions/checkout@v4
- name: Cargo update
uses: actions-rs/cargo@v1
with:
command: update
args: -p [email protected] --precise 0.5.5
- name: Unit tests
uses: actions-rs/cargo@v1
with:
Expand Down
16 changes: 4 additions & 12 deletions ledger_device_sdk/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,11 @@ impl From<SyscallError> for Reply {
// `Error` as `Infallible`. Since we need to convert such error in a status word (`Reply`) we need
// to implement this trait here.
impl From<Infallible> for Reply {
fn from(value: Infallible) -> Self {
fn from(_value: Infallible) -> Self {
Reply(0x9000)
}
}

extern "C" {
pub fn io_usb_hid_send(
sndfct: unsafe extern "C" fn(*mut u8, u16),
sndlength: u16,
apdu_buffer: *const u8,
);
}

/// Possible events returned by [`Comm::next_event`]
#[derive(Eq, PartialEq)]
pub enum Event<T> {
Expand Down Expand Up @@ -153,10 +145,10 @@ impl Comm {

match unsafe { G_io_app.apdu_state } {
APDU_USB_HID => unsafe {
io_usb_hid_send(
io_usb_send_apdu_data,
ledger_secure_sdk_sys::io_usb_hid_send(
Some(io_usb_send_apdu_data),
self.tx as u16,
self.apdu_buffer.as_ptr(),
self.apdu_buffer.as_mut_ptr(),
);
},
APDU_RAW => {
Expand Down
6 changes: 1 addition & 5 deletions ledger_device_sdk/src/random.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ use core::ops::Range;
use num_traits::{Bounded, PrimInt, Unsigned};
use rand_core::{CryptoRng, RngCore};

extern "C" {
pub fn cx_rng_no_throw(buffer: *mut u8, len: u32);
}

/// Fills a byte array with random bytes.
///
/// # Arguments
Expand All @@ -17,7 +13,7 @@ extern "C" {
#[inline]
pub fn rand_bytes(out: &mut [u8]) {
unsafe {
cx_rng_no_throw(out.as_mut_ptr(), out.len() as u32);
ledger_secure_sdk_sys::cx_rng_no_throw(out.as_mut_ptr(), out.len());
}
}

Expand Down
124 changes: 51 additions & 73 deletions ledger_secure_sdk_sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,10 @@ use std::path::{Path, PathBuf};
use std::process::Command;
use std::{env, fs::File, io::BufRead, io::BufReader, io::Read};

// Definitions common to both `cc` and `bindgen`
const DEFINES: [(&str, Option<&str>); 11] = [
("HAVE_LOCAL_APDU_BUFFER", None),
("IO_HID_EP_LENGTH", Some("64")),
("USB_SEGMENT_SIZE", Some("64")),
("OS_IO_SEPROXYHAL", None),
("HAVE_IO_USB", None),
("HAVE_L4_USBLIB", None),
("HAVE_USB_APDU", None),
("__IO", Some("volatile")),
("IO_USB_MAX_ENDPOINTS", Some("6")),
("IO_SEPROXYHAL_BUFFER_SIZE_B", Some("128")),
("main", Some("_start")),
];

// Feature-specific definitions
const DEFINES_BLE: [(&str, Option<&str>); 2] = [("HAVE_BLE", None), ("HAVE_BLE_APDU", None)];

#[cfg(feature = "ccid")]
const DEFINES_CCID: [(&str, Option<&str>); 2] =
[("HAVE_USB_CLASS_CCID", None), ("HAVE_CCID", None)];

const DEFINES_OPTIONAL: [(&str, Option<&str>); 7] = [
("HAVE_SEPROXYHAL_MCU", None),
("HAVE_MCU_PROTECT", None),
("HAVE_MCU_SEPROXYHAL", None),
("HAVE_MCU_SERIAL_STORAGE", None),
("HAVE_SE_BUTTON", None),
("HAVE_BAGL", None),
("HAVE_SE_SCREEN", None),
];

const AUX_C_FILES: [&str; 2] = ["./src/c/src.c", "./src/c/sjlj.s"];

const SDK_C_FILES: [&str; 9] = [
Expand Down Expand Up @@ -279,6 +251,29 @@ fn str2path(bolos_sdk: &Path, pathlist: &[&str]) -> Vec<PathBuf> {
.collect::<Vec<PathBuf>>()
}

/// Get all #define from a header file
fn header2define(headername: &str) -> Vec<(String, Option<String>)> {
let mut headerfile = File::open(headername).unwrap();
let mut header = String::new();
headerfile.read_to_string(&mut header).unwrap();

header
.lines()
.filter_map(|line| {
if line.trim_start().starts_with("#define") {
let parts: Vec<&str> = line.split_whitespace().collect();
match parts.len() {
2 => Some((parts[1].to_string(), None)),
3 => Some((parts[1].to_string(), Some(parts[2].to_string()))),
_ => None,
}
} else {
None
}
})
.collect()
}

struct SDKBuilder {
bolos_sdk: PathBuf,
api_level: u32,
Expand Down Expand Up @@ -402,10 +397,6 @@ impl SDKBuilder {
.files(str2path(&self.bolos_sdk, &SDK_C_FILES))
.files(str2path(&self.bolos_sdk, &SDK_USB_FILES));

for (define, value) in DEFINES {
command.define(define, value);
}

command = command
.include(&self.gcc_toolchain)
.include(self.bolos_sdk.join("include"))
Expand Down Expand Up @@ -473,28 +464,38 @@ impl SDKBuilder {
let headers = str2path(
&self.bolos_sdk,
&[
"lib_cxng/include/libcxng.h",
"include/os.h",
"lib_cxng/include/libcxng.h", /* cxlib */
"include/os.h", /* syscalls */
"include/os_screen.h",
"include/syscalls.h",
"include/os_io_seproxyhal.h",
"include/os_ux.h",
"include/ox.h",
"include/ox.h", /* crypto-related syscalls */
"lib_stusb/STM32_USB_Device_Library/Core/Inc/usbd_def.h",
"include/os_io_usb.h",
],
);

let mut bindings = bindgen::Builder::default()
let mut bindings = bindgen::builder()
.clang_args(&args)
.prepend_enum_name(false)
.generate_comments(false)
.derive_default(true)
.use_core();

// Target specific files
let (include_path, header) = match self.device {
Device::NanoS => ("nanos", "sdk_nanos.h"),
Device::NanoX => ("nanox", "sdk_nanox.h"),
Device::NanoSPlus => ("nanos2", "sdk_nanosp.h"),
};
bindings = bindings.clang_arg(format!("-I{bsdk}/target/{include_path}/include/"));
bindings = bindings.header(header);

// SDK headers to bind against
for header in headers.iter().map(|p| p.to_str().unwrap()) {
bindings = bindings.header(header);
}
bindings = bindings.header("sdk.h");

match self.device {
Device::NanoS => {
Expand All @@ -510,35 +511,6 @@ impl SDKBuilder {
}
_ => (),
}
for (define, value) in DEFINES.iter().chain(DEFINES_BLE.iter()) {
let flag = match value {
Some(v) => format!("-D{define}={v}"),
_ => format!("-D{define}"),
};
bindings = bindings.clang_arg(flag);
}

// Add in target main include path
let include_path = match self.device {
Device::NanoS => "nanos",
Device::NanoX => "nanox",
Device::NanoSPlus => "nanos2",
};
bindings = bindings.clang_arg(format!("-I{bsdk}/target/{include_path}/include/"));

// Add in optional definitions tied to a specific device
match self.device {
Device::NanoX | Device::NanoSPlus => {
for (define, value) in DEFINES_OPTIONAL {
let flag = match value {
Some(v) => format!("-D{define}={v}"),
_ => format!("-D{define}"),
};
bindings = bindings.clang_arg(flag);
}
}
_ => (),
}

for define in &self.cxdefines {
bindings = bindings.clang_arg(format!("-D{define}"));
Expand Down Expand Up @@ -568,6 +540,11 @@ fn main() {
}

fn finalize_nanos_configuration(command: &mut cc::Build, bolos_sdk: &Path) {
let defines = header2define("sdk_nanos.h");
for (define, value) in defines {
command.define(define.as_str(), value.as_deref());
}

command
.target("thumbv6m-none-eabi")
.define("ST31", None)
Expand All @@ -578,12 +555,11 @@ fn finalize_nanos_configuration(command: &mut cc::Build, bolos_sdk: &Path) {
}

fn finalize_nanox_configuration(command: &mut cc::Build, bolos_sdk: &Path) {
for (define, value) in DEFINES_BLE {
command.define(define, value);
}
for (define, value) in DEFINES_OPTIONAL {
command.define(define, value);
let defines = header2define("sdk_nanox.h");
for (define, value) in defines {
command.define(define.as_str(), value.as_deref());
}

command
.target("thumbv6m-none-eabi")
.define("ST33", None)
Expand Down Expand Up @@ -611,9 +587,11 @@ fn finalize_nanox_configuration(command: &mut cc::Build, bolos_sdk: &Path) {
}

fn finalize_nanosplus_configuration(command: &mut cc::Build, bolos_sdk: &Path) {
for (define, value) in DEFINES_OPTIONAL {
command.define(define, value);
let defines = header2define("sdk_nanosp.h");
for (define, value) in defines {
command.define(define.as_str(), value.as_deref());
}

command
.target("thumbv8m.main-none-eabi")
.define("ST33K1M5", None)
Expand Down
11 changes: 11 additions & 0 deletions ledger_secure_sdk_sys/sdk_nanos.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#define HAVE_LOCAL_APDU_BUFFER
#define IO_HID_EP_LENGTH 64
#define USB_SEGMENT_SIZE 64
#define OS_IO_SEPROXYHAL
#define HAVE_IO_USB
#define HAVE_L4_USBLIB
#define HAVE_USB_APDU
#define __IO volatile
#define IO_USB_MAX_ENDPOINTS 6
#define IO_SEPROXYHAL_BUFFER_SIZE_B 128
#define main _start
19 changes: 19 additions & 0 deletions ledger_secure_sdk_sys/sdk_nanosp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#define HAVE_LOCAL_APDU_BUFFER
#define IO_HID_EP_LENGTH 64
#define USB_SEGMENT_SIZE 64
#define OS_IO_SEPROXYHAL
#define HAVE_IO_USB
#define HAVE_L4_USBLIB
#define HAVE_USB_APDU
#define __IO volatile
#define IO_USB_MAX_ENDPOINTS 6
#define IO_SEPROXYHAL_BUFFER_SIZE_B 128
#define main _start

#define HAVE_SEPROXYHAL_MCU
#define HAVE_MCU_PROTECT
#define HAVE_MCU_SEPROXYHAL
#define HAVE_MCU_SERIAL_STORAGE
#define HAVE_SE_BUTTON
#define HAVE_BAGL
#define HAVE_SE_SCREEN
17 changes: 4 additions & 13 deletions ledger_secure_sdk_sys/sdk.h → ledger_secure_sdk_sys/sdk_nanox.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#include "bolos_target.h"

// Definitions common to both `cc` and `bindgen`
#define HAVE_LOCAL_APDU_BUFFER
#define IO_HID_EP_LENGTH 64
#define USB_SEGMENT_SIZE 64
Expand All @@ -11,21 +8,15 @@
#define __IO volatile
#define IO_USB_MAX_ENDPOINTS 6
#define IO_SEPROXYHAL_BUFFER_SIZE_B 128
#define main _start

#if defined(TARGET_NANOX)
#define HAVE_BLE
#define HAVE_BLE_APDU
#endif

// #define HAVE_USB_CLASS_CCID
// #define HAVE_CCID

#if defined(TARGET_NANOX) || defined(TARGET_NANOS2)
#define HAVE_SEPROXYHAL_MCU
#define HAVE_MCU_PROTECT
#define HAVE_MCU_SEPROXYHAL
#define HAVE_MCU_SERIAL_STORAGE
#define HAVE_SE_BUTTON
#define HAVE_BAGL
#define HAVE_SE_SCREEN
#endif

#define HAVE_BLE
#define HAVE_BLE_APDU
Loading