From 33d31e03b08646f0c75522a353c762f204b45211 Mon Sep 17 00:00:00 2001 From: Xe Iaso Date: Thu, 10 Apr 2025 10:31:36 -0400 Subject: [PATCH] wasm: move data buffer to library crate (DRY) Signed-off-by: Xe Iaso --- wasm/anubis/src/lib.rs | 31 +++++++++++++++++++++++++++++++ wasm/pow/argon2id/src/lib.rs | 29 +---------------------------- wasm/pow/sha256/src/lib.rs | 29 +---------------------------- 3 files changed, 33 insertions(+), 56 deletions(-) diff --git a/wasm/anubis/src/lib.rs b/wasm/anubis/src/lib.rs index 25a61b8f..2b16137f 100644 --- a/wasm/anubis/src/lib.rs +++ b/wasm/anubis/src/lib.rs @@ -1,5 +1,10 @@ +use std::boxed::Box; +use std::sync::{LazyLock, Mutex}; + #[cfg(target_arch = "wasm32")] mod hostimport { + use crate::{DATA_BUFFER, DATA_LENGTH}; + #[link(wasm_import_module = "anubis")] unsafe extern "C" { /// The runtime expects this function to be defined. It is called whenever the Anubis check @@ -13,6 +18,18 @@ mod hostimport { anubis_update_nonce(nonce); } } + + #[unsafe(no_mangle)] + pub extern "C" fn data_ptr() -> *const u8 { + let challenge = &DATA_BUFFER; + challenge.as_ptr() + } + + #[unsafe(no_mangle)] + pub extern "C" fn set_data_length(len: u32) { + let mut data_length = DATA_LENGTH.lock().unwrap(); + *data_length = len as usize; + } } #[cfg(not(target_arch = "wasm32"))] @@ -22,4 +39,18 @@ mod hostimport { } } +/// The data buffer is a bit weird in that it doesn't have an explicit length as it can +/// and will change depending on the challenge input that was sent by the server. +/// However, it can only fit 4096 bytes of data (one amd64 machine page). This is +/// slightly overkill for the purposes of an Anubis check, but it's fine to assume +/// that the browser can afford this much ram usage. +/// +/// Callers should fetch the base data pointer, write up to 4096 bytes, and then +/// `set_data_length` the number of bytes they have written +/// +/// This is also functionally a write-only buffer, so it doesn't really matter that +/// the length of this buffer isn't exposed. +pub static DATA_BUFFER: LazyLock<[u8; 4096]> = LazyLock::new(|| [0; 4096]); +pub static DATA_LENGTH: LazyLock> = LazyLock::new(|| Mutex::new(0)); + pub use hostimport::update_nonce; diff --git a/wasm/pow/argon2id/src/lib.rs b/wasm/pow/argon2id/src/lib.rs index 7466a5ce..1cdf709d 100644 --- a/wasm/pow/argon2id/src/lib.rs +++ b/wasm/pow/argon2id/src/lib.rs @@ -1,23 +1,8 @@ -use anubis::update_nonce; +use anubis::{DATA_BUFFER, DATA_LENGTH, update_nonce}; use argon2::Argon2; use std::boxed::Box; use std::sync::{LazyLock, Mutex}; -/// The data buffer is a bit weird in that it doesn't have an explicit length as it can -/// and will change depending on the challenge input that was sent by the server. -/// However, it can only fit 4096 bytes of data (one amd64 machine page). This is -/// slightly overkill for the purposes of an Anubis check, but it's fine to assume -/// that the browser can afford this much ram usage. -/// -/// Callers should fetch the base data pointer, write up to 4096 bytes, and then -/// `set_data_length` the number of bytes they have written -/// -/// This is also functionally a write-only buffer, so it doesn't really matter that -/// the length of this buffer isn't exposed. -pub static DATA_BUFFER: LazyLock> = LazyLock::new(|| Box::new([0; 4096])); - -pub static DATA_LENGTH: LazyLock> = LazyLock::new(|| Mutex::new(0)); - /// SHA-256 hashes are 32 bytes (256 bits). These are stored in static buffers due to the /// fact that you cannot easily pass data from host space to WebAssembly space. pub static RESULT_HASH: LazyLock> = LazyLock::new(|| Mutex::new([0; 32])); @@ -189,15 +174,3 @@ pub extern "C" fn verification_hash_ptr() -> *const u8 { pub extern "C" fn verification_hash_size() -> usize { VERIFICATION_HASH.lock().unwrap().len() } - -#[unsafe(no_mangle)] -pub extern "C" fn data_ptr() -> *const u8 { - let challenge = &DATA_BUFFER; - challenge.as_ptr() -} - -#[unsafe(no_mangle)] -pub extern "C" fn set_data_length(len: u32) { - let mut data_length = DATA_LENGTH.lock().unwrap(); - *data_length = len as usize; -} diff --git a/wasm/pow/sha256/src/lib.rs b/wasm/pow/sha256/src/lib.rs index 649c0977..81eeb527 100644 --- a/wasm/pow/sha256/src/lib.rs +++ b/wasm/pow/sha256/src/lib.rs @@ -1,23 +1,8 @@ -use anubis::update_nonce; +use anubis::{DATA_BUFFER, DATA_LENGTH, update_nonce}; use sha2::{Digest, Sha256}; use std::boxed::Box; use std::sync::{LazyLock, Mutex}; -/// The data buffer is a bit weird in that it doesn't have an explicit length as it can -/// and will change depending on the challenge input that was sent by the server. -/// However, it can only fit 4096 bytes of data (one amd64 machine page). This is -/// slightly overkill for the purposes of an Anubis check, but it's fine to assume -/// that the browser can afford this much ram usage. -/// -/// Callers should fetch the base data pointer, write up to 4096 bytes, and then -/// `set_data_length` the number of bytes they have written -/// -/// This is also functionally a write-only buffer, so it doesn't really matter that -/// the length of this buffer isn't exposed. -pub static DATA_BUFFER: LazyLock> = LazyLock::new(|| Box::new([0; 4096])); - -pub static DATA_LENGTH: LazyLock> = LazyLock::new(|| Mutex::new(0)); - /// SHA-256 hashes are 32 bytes (256 bits). These are stored in static buffers due to the /// fact that you cannot easily pass data from host space to WebAssembly space. pub static RESULT_HASH: LazyLock>> = @@ -184,15 +169,3 @@ pub extern "C" fn verification_hash_ptr() -> *const u8 { pub extern "C" fn verification_hash_size() -> usize { VERIFICATION_HASH.lock().unwrap().len() } - -#[unsafe(no_mangle)] -pub extern "C" fn data_ptr() -> *const u8 { - let challenge = &DATA_BUFFER; - challenge.as_ptr() -} - -#[unsafe(no_mangle)] -pub extern "C" fn set_data_length(len: u32) { - let mut data_length = DATA_LENGTH.lock().unwrap(); - *data_length = len as usize; -}