diff --git a/Cargo.lock b/Cargo.lock index 1f58c2f1..1c640445 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,7 +127,7 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cargo-ledger" -version = "1.6.0" +version = "1.7.0" dependencies = [ "cargo_metadata", "clap", @@ -474,7 +474,7 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "ledger_device_sdk" -version = "1.20.4" +version = "1.21.0" dependencies = [ "const-zero", "include_gif", @@ -489,7 +489,7 @@ dependencies = [ [[package]] name = "ledger_secure_sdk_sys" -version = "1.6.7" +version = "1.7.0" dependencies = [ "bindgen", "cc", diff --git a/cargo-ledger/Cargo.toml b/cargo-ledger/Cargo.toml index 60634adb..f05aed9a 100644 --- a/cargo-ledger/Cargo.toml +++ b/cargo-ledger/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cargo-ledger" -version = "1.6.0" +version = "1.7.0" authors = ["yhql", "agrojean-ledger", "y333"] description = "Build and sideload Ledger devices apps" categories = ["development-tools::cargo-plugins"] diff --git a/cargo-ledger/src/setup.rs b/cargo-ledger/src/setup.rs index 822f26d4..3a7f3807 100644 --- a/cargo-ledger/src/setup.rs +++ b/cargo-ledger/src/setup.rs @@ -1,19 +1,39 @@ use std::path::Path; use std::process::Command; +use std::str::from_utf8; pub fn install_targets() { - println!("[ ] Checking for installed custom targets..."); + println!("[ ] Install custom targets..."); // Check if target files are installed + let mut args: Vec = vec![]; + match std::env::var("RUST_NIGHTLY") { + Ok(version) => { + println!( + "Install custom targets for nightly toolchain: {}", + version + ); + args.push(format!("+{}", version)); + } + Err(_) => { + let rustup_cmd = + Command::new("rustup").arg("default").output().unwrap(); + println!( + "Install custom targets for default toolchain {}", + from_utf8(rustup_cmd.stdout.as_slice()).unwrap() + ); + } + } + args.push(String::from("--print")); + args.push(String::from("sysroot")); let sysroot_cmd = Command::new("rustc") - .arg("--print") - .arg("sysroot") + .args(&args) .output() .expect("failed to call rustc") .stdout; let sysroot_cmd = std::str::from_utf8(&sysroot_cmd).unwrap().trim(); let target_files_url = Path::new( - "https://raw.githubusercontent.com/LedgerHQ/ledger-device-rust-sdk/a7fb841160df34b8de268b136704c8b2ed8f9973/ledger_device_sdk/" + "https://raw.githubusercontent.com/LedgerHQ/ledger-device-rust-sdk/refs/tags/ledger_secure_sdk_sys%401.7.0/ledger_secure_sdk_sys" ); let sysroot = Path::new(sysroot_cmd).join("lib").join("rustlib"); diff --git a/ledger_device_sdk/Cargo.toml b/ledger_device_sdk/Cargo.toml index f0d9a880..4884a199 100644 --- a/ledger_device_sdk/Cargo.toml +++ b/ledger_device_sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ledger_device_sdk" -version = "1.20.4" +version = "1.21.0" authors = ["yhql", "yogh333", "agrojean-ledger", "kingofpayne"] edition = "2021" license.workspace = true @@ -21,13 +21,13 @@ rand_core = { version = "0.6.3", default-features = false } zeroize = { version = "1.6.0", default-features = false } numtoa = "0.2.4" const-zero = "0.1.1" -ledger_secure_sdk_sys = { path = "../ledger_secure_sdk_sys", version = "1.6.7" } +ledger_secure_sdk_sys = { path = "../ledger_secure_sdk_sys", version = "1.7.0" } [features] debug = [] speculos = [] -ccid = [] heap = [ "ledger_secure_sdk_sys/heap" ] +nbgl = [ "ledger_secure_sdk_sys/nbgl" ] default = [ "heap" ] diff --git a/ledger_device_sdk/build.rs b/ledger_device_sdk/build.rs deleted file mode 100644 index 1c4d50d4..00000000 --- a/ledger_device_sdk/build.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::path::PathBuf; -use std::{env, error::Error}; - -fn main() -> Result<(), Box> { - enum Device { - NanoS, - NanoSPlus, - NanoX, - Stax, - Flex, - } - use Device::*; - - // determine device - let device = match env::var_os("CARGO_CFG_TARGET_OS").unwrap().to_str().unwrap() { - "nanos" => NanoS, - "nanosplus" => NanoSPlus, - "nanox" => NanoX, - "stax" => Stax, - "flex" => Flex, - target_name => panic!( - "invalid target `{target_name}`, expected one of `nanos`, `nanox`, `nanosplus`, `stax` or `flex`. Run with `-Z build-std=core --target=./.json`" - ), - }; - - // Copy this crate's linker script into the working directory of - // the application so that it can be used there for the layout. - // Trick taken from https://docs.rust-embedded.org/embedonomicon/main.html - let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - - // extend the library search path - println!("cargo:rustc-link-search={}", out_dir.display()); - // copy - let linkerscript = match device { - NanoS => "nanos_layout.ld", - NanoX => "nanox_layout.ld", - NanoSPlus => "nanosplus_layout.ld", - Stax | Flex => "stax_flex_layout.ld", - }; - std::fs::copy(linkerscript, out_dir.join(linkerscript))?; - std::fs::copy("link.ld", out_dir.join("link.ld"))?; - Ok(()) -} diff --git a/ledger_device_sdk/src/ccid.rs b/ledger_device_sdk/src/ccid.rs deleted file mode 100644 index 0b40b2c6..00000000 --- a/ledger_device_sdk/src/ccid.rs +++ /dev/null @@ -1,11 +0,0 @@ -extern "C" { - pub static mut G_io_apdu_buffer: [u8; 260]; - pub fn io_usb_ccid_reply_bare(length: u16); -} - -pub fn send(buf: &[u8]) { - unsafe { - G_io_apdu_buffer[..buf.len()].copy_from_slice(buf); - io_usb_ccid_reply_bare(buf.len() as u16); - } -} diff --git a/ledger_device_sdk/src/io.rs b/ledger_device_sdk/src/io.rs index f689a7b4..2f4558f1 100644 --- a/ledger_device_sdk/src/io.rs +++ b/ledger_device_sdk/src/io.rs @@ -5,8 +5,6 @@ use ledger_secure_sdk_sys::buttons::{get_button_event, ButtonEvent, ButtonsState use ledger_secure_sdk_sys::seph as sys_seph; use ledger_secure_sdk_sys::*; -#[cfg(feature = "ccid")] -use crate::ccid; use crate::seph; use core::convert::{Infallible, TryFrom}; use core::ops::{Index, IndexMut}; @@ -193,10 +191,6 @@ impl Comm { sys_seph::seph_send(&[sys_seph::SephTags::RawAPDU as u8, len[0], len[1]]); sys_seph::seph_send(&self.apdu_buffer[..self.tx]); } - #[cfg(feature = "ccid")] - APDU_USB_CCID => { - ccid::send(&self.apdu_buffer[..self.tx]); - } #[cfg(any(target_os = "nanox", target_os = "stax", target_os = "flex"))] APDU_BLE => { ble::send(&self.apdu_buffer[..self.tx]); @@ -378,6 +372,10 @@ impl Comm { match seph::Events::from(tag) { #[cfg(not(any(target_os = "stax", target_os = "flex")))] seph::Events::ButtonPush => { + #[cfg(feature = "nbgl")] + unsafe { + ux_process_button_event(spi_buffer.as_mut_ptr()); + } let button_info = spi_buffer[3] >> 1; if let Some(btn_evt) = get_button_event(&mut self.buttons, button_info) { return Some(Event::Button(btn_evt)); diff --git a/ledger_device_sdk/src/lib.rs b/ledger_device_sdk/src/lib.rs index 523a220c..5ed408bd 100644 --- a/ledger_device_sdk/src/lib.rs +++ b/ledger_device_sdk/src/lib.rs @@ -10,8 +10,6 @@ #[cfg(any(target_os = "nanox", target_os = "stax", target_os = "flex"))] pub mod ble; -#[cfg(feature = "ccid")] -pub mod ccid; pub mod ecc; pub mod hash; pub mod hmac; @@ -24,9 +22,9 @@ pub mod seph; pub mod testing; -#[cfg(any(target_os = "stax", target_os = "flex"))] +#[cfg(any(target_os = "stax", target_os = "flex", feature = "nbgl"))] pub mod nbgl; -#[cfg(not(any(target_os = "stax", target_os = "flex")))] +#[cfg(not(any(target_os = "stax", target_os = "flex", feature = "nbgl")))] pub mod ui; pub mod uxapp; diff --git a/ledger_device_sdk/src/nbgl.rs b/ledger_device_sdk/src/nbgl.rs index 2ad72609..dcb86907 100644 --- a/ledger_device_sdk/src/nbgl.rs +++ b/ledger_device_sdk/src/nbgl.rs @@ -10,6 +10,7 @@ use ledger_secure_sdk_sys::*; pub mod nbgl_address_review; pub mod nbgl_choice; +#[cfg(any(target_os = "stax", target_os = "flex"))] pub mod nbgl_generic_review; pub mod nbgl_home_and_settings; pub mod nbgl_review; @@ -20,6 +21,7 @@ pub mod nbgl_streaming_review; pub use nbgl_address_review::*; pub use nbgl_choice::*; +#[cfg(any(target_os = "stax", target_os = "flex"))] pub use nbgl_generic_review::*; pub use nbgl_home_and_settings::*; pub use nbgl_review::*; @@ -105,6 +107,7 @@ unsafe extern "C" fn quit_callback() { G_ENDED = true; } +#[cfg(any(target_os = "stax", target_os = "flex"))] unsafe extern "C" fn rejected_callback() { G_RET = SyncNbgl::UxSyncRetRejected.into(); G_ENDED = true; @@ -274,6 +277,7 @@ pub enum TuneIndex { // Direct translation of the C original. This was done to // avoid compiling `os_io_seproxyhal.c` which includes many other things #[no_mangle] +#[cfg(any(target_os = "stax", target_os = "flex"))] extern "C" fn io_seproxyhal_play_tune(tune_index: u8) { let mut buffer = [0u8; 4]; let mut spi_buffer = [0u8; 128]; diff --git a/ledger_device_sdk/src/nbgl/nbgl_home_and_settings.rs b/ledger_device_sdk/src/nbgl/nbgl_home_and_settings.rs index af9eb714..cd250672 100644 --- a/ledger_device_sdk/src/nbgl/nbgl_home_and_settings.rs +++ b/ledger_device_sdk/src/nbgl/nbgl_home_and_settings.rs @@ -173,7 +173,10 @@ impl<'a> NbglHomeAndSettings { }; SWITCH_ARRAY[i].initState = state; SWITCH_ARRAY[i].token = (FIRST_USER_TOKEN + i as u32) as u8; - SWITCH_ARRAY[i].tuneId = TuneIndex::TapCasual as u8; + #[cfg(any(target_os = "stax", target_os = "flex"))] + { + SWITCH_ARRAY[i].tuneId = TuneIndex::TapCasual as u8; + } } self.content = nbgl_content_t { @@ -257,7 +260,10 @@ impl<'a> NbglHomeAndSettings { }; SWITCH_ARRAY[i].initState = state; SWITCH_ARRAY[i].token = (FIRST_USER_TOKEN + i as u32) as u8; - SWITCH_ARRAY[i].tuneId = TuneIndex::TapCasual as u8; + #[cfg(any(target_os = "stax", target_os = "flex"))] + { + SWITCH_ARRAY[i].tuneId = TuneIndex::TapCasual as u8; + } } self.content = nbgl_content_t { diff --git a/ledger_secure_sdk_sys/Cargo.toml b/ledger_secure_sdk_sys/Cargo.toml index b4f5c604..10570a10 100644 --- a/ledger_secure_sdk_sys/Cargo.toml +++ b/ledger_secure_sdk_sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ledger_secure_sdk_sys" -version = "1.6.7" +version = "1.7.0" authors = ["yhql", "agrojean-ledger", "yogh333"] edition = "2021" license.workspace = true @@ -18,7 +18,7 @@ critical-section = { version = "1.1.2", optional = true } [features] heap = ["dep:embedded-alloc", "dep:critical-section"] -ccid = [] +nbgl = [] [lints.rust.unexpected_cfgs] level = "warn" diff --git a/ledger_secure_sdk_sys/build.rs b/ledger_secure_sdk_sys/build.rs index 18f3d23e..0239f2a7 100644 --- a/ledger_secure_sdk_sys/build.rs +++ b/ledger_secure_sdk_sys/build.rs @@ -3,15 +3,12 @@ use glob::glob; use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; +use std::time::Instant; use std::{env, fs::File, io::BufRead, io::BufReader, io::Read}; -#[cfg(feature = "ccid")] -const DEFINES_CCID: [(&str, Option<&str>); 2] = - [("HAVE_USB_CLASS_CCID", None), ("HAVE_CCID", None)]; - const AUX_C_FILES: [&str; 2] = ["./src/c/src.c", "./src/c/sjlj.s"]; -const SDK_C_FILES: [&str; 8] = [ +const SDK_C_FILES: [&str; 9] = [ "src/os_io_usb.c", "src/pic.c", "src/checks.c", @@ -20,6 +17,7 @@ const SDK_C_FILES: [&str; 8] = [ "src/svc_call.s", "src/svc_cx_call.s", "src/syscalls.c", + "src/os_printf.c", ]; const SDK_USB_FILES: [&str; 6] = [ @@ -31,43 +29,106 @@ const SDK_USB_FILES: [&str; 6] = [ "lib_stusb/STM32_USB_Device_Library/Class/HID/Src/usbd_hid.c", ]; -#[cfg(feature = "ccid")] -const CCID_FILES: [&str; 9] = [ - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_core.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_core.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_cmd.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_core.c", - "lib_stusb/STM32_USB_Device_Library/Class/CCID/src/usbd_ccid_if.c", +const CFLAGS_NANOS: [&str; 11] = [ + "-Oz", + "-fomit-frame-pointer", + "-fno-common", + "-fdata-sections", + "-ffunction-sections", + "-mthumb", + "-fno-jump-tables", + "-fshort-enums", + "-mno-unaligned-access", + "-fropi", + "-Wno-unused-command-line-argument", +]; + +const CFLAGS_NANOSPLUS: [&str; 22] = [ + "-Oz", + "-g0", + "-fomit-frame-pointer", + "-momit-leaf-frame-pointer", + "-fno-common", + "-mlittle-endian", + "-std=gnu99", + "-fdata-sections", + "-ffunction-sections", + "-funsigned-char", + "-fshort-enums", + "-mno-unaligned-access", + "-fropi", + "-fno-jump-tables", + "-nostdlib", + "-nodefaultlibs", + "-frwpi", + "--target=armv8m-none-eabi", + "-mcpu=cortex-m35p+nodsp", + "-mthumb", + "-msoft-float", + "-Wno-unused-command-line-argument", +]; +const CFLAGS_STAX: [&str; 22] = CFLAGS_NANOSPLUS; +const CFLAGS_FLEX: [&str; 22] = CFLAGS_NANOSPLUS; +const CFLAGS_NANOX: [&str; 21] = [ + "-Oz", + "-g0", + "-fomit-frame-pointer", + "-momit-leaf-frame-pointer", + "-fno-common", + "-mlittle-endian", + "-std=gnu99", + "-fdata-sections", + "-ffunction-sections", + "-funsigned-char", + "-fshort-enums", + "-mno-unaligned-access", + "-fropi", + "-fno-jump-tables", + "-nostdlib", + "-nodefaultlibs", + "-frwpi", + "-mthumb", + "--target=armv6m-none-eabi", + "-mcpu=cortex-m0plus", + "-Wno-unused-command-line-argument", ]; -#[derive(Debug, PartialEq)] -enum Device { +#[derive(Debug, Default, PartialEq)] +enum DeviceName { NanoS, + #[default] NanoSPlus, NanoX, Stax, Flex, } -impl std::fmt::Display for Device { +#[derive(Debug, Default)] +struct Device<'a> { + pub name: DeviceName, + pub c_sdk: PathBuf, + pub target: &'a str, + pub defines: Vec<(String, Option)>, + pub cflags: Vec<&'a str>, + pub glyphs_folders: Vec, + pub arm_libs: String, + pub linker_script: &'a str, +} + +impl std::fmt::Display for DeviceName { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Device::NanoS => write!(f, "nanos"), - Device::NanoSPlus => write!(f, "nanos2"), - Device::NanoX => write!(f, "nanox"), - Device::Stax => write!(f, "stax"), - Device::Flex => write!(f, "flex"), + DeviceName::NanoS => write!(f, "nanos"), + DeviceName::NanoSPlus => write!(f, "nanos2"), + DeviceName::NanoX => write!(f, "nanox"), + DeviceName::Stax => write!(f, "stax"), + DeviceName::Flex => write!(f, "flex"), } } } #[derive(Default)] -struct SDKInfo { - pub bolos_sdk: PathBuf, +struct CSDKInfo { pub api_level: Option, pub target_id: String, pub target_name: String, @@ -76,179 +137,15 @@ struct SDKInfo { pub c_sdk_version: String, } -impl SDKInfo { +impl CSDKInfo { pub fn new() -> Self { - SDKInfo::default() + CSDKInfo::default() } } -fn retrieve_sdk_info(device: &Device, path: &Path) -> Result { - let mut sdk_info = SDKInfo::new(); - sdk_info.bolos_sdk = path.to_path_buf(); - (sdk_info.api_level, sdk_info.c_sdk_name) = retrieve_makefile_infos(&sdk_info.bolos_sdk)?; - (sdk_info.target_id, sdk_info.target_name) = - retrieve_target_file_infos(device, &sdk_info.bolos_sdk)?; - (sdk_info.c_sdk_hash, sdk_info.c_sdk_version) = retrieve_sdk_git_info(&sdk_info.bolos_sdk); - Ok(sdk_info) -} - -fn retrieve_sdk_git_info(bolos_sdk: &Path) -> (String, String) { - let c_sdk_hash = match Command::new("git") - .arg("-C") - .arg(bolos_sdk) - .arg("describe") - .arg("--always") - .arg("--dirty") - .arg("--exclude") - .arg("*") - .arg("--abbrev=40") - .output() - .ok() - { - Some(output) => { - if output.stdout.is_empty() { - "None".to_string() - } else { - String::from_utf8(output.stdout).unwrap_or("None".to_string()) - } - } - None => "None".to_string(), - }; - - let c_sdk_version = match Command::new("git") - .arg("-C") - .arg(bolos_sdk) - .arg("describe") - .arg("--tags") - .arg("--exact-match") - .arg("--match") - .arg("v[0-9]*") - .arg("--dirty") - .output() - .ok() - { - Some(output) => { - if output.stdout.is_empty() { - "None".to_string() - } else { - String::from_utf8(output.stdout).unwrap_or("None".to_string()) - } - } - None => "None".to_string(), - }; - (c_sdk_hash, c_sdk_version) -} - -fn retrieve_makefile_infos(bolos_sdk: &Path) -> Result<(Option, String), SDKBuildError> { - let makefile_defines = - File::open(bolos_sdk.join("Makefile.defines")).expect("Could not find Makefile.defines"); - let mut api_level: Option = None; - let mut sdk_name: Option = None; - for line in BufReader::new(makefile_defines).lines().flatten() { - if let Some(value) = line.split(":=").nth(1).map(str::trim) { - if line.contains("API_LEVEL") && api_level.is_none() { - api_level = Some(value.parse().map_err(|_| SDKBuildError::InvalidAPILevel)?); - } else if line.contains("SDK_NAME") && sdk_name.is_none() { - sdk_name = Some(value.to_string().replace('\"', "")); - } - } - - if api_level.is_some() && sdk_name.is_some() { - // Both keys found, break out of the loop - break; - } - } - let sdk_name = sdk_name.ok_or(SDKBuildError::MissingSDKName)?; - Ok((api_level, sdk_name)) -} - -fn retrieve_target_file_infos( - device: &Device, - bolos_sdk: &Path, -) -> Result<(String, String), SDKBuildError> { - let prefix = if *device == Device::NanoS { - "".to_string() - } else { - format!("target/{}/", device) - }; - let target_file_path = bolos_sdk.join(format!("{}include/bolos_target.h", prefix)); - let target_file = - File::open(target_file_path).map_err(|_| SDKBuildError::TargetFileNotFound)?; - let mut target_id: Option = None; - let mut target_name: Option = None; - - for line in BufReader::new(target_file).lines().flatten() { - if target_id.is_none() && line.contains("#define TARGET_ID") { - target_id = Some( - line.split_whitespace() - .nth(2) - .ok_or("err") - .map_err(|_| SDKBuildError::MissingTargetId)? - .to_string(), - ); - } else if target_name.is_none() && line.contains("TARGET_") { - target_name = Some( - line.split_whitespace() - .nth(1) - .ok_or("err") - .map_err(|_| SDKBuildError::MissingTargetName)? - .to_string(), - ); - } - - if target_id.is_some() && target_name.is_some() { - // Both tokens found, break out of the loop - break; - } - } - - let target_id = target_id.ok_or(SDKBuildError::MissingTargetId)?; - let target_name = target_name.ok_or(SDKBuildError::MissingTargetName)?; - Ok((target_id, target_name)) -} - -/// Fetch the appropriate C SDK to build -fn clone_sdk(device: &Device) -> PathBuf { - let (repo_url, sdk_branch) = match device { - Device::NanoS => ( - Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), - "API_LEVEL_LNS", - ), - Device::NanoX => ( - Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), - "API_LEVEL_22", - ), - Device::NanoSPlus => ( - Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), - "API_LEVEL_22", - ), - Device::Stax => ( - Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), - "API_LEVEL_22", - ), - Device::Flex => ( - Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), - "API_LEVEL_22", - ), - }; - - let out_dir = env::var("OUT_DIR").unwrap(); - let bolos_sdk = Path::new(out_dir.as_str()).join("ledger-secure-sdk"); - if !bolos_sdk.exists() { - Command::new("git") - .arg("clone") - .arg(repo_url.to_str().unwrap()) - .arg("-b") - .arg(sdk_branch) - .arg(bolos_sdk.as_path()) - .output() - .ok(); - } - bolos_sdk -} - #[derive(Debug)] enum SDKBuildError { + UnsupportedDevice, InvalidAPILevel, MissingSDKName, TargetFileNotFound, @@ -256,57 +153,24 @@ enum SDKBuildError { MissingTargetName, } -/// Helper function to concatenate all paths in pathlist to bolos_sdk's path -fn str2path(bolos_sdk: &Path, pathlist: &[&str]) -> Vec { - pathlist - .iter() - .map(|p| bolos_sdk.join(p)) - .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, +struct SDKBuilder<'a> { api_level: u32, gcc_toolchain: PathBuf, - device: Device, + device: Device<'a>, cxdefines: Vec, } -impl SDKBuilder { +impl SDKBuilder<'_> { pub fn new() -> Self { SDKBuilder { - bolos_sdk: PathBuf::new(), api_level: 0, gcc_toolchain: PathBuf::new(), - device: Device::NanoS, + device: Device::default(), cxdefines: Vec::new(), } } - pub fn gcc_toolchain(&mut self) { + pub fn gcc_toolchain(&mut self) -> Result<(), SDKBuildError> { // Find out where the arm toolchain is located let output = Command::new("arm-none-eabi-gcc") .arg("-print-sysroot") @@ -325,37 +189,163 @@ impl SDKBuilder { format!("{sysroot}") }; self.gcc_toolchain = PathBuf::from(gcc_toolchain); + Ok(()) } - pub fn device(&mut self) { + pub fn device(&mut self) -> Result<(), SDKBuildError> { + println!("cargo:rerun-if-env-changed=LEDGER_SDK_PATH"); // determine device - let device = match env::var_os("CARGO_CFG_TARGET_OS").unwrap().to_str().unwrap() { - "nanos" => Device::NanoS, - "nanosplus" => Device::NanoSPlus, - "nanox" => Device::NanoX, - "stax" => Device::Stax, - "flex" => Device::Flex, - target_name => panic!( - "invalid target `{target_name}`, expected one of `nanos`, `nanox`, `nanosplus`. Run with `-Z build-std=core --target=./.json`" - ), + self.device = match env::var_os("CARGO_CFG_TARGET_OS") + .unwrap() + .to_str() + .unwrap() + { + "nanos" => Device { + name: DeviceName::NanoS, + c_sdk: Default::default(), + target: "thumbv6m-none-eabi", + defines: header2define("csdk_nanos.h"), + cflags: Vec::from(CFLAGS_NANOS), + glyphs_folders: Vec::new(), + arm_libs: Default::default(), + linker_script: "nanos_layout.ld", + }, + "nanosplus" => Device { + name: DeviceName::NanoSPlus, + c_sdk: Default::default(), + target: "thumbv8m.main-none-eabi", + defines: { + let mut v = header2define("csdk_nanos2.h"); + if env::var_os("CARGO_FEATURE_NBGL").is_some() { + println!("cargo:warning=NBGL is built"); + v.push((String::from("HAVE_NBGL"), None)); + v.push((String::from("NBGL_STEP"), None)); + v.push((String::from("NBGL_USE_CASE"), None)); + } else { + println!("cargo:warning=BAGL is built"); + println!("cargo:rustc-env=C_SDK_GRAPHICS={}", "bagl"); + v.push((String::from("HAVE_BAGL"), None)); + } + v + }, + cflags: Vec::from(CFLAGS_NANOSPLUS), + glyphs_folders: Vec::new(), + arm_libs: Default::default(), + linker_script: "nanosplus_layout.ld", + }, + "nanox" => Device { + name: DeviceName::NanoX, + c_sdk: Default::default(), + target: "thumbv6m-none-eabi", + defines: { + let mut v = header2define("csdk_nanox.h"); + if env::var_os("CARGO_FEATURE_NBGL").is_some() { + println!("cargo:warning=NBGL is built"); + v.push((String::from("HAVE_NBGL"), None)); + v.push((String::from("NBGL_STEP"), None)); + v.push((String::from("NBGL_USE_CASE"), None)); + } else { + println!("cargo:warning=BAGL is built"); + println!("cargo:rustc-env=C_SDK_GRAPHICS={}", "bagl"); + v.push((String::from("HAVE_BAGL"), None)); + } + v + }, + cflags: Vec::from(CFLAGS_NANOX), + glyphs_folders: Vec::new(), + arm_libs: Default::default(), + linker_script: "nanox_layout.ld", + }, + "stax" => Device { + name: DeviceName::Stax, + c_sdk: Default::default(), + target: "thumbv8m.main-none-eabi", + defines: header2define("csdk_stax.h"), + cflags: Vec::from(CFLAGS_STAX), + glyphs_folders: Vec::new(), + arm_libs: Default::default(), + linker_script: "stax_layout.ld", + }, + "flex" => Device { + name: DeviceName::Flex, + c_sdk: Default::default(), + target: "thumbv8m.main-none-eabi", + defines: header2define("csdk_flex.h"), + cflags: Vec::from(CFLAGS_FLEX), + glyphs_folders: Vec::new(), + arm_libs: Default::default(), + linker_script: "flex_layout.ld", + }, + _ => { + return Err(SDKBuildError::UnsupportedDevice); + } }; - self.device = device; - // export TARGET into env for 'infos.rs' - println!("cargo:rustc-env=TARGET={}", self.device); - println!("cargo:warning=Device is {:?}", self.device); - } - pub fn bolos_sdk(&mut self) -> Result<(), SDKBuildError> { - println!("cargo:rerun-if-env-changed=LEDGER_SDK_PATH"); - let sdk_path = match env::var("LEDGER_SDK_PATH") { - Err(_) => clone_sdk(&self.device), + // set the C SDK path + self.device.c_sdk = match env::var("LEDGER_SDK_PATH") { + Err(_) => clone_sdk(&self.device.name), Ok(path) => PathBuf::from(path), }; - let sdk_info = retrieve_sdk_info(&self.device, &sdk_path)?; + // set glyphs folders + match self.device.name { + DeviceName::Flex => { + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/wallet")); + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/64px")); + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/40px")); + } + DeviceName::Stax => { + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/wallet")); + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/64px")); + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/32px")); + } + _ => { + self.device + .glyphs_folders + .push(self.device.c_sdk.join("lib_nbgl/glyphs/nano")); + } + } + + // Set ARM pre-compiled libraries path + self.device.arm_libs = match self.device.name { + DeviceName::NanoS => { + let mut path = self.gcc_toolchain.display().to_string(); + path.push_str("/lib"); + path + } + DeviceName::NanoX => { + let mut path = self.device.c_sdk.display().to_string(); + path.push_str("/arch/st33/lib"); + path + } + DeviceName::NanoSPlus | DeviceName::Flex | DeviceName::Stax => { + let mut path = self.device.c_sdk.display().to_string(); + path.push_str("/arch/st33k1/lib"); + path + } + }; - self.bolos_sdk = sdk_info.bolos_sdk; + // export TARGET into env for 'infos.rs' + println!("cargo:rustc-env=TARGET={}", self.device.name); + println!("cargo:warning=Device is {:?}", self.device.name); + Ok(()) + } + pub fn get_info(&mut self) -> Result<(), SDKBuildError> { + // Retrieve the C SDK information + let sdk_info = retrieve_csdk_info(&self.device, &self.device.c_sdk)?; match sdk_info.api_level { Some(api_level) => { self.api_level = api_level; @@ -364,11 +354,12 @@ impl SDKBuilder { println!("cargo:warning=API_LEVEL is {}", self.api_level); } None => { - if self.device != Device::NanoS { + if self.device.name != DeviceName::NanoS { return Err(SDKBuildError::InvalidAPILevel); } } } + // Export other SDK infos into env for 'infos.rs' println!("cargo:rustc-env=TARGET_ID={}", sdk_info.target_id); println!("cargo:warning=TARGET_ID is {}", sdk_info.target_id); @@ -383,8 +374,8 @@ impl SDKBuilder { Ok(()) } - fn cxdefines(&mut self) { - let mut makefile = File::open(self.bolos_sdk.join("Makefile.conf.cx")) + fn cxdefines(&mut self) -> Result<(), SDKBuildError> { + let mut makefile = File::open(self.device.c_sdk.join("Makefile.conf.cx")) .expect("Could not find Makefile.conf.cx"); let mut content = String::new(); makefile.read_to_string(&mut content).unwrap(); @@ -399,62 +390,15 @@ impl SDKBuilder { cxdefines.push("NATIVE_LITTLE_ENDIAN".to_string()); self.cxdefines = cxdefines; + Ok(()) } - pub fn generate_glyphs(&self) { - if self.device == Device::NanoS { - return; - } - - let icon2glyph = self.bolos_sdk.join("lib_nbgl/tools/icon2glyph.py"); - - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - let dest_path = match self.device { - Device::Flex => out_path.join("glyphs_flex"), - Device::Stax => out_path.join("glyphs_stax"), - Device::NanoSPlus => out_path.join("glyphs_nanosplus"), - Device::NanoX => out_path.join("glyphs_nanox"), - Device::NanoS => panic!("Nano S does not support glyphs"), - }; - if !dest_path.exists() { - fs::create_dir_all(&dest_path).ok(); - } - - let mut glyph_folders: Vec = Vec::new(); - match self.device { - Device::Flex => { - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/wallet")); - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/64px")); - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/40px")); - } - Device::Stax => { - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/wallet")); - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/64px")); - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/32px")); - } - _ => { - glyph_folders.push(self.bolos_sdk.join("lib_nbgl/glyphs/nano")); - } - } - - let mut cmd = Command::new(icon2glyph.as_os_str()); - cmd.arg("--glyphcheader") - .arg(dest_path.join("glyphs.h").as_os_str()) - .arg("--glyphcfile") - .arg(dest_path.join("glyphs.c").as_os_str()); - - for folder in glyph_folders.iter() { - for file in std::fs::read_dir(folder).unwrap() { - let path = file.unwrap().path(); - let path_str = path.to_str().unwrap().to_string(); - cmd.arg(path_str); - } + pub fn build_c_sdk(&self) -> Result<(), SDKBuildError> { + // Generate glyphs + if self.device.name != DeviceName::NanoS { + generate_glyphs(&self.device); } - let _ = cmd.output(); - } - - pub fn build_c_sdk(&self) { let mut command = cc::Build::new(); if env::var_os("CC").is_none() { command.compiler("clang"); @@ -464,51 +408,54 @@ impl SDKBuilder { command .files(&AUX_C_FILES) - .files(str2path(&self.bolos_sdk, &SDK_C_FILES)) - .files(str2path(&self.bolos_sdk, &SDK_USB_FILES)); + .files(str2path(&self.device.c_sdk, &SDK_C_FILES)) + .files(str2path(&self.device.c_sdk, &SDK_USB_FILES)); command = command .include(self.gcc_toolchain.join("include")) - .include(self.bolos_sdk.join("include")) - .include(self.bolos_sdk.join("lib_cxng/include")) - .include(self.bolos_sdk.join("lib_stusb")) - .include(self.bolos_sdk.join("lib_stusb_impl")) + .include(self.device.c_sdk.join("include")) + .include(self.device.c_sdk.join("lib_cxng/include")) + .include(self.device.c_sdk.join("lib_stusb")) + .include(self.device.c_sdk.join("lib_stusb_impl")) .include( - self.bolos_sdk + self.device + .c_sdk .join("lib_stusb/STM32_USB_Device_Library/Core/Inc"), ) .include( - self.bolos_sdk + self.device + .c_sdk .join("lib_stusb/STM32_USB_Device_Library/Class/HID/Inc"), ) .debug(true) - .flag("-Oz") - .flag("-fomit-frame-pointer") - .flag("-fno-common") - .flag("-fdata-sections") - .flag("-ffunction-sections") - .flag("-mthumb") - .flag("-fno-jump-tables") - .flag("-fshort-enums") - .flag("-mno-unaligned-access") - .flag("-Wno-unused-command-line-argument") + .define("main", "_start") .clone(); - // #[cfg(feature = "ccid")] - // { - // for (define, value) in DEFINES_CCID { - // command.define(define, value); - // } - // command.files(str2path(&self.bolos_sdk, &CCID_FILES)); - // } - - match self.device { - Device::NanoS => finalize_nanos_configuration(&mut command, &self.bolos_sdk), - Device::NanoX => finalize_nanox_configuration(&mut command, &self.bolos_sdk), - Device::NanoSPlus => finalize_nanosplus_configuration(&mut command, &self.bolos_sdk), - Device::Stax => finalize_stax_configuration(&mut command, &self.bolos_sdk), - Device::Flex => finalize_flex_configuration(&mut command, &self.bolos_sdk), - }; + // Set the #defines + for (define, value) in &self.device.defines { + command.define(define.as_str(), value.as_deref()); + } + + // Set the CFLAGS + for cflag in &self.device.cflags { + command.flag(cflag); + } + + command.target(self.device.target).include( + self.device + .c_sdk + .join(format!("target/{}/include", self.device.name)), + ); + + // Configure BLE and NBGL + for s in self.device.defines.iter() { + if s.0 == "HAVE_BLE" { + configure_lib_ble(&mut command, &self.device.c_sdk); + } + if s.0 == "HAVE_NBGL" { + configure_lib_nbgl(&mut command, &self.device.c_sdk); + } + } // Add the defines found in the Makefile.conf.cx to our build command. for define in self.cxdefines.iter() { @@ -517,26 +464,17 @@ impl SDKBuilder { command.compile("ledger-secure-sdk"); - /* Link with libc for unresolved symbols */ - let mut path = self.bolos_sdk.display().to_string(); - match self.device { - Device::NanoS => { - path = self.gcc_toolchain.display().to_string(); - path.push_str("/lib"); - } - Device::NanoX => { - path.push_str("/arch/st33/lib"); - } - Device::NanoSPlus | Device::Flex | Device::Stax => { - path.push_str("/arch/st33k1/lib"); - } - }; + /* Link with libc, libm and libgcc */ + let path = self.device.arm_libs.clone(); println!("cargo:rustc-link-lib=c"); + println!("cargo:rustc-link-lib=m"); + println!("cargo:rustc-link-lib=gcc"); println!("cargo:rustc-link-search={path}"); + Ok(()) } - fn generate_bindings(&self) { - let bsdk = self.bolos_sdk.display().to_string(); + fn generate_bindings(&self) -> Result<(), SDKBuildError> { + let bsdk = self.device.c_sdk.display().to_string(); let gcc_tc = self.gcc_toolchain.display().to_string(); let args = [ "--target=thumbv6m-none-eabi".to_string(), // exact target is irrelevant for bindings @@ -547,9 +485,8 @@ impl SDKBuilder { format!("-I{bsdk}/lib_stusb/STM32_USB_Device_Library/Core/Inc/"), format!("-I{bsdk}/lib_stusb/"), ]; - let headers = str2path( - &self.bolos_sdk, + &self.device.c_sdk, &[ "lib_cxng/include/libcxng.h", /* cxlib */ "include/os.h", /* syscalls */ @@ -572,14 +509,10 @@ impl SDKBuilder { .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"), - Device::Stax => ("stax", "sdk_stax.h"), - Device::Flex => ("flex", "sdk_flex.h"), - }; - bindings = bindings.clang_arg(format!("-I{bsdk}/target/{include_path}/include/")); + let csdk_target_name = self.device.name.to_string(); + let header = format!("csdk_{csdk_target_name}.h"); + + bindings = bindings.clang_arg(format!("-I{bsdk}/target/{csdk_target_name}/include/")); bindings = bindings.header(header); // SDK headers to bind against @@ -587,53 +520,59 @@ impl SDKBuilder { bindings = bindings.header(header); } - match self.device { - Device::NanoS => { - bindings = bindings.header(self.bolos_sdk.join("include/bagl.h").to_str().unwrap()) + // BAGL or NBGL bindings + match self.device.name { + DeviceName::NanoS => { + bindings = + bindings.header(self.device.c_sdk.join("include/bagl.h").to_str().unwrap()) } - Device::NanoX => { + DeviceName::NanoSPlus | DeviceName::NanoX | DeviceName::Stax | DeviceName::Flex => { + if ((self.device.name == DeviceName::NanoX + || self.device.name == DeviceName::NanoSPlus) + && env::var_os("CARGO_FEATURE_NBGL").is_some()) + || self.device.name == DeviceName::Stax + || self.device.name == DeviceName::Flex + { + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + let mut include_path = "-I".to_string(); + let glyphs = out_path.join("glyphs"); + include_path += glyphs.to_str().unwrap(); + bindings = bindings.clang_args([include_path.as_str()]); + + bindings = bindings.clang_args([ + format!("-I{bsdk}/lib_nbgl/include/").as_str(), + format!("-I{bsdk}/lib_ux_nbgl/").as_str(), + ]); + bindings = bindings + .header( + self.device + .c_sdk + .join("lib_nbgl/include/nbgl_use_case.h") + .to_str() + .unwrap(), + ) + .header( + self.device + .c_sdk + .join("lib_ux_nbgl/ux_nbgl.h") + .to_str() + .unwrap(), + ); + } + } + } + + // BLE bindings + match self.device.name { + DeviceName::NanoX | DeviceName::Flex | DeviceName::Stax => { bindings = bindings.header( - self.bolos_sdk + self.device + .c_sdk .join("lib_blewbxx_impl/include/ledger_ble.h") .to_str() .unwrap(), ) } - Device::Stax | Device::Flex => { - let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); - let mut include_path = "-I".to_string(); - let glyphs = match self.device { - Device::Stax => out_path.join("glyphs_stax"), - Device::Flex => out_path.join("glyphs_flex"), - _ => panic!("Invalid device"), - }; - include_path += glyphs.to_str().unwrap(); - bindings = bindings.clang_args([include_path.as_str()]); - - bindings = bindings.clang_args([ - format!("-I{bsdk}/lib_nbgl/include/").as_str(), - format!("-I{bsdk}/lib_ux_nbgl/").as_str(), - ]); - bindings = bindings - .header( - self.bolos_sdk - .join("lib_nbgl/include/nbgl_use_case.h") - .to_str() - .unwrap(), - ) - .header( - self.bolos_sdk - .join("lib_ux_nbgl/ux_nbgl.h") - .to_str() - .unwrap(), - ) - .header( - self.bolos_sdk - .join("lib_blewbxx_impl/include/ledger_ble.h") - .to_str() - .unwrap(), - ) - } _ => (), } @@ -651,9 +590,11 @@ impl SDKBuilder { bindings .write_to_file(out_path.join("bindings.rs")) .expect("Couldn't write bindings"); + + Ok(()) } - fn generate_heap_size(&self) { + fn generate_heap_size(&self) -> Result<(), SDKBuildError> { // Read the HEAP_SIZE environment variable, default to 8192 if not set let heap_size = env::var("HEAP_SIZE").unwrap_or_else(|_| "8192".to_string()); @@ -672,190 +613,317 @@ impl SDKBuilder { format!("pub const HEAP_SIZE: usize = {};", heap_size), ) .expect("Unable to write file"); + Ok(()) + } + + fn copy_linker_script(&self) -> Result<(), SDKBuildError> { + let out_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap()); + // extend the library search path + println!("cargo:rustc-link-search={}", out_dir.display()); + // copy + std::fs::copy( + self.device.linker_script, + out_dir.join(self.device.linker_script), + ) + .unwrap(); + std::fs::copy("link.ld", out_dir.join("link.ld")).unwrap(); + Ok(()) } } fn main() { + let start = Instant::now(); let mut sdk_builder = SDKBuilder::new(); - sdk_builder.gcc_toolchain(); - sdk_builder.device(); - sdk_builder.bolos_sdk().unwrap(); - sdk_builder.cxdefines(); - sdk_builder.generate_glyphs(); - sdk_builder.build_c_sdk(); - sdk_builder.generate_bindings(); - sdk_builder.generate_heap_size(); + sdk_builder.gcc_toolchain().unwrap(); + sdk_builder.device().unwrap(); + sdk_builder.get_info().unwrap(); + sdk_builder.cxdefines().unwrap(); + sdk_builder.build_c_sdk().unwrap(); + sdk_builder.generate_bindings().unwrap(); + sdk_builder.generate_heap_size().unwrap(); + sdk_builder.copy_linker_script().unwrap(); + let end = start.elapsed(); + println!( + "cargo:warning=Total build.rs time: {} seconds", + end.as_secs() + ); } -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()); - } +// -------------------------------------------------- +// Helper functions +// -------------------------------------------------- +fn configure_lib_ble(command: &mut cc::Build, c_sdk: &Path) { command - .target("thumbv6m-none-eabi") - .define("ST31", None) - .define("BAGL_HEIGHT", Some("32")) - .define("BAGL_WIDTH", Some("128")) - .include(bolos_sdk.join("target/nanos/include")) - .flag("-fropi"); + .file(c_sdk.join("src/ledger_protocol.c")) + .file(c_sdk.join("lib_blewbxx/core/auto/ble_gap_aci.c")) + .file(c_sdk.join("lib_blewbxx/core/auto/ble_gatt_aci.c")) + .file(c_sdk.join("lib_blewbxx/core/auto/ble_hal_aci.c")) + .file(c_sdk.join("lib_blewbxx/core/auto/ble_hci_le.c")) + .file(c_sdk.join("lib_blewbxx/core/auto/ble_l2cap_aci.c")) + .file(c_sdk.join("lib_blewbxx/core/template/osal.c")) + .file(c_sdk.join("lib_blewbxx_impl/src/ledger_ble.c")) + .include(c_sdk.join("lib_blewbxx/include")) + .include(c_sdk.join("lib_blewbxx/core")) + .include(c_sdk.join("lib_blewbxx/core/auto")) + .include(c_sdk.join("lib_blewbxx/core/template")) + .include(c_sdk.join("lib_blewbxx_impl/include")); } -fn finalize_nanox_configuration(command: &mut cc::Build, bolos_sdk: &Path) { - let defines = header2define("sdk_nanox.h"); - for (define, value) in defines { - command.define(define.as_str(), value.as_deref()); - } +fn configure_lib_nbgl(command: &mut cc::Build, c_sdk: &Path) { + println!("cargo:rustc-env=C_SDK_GRAPHICS={}", "nbgl"); + let glyphs_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("glyphs"); command - .target("thumbv6m-none-eabi") - .define("ST33", None) - .define("BAGL_HEIGHT", Some("64")) - .define("BAGL_WIDTH", Some("128")) - .file(bolos_sdk.join("src/ledger_protocol.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_gap_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_gatt_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_hal_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_hci_le.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_l2cap_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/template/osal.c")) - .file(bolos_sdk.join("lib_blewbxx_impl/src/ledger_ble.c")) - .include(bolos_sdk.join("lib_blewbxx/include")) - .include(bolos_sdk.join("lib_blewbxx/core")) - .include(bolos_sdk.join("lib_blewbxx/core/auto")) - .include(bolos_sdk.join("lib_blewbxx/core/template")) - .include(bolos_sdk.join("lib_blewbxx_impl/include")) - .include(bolos_sdk.join("target/nanox/include")) - .flag("-mno-movt") - .flag("-ffixed-r9") - .flag("-fropi") - .flag("-frwpi"); - configure_lib_bagl(command, bolos_sdk); + .include(c_sdk.join("lib_nbgl/include/")) + .include(c_sdk.join("lib_nbgl/include/fonts/")) + .include(c_sdk.join("lib_ux_nbgl/")) + .include(c_sdk.join("qrcode/include/")) + .include(c_sdk.join("lib_bagl/include/")) + .file(c_sdk.join("lib_ux_nbgl/ux.c")) + .file(c_sdk.join("qrcode/src/qrcodegen.c")) + .files( + glob(c_sdk.join("lib_nbgl/src/*.c").to_str().unwrap()) + .unwrap() + .map(|x| x.unwrap()) + .collect::>(), + ) + .include(&glyphs_path) + .file(glyphs_path.join("glyphs.c")); } -fn finalize_nanosplus_configuration(command: &mut cc::Build, bolos_sdk: &Path) { - let defines = header2define("sdk_nanosp.h"); - for (define, value) in defines { - command.define(define.as_str(), value.as_deref()); - } +fn retrieve_csdk_info(device: &Device, path: &PathBuf) -> Result { + let mut csdk_info = CSDKInfo::new(); + (csdk_info.api_level, csdk_info.c_sdk_name) = retrieve_makefile_infos(path)?; + (csdk_info.target_id, csdk_info.target_name) = retrieve_target_file_infos(device, path)?; + (csdk_info.c_sdk_hash, csdk_info.c_sdk_version) = retrieve_csdk_git_info(path); + Ok(csdk_info) +} - command - .target("thumbv8m.main-none-eabi") - .define("ST33K1M5", None) - .define("BAGL_HEIGHT", Some("64")) - .define("BAGL_WIDTH", Some("128")) - .include(bolos_sdk.join("target/nanos2/include")) - .flag("-fropi") - .flag("-frwpi"); - configure_lib_bagl(command, bolos_sdk); +fn retrieve_csdk_git_info(c_sdk: &Path) -> (String, String) { + let c_sdk_hash = match Command::new("git") + .arg("-C") + .arg(c_sdk) + .arg("describe") + .arg("--always") + .arg("--dirty") + .arg("--exclude") + .arg("*") + .arg("--abbrev=40") + .output() + .ok() + { + Some(output) => { + if output.stdout.is_empty() { + "None".to_string() + } else { + String::from_utf8(output.stdout).unwrap_or("None".to_string()) + } + } + None => "None".to_string(), + }; + + let c_sdk_version = match Command::new("git") + .arg("-C") + .arg(c_sdk) + .arg("describe") + .arg("--tags") + .arg("--match") + .arg("v[0-9]*") + .arg("--dirty") + .output() + .ok() + { + Some(output) => { + if output.status.success() { + String::from_utf8(output.stdout).unwrap_or("None".to_string()) + } else { + String::from_utf8(output.stderr).unwrap_or("None".to_string()) + } + } + None => "None".to_string(), + }; + (c_sdk_hash, c_sdk_version) } -fn configure_lib_bagl(command: &mut cc::Build, bolos_sdk: &Path) { - if env::var_os("CARGO_FEATURE_LIB_BAGL").is_some() { - command - .define("HAVE_BAGL", None) - // Just include all the fonts for now; we can shrink the X and S+ images later. - .define("HAVE_BAGL_FONT_LUCIDA_CONSOLE_8PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16_22PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_REGULAR_8_11PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_REGULAR_10_13PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11_14PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_REGULAR_13_18PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_REGULAR_22_30PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_SEMIBOLD_8_11PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_SEMIBOLD_10_13PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_SEMIBOLD_11_16PX", None) - .define("HAVE_BAGL_FONT_OPEN_SANS_SEMIBOLD_13_18PX", None) - .define("HAVE_BAGL_FONT_SYMBOLS_0", None) - .define("HAVE_BAGL_FONT_SYMBOLS_1", None) - .include(bolos_sdk.join("lib_bagl/src/")) - .file(bolos_sdk.join("lib_bagl/src/bagl.c")) - .file(bolos_sdk.join("lib_bagl/src/bagl_fonts.c")) - .file(bolos_sdk.join("lib_bagl/src/bagl_glyphs.c")); +fn retrieve_makefile_infos(c_sdk: &Path) -> Result<(Option, String), SDKBuildError> { + let makefile = + File::open(c_sdk.join("Makefile.defines")).expect("Could not find Makefile.defines"); + let mut api_level: Option = None; + for line in BufReader::new(makefile).lines().flatten() { + if let Some(value) = line.split(":=").nth(1).map(str::trim) { + if line.contains("API_LEVEL") && api_level.is_none() { + api_level = Some(value.parse().map_err(|_| SDKBuildError::InvalidAPILevel)?); + } + } + if api_level.is_some() { + // Key found, break out of the loop + break; + } + } + let makefile = + File::open(c_sdk.join("Makefile.target")).expect("Could not find Makefile.defines"); + let mut sdk_name: Option = None; + for line in BufReader::new(makefile).lines().flatten() { + if let Some(value) = line.split(":=").nth(1).map(str::trim) { + if line.contains("SDK_NAME") && sdk_name.is_none() { + sdk_name = Some(value.to_string().replace('\"', "")); + } + } + if sdk_name.is_some() { + // Key found, break out of the loop + break; + } } + + let sdk_name = sdk_name.ok_or(SDKBuildError::MissingSDKName)?; + Ok((api_level, sdk_name)) } -fn finalize_stax_configuration(command: &mut cc::Build, bolos_sdk: &Path) { - let defines = header2define("sdk_stax.h"); - for (define, value) in defines { - command.define(define.as_str(), value.as_deref()); +fn retrieve_target_file_infos( + device: &Device, + c_sdk: &Path, +) -> Result<(String, String), SDKBuildError> { + let prefix = if device.name == DeviceName::NanoS { + "".to_string() + } else { + format!("target/{}/", device.name) + }; + let target_file_path = c_sdk.join(format!("{}include/bolos_target.h", prefix)); + let target_file = + File::open(target_file_path).map_err(|_| SDKBuildError::TargetFileNotFound)?; + let mut target_id: Option = None; + let mut target_name: Option = None; + + for line in BufReader::new(target_file).lines().flatten() { + if target_id.is_none() && line.contains("#define TARGET_ID") { + target_id = Some( + line.split_whitespace() + .nth(2) + .ok_or("err") + .map_err(|_| SDKBuildError::MissingTargetId)? + .to_string(), + ); + } else if target_name.is_none() + && line.contains("#define TARGET_") + && !line.contains("#define TARGET_ID") + { + target_name = Some( + line.split_whitespace() + .nth(1) + .ok_or("err") + .map_err(|_| SDKBuildError::MissingTargetName)? + .to_string(), + ); + } + + if target_id.is_some() && target_name.is_some() { + // Both tokens found, break out of the loop + break; + } } - let glyphs_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("glyphs_stax"); - command - .target("thumbv8m.main-none-eabi") - .file(bolos_sdk.join("src/ledger_protocol.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_gap_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_gatt_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_hal_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_hci_le.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_l2cap_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/template/osal.c")) - .file(bolos_sdk.join("lib_blewbxx_impl/src/ledger_ble.c")) - .include(bolos_sdk.join("lib_blewbxx/include")) - .include(bolos_sdk.join("lib_blewbxx/core")) - .include(bolos_sdk.join("lib_blewbxx/core/auto")) - .include(bolos_sdk.join("lib_blewbxx/core/template")) - .include(bolos_sdk.join("lib_blewbxx_impl/include")) - .include(bolos_sdk.join("target/stax/include/")) - .flag("-fropi") - .flag("-frwpi") - .include(&glyphs_path) - .file(glyphs_path.join("glyphs.c")); - configure_lib_nbgl(command, bolos_sdk); + let target_id = target_id.ok_or(SDKBuildError::MissingTargetId)?; + let target_name = target_name.ok_or(SDKBuildError::MissingTargetName)?; + Ok((target_id, target_name)) +} + +/// Fetch the appropriate C SDK to build +fn clone_sdk(devicename: &DeviceName) -> PathBuf { + let (repo_url, sdk_branch) = match devicename { + DeviceName::NanoS => ( + Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), + "API_LEVEL_LNS", + ), + DeviceName::NanoX => ( + Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), + "API_LEVEL_22", + ), + DeviceName::NanoSPlus => ( + Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), + "API_LEVEL_22", + ), + DeviceName::Stax => ( + Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), + "API_LEVEL_22", + ), + DeviceName::Flex => ( + Path::new("https://github.com/LedgerHQ/ledger-secure-sdk"), + "API_LEVEL_22", + ), + }; + + let out_dir = env::var("OUT_DIR").unwrap(); + let c_sdk = Path::new(out_dir.as_str()).join("ledger-secure-sdk"); + if !c_sdk.exists() { + Command::new("git") + .arg("clone") + .arg(repo_url.to_str().unwrap()) + .arg("-b") + .arg(sdk_branch) + .arg(c_sdk.as_path()) + .output() + .ok(); + } + c_sdk } -fn finalize_flex_configuration(command: &mut cc::Build, bolos_sdk: &Path) { - let defines = header2define("sdk_flex.h"); - for (define, value) in defines { - command.define(define.as_str(), value.as_deref()); +fn generate_glyphs(device: &Device) { + let icon2glyph = device.c_sdk.join("lib_nbgl/tools/icon2glyph.py"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + let dest_path = out_path.join("glyphs"); + if !dest_path.exists() { + fs::create_dir_all(&dest_path).ok(); } - let glyphs_path = PathBuf::from(env::var("OUT_DIR").unwrap()).join("glyphs_flex"); - command - .target("thumbv8m.main-none-eabi") - .file(bolos_sdk.join("src/ledger_protocol.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_gap_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_gatt_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_hal_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_hci_le.c")) - .file(bolos_sdk.join("lib_blewbxx/core/auto/ble_l2cap_aci.c")) - .file(bolos_sdk.join("lib_blewbxx/core/template/osal.c")) - .file(bolos_sdk.join("lib_blewbxx_impl/src/ledger_ble.c")) - .include(bolos_sdk.join("lib_blewbxx/include")) - .include(bolos_sdk.join("lib_blewbxx/core")) - .include(bolos_sdk.join("lib_blewbxx/core/auto")) - .include(bolos_sdk.join("lib_blewbxx/core/template")) - .include(bolos_sdk.join("lib_blewbxx_impl/include")) - .include(bolos_sdk.join("target/flex/include/")) - .flag("-fropi") - .flag("-frwpi") - .include(&glyphs_path) - .file(glyphs_path.join("glyphs.c")); - configure_lib_nbgl(command, bolos_sdk); + let mut cmd = Command::new(icon2glyph.as_os_str()); + cmd.arg("--glyphcheader") + .arg(dest_path.join("glyphs.h").as_os_str()) + .arg("--glyphcfile") + .arg(dest_path.join("glyphs.c").as_os_str()); + + if device.name == DeviceName::NanoSPlus || device.name == DeviceName::NanoX { + cmd.arg("--reverse"); + } + + for folder in device.glyphs_folders.iter() { + for file in std::fs::read_dir(folder).unwrap() { + let path = file.unwrap().path(); + let path_str = path.to_str().unwrap().to_string(); + cmd.arg(path_str); + } + } + let _ = cmd.output(); } -fn configure_lib_nbgl(command: &mut cc::Build, bolos_sdk: &Path) { - command - .flag("-Wno-microsoft-anon-tag") - .flag("-fms-extensions") - .include(bolos_sdk.join("lib_nbgl/include/")) - .include(bolos_sdk.join("lib_nbgl/include/fonts/")) - .include(bolos_sdk.join("lib_ux_nbgl/")) - .include(bolos_sdk.join("qrcode/include/")) - .include(bolos_sdk.join("lib_bagl/include/")) - .file(bolos_sdk.join("lib_ux_nbgl/ux.c")) - .file(bolos_sdk.join("lib_bagl/src/bagl_fonts.c")) - .file(bolos_sdk.join("src/os_printf.c")) - .file(bolos_sdk.join("qrcode/src/qrcodegen.c")) - .files( - glob(bolos_sdk.join("lib_nbgl/src/*.c").to_str().unwrap()) - .unwrap() - .map(|x| x.unwrap()) - .collect::>(), - ); +/// Helper function to concatenate all paths in pathlist to c_sdk's path +fn str2path(c_sdk: &Path, pathlist: &[&str]) -> Vec { + pathlist + .iter() + .map(|p| c_sdk.join(p)) + .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() } diff --git a/ledger_secure_sdk_sys/c_sdk_build_flex.cflags b/ledger_secure_sdk_sys/c_sdk_build_flex.cflags new file mode 100644 index 00000000..519cb514 --- /dev/null +++ b/ledger_secure_sdk_sys/c_sdk_build_flex.cflags @@ -0,0 +1,34 @@ +--sysroot="/usr/arm-none-eabi" +-Oz +-g0 +-fomit-frame-pointer +-momit-leaf-frame-pointer +-fno-common +-mlittle-endian +-std=gnu99 +-Wall +-Wextra +-Wno-main +-Werror=int-to-pointer-cast +-Wno-error=int-conversion +-Wimplicit-fallthrough +-Wvla +-Wundef +-Wshadow +-Wformat=2 +-Wformat-security +-Wwrite-strings +-fdata-sections +-ffunction-sections +-funsigned-char +-fshort-enums +-mno-unaligned-access +-fropi +-fno-jump-tables +-nostdlib +-nodefaultlibs +-frwpi +-mthumb +--target=armv8m-none-eabi +-mcpu=cortex-m35p+nodsp +-msoft-float \ No newline at end of file diff --git a/ledger_secure_sdk_sys/c_sdk_build_nanosplus.cflags b/ledger_secure_sdk_sys/c_sdk_build_nanosplus.cflags new file mode 100644 index 00000000..519cb514 --- /dev/null +++ b/ledger_secure_sdk_sys/c_sdk_build_nanosplus.cflags @@ -0,0 +1,34 @@ +--sysroot="/usr/arm-none-eabi" +-Oz +-g0 +-fomit-frame-pointer +-momit-leaf-frame-pointer +-fno-common +-mlittle-endian +-std=gnu99 +-Wall +-Wextra +-Wno-main +-Werror=int-to-pointer-cast +-Wno-error=int-conversion +-Wimplicit-fallthrough +-Wvla +-Wundef +-Wshadow +-Wformat=2 +-Wformat-security +-Wwrite-strings +-fdata-sections +-ffunction-sections +-funsigned-char +-fshort-enums +-mno-unaligned-access +-fropi +-fno-jump-tables +-nostdlib +-nodefaultlibs +-frwpi +-mthumb +--target=armv8m-none-eabi +-mcpu=cortex-m35p+nodsp +-msoft-float \ No newline at end of file diff --git a/ledger_secure_sdk_sys/c_sdk_build_nanox.cflags b/ledger_secure_sdk_sys/c_sdk_build_nanox.cflags new file mode 100644 index 00000000..db9a2818 --- /dev/null +++ b/ledger_secure_sdk_sys/c_sdk_build_nanox.cflags @@ -0,0 +1,34 @@ +--sysroot="/usr/arm-none-eabi" +-Oz +-g0 +-fomit-frame-pointer +-momit-leaf-frame-pointer +-fno-common +-mlittle-endian +-std=gnu99 +-Wall +-Wextra +-Wno-main +-Werror=int-to-pointer-cast +-Wno-error=int-conversion +-Wimplicit-fallthrough +-Wvla +-Wundef +-Wshadow +-Wformat=2 +-Wformat-security +-Wwrite-strings +-fdata-sections +-ffunction-sections +-funsigned-char +-fshort-enums +-mno-unaligned-access +-fropi +-fno-jump-tables +-nostdlib +-nodefaultlibs +-frwpi +-mthumb +--target=armv6m-none-eabi +-mcpu=cortex-m0plus + diff --git a/ledger_secure_sdk_sys/c_sdk_build_stax.cflags b/ledger_secure_sdk_sys/c_sdk_build_stax.cflags new file mode 100644 index 00000000..519cb514 --- /dev/null +++ b/ledger_secure_sdk_sys/c_sdk_build_stax.cflags @@ -0,0 +1,34 @@ +--sysroot="/usr/arm-none-eabi" +-Oz +-g0 +-fomit-frame-pointer +-momit-leaf-frame-pointer +-fno-common +-mlittle-endian +-std=gnu99 +-Wall +-Wextra +-Wno-main +-Werror=int-to-pointer-cast +-Wno-error=int-conversion +-Wimplicit-fallthrough +-Wvla +-Wundef +-Wshadow +-Wformat=2 +-Wformat-security +-Wwrite-strings +-fdata-sections +-ffunction-sections +-funsigned-char +-fshort-enums +-mno-unaligned-access +-fropi +-fno-jump-tables +-nostdlib +-nodefaultlibs +-frwpi +-mthumb +--target=armv8m-none-eabi +-mcpu=cortex-m35p+nodsp +-msoft-float \ No newline at end of file diff --git a/ledger_secure_sdk_sys/csdk_flex.h b/ledger_secure_sdk_sys/csdk_flex.h new file mode 100644 index 00000000..b878a6ab --- /dev/null +++ b/ledger_secure_sdk_sys/csdk_flex.h @@ -0,0 +1,66 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.standard_app +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BLUETOOTH +#define HAVE_BLE +#define HAVE_BLE_APDU +#define BLE_COMMAND_TIMEOUT_MS 2000 +#define BLE_SEGMENT_SIZE 32 +// NFC SUPPORT (feature dependent) +//#define HAVE_NFC +//#define HAVE_NFC_READER +// APP STORAGE (feature dependent) +//#define HAVE_APP_STORAGE +// IO SEPROXY BUFFER SIZE +#define IO_SEPROXYHAL_BUFFER_SIZE_B 300 +// NBGL QRCODE (feature dependent) +#define NBGL_QRCODE +// NBGL KEYBOARD (feature dependent) +//#define NBGL_KEYBOARD +// NBGL KEYPAD (feature dependent) +//#define NBGL_KEYPAD +// STANDARD DEFINES +#define IO_HID_EP_LENGTH 64 +#define HAVE_SPRINTF +#define HAVE_SNPRINTF_FORMAT_U +#define HAVE_IO_USB +#define HAVE_L4_USBLIB +#define IO_USB_MAX_ENDPOINTS 4 +#define HAVE_USB_APDU +#define USB_SEGMENT_SIZE 64 +//#define HAVE_WEBUSB +//#define WEBUSB_URL_SIZE_B +//#define WEBUSB_URL +#define OS_IO_SEPROXYHAL +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.defines +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define gcc +#define __IO volatile +// Flex +#define HAVE_BAGL_FONT_INTER_REGULAR_28PX +#define HAVE_BAGL_FONT_INTER_SEMIBOLD_28PX +#define HAVE_BAGL_FONT_INTER_MEDIUM_36PX +#define HAVE_INAPP_BLE_PAIRING +#define HAVE_NBGL +#define HAVE_PIEZO_SOUND +#define HAVE_SE_TOUCH +#define HAVE_SE_EINK_DISPLAY +//#define HAVE_HW_TOUCH_SWIPE +#define NBGL_PAGE +#define NBGL_USE_CASE +#define SCREEN_SIZE_WALLET +#define HAVE_FAST_HOLD_TO_APPROVE + +#define HAVE_LEDGER_PKI + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Misc +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define HAVE_LOCAL_APDU_BUFFER + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEBUG C SDK +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//#define HAVE_PRINTF +//#define PRINTF mcu_usb_printf \ No newline at end of file diff --git a/ledger_secure_sdk_sys/sdk_nanos.h b/ledger_secure_sdk_sys/csdk_nanos.h similarity index 93% rename from ledger_secure_sdk_sys/sdk_nanos.h rename to ledger_secure_sdk_sys/csdk_nanos.h index 7d665ec9..157b0b37 100644 --- a/ledger_secure_sdk_sys/sdk_nanos.h +++ b/ledger_secure_sdk_sys/csdk_nanos.h @@ -8,4 +8,4 @@ #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 +#define ST31 \ No newline at end of file diff --git a/ledger_secure_sdk_sys/csdk_nanos2.h b/ledger_secure_sdk_sys/csdk_nanos2.h new file mode 100644 index 00000000..126ba21f --- /dev/null +++ b/ledger_secure_sdk_sys/csdk_nanos2.h @@ -0,0 +1,56 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.standard_app +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// APP STORAGE (feature dependent) +//#define HAVE_APP_STORAGE +// IO SEPROXY BUFFER SIZE +#define IO_SEPROXYHAL_BUFFER_SIZE_B 300 +// NBGL KEYBOARD (feature dependent) +//#define NBGL_KEYBOARD +// NBGL KEYPAD (feature dependent) +//#define NBGL_KEYPAD +// STANDARD DEFINES +#define IO_HID_EP_LENGTH 64 +#define HAVE_SPRINTF +#define HAVE_SNPRINTF_FORMAT_U +#define HAVE_IO_USB +#define HAVE_L4_USBLIB +#define IO_USB_MAX_ENDPOINTS 4 +#define HAVE_USB_APDU +#define USB_SEGMENT_SIZE 64 +//#define HAVE_WEBUSB +//#define WEBUSB_URL_SIZE_B +//#define WEBUSB_URL +#define OS_IO_SEPROXYHAL +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.defines +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define gcc +#define __IO volatile + +#define BAGL_HEIGHT 64 +#define BAGL_WIDTH 128 +#define HAVE_BAGL_ELLIPSIS +#define HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX +#define HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX +#define HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX +#define SCREEN_SIZE_NANO + +#define HAVE_SE_BUTTON +#define HAVE_SE_SCREEN +#define HAVE_FONTS +#define HAVE_INAPP_BLE_PAIRING +#define HAVE_BATTERY + +#define HAVE_LEDGER_PKI + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Misc +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define HAVE_LOCAL_APDU_BUFFER + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEBUG C SDK +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//#define HAVE_PRINTF +//#define PRINTF mcu_usb_printf diff --git a/ledger_secure_sdk_sys/csdk_nanox.h b/ledger_secure_sdk_sys/csdk_nanox.h new file mode 100644 index 00000000..c6f69c1d --- /dev/null +++ b/ledger_secure_sdk_sys/csdk_nanox.h @@ -0,0 +1,63 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.standard_app +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BLUETOOTH +#define HAVE_BLE +#define HAVE_BLE_APDU +#define BLE_COMMAND_TIMEOUT_MS 2000 +#define BLE_SEGMENT_SIZE 32 +// APP STORAGE (feature dependent) +//#define HAVE_APP_STORAGE +// IO SEPROXY BUFFER SIZE +#define IO_SEPROXYHAL_BUFFER_SIZE_B 300 +// NBGL KEYBOARD (feature dependent) +//#define NBGL_KEYBOARD +// NBGL KEYPAD (feature dependent) +//#define NBGL_KEYPAD +// STANDARD DEFINES +#define IO_HID_EP_LENGTH 64 +#define HAVE_SPRINTF +#define HAVE_SNPRINTF_FORMAT_U +#define HAVE_IO_USB +#define HAVE_L4_USBLIB +#define IO_USB_MAX_ENDPOINTS 4 +#define HAVE_USB_APDU +#define USB_SEGMENT_SIZE 64 +//#define HAVE_WEBUSB +//#define WEBUSB_URL_SIZE_B +//#define WEBUSB_URL +#define OS_IO_SEPROXYHAL +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.defines +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define gcc +#define __IO volatile + +#define BAGL_HEIGHT 64 +#define BAGL_WIDTH 128 +#define HAVE_BAGL_ELLIPSIS +#define HAVE_BAGL_FONT_OPEN_SANS_REGULAR_11PX +#define HAVE_BAGL_FONT_OPEN_SANS_EXTRABOLD_11PX +#define HAVE_BAGL_FONT_OPEN_SANS_LIGHT_16PX +#define SCREEN_SIZE_NANO + +#define HAVE_SE_BUTTON +#define HAVE_SE_SCREEN +#define HAVE_FONTS +#define HAVE_INAPP_BLE_PAIRING +#define HAVE_BATTERY + +#define HAVE_LEDGER_PKI + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Misc +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define HAVE_LOCAL_APDU_BUFFER +#define HAVE_SEPROXYHAL_MCU +#define HAVE_MCU_PROTECT + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEBUG C SDK +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//#define HAVE_PRINTF +//#define PRINTF mcu_usb_printf \ No newline at end of file diff --git a/ledger_secure_sdk_sys/csdk_stax.h b/ledger_secure_sdk_sys/csdk_stax.h new file mode 100644 index 00000000..bfb3d7fa --- /dev/null +++ b/ledger_secure_sdk_sys/csdk_stax.h @@ -0,0 +1,64 @@ +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.standard_app +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// BLUETOOTH +#define HAVE_BLE +#define HAVE_BLE_APDU +#define BLE_COMMAND_TIMEOUT_MS 2000 +#define BLE_SEGMENT_SIZE 32 +// NFC SUPPORT (feature dependent) +//#define HAVE_NFC +//#define HAVE_NFC_READER +// APP STORAGE (feature dependent) +//#define HAVE_APP_STORAGE +// IO SEPROXY BUFFER SIZE +#define IO_SEPROXYHAL_BUFFER_SIZE_B 300 +// NBGL QRCODE (feature dependent) +#define NBGL_QRCODE +// NBGL KEYBOARD (feature dependent) +//#define NBGL_KEYBOARD +// NBGL KEYPAD (feature dependent) +//#define NBGL_KEYPAD +// STANDARD DEFINES +#define IO_HID_EP_LENGTH 64 +#define HAVE_SPRINTF +#define HAVE_SNPRINTF_FORMAT_U +#define HAVE_IO_USB +#define HAVE_L4_USBLIB +#define IO_USB_MAX_ENDPOINTS 4 +#define HAVE_USB_APDU +#define USB_SEGMENT_SIZE 64 +//#define HAVE_WEBUSB +//#define WEBUSB_URL_SIZE_B +//#define WEBUSB_URL +#define OS_IO_SEPROXYHAL +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Makefile.defines +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define gcc +#define __IO volatile +// Stax +#define HAVE_BAGL_FONT_INTER_REGULAR_24PX +#define HAVE_BAGL_FONT_INTER_SEMIBOLD_24PX +#define HAVE_BAGL_FONT_INTER_MEDIUM_32PX +#define HAVE_INAPP_BLE_PAIRING +#define HAVE_NBGL +#define HAVE_PIEZO_SOUND +#define HAVE_SE_TOUCH +#define HAVE_SE_EINK_DISPLAY +#define NBGL_PAGE +#define NBGL_USE_CASE +#define SCREEN_SIZE_WALLET + +#define HAVE_LEDGER_PKI + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Misc +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#define HAVE_LOCAL_APDU_BUFFER + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// DEBUG C SDK +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//#define HAVE_PRINTF +//#define PRINTF mcu_usb_printf \ No newline at end of file diff --git a/ledger_device_sdk/flex.json b/ledger_secure_sdk_sys/flex.json similarity index 90% rename from ledger_device_sdk/flex.json rename to ledger_secure_sdk_sys/flex.json index af01a46e..e4039ab9 100644 --- a/ledger_device_sdk/flex.json +++ b/ledger_secure_sdk_sys/flex.json @@ -13,11 +13,11 @@ "panic-strategy": "abort", "pre-link-args": { "ld.lld": [ - "-Tstax_flex_layout.ld", + "-Tflex_layout.ld", "-Tlink.ld" ], "ld": [ - "-Tstax_flex_layout.ld", + "-Tflex_layout.ld", "-Tlink.ld" ] }, diff --git a/ledger_device_sdk/nanosplus_layout.ld b/ledger_secure_sdk_sys/flex_layout.ld similarity index 100% rename from ledger_device_sdk/nanosplus_layout.ld rename to ledger_secure_sdk_sys/flex_layout.ld diff --git a/ledger_device_sdk/link.ld b/ledger_secure_sdk_sys/link.ld similarity index 98% rename from ledger_device_sdk/link.ld rename to ledger_secure_sdk_sys/link.ld index 4d5fd241..5736654c 100644 --- a/ledger_device_sdk/link.ld +++ b/ledger_secure_sdk_sys/link.ld @@ -141,6 +141,7 @@ SECTIONS ledger.rust_sdk_name (INFO): { KEEP(*(ledger.rust_sdk_name)) } ledger.sdk_name (INFO): { KEEP(*(ledger.sdk_name)) } ledger.sdk_hash (INFO): { KEEP(*(ledger.sdk_hash)) } + ledger.sdk_graphics (INFO): { KEEP(*(ledger.sdk_graphics)) } } PROVIDE(_nvram = ABSOLUTE(_nvram_start)); diff --git a/ledger_device_sdk/link_wrap.sh b/ledger_secure_sdk_sys/link_wrap.sh similarity index 100% rename from ledger_device_sdk/link_wrap.sh rename to ledger_secure_sdk_sys/link_wrap.sh diff --git a/ledger_device_sdk/nanos.json b/ledger_secure_sdk_sys/nanos.json similarity index 100% rename from ledger_device_sdk/nanos.json rename to ledger_secure_sdk_sys/nanos.json diff --git a/ledger_device_sdk/nanos_layout.ld b/ledger_secure_sdk_sys/nanos_layout.ld similarity index 100% rename from ledger_device_sdk/nanos_layout.ld rename to ledger_secure_sdk_sys/nanos_layout.ld diff --git a/ledger_device_sdk/nanosplus.json b/ledger_secure_sdk_sys/nanosplus.json similarity index 100% rename from ledger_device_sdk/nanosplus.json rename to ledger_secure_sdk_sys/nanosplus.json diff --git a/ledger_device_sdk/stax_flex_layout.ld b/ledger_secure_sdk_sys/nanosplus_layout.ld similarity index 100% rename from ledger_device_sdk/stax_flex_layout.ld rename to ledger_secure_sdk_sys/nanosplus_layout.ld diff --git a/ledger_device_sdk/nanox.json b/ledger_secure_sdk_sys/nanox.json similarity index 100% rename from ledger_device_sdk/nanox.json rename to ledger_secure_sdk_sys/nanox.json diff --git a/ledger_device_sdk/nanox_layout.ld b/ledger_secure_sdk_sys/nanox_layout.ld similarity index 100% rename from ledger_device_sdk/nanox_layout.ld rename to ledger_secure_sdk_sys/nanox_layout.ld diff --git a/ledger_secure_sdk_sys/sdk_flex.h b/ledger_secure_sdk_sys/sdk_flex.h deleted file mode 100644 index b3350ab9..00000000 --- a/ledger_secure_sdk_sys/sdk_flex.h +++ /dev/null @@ -1,33 +0,0 @@ -#define HAVE_SPRINTF -#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 300 -#define main _start - -#define NBGL_QRCODE - -// from Makefile.defines -#define HAVE_BAGL_FONT_INTER_REGULAR_28PX -#define HAVE_BAGL_FONT_INTER_SEMIBOLD_28PX -#define HAVE_BAGL_FONT_INTER_MEDIUM_36PX -#define HAVE_INAPP_BLE_PAIRING -#define HAVE_NBGL -#define HAVE_PIEZO_SOUND -#define HAVE_SE_TOUCH -#define HAVE_SE_EINK_DISPLAY -#define NBGL_PAGE -#define NBGL_USE_CASE -#define SCREEN_SIZE_WALLET -#define HAVE_FAST_HOLD_TO_APPROVE - -#define HAVE_BLE -#define HAVE_BLE_APDU -#define BLE_COMMAND_TIMEOUT_MS 2000 -#define BLE_SEGMENT_SIZE 32 \ No newline at end of file diff --git a/ledger_secure_sdk_sys/sdk_nanosp.h b/ledger_secure_sdk_sys/sdk_nanosp.h deleted file mode 100644 index ce099221..00000000 --- a/ledger_secure_sdk_sys/sdk_nanosp.h +++ /dev/null @@ -1,19 +0,0 @@ -#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_nanox.h b/ledger_secure_sdk_sys/sdk_nanox.h deleted file mode 100644 index aa4c956a..00000000 --- a/ledger_secure_sdk_sys/sdk_nanox.h +++ /dev/null @@ -1,22 +0,0 @@ -#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 - -#define HAVE_BLE -#define HAVE_BLE_APDU \ No newline at end of file diff --git a/ledger_secure_sdk_sys/sdk_stax.h b/ledger_secure_sdk_sys/sdk_stax.h deleted file mode 100644 index ace4a4b5..00000000 --- a/ledger_secure_sdk_sys/sdk_stax.h +++ /dev/null @@ -1,32 +0,0 @@ -#define HAVE_SPRINTF -#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 300 -#define main _start - -#define NBGL_QRCODE - -// from Makefile.defines -#define HAVE_BAGL_FONT_INTER_REGULAR_24PX -#define HAVE_BAGL_FONT_INTER_SEMIBOLD_24PX -#define HAVE_BAGL_FONT_INTER_MEDIUM_32PX -#define HAVE_INAPP_BLE_PAIRING -#define HAVE_NBGL -#define HAVE_PIEZO_SOUND -#define HAVE_SE_TOUCH -#define HAVE_SE_EINK_DISPLAY -#define NBGL_PAGE -#define NBGL_USE_CASE -#define SCREEN_SIZE_WALLET - -#define HAVE_BLE -#define HAVE_BLE_APDU -#define BLE_COMMAND_TIMEOUT_MS 2000 -#define BLE_SEGMENT_SIZE 32 \ No newline at end of file diff --git a/ledger_secure_sdk_sys/src/c/src.c b/ledger_secure_sdk_sys/src/c/src.c index 74cbadab..cef9464b 100644 --- a/ledger_secure_sdk_sys/src/c/src.c +++ b/ledger_secure_sdk_sys/src/c/src.c @@ -253,11 +253,6 @@ void link_pass_nvram( nvm_write(nvram_prev_val_ptr, &nvram_current, sizeof(void*)); } -#ifdef HAVE_CCID - #include "usbd_ccid_if.h" -uint8_t G_io_apdu_buffer[260]; -#endif - void c_reset_bss() { size_t bss_len; SYMBOL_ABSOLUTE_VALUE(bss_len, _bss_len); @@ -312,9 +307,6 @@ void c_boot_std() { USB_power(0); USB_power(1); -#ifdef HAVE_CCID - io_usb_ccid_set_card_inserted(1); -#endif #ifdef HAVE_BLE memset(&G_io_asynch_ux_callback, 0, sizeof(G_io_asynch_ux_callback)); @@ -377,4 +369,16 @@ int c_main(int arg0) { END_TRY; } return 0; -} \ No newline at end of file +} + +#ifdef HAVE_PRINTF +void mcu_usb_prints(const char *str, unsigned int charcount) +{ + unsigned char buf[4]; + buf[0] = SEPROXYHAL_TAG_PRINTF; + buf[1] = charcount >> 8; + buf[2] = charcount; + io_seproxyhal_spi_send(buf, 3); + io_seproxyhal_spi_send((const uint8_t *) str, charcount); +} +#endif \ No newline at end of file diff --git a/ledger_secure_sdk_sys/src/infos.rs b/ledger_secure_sdk_sys/src/infos.rs index 70013478..f0550a9b 100644 --- a/ledger_secure_sdk_sys/src/infos.rs +++ b/ledger_secure_sdk_sys/src/infos.rs @@ -59,3 +59,8 @@ const_cstr!( "ledger.sdk_version", env!("C_SDK_VERSION") ); +const_cstr!( + ELF_C_SDK_GRAPHICS, + "ledger.sdk_graphics", + env!("C_SDK_GRAPHICS") +); diff --git a/ledger_device_sdk/stax.json b/ledger_secure_sdk_sys/stax.json similarity index 90% rename from ledger_device_sdk/stax.json rename to ledger_secure_sdk_sys/stax.json index c39cd3d0..035c1e11 100644 --- a/ledger_device_sdk/stax.json +++ b/ledger_secure_sdk_sys/stax.json @@ -13,11 +13,11 @@ "panic-strategy": "abort", "pre-link-args": { "ld.lld": [ - "-Tstax_flex_layout.ld", + "-Tstax_layout.ld", "-Tlink.ld" ], "ld": [ - "-Tstax_flex_layout.ld", + "-Tstax_layout.ld", "-Tlink.ld" ] }, diff --git a/ledger_secure_sdk_sys/stax_layout.ld b/ledger_secure_sdk_sys/stax_layout.ld new file mode 100644 index 00000000..9418ef65 --- /dev/null +++ b/ledger_secure_sdk_sys/stax_layout.ld @@ -0,0 +1,10 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0xc0de0000, LENGTH = 400K + DATA (r) : ORIGIN = 0xc0de0000, LENGTH = 400K + SRAM (rwx) : ORIGIN = 0xda7a0000, LENGTH = 44K +} + +PAGE_SIZE = 512; +STACK_SIZE = 1500; +END_STACK = ORIGIN(SRAM) + LENGTH(SRAM); \ No newline at end of file