blob: 3d2f3eaf460ad2959f3bb6965c85b0faf94b02fb [file] [log] [blame]
David Brownde7729e2017-01-09 10:41:35 -07001/// Interface wrappers to C API entering to the bootloader
2
David Brown65de6d12019-01-02 11:38:38 -07003use crate::area::AreaDesc;
David Brown76101572019-02-28 11:29:03 -07004use simflash::SimMultiFlash;
David Brownde7729e2017-01-09 10:41:35 -07005use libc;
David Brown65de6d12019-01-02 11:38:38 -07006use crate::api;
David Brownde7729e2017-01-09 10:41:35 -07007
8/// Invoke the bootloader on this flash device.
David Brown76101572019-02-28 11:29:03 -07009pub fn boot_go(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc,
Fabio Utzigafb2bc92018-11-19 16:11:52 -020010 counter: Option<&mut i32>, catch_asserts: bool) -> (i32, u8) {
David Brownee61c832017-11-06 11:13:25 -070011 unsafe {
David Brown76101572019-02-28 11:29:03 -070012 for (&dev_id, flash) in multiflash.iter_mut() {
Fabio Utzigafb2bc92018-11-19 16:11:52 -020013 api::set_flash(dev_id, flash);
14 }
Fabio Utzig8000e322019-08-05 08:14:32 -030015 }
16 let mut sim_ctx = api::CSimContext {
17 flash_counter: match counter {
David Brownee61c832017-11-06 11:13:25 -070018 None => 0,
19 Some(ref c) => **c as libc::c_int
Fabio Utzig8000e322019-08-05 08:14:32 -030020 },
21 jumped: 0,
22 c_asserts: 0,
23 c_catch_asserts: if catch_asserts { 1 } else { 0 },
24 boot_jmpbuf: [0; 16],
25 };
26 let result = unsafe {
27 raw::invoke_boot_go(&mut sim_ctx as *mut _, &areadesc.get_c() as *const _) as i32
28 };
29 let asserts = sim_ctx.c_asserts;
30 counter.map(|c| *c = sim_ctx.flash_counter);
David Brownee61c832017-11-06 11:13:25 -070031 unsafe {
David Brown76101572019-02-28 11:29:03 -070032 for (&dev_id, _) in multiflash {
Fabio Utzigafb2bc92018-11-19 16:11:52 -020033 api::clear_flash(dev_id);
34 }
David Brownee61c832017-11-06 11:13:25 -070035 };
Fabio Utzig9b0ee902017-11-23 19:49:00 -020036 (result, asserts)
David Brownde7729e2017-01-09 10:41:35 -070037}
38
David Brown541860c2017-11-06 11:25:42 -070039pub fn boot_trailer_sz(align: u8) -> u32 {
Christopher Collins2adef702019-05-22 14:37:31 -070040 unsafe { raw::boot_trailer_sz(align) }
David Brownde7729e2017-01-09 10:41:35 -070041}
42
Fabio Utziga0bc9b52017-06-28 09:19:55 -030043pub fn boot_magic_sz() -> usize {
44 unsafe { raw::BOOT_MAGIC_SZ as usize }
45}
46
47pub fn boot_max_align() -> usize {
David Browne0bb1f92019-10-01 15:57:01 -060048 unsafe { raw::boot_max_align() as usize }
Fabio Utziga0bc9b52017-06-28 09:19:55 -030049}
50
Fabio Utzig1e48b912018-09-18 09:04:18 -030051pub fn rsa_oaep_encrypt(pubkey: &[u8], seckey: &[u8]) -> Result<[u8; 256], &'static str> {
52 unsafe {
53 let mut encbuf: [u8; 256] = [0; 256];
54 if raw::rsa_oaep_encrypt_(pubkey.as_ptr(), pubkey.len() as u32,
55 seckey.as_ptr(), seckey.len() as u32,
56 encbuf.as_mut_ptr()) == 0 {
57 return Ok(encbuf);
58 }
59 return Err("Failed to encrypt buffer");
60 }
61}
62
63pub fn kw_encrypt(kek: &[u8], seckey: &[u8]) -> Result<[u8; 24], &'static str> {
64 unsafe {
65 let mut encbuf = [0u8; 24];
66 if raw::kw_encrypt_(kek.as_ptr(), seckey.as_ptr(), encbuf.as_mut_ptr()) == 0 {
67 return Ok(encbuf);
68 }
69 return Err("Failed to encrypt buffer");
70 }
71}
72
David Brownde7729e2017-01-09 10:41:35 -070073mod raw {
David Brown65de6d12019-01-02 11:38:38 -070074 use crate::area::CAreaDesc;
Fabio Utzig8000e322019-08-05 08:14:32 -030075 use crate::api::CSimContext;
David Brownde7729e2017-01-09 10:41:35 -070076 use libc;
77
78 extern "C" {
79 // This generates a warning about `CAreaDesc` not being foreign safe. There doesn't appear to
80 // be any way to get rid of this warning. See https://github.com/rust-lang/rust/issues/34798
81 // for information and tracking.
Fabio Utzig8000e322019-08-05 08:14:32 -030082 pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc) -> libc::c_int;
David Brownde7729e2017-01-09 10:41:35 -070083
Christopher Collins2adef702019-05-22 14:37:31 -070084 pub fn boot_trailer_sz(min_write_sz: u8) -> u32;
Fabio Utziga0bc9b52017-06-28 09:19:55 -030085
86 pub static BOOT_MAGIC_SZ: u32;
David Browne0bb1f92019-10-01 15:57:01 -060087 pub fn boot_max_align() -> u32;
Fabio Utzig92be3fb2017-12-05 08:52:53 -020088
Fabio Utzig1e48b912018-09-18 09:04:18 -030089 pub fn rsa_oaep_encrypt_(pubkey: *const u8, pubkey_len: libc::c_uint,
90 seckey: *const u8, seckey_len: libc::c_uint,
91 encbuf: *mut u8) -> libc::c_int;
92
93 pub fn kw_encrypt_(kek: *const u8, seckey: *const u8,
94 encbuf: *mut u8) -> libc::c_int;
David Brownde7729e2017-01-09 10:41:35 -070095 }
96}