diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d73bfbcf..4a91a34e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 home@0.5.9 --precise 0.5.5 - name: Cargo clippy uses: actions-rs/cargo@v1 with: @@ -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 home@0.5.9 --precise 0.5.5 - name: Cargo build uses: actions-rs/cargo@v1 with: @@ -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 home@0.5.9 --precise 0.5.5 - name: Cargo build uses: actions-rs/cargo@v1 with: @@ -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 home@0.5.9 --precise 0.5.5 - name: Unit tests uses: actions-rs/cargo@v1 with: diff --git a/ledger_device_sdk/src/io.rs b/ledger_device_sdk/src/io.rs index 5ef272f3..f46e5623 100644 --- a/ledger_device_sdk/src/io.rs +++ b/ledger_device_sdk/src/io.rs @@ -78,19 +78,11 @@ impl From 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 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 { @@ -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 => { diff --git a/ledger_device_sdk/src/random.rs b/ledger_device_sdk/src/random.rs index ea704743..b3d4c2af 100644 --- a/ledger_device_sdk/src/random.rs +++ b/ledger_device_sdk/src/random.rs @@ -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 @@ -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()); } } diff --git a/ledger_secure_sdk_sys/build.rs b/ledger_secure_sdk_sys/build.rs index 87a5688e..ac6c53d0 100644 --- a/ledger_secure_sdk_sys/build.rs +++ b/ledger_secure_sdk_sys/build.rs @@ -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] = [ @@ -279,6 +251,29 @@ fn str2path(bolos_sdk: &Path, pathlist: &[&str]) -> Vec { .collect::>() } +/// Get all #define from a header file +fn header2define(headername: &str) -> Vec<(String, Option)> { + 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, @@ -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")) @@ -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 => { @@ -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}")); @@ -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) @@ -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) @@ -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) diff --git a/ledger_secure_sdk_sys/sdk_nanos.h b/ledger_secure_sdk_sys/sdk_nanos.h new file mode 100644 index 00000000..7d665ec9 --- /dev/null +++ b/ledger_secure_sdk_sys/sdk_nanos.h @@ -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 \ No newline at end of file diff --git a/ledger_secure_sdk_sys/sdk_nanosp.h b/ledger_secure_sdk_sys/sdk_nanosp.h new file mode 100644 index 00000000..ce099221 --- /dev/null +++ b/ledger_secure_sdk_sys/sdk_nanosp.h @@ -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 \ No newline at end of file diff --git a/ledger_secure_sdk_sys/sdk.h b/ledger_secure_sdk_sys/sdk_nanox.h similarity index 65% rename from ledger_secure_sdk_sys/sdk.h rename to ledger_secure_sdk_sys/sdk_nanox.h index 51df1290..aa4c956a 100644 --- a/ledger_secure_sdk_sys/sdk.h +++ b/ledger_secure_sdk_sys/sdk_nanox.h @@ -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 @@ -11,16 +8,8 @@ #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 @@ -28,4 +17,6 @@ #define HAVE_SE_BUTTON #define HAVE_BAGL #define HAVE_SE_SCREEN -#endif + +#define HAVE_BLE +#define HAVE_BLE_APDU \ No newline at end of file