Slint handle acceptation
This commit is contained in:
parent
35c017535e
commit
b5535d6f52
|
|
@ -16,6 +16,7 @@ LIBXKBCOMMON_BUILD_DIR = "libxkbcommon/build"
|
|||
SPECTRE_API_BUILD_DIR = "spectre-api/build"
|
||||
SPECTRE_API_SYS_CC = "xtensa-esp32s3-elf-cc.exe"
|
||||
ESP_LOG = "warn"
|
||||
ESP_BACKTRACE_CONFIG_BACKTRACE_FRAMES = "20"
|
||||
# This is overkill, but we can afford it.
|
||||
SLINT_FONT_SIZES = "8,11,10,12,13,14,15,16,18,20,22,24,32"
|
||||
|
||||
|
|
@ -23,8 +24,8 @@ SLINT_FONT_SIZES = "8,11,10,12,13,14,15,16,18,20,22,24,32"
|
|||
# Needed for nightly, until llvm upstream has support for Rust Xtensa.
|
||||
# TODO: RE-ENABLE WHEN acid-firmware IS MOVED TO ITS OWN SUBDIRECTORY.
|
||||
# For now, `-Zbuild-std="core,alloc"` can be used instead.
|
||||
# [unstable]
|
||||
# build-std = ["alloc", "core"]
|
||||
[unstable]
|
||||
build-std = ["alloc", "core"]
|
||||
|
||||
[patch."https://github.com/Limeth/spectre-api-sys"]
|
||||
spectre-api-sys = { path = "../../../rust/spectre-api-sys" }
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ enumset = "1.1.10"
|
|||
printf-compat = { version = "0.2.1", default-features = false }
|
||||
spectre-api-sys = { git = "https://github.com/Limeth/spectre-api-sys" }
|
||||
sha2 = { version = "0.10.9", default-features = false }
|
||||
password-hash = { path = "password-hash" }
|
||||
password-hash = { path = "password-hash", default-features = false }
|
||||
|
||||
# Crates for serial UART CLI
|
||||
embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
fn main() {
|
||||
#[cfg(feature = "cmd")]
|
||||
{
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
fn main() {
|
||||
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
|
|
@ -25,3 +27,4 @@ fn main() {
|
|||
libsodium_install_dir.join("lib/libsodium.a").display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ fn main() {
|
|||
SpectreAlgorithm::Current,
|
||||
)
|
||||
};
|
||||
let encryption_key = derive_encryption_key(username.as_bytes(), secret.as_bytes(), Global);
|
||||
let salt = username.as_bytes(); // TODO: Derive the same salt that spectre passes to scrypt.
|
||||
let encryption_key = derive_encryption_key(salt, secret.as_bytes(), Global);
|
||||
let mut encrypted_user_key = encryption_key;
|
||||
|
||||
assert_eq!(encrypted_user_key.len(), user_key.bytes.len());
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
extern crate alloc;
|
||||
|
||||
use alloc::alloc::Allocator;
|
||||
use alloc::vec::Vec;
|
||||
use argon2::{Algorithm, Argon2, ParamsBuilder, Version};
|
||||
|
||||
use crate::blocks::Argon2Blocks;
|
||||
|
|
@ -28,7 +29,11 @@ pub const ARGON2_T_COST: u32 =
|
|||
pub const ARGON2_P_COST: u32 = argon2::Params::DEFAULT_P_COST;
|
||||
pub const ARGON2_SALT_PREFIX: &[u8] = b"acid-firmware\0";
|
||||
|
||||
pub fn derive_encryption_key(username: &[u8], secret: &[u8], allocator: impl Allocator) -> Key {
|
||||
pub fn derive_encryption_key(
|
||||
unprefixed_salt: &[u8],
|
||||
secret: &[u8],
|
||||
allocator: impl Allocator,
|
||||
) -> Key {
|
||||
let argon2 = Argon2::new(
|
||||
Algorithm::Argon2id,
|
||||
Version::default(),
|
||||
|
|
@ -41,10 +46,11 @@ pub fn derive_encryption_key(username: &[u8], secret: &[u8], allocator: impl All
|
|||
);
|
||||
let mut blocks = Argon2Blocks::new_in(ARGON2_M_COST as usize, &allocator).unwrap();
|
||||
let mut key: Key = [0u8; _];
|
||||
// Username is prefixed to form a salt that is long enough for Argon2.
|
||||
let mut salt = Vec::with_capacity_in(username.len() + ARGON2_SALT_PREFIX.len(), &allocator);
|
||||
// Salt is prefixed to form a salt that is long enough for Argon2.
|
||||
let mut salt =
|
||||
Vec::with_capacity_in(unprefixed_salt.len() + ARGON2_SALT_PREFIX.len(), &allocator);
|
||||
salt.extend_from_slice(ARGON2_SALT_PREFIX);
|
||||
salt.extend_from_slice(username);
|
||||
salt.extend_from_slice(unprefixed_salt);
|
||||
argon2
|
||||
.hash_password_into_with_memory(secret, &salt, &mut key, &mut blocks)
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ use sha2::{
|
|||
Digest, Sha256,
|
||||
digest::{consts::U32, generic_array::GenericArray},
|
||||
};
|
||||
use spectre_api_sys::{SpectreKeyPurpose, spectre_purpose_scope};
|
||||
|
||||
use crate::PSRAM_ALLOCATOR;
|
||||
|
||||
// Just a way to mark non-null pointers.
|
||||
// Rust's `NonNull` is for mutable pointers only.
|
||||
|
|
@ -43,20 +46,20 @@ unsafe extern "C" fn __spre_crypto_pwhash_scryptsalsa208sha256_ll(
|
|||
let password: &[u8] = core::slice::from_raw_parts(password, password_len);
|
||||
let salt: &[u8] = core::slice::from_raw_parts(salt, salt_len);
|
||||
let output: &mut [u8] = core::slice::from_raw_parts_mut(output, output_len);
|
||||
let log_n = n.ilog2() as u8;
|
||||
|
||||
if n != 1 << log_n {
|
||||
return -1;
|
||||
let purpose = spectre_purpose_scope(SpectreKeyPurpose::Authentication);
|
||||
let result = password_hash::derive_encryption_key(salt, password, &PSRAM_ALLOCATOR);
|
||||
|
||||
assert_eq!(
|
||||
output.len(),
|
||||
result.len(),
|
||||
"Derived invalid encryption key."
|
||||
);
|
||||
|
||||
output.copy_from_slice(&result);
|
||||
}
|
||||
|
||||
// TODO: Store encrypted password and decrypt it using argon2
|
||||
// let params = scrypt::Params::new(log_n, r, p).unwrap();
|
||||
// match scrypt::scrypt_in(password, salt, ¶ms, output, &PSRAM_ALLOCATOR) {
|
||||
// Ok(()) => 0,
|
||||
// Err(_) => -1,
|
||||
// }
|
||||
todo!()
|
||||
}
|
||||
0
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ use core::sync::atomic::{AtomicBool, Ordering};
|
|||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::vec;
|
||||
use argon2::{Algorithm, Argon2};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
|
||||
use embassy_sync::channel::Channel;
|
||||
|
|
@ -62,7 +61,6 @@ use spectre_api_sys::SpectreAlgorithm;
|
|||
use static_cell::StaticCell;
|
||||
use {esp_alloc as _, esp_backtrace as _};
|
||||
|
||||
use crate::crypto::Argon2Blocks;
|
||||
use crate::keymap::create_hid_report_interceptor;
|
||||
use crate::logging::LOG_LEVEL_FILTER;
|
||||
use crate::matrix::IoeMatrix;
|
||||
|
|
@ -384,21 +382,6 @@ async fn main(_spawner: Spawner) {
|
|||
|
||||
let mut user_controller = UserController::new();
|
||||
|
||||
warn!("Yeet");
|
||||
|
||||
let key = password_hash::hash(&PSRAM_ALLOCATOR);
|
||||
|
||||
warn!("Argon2 passed. Key = {key:02x?}");
|
||||
|
||||
unsafe {
|
||||
let user_key = &*spectre_api_sys::spectre_user_key(
|
||||
c"Jakub Hlusička".as_ptr(),
|
||||
c"test".as_ptr(),
|
||||
SpectreAlgorithm::Current,
|
||||
);
|
||||
warn!("{user_key:?}");
|
||||
}
|
||||
|
||||
info!("Awaiting on all tasks...");
|
||||
|
||||
// TODO: Probably want to select! instead and re-try.
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
// #![cfg_attr(not(feature = "simulator"), no_main)]
|
||||
|
||||
use alloc::boxed::Box;
|
||||
use alloc::{boxed::Box, ffi::CString};
|
||||
use log::{info, warn};
|
||||
use slint::SharedString;
|
||||
use spectre_api_sys::{SpectreAlgorithm, SpectreCounter, SpectreKeyPurpose, SpectreUserKey};
|
||||
|
||||
#[cfg(feature = "limit-fps")]
|
||||
use crate::FRAME_DURATION_MIN;
|
||||
use crate::{
|
||||
SIGNAL_LCD_SUBMIT, SIGNAL_UI_RENDER, ui::backend::SlintBackend,
|
||||
};
|
||||
use crate::{SIGNAL_LCD_SUBMIT, SIGNAL_UI_RENDER, ui::backend::SlintBackend};
|
||||
|
||||
pub mod backend;
|
||||
pub mod window_adapter;
|
||||
|
|
@ -19,6 +20,33 @@ pub async fn run_renderer_task(backend: SlintBackend) {
|
|||
|
||||
let main = AppWindow::new().unwrap();
|
||||
|
||||
let mut buffer = CString::default();
|
||||
main.on_accepted(|string| {
|
||||
warn!("Accepted: {string}");
|
||||
let Ok(c_string) = CString::new(&*string) else {
|
||||
warn!("String cannot be converted to a C string: {string:?}");
|
||||
return;
|
||||
};
|
||||
unsafe {
|
||||
let user_key = &*spectre_api_sys::spectre_user_key(
|
||||
c"test".as_ptr(),
|
||||
c_string.as_ptr(),
|
||||
SpectreAlgorithm::Current,
|
||||
);
|
||||
warn!("{user_key:?}");
|
||||
let site_key = &*spectre_api_sys::spectre_site_key(
|
||||
user_key as *const SpectreUserKey,
|
||||
c"example.org".as_ptr(),
|
||||
SpectreCounter::Initial,
|
||||
SpectreKeyPurpose::Authentication,
|
||||
c"".as_ptr(),
|
||||
);
|
||||
warn!("{site_key:?}");
|
||||
|
||||
// TODO: Free memory
|
||||
}
|
||||
});
|
||||
|
||||
// Instead of having a `loop` in the non-async `SlintBackend::run_event_loop`, we achieve
|
||||
// async by having only one iteration of the loop run, and `await`ing here.
|
||||
// The following block is analogous to `main.run()`.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,24 @@
|
|||
/*
|
||||
import {
|
||||
Button,
|
||||
VerticalBox,
|
||||
LineEdit,
|
||||
GridBox,
|
||||
TabWidget,
|
||||
Button,
|
||||
} from "std-widgets.slint";
|
||||
*/
|
||||
import { Button, VerticalBox, LineEdit, GridBox } from "std-widgets.slint";
|
||||
|
||||
// See https://github.com/slint-ui/slint/issues/4956 for issues with fonts.
|
||||
import "../fonts/IBM_Plex_Mono/IBMPlexMono-Regular.ttf";
|
||||
|
||||
/*
|
||||
export enum AppState {
|
||||
PasswordForm,
|
||||
}
|
||||
*/
|
||||
|
||||
export component AppWindow inherits Window {
|
||||
in property <string> dummy: "ÄÖÜÁÉÍÓÚÝŔŚĹŹĆŃĚĽŽŠČŘĎŤŇŮÅäöüáéíóúýŕśĺźćńěľžščřďťňůåß„“”‘’—–@&$%+=¡¿¢£$¥€²³¼½¬¤¦§©®™°";
|
||||
default-font-family: "IBM Plex Mono";
|
||||
|
|
@ -11,6 +27,7 @@ export component AppWindow inherits Window {
|
|||
width: 960px;
|
||||
in-out property <int> counter: 42;
|
||||
callback request-increase-value();
|
||||
callback accepted(string);
|
||||
VerticalBox {
|
||||
width: 960px;
|
||||
height: 368px;
|
||||
|
|
@ -31,6 +48,7 @@ export component AppWindow inherits Window {
|
|||
Button {
|
||||
text: "Increase value";
|
||||
clicked => {
|
||||
root.counter += 1;
|
||||
root.request-increase-value();
|
||||
}
|
||||
}
|
||||
|
|
@ -38,16 +56,32 @@ export component AppWindow inherits Window {
|
|||
LineEdit {
|
||||
input-type: InputType.text;
|
||||
text: "LineEdit";
|
||||
accepted(text) => {
|
||||
root.accepted(text);
|
||||
}
|
||||
/*changed text => {
|
||||
root.changed(self.text);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
TabWidget {
|
||||
Tab {
|
||||
title: "first";
|
||||
Button {
|
||||
text: "Button";
|
||||
text: "First";
|
||||
}
|
||||
}
|
||||
|
||||
Tab {
|
||||
title: "second";
|
||||
Button {
|
||||
text: "Button";
|
||||
}
|
||||
text: "Second";
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue