commit 8ed0b781a3476d28c8fe86d5ba8d7bb9b8bcc37c Author: Alain Zscheile Date: Fri Sep 23 04:45:34 2022 +0200 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a8ea10b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +result +result-* +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..0357d55 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,105 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "fogtix-bytecode" +version = "0.0.0" +dependencies = [ + "int-enum", + "siphasher", +] + +[[package]] +name = "int-enum" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b1428b2b1abe959e6eedb0a17d0ab12f6ba20e1106cc29fc4874e3ba393c177" +dependencies = [ + "cfg-if", + "int-enum-impl", +] + +[[package]] +name = "int-enum-impl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2c3cecaad8ca1a5020843500c696de2b9a07b63b624ddeef91f85f9bafb3671" +dependencies = [ + "cfg-if", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "syn" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52205623b1b0f064a4e71182c3b18ae902267282930c6d5462c91b859668426e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "unicode-ident" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..08aed47 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +members = ["crates/*"] + +[profile.release] +codegen-units = 2 +debug = true +lto = "thin" diff --git a/crates/fogtix-bytecode/Cargo.toml b/crates/fogtix-bytecode/Cargo.toml new file mode 100644 index 0000000..bdc97c6 --- /dev/null +++ b/crates/fogtix-bytecode/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "fogtix-bytecode" +version = "0.0.0" +edition = "2021" + +[dependencies] + +[dependencies.int-enum] +version = "0.4" +default-features = false + +[dependencies.siphasher] +version = "0.3" +default-features = false diff --git a/crates/fogtix-bytecode/src/consts.rs b/crates/fogtix-bytecode/src/consts.rs new file mode 100644 index 0000000..9264339 --- /dev/null +++ b/crates/fogtix-bytecode/src/consts.rs @@ -0,0 +1,7 @@ +#[repr(u8)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, int_enum::IntEnum)] +pub enum Type { + Bytes = 0x42 /* B */, + Int_ = 0x49 /* I */, + Pointer = 0x50 /* P */, +} diff --git a/crates/fogtix-bytecode/src/lib.rs b/crates/fogtix-bytecode/src/lib.rs new file mode 100644 index 0000000..82cc5f3 --- /dev/null +++ b/crates/fogtix-bytecode/src/lib.rs @@ -0,0 +1,4 @@ +/// Fogtix bytecode is structured as length-type-value items, which can be nested. + +pub mod consts; +pub mod value; diff --git a/crates/fogtix-bytecode/src/value.rs b/crates/fogtix-bytecode/src/value.rs new file mode 100644 index 0000000..b77e087 --- /dev/null +++ b/crates/fogtix-bytecode/src/value.rs @@ -0,0 +1,97 @@ +use crate::consts::Type;use siphasher::sip::SipHasher24 as SipHasher; + +/// A key used to sign a pointer +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(align(16))] +pub struct PointerKey(pub u64, pub u64); + +impl PointerKey { + #[inline(always)] + fn build_hasher(&self) -> SipHasher { + SipHasher::new_with_keys(self.0, self.1) + } +} + +/// A signed pointer, the `payload` should never by dereferenced +/// without verifying the pointer first +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(align(16))] +pub struct Pointer { + pub hmac: u64, + pub payload: u64, +} + +impl From for PointerKey { + #[inline(always)] + /// allows to derive a pointer key from a pointer + fn from(x: Pointer) -> Self { + Self(x.hmac, x.payload) + } +} + +impl Pointer { + fn calculate_hmac(payload: u64, key: &PointerKey) -> u64 { + use core::hash::Hasher; + let mut h = key.build_hasher(); + h.write_u64(payload); + h.finish() + } + + #[inline] + pub fn new_with_key(payload: u64, key: &PointerKey) -> Pointer { + Pointer { + hmac: Self::calculate_hmac(payload, key), + payload, + } + } + + #[inline] + pub fn verify(&self, key: &PointerKey) -> Option { + if self.hmac == Self::calculate_hmac(self.payload, key) { + Some(self.payload) + } else { + None + } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub enum Value { + Pointer(Pointer), + Int(u64), + Bytes(Vec), +} + +impl Value { + #[inline] + pub fn typ(&self) -> Type { + match self { + Value::Pointer(_) => Type::Pointer, + Value::Int(_) => Type::Int_, + Value::Bytes(_) => Type::Bytes, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn pointer_repr() { + use core::mem; + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::align_of::(), 16); + assert_eq!(mem::size_of::(), 16); + assert_eq!(mem::align_of::(), 16); + } + + #[test] + fn pointer_usage() { + let k = PointerKey(0xdead, 0xbeef); + let p = Pointer::new_with_key(0xfefe, &k); + // verify that this is the same value on all systems + assert_eq!(p.hmac, 0xf5779875fe3ef8e); + assert_eq!(p.verify(&k), Some(0xfefe)); + } +} diff --git a/docs/design.md b/docs/design.md new file mode 100644 index 0000000..41d5710 --- /dev/null +++ b/docs/design.md @@ -0,0 +1,5 @@ +# basic ideas + +* use tagged, signed pointers for memory addresses +* use a separate call stack to prevent ROP +* implement message passing