Update src/ to the new libtock.

This commit is contained in:
Guillaume Endignoux
2020-07-10 10:39:28 +02:00
parent b30b88156a
commit 3c5e0c9cf1
6 changed files with 79 additions and 66 deletions

View File

@@ -10,7 +10,9 @@ license = "Apache-2.0"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
libtock = { path = "third_party/libtock-rs" } libtock_core = { path = "third_party/libtock-rs/core" }
libtock_drivers = { path = "third_party/libtock-drivers" }
lang_items = { path = "third_party/lang-items" }
cbor = { path = "libraries/cbor" } cbor = { path = "libraries/cbor" }
crypto = { path = "libraries/crypto" } crypto = { path = "libraries/crypto" }
byteorder = { version = "1", default-features = false } byteorder = { version = "1", default-features = false }
@@ -18,12 +20,12 @@ arrayref = "0.3.6"
subtle = { version = "2.2", default-features = false, features = ["nightly"] } subtle = { version = "2.2", default-features = false, features = ["nightly"] }
[features] [features]
debug_allocations = ["libtock/debug_allocations"] debug_allocations = ["lang_items/debug_allocations"]
debug_ctap = ["crypto/derive_debug"] debug_ctap = ["crypto/derive_debug", "libtock_drivers/debug_ctap"]
panic_console = ["libtock/panic_console"] panic_console = ["lang_items/panic_console"]
std = ["cbor/std", "crypto/std", "crypto/derive_debug"] std = ["cbor/std", "crypto/std", "crypto/derive_debug", "lang_items/std"]
ram_storage = [] ram_storage = []
verbose = ["debug_ctap"] verbose = ["debug_ctap", "libtock_drivers/verbose_usb"]
with_ctap1 = ["crypto/with_ctap1"] with_ctap1 = ["crypto/with_ctap1"]
with_ctap2_1 = [] with_ctap2_1 = []

View File

@@ -28,7 +28,7 @@ use alloc::vec::Vec;
use core::fmt::Write; use core::fmt::Write;
use crypto::rng256::Rng256; use crypto::rng256::Rng256;
#[cfg(feature = "debug_ctap")] #[cfg(feature = "debug_ctap")]
use libtock::console::Console; use libtock_drivers::console::Console;
// CTAP specification (version 20190130) section 8.1 // CTAP specification (version 20190130) section 8.1
// TODO: Channel allocation, section 8.1.3? // TODO: Channel allocation, section 8.1.3?

View File

@@ -59,8 +59,8 @@ use crypto::rng256::Rng256;
use crypto::sha256::Sha256; use crypto::sha256::Sha256;
use crypto::Hash256; use crypto::Hash256;
#[cfg(feature = "debug_ctap")] #[cfg(feature = "debug_ctap")]
use libtock::console::Console; use libtock_drivers::console::Console;
use libtock::timer::{Duration, Timestamp}; use libtock_drivers::timer::{Duration, Timestamp};
use subtle::ConstantTimeEq; use subtle::ConstantTimeEq;
// This flag enables or disables basic attestation for FIDO2. U2F is unaffected by // This flag enables or disables basic attestation for FIDO2. U2F is unaffected by

View File

