blob: 5f518f5087fbaa0983d927f1497620a9272200b7 [file] [log] [blame]
David Browne2acfae2020-01-21 16:45:01 -07001// Copyright (c) 2017-2019 Linaro LTD
2// Copyright (c) 2017-2019 JUUL Labs
3// Copyright (c) 2019 Arm Limited
4//
5// SPDX-License-Identifier: Apache-2.0
6
7//! Interface wrappers to C API entering to the bootloader
David Brownde7729e2017-01-09 10:41:35 -07008
David Brown65de6d12019-01-02 11:38:38 -07009use crate::area::AreaDesc;
David Brown76101572019-02-28 11:29:03 -070010use simflash::SimMultiFlash;
David Brown65de6d12019-01-02 11:38:38 -070011use crate::api;
David Brownde7729e2017-01-09 10:41:35 -070012
13/// Invoke the bootloader on this flash device.
David Brown76101572019-02-28 11:29:03 -070014pub fn boot_go(multiflash: &mut SimMultiFlash, areadesc: &AreaDesc,
Fabio Utzigafb2bc92018-11-19 16:11:52 -020015 counter: Option<&mut i32>, catch_asserts: bool) -> (i32, u8) {
David Brown7cc45262021-03-10 05:13:44 -070016 for (&dev_id, flash) in multiflash.iter_mut() {
17 api::set_flash(dev_id, flash);
Fabio Utzig8000e322019-08-05 08:14:32 -030018 }
19 let mut sim_ctx = api::CSimContext {
20 flash_counter: match counter {
David Brownee61c832017-11-06 11:13:25 -070021 None => 0,
22 Some(ref c) => **c as libc::c_int
Fabio Utzig8000e322019-08-05 08:14:32 -030023 },
24 jumped: 0,
25 c_asserts: 0,
26 c_catch_asserts: if catch_asserts { 1 } else { 0 },
27 boot_jmpbuf: [0; 16],
28 };
29 let result = unsafe {
30 raw::invoke_boot_go(&mut sim_ctx as *mut _, &areadesc.get_c() as *const _) as i32
31 };
32 let asserts = sim_ctx.c_asserts;
David Brown8608c532021-03-10 05:18:11 -070033 if let Some(c) = counter {
34 *c = sim_ctx.flash_counter;
35 }
David Brown7cc45262021-03-10 05:13:44 -070036 for &dev_id in multiflash.keys() {
37 api::clear_flash(dev_id);
38 }
Fabio Utzig9b0ee902017-11-23 19:49:00 -020039 (result, asserts)
David Brownde7729e2017-01-09 10:41:35 -070040}
41
Fabio Utzig3fbbdac2019-12-19 15:18:23 -030042pub fn boot_trailer_sz(align: u32) -> u32 {
Christopher Collins2adef702019-05-22 14:37:31 -070043 unsafe { raw::boot_trailer_sz(align) }
David Brownde7729e2017-01-09 10:41:35 -070044}
45
Fabio Utzig3fbbdac2019-12-19 15:18:23 -030046pub fn boot_status_sz(align: u32) -> u32 {
47 unsafe { raw::boot_status_sz(align) }
48}
49
Fabio Utziga0bc9b52017-06-28 09:19:55 -030050pub fn boot_magic_sz() -> usize {
David Brown2b8a6952019-10-01 16:14:53 -060051 unsafe { raw::boot_magic_sz() as usize }
Fabio Utziga0bc9b52017-06-28 09:19:55 -030052}
53
54pub fn boot_max_align() -> usize {
David Browne0bb1f92019-10-01 15:57:01 -060055 unsafe { raw::boot_max_align() as usize }
Fabio Utziga0bc9b52017-06-28 09:19:55 -030056}
57
Fabio Utzig1e48b912018-09-18 09:04:18 -030058pub fn rsa_oaep_encrypt(pubkey: &[u8], seckey: &[u8]) -> Result<[u8; 256], &'static str> {
59 unsafe {
60 let mut encbuf: [u8; 256] = [0; 256];
61 if raw::rsa_oaep_encrypt_(pubkey.as_ptr(), pubkey.len() as u32,
62 seckey.as_ptr(), seckey.len() as u32,
63 encbuf.as_mut_ptr()) == 0 {
64 return Ok(encbuf);
65 }
David Brownc20bbb22021-03-10 05:19:14 -070066 Err("Failed to encrypt buffer")
Fabio Utzig1e48b912018-09-18 09:04:18 -030067 }
68}
69
70pub fn kw_encrypt(kek: &[u8], seckey: &[u8]) -> Result<[u8; 24], &'static str> {
71 unsafe {
72 let mut encbuf = [0u8; 24];
73 if raw::kw_encrypt_(kek.as_ptr(), seckey.as_ptr(), encbuf.as_mut_ptr()) == 0 {
74 return Ok(encbuf);
75 }
David Brownc20bbb22021-03-10 05:19:14 -070076 Err("Failed to encrypt buffer")
Fabio Utzig1e48b912018-09-18 09:04:18 -030077 }
78}
79
David Brownde7729e2017-01-09 10:41:35 -070080mod raw {
David Brown65de6d12019-01-02 11:38:38 -070081 use crate::area::CAreaDesc;
Fabio Utzig8000e322019-08-05 08:14:32 -030082 use crate::api::CSimContext;
David Brownde7729e2017-01-09 10:41:35 -070083
84 extern "C" {
85 // This generates a warning about `CAreaDesc` not being foreign safe. There doesn't appear to
86 // be any way to get rid of this warning. See https://github.com/rust-lang/rust/issues/34798
87 // for information and tracking.
Fabio Utzig8000e322019-08-05 08:14:32 -030088 pub fn invoke_boot_go(sim_ctx: *mut CSimContext, areadesc: *const CAreaDesc) -> libc::c_int;
David Brownde7729e2017-01-09 10:41:35 -070089
Fabio Utzig3fbbdac2019-12-19 15:18:23 -030090 pub fn boot_trailer_sz(min_write_sz: u32) -> u32;
91 pub fn boot_status_sz(min_write_sz: u32) -> u32;
Fabio Utziga0bc9b52017-06-28 09:19:55 -030092
David Brown2b8a6952019-10-01 16:14:53 -060093 pub fn boot_magic_sz() -> u32;
David Browne0bb1f92019-10-01 15:57:01 -060094 pub fn boot_max_align() -> u32;
Fabio Utzig92be3fb2017-12-05 08:52:53 -020095
Fabio Utzig1e48b912018-09-18 09:04:18 -030096 pub fn rsa_oaep_encrypt_(pubkey: *const u8, pubkey_len: libc::c_uint,
97 seckey: *const u8, seckey_len: libc::c_uint,
98 encbuf: *mut u8) -> libc::c_int;
99
100 pub fn kw_encrypt_(kek: *const u8, seckey: *const u8,
101 encbuf: *mut u8) -> libc::c_int;
David Brownde7729e2017-01-09 10:41:35 -0700102 }
103}