diff --git a/.cargo/config.toml b/.cargo/config.toml index f1c54d3..065fc79 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -12,3 +12,6 @@ # enable the unstable artifact-dependencies feature, see # https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#artifact-dependencies bindeps = true + +[build] +rustflags = ["--cfg", "aes_force_soft"] \ No newline at end of file diff --git a/.gitignore b/.gitignore index ea8c4bf..212de44 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +.DS_Store \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 9a56b10..89881e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,50 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "anstream" version = "0.6.4" @@ -56,6 +100,21 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bit_field" version = "0.10.2" @@ -74,12 +133,37 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.4.8" @@ -141,6 +225,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e763eef8846b13b380f37dfecda401770b0ca4e56e95170237bd7c25c7db3582" +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -160,12 +253,59 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-bigint" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83bd3bb4314701c568e340cd8cf78c975aa0ca79e03d3f6d1677d5b0c9c0c03" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "downcast-rs" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "elliptic-curve" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beca177dcb8eb540133e7680baff45e7cc4d93bf22002676cec549f82343721b" +dependencies = [ + "crypto-bigint", + "ff", + "generic-array", + "group", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "futures-core" version = "0.3.29" @@ -190,33 +330,112 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash", + "allocator-api2", +] + [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + [[package]] name = "indexmap-nostd" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "kernel" version = "0.1.0" dependencies = [ + "aes", "bitflags 2.4.1", "conquer-once", "crossbeam-queue", "futures-util", + "getrandom", + "hashbrown", + "hex", "lazy_static", "linked_list_allocator", "multiboot2", "object", + "p256", "pc-keyboard", "pci", "pic8259", + "rand", + "rand_core", "raw-cpuid 11.0.1", "spin 0.9.8", "uart_16550", @@ -234,6 +453,12 @@ dependencies = [ "spin 0.5.2", ] +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + [[package]] name = "libm" version = "0.2.8" @@ -265,6 +490,26 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + [[package]] name = "multiboot2" version = "0.12.2" @@ -283,6 +528,16 @@ dependencies = [ "autocfg", ] +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "object" version = "0.32.1" @@ -292,6 +547,44 @@ dependencies = [ "memchr", ] +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "p256" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d053368e1bae4c8a672953397bd1bd7183dde1c72b0b7612a15719173148d186" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + [[package]] name = "paste" version = "1.0.14" @@ -331,6 +624,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro2" version = "1.0.69" @@ -349,6 +648,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "raw-cpuid" version = "10.7.0" @@ -367,6 +696,21 @@ dependencies = [ "bitflags 2.4.1", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustversion" version = "1.0.14" @@ -379,12 +723,51 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + [[package]] name = "smallvec" version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "soupOS" version = "0.1.0" @@ -393,6 +776,19 @@ dependencies = [ "kernel", ] +[[package]] +name = "soup_os_client" +version = "0.1.0" +dependencies = [ + "aes", + "hex", + "lazy_static", + "p256", + "rand", + "rand_core", + "tokio", +] + [[package]] name = "spin" version = "0.5.2" @@ -423,6 +819,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "2.0.39" @@ -434,6 +836,42 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "uart_16550" version = "0.3.0" @@ -457,6 +895,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "volatile" version = "0.2.7" @@ -469,6 +913,12 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "442887c63f2c839b346c192d047a7c87e73d0689c9157b00b53dcc27dd5ea793" +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-demos" version = "0.1.0" @@ -601,3 +1051,29 @@ dependencies = [ "rustversion", "volatile 0.4.6", ] + +[[package]] +name = "zerocopy" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" diff --git a/Cargo.toml b/Cargo.toml index cfc8e60..8cd328c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,4 +11,4 @@ kernel = { path = "kernel", target = "x86_64-unknown-none", artifact="staticlib" clap = { version = "4.4.6", features = ["derive"] } [workspace] -members = ["kernel", "wasm-demos"] +members = ["kernel", "wasm-demos", "client"] diff --git a/README.md b/README.md index 36cc83d..3eb41f8 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,10 @@ On macOS, first [run this script](https://gist.github.com/Coder-256/dc300ca6999df3b91706d419eacb24f1) to install the required dependencies. +### Nightly build + +`rustup override set nightly` + ### Build kernel `cargo build` diff --git a/client/Cargo.lock b/client/Cargo.lock new file mode 100644 index 0000000..4dcfcf6 --- /dev/null +++ b/client/Cargo.lock @@ -0,0 +1,358 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "libc" +version = "0.2.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "soup_os_client" +version = "0.1.0" +dependencies = [ + "tokio", +] + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tokio" +version = "1.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/client/Cargo.toml b/client/Cargo.toml new file mode 100644 index 0000000..3897212 --- /dev/null +++ b/client/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "soup_os_client" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +lazy_static = "1.4.0" +p256={version = "0.9.0", default-features=false, features = ["ecdh"]} +hex = { version = "0.4", default-features = false, features = ["alloc"] } +rand_core="0.6.3" +rand = "0.8.5" +tokio = { version = "1", features = ["full"] } +aes = { version = "0.8.3", default-features = false} diff --git a/client/src/aes.rs b/client/src/aes.rs new file mode 100644 index 0000000..0af2bf7 --- /dev/null +++ b/client/src/aes.rs @@ -0,0 +1,53 @@ +use aes::Aes256; +use aes::cipher::{ + BlockEncrypt, BlockDecrypt, KeyInit, + generic_array::{GenericArray, typenum::U16}, +}; + +pub struct ServerAES { + cipher: Aes256, +} + +impl ServerAES { + pub fn _new(key: [u8; 32]) -> Self { + let key_arr = GenericArray::from(key); + let cipher = Aes256::new(&key_arr); + Self { + cipher, + } + } + + pub fn _encrypt_msg(&self, msg: Vec) -> Vec { + // Create an empty vector to store the encrypted bytes + let mut encrypted_bytes = Vec::new(); + + // Loop over chunks of 16 bytes + for chunk in msg.chunks_exact(16) { + let mut bytes: GenericArray<_, U16> = GenericArray::clone_from_slice(chunk); + self.cipher.encrypt_block(&mut bytes); + encrypted_bytes.extend_from_slice(bytes.as_slice()); + } + encrypted_bytes + } + + pub fn _decrypt_msg(&self, msg: Vec) -> Vec { + // Create an empty vector to store the decrypted bytes + let mut decrypted_bytes = Vec::new(); + + // Loop over chunks of 16 bytes + for chunk in msg.chunks_exact(16) { + let mut bytes: GenericArray<_, U16> = GenericArray::clone_from_slice(chunk); + self.cipher.decrypt_block(&mut bytes); + decrypted_bytes.extend_from_slice(bytes.as_slice()); + } + decrypted_bytes + } +} + +impl Clone for ServerAES { + fn clone(&self) -> Self { + Self { + cipher: self.cipher.clone(), + } + } +} \ No newline at end of file diff --git a/client/src/ecdh.rs b/client/src/ecdh.rs new file mode 100644 index 0000000..19c7d59 --- /dev/null +++ b/client/src/ecdh.rs @@ -0,0 +1,44 @@ +use p256::{EncodedPoint, PublicKey, ecdh::EphemeralSecret, ecdh::SharedSecret}; +use rand_core::OsRng; +pub struct ECDH { + ephemeral_secret: EphemeralSecret, + public_key_obj: PublicKey, + public_key_hex: String, + shared_key: Option, +} + +impl ECDH { + pub fn new() -> Self { + let ephemeral_secret = EphemeralSecret::random(&mut OsRng); + let encoded = EncodedPoint::from(ephemeral_secret.public_key()); + let public_key_hex = hex::encode(encoded.as_ref()); + let public_key_obj = PublicKey::from_sec1_bytes(encoded.as_ref()).expect("Alice's public key invalid"); + Self { + ephemeral_secret, + public_key_obj, + public_key_hex, + shared_key: None, + } + } + pub fn generate_shared_key(&mut self, client_key: PublicKey) { + let shared_key = self.ephemeral_secret.diffie_hellman(&client_key); + self.shared_key = Some(shared_key); + } + + pub fn get_public_key_obj(&self) -> PublicKey{ + self.public_key_obj + } + + pub fn get_public_key_hex(&self) -> String { + self.public_key_hex.clone() + } + + pub fn get_shared_key_hex(&self) -> String { + hex::encode(self.shared_key.as_ref().expect("Failed to unwrap shared key").as_bytes()) + } +} + +pub fn create_pubkey_from_hex_string(hex: String) -> PublicKey { + let bytes = hex::decode(hex).expect("Failed to decode hexadecimal string"); + PublicKey::from_sec1_bytes(&bytes).expect("Failed to create PublicKey from hex") +} \ No newline at end of file diff --git a/client/src/lib.rs b/client/src/lib.rs new file mode 100644 index 0000000..edeb3b5 --- /dev/null +++ b/client/src/lib.rs @@ -0,0 +1,2 @@ +pub mod aes; +pub mod ecdh; \ No newline at end of file diff --git a/client/src/main.rs b/client/src/main.rs new file mode 100644 index 0000000..6b80a8a --- /dev/null +++ b/client/src/main.rs @@ -0,0 +1,256 @@ +mod aes; +use soup_os_client::{ + aes::ServerAES, + ecdh::{ECDH, create_pubkey_from_hex_string}, +}; +use std::{ + env, + error::Error, + io::stdin, + net::SocketAddr, + fs, +}; +use tokio::{ + io, + net::UdpSocket, +}; +use rand::Rng; +use hex::FromHex; + +const DEBUG: bool = true; +const MAX_DATAGRAM_SIZE: usize = 65_507; + +#[tokio::main] +async fn main() -> Result<(), Box> { + + // create ecdh and aes structs to use for encryption + let mut ecdh_struct = ECDH::new(); + let mut aes_struct = ServerAES::_new([0u8; 32]); + + // connect to server + let socket = connect_to_server().await?; + + // recieve data from the command line + let mut data_as_string = get_stdin_data()?.trim_end().to_string(); + + // loop while user doesn't exit + while data_as_string != "exit" { + + // send and res buffers + let mut _res: Vec = Vec::new(); + + // user has to send generate_key before running any commands + if data_as_string == "generate_key" { + + if DEBUG { + println!("Sending request: {}", format!("key_reg{}", ecdh_struct.get_public_key_hex())); + } + + // append key_req onto hex public key and send to server + _res = send_to_server(&socket, (format!("key_reg{}", ecdh_struct.get_public_key_hex())).into()).await?; + ecdh_struct.generate_shared_key(create_pubkey_from_hex_string(String::from_utf8(_res.clone()).expect("Failed to stringify response"))); + + if DEBUG { + println!("Recieved public key: {}", (String::from_utf8(_res.clone()).expect("Failed to stringify response"))); + println!("Generated shared key: {:?}", ecdh_struct.get_shared_key_hex()); + } + + // convert the generated shared key to a [u8; 32] to use for aes cipher + match <[u8; 32]>::from_hex(ecdh_struct.get_shared_key_hex()) { + Ok(result) => aes_struct = ServerAES::_new(result), + Err(e) => println!("Conversion to [u8; 32] failed: {}", e), + } + } + else if data_as_string.starts_with("ping_message") { + + let mut data_vec = "ping_me".as_bytes().to_vec(); + + // get data without "send_message" + data_vec.extend(data_as_string[13..].as_bytes().to_vec()); + + // encode and prepare message + let send_data = encode_message(data_vec, aes_struct.clone(), &ecdh_struct); + + // send to server + _res = send_to_server(&socket, send_data).await?; + + // decode response + let response = decode_message(_res, aes_struct.clone()); + let str_res = std::str::from_utf8(&response).unwrap(); + if DEBUG { + + println!("Server responded with: {:?}", str_res); + } + + } + else if data_as_string.starts_with("run_wasm") { + let mut data_vec = "runwasm".as_bytes().to_vec(); + + let data_in: Vec<&str> = data_as_string.split(" ").collect(); + let mut file_contents = Vec::new(); + let _ = get_file(data_in[1], &mut file_contents); + + // get data without "send_message" + data_vec.extend(file_contents); + + // encode and prepare message + let send_data = encode_message(data_vec, aes_struct.clone(), &ecdh_struct); + + // send to server + _res = send_to_server(&socket, send_data).await?; + + // decode response + let response = decode_message(_res, aes_struct.clone()); + let str_res = std::str::from_utf8(&response).unwrap(); + if DEBUG { + + println!("Server responded with: {:?}", str_res); + } + } + else { + + } + + // get next command from command line + data_as_string = get_stdin_data()?.trim_end().to_string(); + } + Ok(()) +} + +async fn connect_to_server() -> io::Result { + let remote_addr: SocketAddr = env::args() + .nth(1) + .unwrap_or_else(|| "127.0.0.1:5555".into()) + .parse() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?; + + let local_addr: SocketAddr = if remote_addr.is_ipv4() { + "0.0.0.0:0" + } else { + "[::]:0" + } + .parse() + .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?; + + let socket = UdpSocket::bind(local_addr).await?; + socket.connect(&remote_addr).await?; + + Ok(socket) +} + +async fn send_to_server(socket: &UdpSocket, data: Vec) -> io::Result> { + socket.send(&data).await?; + let mut buffer = vec![0u8; MAX_DATAGRAM_SIZE]; + let len = socket.recv(&mut buffer).await?; + let res = buffer[..len].to_vec(); + Ok(res) +} + +fn get_stdin_data() -> Result> { + let mut buf = String::new(); + stdin().read_line(&mut buf)?; + Ok(buf) +} + +fn get_file(file_path: &str, file_contents: &mut Vec) -> Result<(), std::io::Error> { + *file_contents = fs::read(file_path)?; + Ok(()) +} + +fn pad_to_16(data: &mut Vec) { + let remaining_bytes = 16 - (data.len() % 16); + + if remaining_bytes != 16 { + let mut rng = rand::thread_rng(); + let random_bytes: Vec = (0..remaining_bytes).map(|_| rng.gen()).collect(); + data.extend(random_bytes); + } +} + +fn u64_to_bytes(length: usize) -> Vec { + length.to_le_bytes().to_vec() +} + +fn bytes_to_u64(bytes: Vec) -> u64 { + if bytes.len() != 8 { + panic!("Input vector must have exactly 8 bytes"); + } + let mut array = [0u8; 8]; + array.copy_from_slice(&bytes); + u64::from_le_bytes(array) +} + +fn get_first_x_bytes(data: Vec, x: u64) -> Vec { + let mut collected = Vec::new(); + for i in 0..x { + collected.push(data[i as usize]); + } + collected +} + +fn decode_message(message: Vec, aes: ServerAES) -> Vec { + let mut _unencrypted_message = Vec::new(); + + if message.starts_with(b"ERR") { + if DEBUG { + println!("Server responded with error: {:?}", String::from_utf8(message.clone())); + } + _unencrypted_message = message + } + else { + if DEBUG { + println!("Decrypting message: {:?}", message.to_vec()); + } + + // decrypt the rest of the message + let request = aes._decrypt_msg(message.to_vec()); + + if DEBUG { + println!("Decrypted message: {:?}", request); + } + + // get the size of the unencrypted message + let message_size = bytes_to_u64(get_first_x_bytes(request.clone(), 8)); + + // get the actual message + _unencrypted_message = get_first_x_bytes(request[8..].to_vec(), message_size); + + if DEBUG { + println!("Unencrypted message: {:?}", _unencrypted_message.clone()); + } + } + + _unencrypted_message +} + +fn encode_message(data_vec: Vec, aes_struct: ServerAES, ecdh_struct: &ECDH) -> Vec { + let mut data_size = u64_to_bytes(data_vec.len()); + + // combine the message with length of message before padding + data_size.extend(data_vec); + + // pad data to multiple of 16 with random bytes + pad_to_16(&mut data_size); + + // encrypt the data + if DEBUG { + println!("Encrypting message: {:?}", data_size); + } + let message = aes_struct._encrypt_msg(data_size); + + if DEBUG { + println!("Encrypted message: {:?}", message); + } + + // combine the message with the public key + let mut publickey_vec = ecdh_struct.get_public_key_hex().as_bytes().to_vec(); + println!("pubkey: {:?}", publickey_vec); + publickey_vec.extend(message); + + // send the request to server and decrypt the response + if DEBUG { + println!("Sending request: {:?}", publickey_vec); + } + + publickey_vec +} \ No newline at end of file diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index ac7fd85..7040ad2 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -28,6 +28,17 @@ multiboot2 = "0.12.0" bitflags = "2.4.1" #"0.9.1" linked_list_allocator = "0.10.5" object = { version = "0.32.1", default-features = false, features = ["read"] } +getrandom = { version = "0.2", features = ["custom"] } +p256={version = "0.9.0", default-features=false, features = ["ecdh"]} +hex = { version = "0.4", default-features = false, features = ["alloc", "serde"] } +rand_core="0.6.3" +aes = { version = "0.8.3", default-features = false} +hashbrown = "0.14.2" + +[dependencies.rand] +version = "0.8.3" +default-features = false +features = ["getrandom", "small_rng"] [dependencies.wasmi] version = "0.31.0" diff --git a/kernel/src/api/aes.rs b/kernel/src/api/aes.rs new file mode 100644 index 0000000..be78f94 --- /dev/null +++ b/kernel/src/api/aes.rs @@ -0,0 +1,48 @@ +use aes::Aes256; +use aes::cipher::{ + BlockEncrypt, BlockDecrypt, KeyInit, + generic_array::{GenericArray, typenum::U16}, +}; +use alloc::vec::Vec; + +const BLOCK_SIZE: usize = 16; + +pub struct ServerAES { + cipher: Aes256, +} + +impl ServerAES { + pub fn new(key: [u8; 32]) -> Self { + let key_arr = GenericArray::from(key); + let cipher = Aes256::new(&key_arr); + Self { + cipher, + } + } + + pub fn encrypt_msg(&self, msg: Vec) -> Vec { + // Create an empty vector to store the encrypted bytes + let mut encrypted_bytes = Vec::new(); + + // Loop over chunks of 16 bytes + for chunk in msg.chunks_exact(BLOCK_SIZE) { + let mut bytes: GenericArray<_, U16> = GenericArray::clone_from_slice(chunk); + self.cipher.encrypt_block(&mut bytes); + encrypted_bytes.extend_from_slice(bytes.as_slice()); + } + encrypted_bytes + } + + pub fn decrypt_msg(&self, msg: Vec) -> Vec { + // Create an empty vector to store the decrypted bytes + let mut decrypted_bytes = Vec::new(); + + // Loop over chunks of 16 bytes + for chunk in msg.chunks_exact(BLOCK_SIZE) { + let mut bytes: GenericArray<_, U16> = GenericArray::clone_from_slice(chunk); + self.cipher.decrypt_block(&mut bytes); + decrypted_bytes.extend_from_slice(bytes.as_slice()); + } + decrypted_bytes + } +} \ No newline at end of file diff --git a/kernel/src/api/ecdh.rs b/kernel/src/api/ecdh.rs new file mode 100644 index 0000000..c01cadb --- /dev/null +++ b/kernel/src/api/ecdh.rs @@ -0,0 +1,45 @@ +use alloc::string::String; +use p256::{EncodedPoint, PublicKey, ecdh::EphemeralSecret, ecdh::SharedSecret}; +use rand_core::OsRng; +pub struct ECDH { + ephemeral_secret: EphemeralSecret, + public_key_obj: PublicKey, + public_key_hex: String, + shared_key: Option, +} + +impl ECDH { + pub fn new() -> Self { + let ephemeral_secret = EphemeralSecret::random(&mut OsRng); + let encoded = EncodedPoint::from(ephemeral_secret.public_key()); + let public_key_hex = hex::encode(encoded.as_ref()); + let public_key_obj = PublicKey::from_sec1_bytes(encoded.as_ref()).expect("Alice's public key invalid"); + Self { + ephemeral_secret, + public_key_obj, + public_key_hex, + shared_key: None, + } + } + pub fn generate_shared_key(&mut self, client_key: PublicKey) { + let shared_key = self.ephemeral_secret.diffie_hellman(&client_key); + self.shared_key = Some(shared_key); + } + + pub fn get_public_key_obj(&self) -> PublicKey{ + self.public_key_obj + } + + pub fn get_public_key_hex(&self) -> String { + self.public_key_hex.clone() + } + + pub fn get_shared_key_hex(&self) -> String { + hex::encode(self.shared_key.as_ref().expect("Failed to unwrap shared key").as_bytes()) + } +} + +pub fn create_pubkey_from_hex_string(hex: String) -> PublicKey { + let bytes = hex::decode(hex).expect("Failed to decode hexadecimal string"); + PublicKey::from_sec1_bytes(&bytes).expect("Failed to create PublicKey from hex") +} \ No newline at end of file diff --git a/kernel/src/api/mod.rs b/kernel/src/api/mod.rs new file mode 100644 index 0000000..ccd204a --- /dev/null +++ b/kernel/src/api/mod.rs @@ -0,0 +1,4 @@ +pub mod request; +pub mod aes; +pub mod ecdh; +pub mod random; \ No newline at end of file diff --git a/kernel/src/api/random.rs b/kernel/src/api/random.rs new file mode 100644 index 0000000..e1b2691 --- /dev/null +++ b/kernel/src/api/random.rs @@ -0,0 +1,48 @@ +use rand::RngCore; + +// Custom `getrandom` implementation that uses a simple PRNG (XorShift). +pub fn get_rand(buf: &mut [u8]) -> Result<(), getrandom::Error> { + let mut rng = XorShiftRng::new(); + rng.fill_bytes(buf); + Ok(()) +} + +// XorShiftRng: A simple pseudo-random number generator (PRNG). +struct XorShiftRng { + state: u32, +} + +impl XorShiftRng { + fn new() -> Self { + // Seed the PRNG with some initial value (e.g., current timestamp). + Self { state: 123456789 } + } +} + +impl RngCore for XorShiftRng { + fn next_u32(&mut self) -> u32 { + self.state ^= self.state << 13; + self.state ^= self.state >> 17; + self.state ^= self.state << 5; + self.state + } + + fn next_u64(&mut self) -> u64 { + // Combine two 32-bit outputs to form a 64-bit output. + ((self.next_u32() as u64) << 32) | (self.next_u32() as u64) + } + + fn fill_bytes(&mut self, dest: &mut [u8]) { + // Use `slice::chunks_mut` to fill the destination buffer efficiently. + for chunk in dest.chunks_mut(4) { + let value = self.next_u32(); + chunk.copy_from_slice(&value.to_le_bytes()); + } + } + + fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand::Error> { + // For simplicity, always succeed in filling the buffer. + self.fill_bytes(dest); + Ok(()) + } +} \ No newline at end of file diff --git a/kernel/src/api/request.rs b/kernel/src/api/request.rs new file mode 100644 index 0000000..1aea2c5 --- /dev/null +++ b/kernel/src/api/request.rs @@ -0,0 +1,181 @@ +use alloc::{vec::Vec, string::String}; +use lazy_static::lazy_static; +use spin::Mutex; +use crate::{println, api::{ecdh::{ECDH, create_pubkey_from_hex_string}, aes::ServerAES}}; +use hex::FromHex; +use hashbrown::HashMap; +use rand_core::{RngCore, OsRng}; +const DEBUG: bool = true; + +lazy_static! { + static ref ECDH_KEY: Mutex = Mutex::new(ECDH::new()); + static ref AES_KEY: Mutex = Mutex::new(ServerAES::new([0u8; 32])); + static ref KEY_MAP: Mutex> = Mutex::new(HashMap::new()); +} + +pub fn handle_request(message: Vec) -> Vec { + println!("[USER] {:?}", message); + + let mut res = Vec::new(); + + if message.len() < 7 { + if DEBUG { + println!("Client's message too short to contain command"); + } + res = Vec::from("ERR: Command too short"); + } + else { + if message.starts_with(b"key_reg") { + if DEBUG { + println!("Recieved client public key: {}", (String::from_utf8(message.to_vec()).expect("Failed to stringify response"))); + } + let message: Vec = (&message[7..]).to_vec(); + // set up ecdh shared key and respond with server's public key + let mut ecdh = ECDH::new(); + ecdh.generate_shared_key(create_pubkey_from_hex_string(String::from_utf8(message.to_vec()).expect("failed to make string"))); + res = ecdh.get_public_key_hex().into_bytes().to_vec(); + + // set up aes cipher + let mut aes = ServerAES::new([0u8;32]); + // use shared key as [u8; 32] for the aes cipher + match <[u8; 32]>::from_hex(ecdh.get_shared_key_hex()) { + Ok(result) => aes = ServerAES::new(result), + Err(e) => println!("Conversion to [u8; 32] failed: {}", e), + } + + // use client public key as key and set values to the ecdh and aes structs + let mut key_map = KEY_MAP.lock(); + key_map.insert(String::from_utf8(message.to_vec()).expect("failed to convert to string"), (ecdh, aes)); + } + else { + // get ecdh and aes contexts from map + let unlocked_key_map = KEY_MAP.lock(); + // key will be the first 130 bytes + if message.len() < 137 { + res = Vec::from("ERR: Missing public key or command"); + } + else { + // then request will be in form publickey+enc(length+command+message) + let pubkey = (&message[..130]).to_vec(); + + if let Ok(key_str) = String::from_utf8(pubkey) { + if let Some((_ecdh, aes)) = unlocked_key_map.get(&key_str) { + + if DEBUG { + println!("found public key"); + } + + let decoded = decode_message((&message[130..]).to_vec(), aes); + + let command = (&decoded[..7]).to_vec(); + let message: Vec = (&decoded[7..]).to_vec(); + + // determine what to do based on command + if command.starts_with(b"runwasm") { + // call scheduler with bits + // let program_res = schedule_task(message) + // res = encode_message(program_res, aes); + res = encode_message(Vec::from("running task"), aes); + } + else if command.starts_with(b"ping_me") { + let mut return_message = Vec::from("Pong: "); + return_message.extend(message); + res = encode_message(return_message, aes); + } + else { + res = encode_message(Vec::from("ERR: Invalid command"), aes); + } + } else { + if DEBUG { + println!("Couldn't find Client's public key"); + } + res = Vec::from("ERR: Client's public key not found"); + } + } else { + res = Vec::from("ERR: Client's public key format is incorrect"); + } + } + } + } + res +} + +fn decode_message(message: Vec, aes: &ServerAES) -> Vec { + + if DEBUG { + println!("Decrypting message: {:?}", message); + } + + // decrypt the rest of the message + let request = aes.decrypt_msg(message); + + if DEBUG { + println!("Decrypted message: {:?}", request); + } + + // get the size of the unencrypted message + let message_size = bytes_to_u64(get_first_x_bytes(request.clone(), 8)); + + // get the actual message + let unencrypted_message = get_first_x_bytes(request[8..].to_vec(), message_size); + + if DEBUG { + println!("Unencrypted message: {:?}", unencrypted_message.clone()); + } + unencrypted_message +} + +fn encode_message(data_vec: Vec, aes_struct: &ServerAES) -> Vec { + let mut data_size = u64_to_bytes(data_vec.len() as u64); + + // combine the message with length of message before padding + data_size.extend(data_vec); + + // pad data to multiple of 16 with random bytes + pad_to_16(&mut data_size); + + // encrypt the data + if DEBUG { + println!("Encrypting message: {:?}", data_size); + } + let message = aes_struct.encrypt_msg(data_size); + + if DEBUG { + println!("Encrypted message: {:?}", message); + } + + // send the request to server and decrypt the response + if DEBUG { + println!("Sending request: {:?}", message); + } + + message +} + +fn u64_to_bytes(length: u64) -> Vec { + length.to_le_bytes().to_vec() +} + +fn bytes_to_u64(bytes: Vec) -> u64 { + let mut array = [0u8; 8]; + array.copy_from_slice(&bytes); + u64::from_le_bytes(array) +} + +fn get_first_x_bytes(data: Vec, x: u64) -> Vec { + let mut collected = Vec::new(); + for i in 0..x { + collected.push(data[i as usize]); + } + collected +} + +fn pad_to_16(data: &mut Vec) { + let remaining_bytes = 16 - (data.len() % 16); + + if remaining_bytes != 16 { + let mut rng = OsRng::default(); // Use OsRng to generate random bytes + let random_bytes: Vec = (0..remaining_bytes).map(|_| rng.next_u32() as u8).collect(); + data.extend(random_bytes); + } +} \ No newline at end of file diff --git a/kernel/src/apic.rs b/kernel/src/apic.rs index fc02298..d8c4d95 100644 --- a/kernel/src/apic.rs +++ b/kernel/src/apic.rs @@ -1,90 +1,300 @@ +#![no_std] +#![feature(ascii_char)] +use lapic::addr; +use raw_cpuid::CpuId; +use raw_cpuid::native_cpuid; +use core::sync::atomic::AtomicU32; +use core::sync::atomic::Ordering; use core::arch::asm; use core::arch::x86_64; -use raw_cpuid::CpuId; +use core::str; +use core::time; -use crate::interrupts; +extern crate x86_64 as lapic; +use lapic::registers::model_specific::Msr; +use lapic::structures::idt::{InterruptDescriptorTable, InterruptStackFrame}; /// Start of the local apic address according to Intel Documentation /// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf -const LAPIC_BASE_ADDR: u64 = 0xfee00000; -const CPU_FEATURE_FLAG: u32 = 1 << 9; +const LAPIC_BASE_ADDR: u64 = 0xfee00000; // Default physical address of Local Apic hardcoded +const MAX_BRAND_STRING_SIZE: usize = 32; +const IOAPIC_BASE_ADDR: u64 = 0xFEC00000; // Default physical address of I/O Apic hardcoded +const IOAPIC_REG_ID: u32 = 0; +const IOAPIC_REG_VERSION: u32 = 1; +const LAPIC_TIMER_REGISTER: u64 = 0x320; +const LAPIC_SVR_REGISTER: u64 = 0x0F0; +const IA32_APIC_BASE_MSR: u32 = 0x1B; +const IA32_APIC_BASE_MSR_ENABLE: u32 = 0x800; + -// need to create some sort of IVT +static CPU_COUNT : AtomicU32 = AtomicU32::new(0); -struct CpuInfo { - id: u32, +/// An interrupt manager for registering and blocking/unblocking interrupts +pub struct InterruptHandler { + idt: InterruptDescriptorTable, } -/// Struct for Local APIC -pub struct LocalApic { - base_address: u64, +static IDT: InterruptDescriptorTable = InterruptDescriptorTable::new(); + +extern "x86-interrupt" fn timer_interrupt_handler(stack_frame: InterruptStackFrame) { + } -pub const TPR: (u32, u32) = (0x808, 0x080); +pub struct IOApic { + reg: *mut u32, + pad: [u32; 3], + data: *mut u32, +} + +// pub unsafe fn enable_ioapic(ioapic_base: usize) { +// let ioapic = ioapic_base as *mut IOApic; + +// let ioapic_id = ioapic.add(IOAPIC_REG_ID as usize).read_volatile(); +// } + +// unsafe fn write_ioapic(ioapic: *mut IOApic, reg: u32, value: u32) { +// ioapic.add(IOAPIC_REG_ID as usize).write_volatile(reg); +// // Looping for some delay +// let mut i = 0; + +// while i < 1000 { +// i += 1; +// } + +// ioapic.add(IOAPIC_REG_VERSION as usize).write_volatile(value); +// } + + +pub enum LocalApicMode { + Apic { + apic_base: u64, + }, + + X2Apic, +} + +/// Struct for Local APIC register #[derive(Debug)] pub struct LocalApicRegister { - base: u64, - offset: u64, + base : u64, + offset : u64, } #[derive(Debug)] pub struct LocalApicRegisters { - tpr: LocalApicRegister, - apr: LocalApicRegister, - ppr: LocalApicRegister, - eoi: LocalApicRegister, - rrd: LocalApicRegister, - isr: LocalApicRegister, + tpr : LocalApicRegister, + apr : LocalApicRegister, + ppr : LocalApicRegister, + eoi : LocalApicRegister, + rrd : LocalApicRegister, + isr : LocalApicRegister, + self_ipi : LocalApicRegister, + tmr : LocalApicRegister, +} + +impl LocalApicRegister { + + /// Initialize a local apic register + pub fn new(mode: LocalApicMode, loc: (u32, u32)) -> Self { + match mode { + LocalApicMode::Apic { apic_base } => { + Self::offset(apic_base + loc.1 as u64) + } + LocalApicMode::X2Apic => Self::base(Msr::new(loc.0)), + } + } + + /// Read from a certain register + pub fn read(&self) -> u32 { + unsafe { + match self { + Self::offset(addr) => { + core::ptr::read_volatile(*addr as *const u32) + } + Self::base(msr) => msr.read() as u32, + } + } + } + + /// Write to a certain register + pub fn write(&mut self, value : u32) { + unsafe { + match self { + LocalApicRegister::offset(offset) => { + core::ptr::write_volatile(*offset as *mut u32, value) + } + LocalApicRegister::base(msr) => msr.write(value as u64), + } + } + } } -impl LocalApicRegisters { - // pub fn new(mode: Loca) +pub struct LocalApic { + base_address : u64, + // mode : LocalApicMode, + // registers : LocalApicRegisters, } + impl LocalApic { - /// Create a new LocalApic instance - pub fn new(base_address: u64) -> LocalApic { - LocalApic { base_address } + + pub fn new() -> Self { + LocalApic {base_address: LAPIC_BASE_ADDR} } - pub fn enable(&self) { - // unsafe { - // // Set the APIC base address in the MSR - // asm!("wrmsr" :: "c"(0x1b), "a"(self.base_address & 0xFFFFFFFF), "d"(self.base_address >> 32)); - // } + pub fn enable(&mut self) { + let mut eax: u32; + let mut edx: u32; + + // Read IA32_APIC_BASE MSR + unsafe { + asm!( + "rdmsr", + inlateout("ecx") IA32_APIC_BASE_MSR => eax, + lateout("edx") edx, + ); + } + + // Set the APIC Enabled bit (bit 11) + edx |= IA32_APIC_BASE_MSR_ENABLE; + + // Write back to IA32_APIC_BASE MSR to enable APIC + unsafe { + asm!( + "wrmsr", + in("ecx") IA32_APIC_BASE_MSR, + in("eax") eax, + in("edx") edx, + ); + } } + + /// Enable interrupt handler - pub fn set_interrupt_handler(&self, vector: u8, handler: fn()) {} + pub fn set_interrupt_handler(&self, vector: u8, handler: fn()) { + + } /// Enable a specific interrupt vector pub fn enable_interrupt(&self, vector: u8) { - // Add code to enable a specific interrupt vector } /// Send an interrupt to another process - pub fn send_interrupt_process(&self, cpu_id: u64, vector: u8) { - let destination = cpu_id << 24; + pub fn send_interrupt_process(&self, cpu_id : u64, vector : u8) { + let destination = (cpu_id as u64) << 24; let icr_register = self.base_address + 0x300; let icr_value = destination | (vector as u64); - unsafe { core::ptr::write_volatile(icr_register as *mut u32, icr_value as u32) } + unsafe { + core::ptr::write_volatile(icr_register as *mut u32, icr_value as u32) + } } + + /// Setting the apic timer interrupt, write to the base + offset + pub fn set_apic_timer(&self, value: u32) { + let mut timer_reg = self.base_address + LAPIC_TIMER_REGISTER as u64; + unsafe { + core::ptr::write_volatile(timer_reg as *mut u32, value); + } + } + + /// Setting the spurious interrupt vector register + pub fn set_svr(&self, value: u32) { + let mut svr = self.base_address + LAPIC_SVR_REGISTER as u64; + unsafe { + core::ptr::write_volatile(svr as *mut u32, value); + } + } + } /// Check if the CPU architecture supports APIC pub fn check_apic() -> bool { let cpuid = CpuId::new(); + if let Some(features) = cpuid.get_feature_info() { + if features.has_apic() { + return true; + } else { + return false; + } + } + false +} + +pub fn get_local_apic_id() -> u8 { + let cpuid = CpuId::new(); if let Some(features) = cpuid.get_feature_info() { - features.has_apic() + return features.initial_local_apic_id(); + } + return 0; +} + +pub fn is_apic_enabled() -> bool { + let mut eax: u32; + let mut edx: u32; + + // Read IA32_APIC_BASE MSR + unsafe { + asm!( + "rdmsr", + inlateout("ecx") IA32_APIC_BASE_MSR => eax, + lateout("edx") edx, + ); + } + + // Check if the APIC Enabled bit (bit 11) is set + (edx & IA32_APIC_BASE_MSR_ENABLE) != 0 + +} + + +// 320h LVT Timer Register Read/Write + +/// Returning the information of the cpu, specifically the brand +#[cfg(target_arch = "x86_64")] +pub fn get_processor_brand() -> [u8; MAX_BRAND_STRING_SIZE] { + let cpuid = CpuId::new(); + + if let Some(features) = cpuid.get_processor_brand_string() { + let mut result = [0u8; MAX_BRAND_STRING_SIZE]; + let bytes = features.as_str().as_bytes(); + result[..bytes.len()].copy_from_slice(bytes); + return result; } else { - false + return [0u8; MAX_BRAND_STRING_SIZE]; } } -/// Read the current timestamp + + +#[cfg(target_arch = "x86_64")] +pub fn get_num_cores() -> u32 { + let cpuid = CpuId::new(); + + let feature_info = cpuid.get_feature_info().expect("CPUID not supported"); + + // Extract the number of CPUs from the ebx register + let num_cpus = ((feature_info. >> 16) & 0xFF) + 1; + + num_cpus + +} + + pub fn get_time_stamp() -> u64 { - unsafe { x86_64::_rdtsc() } + unsafe { + x86_64::_rdtsc() + } } + + + + + + + + + diff --git a/kernel/src/interrupts.rs b/kernel/src/interrupts.rs index c37fe4d..8d8cf61 100644 --- a/kernel/src/interrupts.rs +++ b/kernel/src/interrupts.rs @@ -1,21 +1,178 @@ -use crate::{print, println}; +use crate::apic::LocalApic; +use crate::println; +use crate::{gdt, hlt_loop, task::timeout::poll_timeouts}; use lazy_static::lazy_static; use pic8259::ChainedPics; use spin; +use x86_64::instructions::interrupts; use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode}; +use x86_64::instructions::port::Port; -#[derive(Debug)] -pub struct IVT {} +pub const PIC_1_OFFSET: u8 = 32; +pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8; -// lazy_static! { -// static ref IDT : InterruptDescriptorTable = { -// let mut idt = InterruptDescriptorTable::new(); -// idt.divide_error.set_handler_fn(divide_by_zero); -// }; +//pub static PICS: spin::Mutex = spin::Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) }); + +#[derive(Debug, Clone, Copy)] +#[repr(u8)] +pub enum InterruptIndex { + Timer = PIC_1_OFFSET, + Keyboard, +} + +impl InterruptIndex { + pub fn as_u8(self) -> u8 { + self as u8 + } + + fn as_usize(self) -> usize { + usize::from(self.as_u8()) + } +} + +/// An interrupt manager for registering and blocking/unblocking interrupts +pub struct InterruptHandler { + idt: InterruptDescriptorTable, +} + +pub type InterruptHandlerFunc = extern "x86-interrupt" fn(InterruptStackFrame) -> (); +impl InterruptHandler { + /// Create an interrupt manager + /// Will create a IDT and maintain it with helper functions belonging to this object + pub fn new() -> Self { + let mut idt = InterruptDescriptorTable::new(); + idt.breakpoint.set_handler_fn(breakpoint_handler); + idt.page_fault.set_handler_fn(page_fault_handler); + unsafe { + idt.double_fault + .set_handler_fn(double_fault_handler) + .set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX); + } + idt[InterruptIndex::Timer.as_usize()].set_handler_fn(timer_interrupt_handler); + idt[0x27].set_handler_fn(handle_irq7); + idt[0x2f].set_handler_fn(handle_irq15); + InterruptHandler { idt } + } + + /// Initialize the interrupt handler + pub fn init(&self) { + unsafe { self.idt.load_unsafe() }; + } + + /// Static function for unblocking an interrupt by irq_num + pub fn unblock_irq(irq_num: u8) { + let mut locked_pics = PICS.lock(); + let data = unsafe { locked_pics.read_masks() }; + // set the irq bit to 0 + if irq_num < 8 { + unsafe { locked_pics.write_masks(data[0] & !(1 << irq_num), data[1]) }; + } else { + unsafe { locked_pics.write_masks(data[0], data[1] & !(1 << (irq_num - 8))) }; + } + } + + /// Static function for blocking an interrupt by irq_num + pub fn block_irq(irq_num: u8) { + let mut locked_pics = PICS.lock(); + let data = unsafe { locked_pics.read_masks() }; + // set the irq bit to 1 + if irq_num < 8 { + unsafe { locked_pics.write_masks(data[0] | 1 << irq_num, data[1]) }; + } else { + unsafe { locked_pics.write_masks(data[0], data[1] | 1 << (irq_num - 8)) }; + } + } + + /// Register an interrupt handler + /// Used by the RTL card to receive device interrupts + pub fn register_irq(&mut self, irq_num: usize, handler: InterruptHandlerFunc) { + println!("Registered Handler @ {}", irq_num + PIC_1_OFFSET as usize); + self.idt[irq_num + PIC_1_OFFSET as usize].set_handler_fn(handler); + unsafe { self.idt.load_unsafe() }; + println!("Registered IRQ @ {}", irq_num); + } +} + +lazy_static! { + /// An interrupt manager object protected by a mutex + pub static ref IDT: spin::Mutex = spin::Mutex::new(InterruptHandler::new()); +} + +/// Initialize the IDT +pub fn init_idt() { + IDT.lock().init(); +} + +extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) { + println!("EXCEPTION: BREAKPOINT\n{:#?}", stack_frame); +} + +extern "x86-interrupt" fn page_fault_handler(stack_frame: InterruptStackFrame, error_code: PageFaultErrorCode) { + use x86_64::registers::control::Cr2; + + println!("EXCEPTION: PAGE FAULT"); + println!("Accessed Address: {:?}", Cr2::read()); + println!("Error Code: {:?}", error_code); + println!("{:#?}", stack_frame); + hlt_loop(); +} + +extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame, _error_code: u64) -> ! { + panic!("EXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); +} + +extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) { + interrupts::disable(); + unsafe { + LocalApic::send_interrupt_process(&self, cpu_id, vector) + } +} + +unsafe fn pic_get_irq_reg(ocw3: u8) -> u16 { + let mut pic1_cmd = Port::::new(0x20); + let mut pic2_cmd = Port::::new(0xA0); + pic1_cmd.write(ocw3); + pic2_cmd.write(ocw3); + let reg1 = pic1_cmd.read(); + let reg2 = pic2_cmd.read(); + ((reg2 as u16) << 8) | (reg1 as u16) +} + +fn pic_get_irr() -> u16 { + unsafe { pic_get_irq_reg(0x0a) } +} + +fn pic_get_isr() -> u16 { + unsafe { pic_get_irq_reg(0x0b) } +} + +// extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStackFrame) { +// let mut port = Port::new(0x60); +// let scancode: u8 = unsafe { port.read() }; +// crate::task::keyboard::add_scancode(scancode); + +// unsafe { +// PICS.lock().notify_end_of_interrupt(InterruptIndex::Keyboard.as_u8()); +// } // } -/// Divide by zero interrupt handler -extern "x86-interrupt" fn divide_by_zero(stack_frame: InterruptStackFrame) { - println!("EXCEPTION: DIVIDE ERROR\n{:#?}", stack_frame); - loop {} +extern "x86-interrupt" fn handle_irq7(_stack_frame: InterruptStackFrame) { + let _irr = pic_get_irr(); + let isr = pic_get_isr(); + + if isr & (1 << 7) != 0 { + panic!("Non-spurious IRQ7?!"); + } +} + +extern "x86-interrupt" fn handle_irq15(_stack_frame: InterruptStackFrame) { + let _irr = pic_get_irr(); + let isr = pic_get_isr(); + + if isr & (1 << 15) != 0 { + panic!("Non-spurious IRQ15?!"); + } + unsafe { + PICS.lock().notify_end_of_interrupt(PIC_1_OFFSET); + } } diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index fa426c1..b04d2ad 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -4,60 +4,62 @@ #![feature(const_mut_refs)] #![feature(ptr_internals)] #![feature(type_name_of_val)] -#![allow(clippy::missing_safety_doc)] -#![allow(clippy::let_and_return)] -#![allow(clippy::new_without_default)] -pub mod allocator; pub mod apic; -pub mod gdt; -pub mod interrupts; -pub mod network; -pub mod prelude; -pub mod process; -pub mod qemu; -pub mod serial; -pub mod task; pub mod vga_buffer; -extern crate alloc; - use core::panic::PanicInfo; +use core::str; +extern crate multiboot2; +use multiboot2::BootInformation; + +use crate::apic::{get_processor_brand, get_num_cores, get_local_apic_id}; #[panic_handler] -fn panic(info: &PanicInfo) -> ! { - use qemu::*; - serial_println!("[failed]\n"); - serial_println!("Error: {}\n", info); - exit_qemu(QemuExitCode::Failed); - hlt_loop() +fn panic(info : &PanicInfo) -> ! { + loop {} } -pub fn hlt_loop() -> ! { - loop { - x86_64::instructions::hlt(); - } -} /// The entry point into the kernel as we will have to initialize gdt, idt, apic, etc. #[no_mangle] -pub extern "C" fn kernel_main( - multiboot_information_address: usize, - stack_start: usize, - stack_end: usize, -) -> ! { - /// println!("Soup OS"); +pub extern "C" fn kernel_main(multiboot_information_address: usize, stack_start : usize, stack_end : usize) -> ! { + println!("Soup OS"); + let boot_info = unsafe { multiboot2::load(multiboot_information_address).unwrap() }; - if apic::check_apic() { + if apic::check_apic() == true { println!("We have an apic!"); - let local_apic = apic::LocalApic::new(0xfee00000); + + + let mut lapic = apic::LocalApic::new(); + lapic.enable(); + + if apic::is_apic_enabled() == true { + println!("Apic is enabled"); + } else { + println!("Apic is not enabled"); + } + + let apid_id = get_local_apic_id(); + + println!("Local Apic ID: {}", apid_id); + + let processor_brand_string = get_processor_brand(); + let brand_str = str::from_utf8(&processor_brand_string).unwrap_or(""); + + println!("CPU Information: {} ", brand_str); + + let core_count = get_num_cores(); + + println!("Number of cores on CPU: {}", core_count); + + // local_apic.send_interrupt_process(1, 0x20); // println!("Sent an interrupt!"); } - println!("Looks good :)"); - serial_println!("Serial looks good!"); - hlt_loop() + + loop {} }