@@ -14,7 +14,7 @@
use super::{Index, Storage, StorageError, StorageResult}; use super::{Index, Storage, StorageError, StorageResult};
use alloc::vec::Vec; use alloc::vec::Vec;
use libtock::syscalls; use libtock_core::syscalls;
const DRIVER_NUMBER: usize = 0x50003; const DRIVER_NUMBER: usize = 0x50003;
@@ -41,16 +41,14 @@ mod memop_nr {
} }
fn get_info(nr: usize, arg: usize) -> StorageResult<usize> { fn get_info(nr: usize, arg: usize) -> StorageResult<usize> {
let code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::GET_INFO, nr, arg) }; let code = syscalls::command(DRIVER_NUMBER, command_nr::GET_INFO, nr, arg);
if code < 0 { code.map_err(|e| StorageError::KernelError {
Err(StorageError::KernelError { code }) code: e.return_code,
} else { })
Ok(code as usize)
}
} }
fn memop(nr: u32, arg: usize) -> StorageResult<usize> { fn memop(nr: u32, arg: usize) -> StorageResult<usize> {
let code = unsafe { syscalls::memop(nr, arg) }; let code = unsafe { syscalls::raw::memop(nr, arg) };
if code < 0 { if code < 0 {
Err(StorageError::KernelError { code }) Err(StorageError::KernelError { code })
} else { } else {
@@ -153,8 +151,9 @@ impl Storage for SyscallStorage {
return Err(StorageError::NotAligned); return Err(StorageError::NotAligned);
} }
let ptr = self.read_slice(index, value.len())?.as_ptr() as usize; let ptr = self.read_slice(index, value.len())?.as_ptr() as usize;
let code = unsafe { let code = unsafe {
syscalls::allow_ptr( syscalls::raw::allow(
DRIVER_NUMBER, DRIVER_NUMBER,
allow_nr::WRITE_SLICE, allow_nr::WRITE_SLICE,
// We rely on the driver not writing to the slice. This should use read-only allow // We rely on the driver not writing to the slice. This should use read-only allow
@@ -166,11 +165,14 @@ impl Storage for SyscallStorage {
if code < 0 { if code < 0 {
return Err(StorageError::KernelError { code }); return Err(StorageError::KernelError { code });
} }
let code =
unsafe { syscalls::command(DRIVER_NUMBER, command_nr::WRITE_SLICE, ptr, value.len()) }; let code = syscalls::command(DRIVER_NUMBER, command_nr::WRITE_SLICE, ptr, value.len());
if code < 0 { if let Err(e) = code {
return Err(StorageError::KernelError { code }); return Err(StorageError::KernelError {
code: e.return_code,
});
} }
Ok(()) Ok(())
} }
@@ -178,9 +180,11 @@ impl Storage for SyscallStorage {
let index = Index { page, byte: 0 }; let index = Index { page, byte: 0 };
let length = self.page_size(); let length = self.page_size();
let ptr = self.read_slice(index, length)?.as_ptr() as usize; let ptr = self.read_slice(index, length)?.as_ptr() as usize;
let code = unsafe { syscalls::command(DRIVER_NUMBER, command_nr::ERASE_PAGE, ptr, length) }; let code = syscalls::command(DRIVER_NUMBER, command_nr::ERASE_PAGE, ptr, length);
if code < 0 { if let Err(e) = code {
return Err(StorageError::KernelError { code }); return Err(StorageError::KernelError {
code: e.return_code,
});
} }
Ok(()) Ok(())
} }

View File

@@ -16,6 +16,8 @@
#[macro_use] #[macro_use]
extern crate alloc; extern crate alloc;
extern crate libtock; extern crate lang_items;
extern crate libtock_core;
extern crate libtock_drivers;
pub mod embedded_flash; pub mod embedded_flash;

View File

@@ -22,14 +22,12 @@ extern crate byteorder;
#[cfg(feature = "std")] #[cfg(feature = "std")]
extern crate core; extern crate core;
extern crate ctap2; extern crate ctap2;
extern crate libtock;
extern crate subtle; extern crate subtle;
#[macro_use] #[macro_use]
extern crate cbor; extern crate cbor;
extern crate crypto; extern crate crypto;
mod ctap; mod ctap;
mod usb_ctap_hid;
use core::cell::Cell; use core::cell::Cell;
#[cfg(feature = "debug_ctap")] #[cfg(feature = "debug_ctap")]
@@ -38,17 +36,18 @@ use crypto::rng256::TockRng256;
use ctap::hid::{ChannelID, CtapHid, KeepaliveStatus, ProcessedPacket}; use ctap::hid::{ChannelID, CtapHid, KeepaliveStatus, ProcessedPacket};
use ctap::status_code::Ctap2StatusCode; use ctap::status_code::Ctap2StatusCode;
use ctap::CtapState; use ctap::CtapState;
use libtock::buttons; use libtock_core::result::{CommandError, EALREADY};
use libtock::buttons::ButtonState; use libtock_drivers::buttons;
use libtock_drivers::buttons::ButtonState;
#[cfg(feature = "debug_ctap")] #[cfg(feature = "debug_ctap")]
use libtock::console::Console; use libtock_drivers::console::Console;
use libtock::led; use libtock_drivers::led;
use libtock::result::TockValue; use libtock_drivers::result::{FlexUnwrap, TockError};
use libtock::syscalls; use libtock_drivers::timer;
use libtock::timer;
#[cfg(feature = "debug_ctap")] #[cfg(feature = "debug_ctap")]
use libtock::timer::Timer; use libtock_drivers::timer::Timer;
use libtock::timer::{Duration, StopAlarmError, Timestamp}; use libtock_drivers::timer::{Duration, Timestamp};
use libtock_drivers::usb_ctap_hid;
const KEEPALIVE_DELAY_MS: isize = 100; const KEEPALIVE_DELAY_MS: isize = 100;
const KEEPALIVE_DELAY: Duration<isize> = Duration::from_ms(KEEPALIVE_DELAY_MS); const KEEPALIVE_DELAY: Duration<isize> = Duration::from_ms(KEEPALIVE_DELAY_MS);
@@ -58,7 +57,7 @@ fn main() {
// Setup the timer with a dummy callback (we only care about reading the current time, but the // Setup the timer with a dummy callback (we only care about reading the current time, but the
// API forces us to set an alarm callback too). // API forces us to set an alarm callback too).
let mut with_callback = timer::with_callback(|_, _| {}); let mut with_callback = timer::with_callback(|_, _| {});
let timer = with_callback.init().unwrap(); let timer = with_callback.init().flex_unwrap();
// Setup USB driver. // Setup USB driver.
if !usb_ctap_hid::setup() { if !usb_ctap_hid::setup() {
@@ -70,7 +69,7 @@ fn main() {
let mut ctap_hid = CtapHid::new(); let mut ctap_hid = CtapHid::new();
let mut led_counter = 0; let mut led_counter = 0;
let mut last_led_increment = timer.get_current_clock(); let mut last_led_increment = timer.get_current_clock().flex_unwrap();
// Main loop. If CTAP1 is used, we register button presses for U2F while receiving and waiting. // Main loop. If CTAP1 is used, we register button presses for U2F while receiving and waiting.
// The way TockOS and apps currently interact, callbacks need a yield syscall to execute, // The way TockOS and apps currently interact, callbacks need a yield syscall to execute,
@@ -87,11 +86,11 @@ fn main() {
}; };
}); });
#[cfg(feature = "with_ctap1")] #[cfg(feature = "with_ctap1")]
let mut buttons = buttons_callback.init().unwrap(); let mut buttons = buttons_callback.init().flex_unwrap();
#[cfg(feature = "with_ctap1")] #[cfg(feature = "with_ctap1")]
// At the moment, all buttons are accepted. You can customize your setup here. // At the moment, all buttons are accepted. You can customize your setup here.
for mut button in &mut buttons { for mut button in &mut buttons {
button.enable().unwrap(); button.enable().flex_unwrap();
} }
let mut pkt_request = [0; 64]; let mut pkt_request = [0; 64];
@@ -105,7 +104,7 @@ fn main() {
None => false, None => false,
}; };
let now = timer.get_current_clock(); let now = timer.get_current_clock().flex_unwrap();
#[cfg(feature = "with_ctap1")] #[cfg(feature = "with_ctap1")]
{ {
if button_touched.get() { if button_touched.get() {
@@ -115,7 +114,7 @@ fn main() {
// Heavy computation mostly follows a registered touch luckily. Unregistering // Heavy computation mostly follows a registered touch luckily. Unregistering
// callbacks is important to not clash with those from check_user_presence. // callbacks is important to not clash with those from check_user_presence.
for mut button in &mut buttons { for mut button in &mut buttons {
button.disable().unwrap(); button.disable().flex_unwrap();
} }
drop(buttons); drop(buttons);
drop(buttons_callback); drop(buttons_callback);
@@ -153,7 +152,7 @@ fn main() {
} }
} }
let now = timer.get_current_clock(); let now = timer.get_current_clock().flex_unwrap();
if let Some(wait_duration) = now.wrapping_sub(last_led_increment) { if let Some(wait_duration) = now.wrapping_sub(last_led_increment) {
if wait_duration > KEEPALIVE_DELAY { if wait_duration > KEEPALIVE_DELAY {
// Loops quickly when waiting for U2F user presence, so the next LED blink // Loops quickly when waiting for U2F user presence, so the next LED blink
@@ -188,8 +187,8 @@ fn main() {
#[cfg(feature = "debug_ctap")] #[cfg(feature = "debug_ctap")]
fn print_packet_notice(notice_text: &str, timer: &Timer) { fn print_packet_notice(notice_text: &str, timer: &Timer) {
let now_us = let now = timer.get_current_clock().flex_unwrap();
(Timestamp::<f64>::from_clock_value(timer.get_current_clock()).ms() * 1000.0) as u64; let now_us = (Timestamp::<f64>::from_clock_value(now).ms() * 1000.0) as u64;
writeln!( writeln!(
Console::new(), Console::new(),
"{} at {}.{:06} s", "{} at {}.{:06} s",
@@ -264,17 +263,17 @@ fn send_keepalive_up_needed(
Ok(()) Ok(())
} }
fn blink_leds(pattern_seed: isize) { fn blink_leds(pattern_seed: usize) {
for l in 0..led::count() { for l in 0..led::count().flex_unwrap() {
if (pattern_seed ^ l).count_ones() & 1 != 0 { if (pattern_seed ^ l).count_ones() & 1 != 0 {
led::get(l).unwrap().on(); led::get(l).flex_unwrap().on().flex_unwrap();
} else { } else {
led::get(l).unwrap().off(); led::get(l).flex_unwrap().off().flex_unwrap();
} }
} }
} }
fn wink_leds(pattern_seed: isize) { fn wink_leds(pattern_seed: usize) {
// This generates a "snake" pattern circling through the LEDs. // This generates a "snake" pattern circling through the LEDs.
// Fox example with 4 LEDs the sequence of lit LEDs will be the following. // Fox example with 4 LEDs the sequence of lit LEDs will be the following.
// 0 1 2 3 // 0 1 2 3
@@ -287,7 +286,7 @@ fn wink_leds(pattern_seed: isize) {
// * * // * *
// * * * // * * *
// * * // * *
let count = led::count(); let count = led::count().flex_unwrap();
let a = (pattern_seed / 2) % count; let a = (pattern_seed / 2) % count;
let b = ((pattern_seed + 1) / 2) % count; let b = ((pattern_seed + 1) / 2) % count;
let c = ((pattern_seed + 3) / 2) % count; let c = ((pattern_seed + 3) / 2) % count;
@@ -300,22 +299,22 @@ fn wink_leds(pattern_seed: isize) {
_ => l, _ => l,
}; };
if k == a || k == b || k == c { if k == a || k == b || k == c {
led::get(l).unwrap().on(); led::get(l).flex_unwrap().on().flex_unwrap();
} else { } else {
led::get(l).unwrap().off(); led::get(l).flex_unwrap().off().flex_unwrap();
} }
} }
} }
fn switch_off_leds() { fn switch_off_leds() {
for l in 0..led::count() { for l in 0..led::count().flex_unwrap() {
led::get(l).unwrap().off(); led::get(l).flex_unwrap().off().flex_unwrap();
} }
} }
fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> { fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> {
// The timeout is N times the keepalive delay. // The timeout is N times the keepalive delay.
const TIMEOUT_ITERATIONS: isize = ctap::TOUCH_TIMEOUT_MS / KEEPALIVE_DELAY_MS; const TIMEOUT_ITERATIONS: usize = ctap::TOUCH_TIMEOUT_MS as usize / KEEPALIVE_DELAY_MS as usize;
// First, send a keep-alive packet to notify that the keep-alive status has changed. // First, send a keep-alive packet to notify that the keep-alive status has changed.
send_keepalive_up_needed(cid, KEEPALIVE_DELAY)?; send_keepalive_up_needed(cid, KEEPALIVE_DELAY)?;
@@ -328,10 +327,10 @@ fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> {
ButtonState::Released => (), ButtonState::Released => (),
}; };
}); });
let mut buttons = buttons_callback.init().unwrap(); let mut buttons = buttons_callback.init().flex_unwrap();
// At the moment, all buttons are accepted. You can customize your setup here. // At the moment, all buttons are accepted. You can customize your setup here.
for mut button in &mut buttons { for mut button in &mut buttons {
button.enable().unwrap(); button.enable().flex_unwrap();
} }
let mut keepalive_response = Ok(()); let mut keepalive_response = Ok(());
@@ -343,19 +342,25 @@ fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> {
let mut keepalive_callback = timer::with_callback(|_, _| { let mut keepalive_callback = timer::with_callback(|_, _| {
keepalive_expired.set(true); keepalive_expired.set(true);
}); });
let mut keepalive = keepalive_callback.init().unwrap(); let mut keepalive = keepalive_callback.init().flex_unwrap();
let keepalive_alarm = keepalive.set_alarm(KEEPALIVE_DELAY).unwrap(); let keepalive_alarm = keepalive.set_alarm(KEEPALIVE_DELAY).flex_unwrap();
// Wait for a button touch or an alarm. // Wait for a button touch or an alarm.
syscalls::yieldk_for(|| button_touched.get() || keepalive_expired.get()); libtock_drivers::util::yieldk_for(|| button_touched.get() || keepalive_expired.get());
// Cleanup alarm callback. // Cleanup alarm callback.
match keepalive.stop_alarm(keepalive_alarm) { match keepalive.stop_alarm(keepalive_alarm) {
Ok(()) => (), Ok(()) => (),
Err(TockValue::Expected(StopAlarmError::AlreadyDisabled)) => { Err(TockError::Command(CommandError {
assert!(keepalive_expired.get()) return_code: EALREADY,
..
})) => assert!(keepalive_expired.get()),
Err(_e) => {
#[cfg(feature = "debug_ctap")]
panic!("Unexpected error when stopping alarm: {:?}", _e);
#[cfg(not(feature = "debug_ctap"))]
panic!("Unexpected error when stopping alarm: <error is only visible with the debug_ctap feature>");
} }
Err(e) => panic!("Unexpected error when stopping alarm: {:?}", e),
} }
// TODO: this may take arbitrary time. The keepalive_delay should be adjusted accordingly, // TODO: this may take arbitrary time. The keepalive_delay should be adjusted accordingly,
@@ -374,7 +379,7 @@ fn check_user_presence(cid: ChannelID) -> Result<(), Ctap2StatusCode> {
// Cleanup button callbacks. // Cleanup button callbacks.
for mut button in &mut buttons { for mut button in &mut buttons {
button.disable().unwrap(); button.disable().flex_unwrap();
} }
// Returns whether the user was present. // Returns whether the user was present.