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