user: add a basic cryptography tool
This commit is contained in:
parent
17dc8e9a4d
commit
ae5aae7fb4
227
userspace/Cargo.lock
generated
227
userspace/Cargo.lock
generated
@ -8,7 +8,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
@ -78,7 +78,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -140,7 +140,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -209,6 +209,17 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypt"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"ed25519-dalek",
|
||||
"rand 0.8.5",
|
||||
"rsa",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
@ -222,8 +233,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/curve25519-dalek.git?branch=alnyan%2Fyggdrasil#5f4dbb09259347077d3a5024ba60c77efde93a3a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
@ -238,12 +248,11 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "curve25519-dalek-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/curve25519-dalek.git?branch=alnyan%2Fyggdrasil#5f4dbb09259347077d3a5024ba60c77efde93a3a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -253,6 +262,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"pem-rfc7468",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
@ -272,6 +282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"const-oid",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
@ -282,17 +293,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
|
||||
dependencies = [
|
||||
"pkcs8",
|
||||
"signature",
|
||||
"signature 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ed25519-dalek"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/curve25519-dalek.git?branch=alnyan%2Fyggdrasil#5f4dbb09259347077d3a5024ba60c77efde93a3a"
|
||||
dependencies = [
|
||||
"curve25519-dalek",
|
||||
"ed25519",
|
||||
"rand_core 0.6.4 (git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4)",
|
||||
"serde",
|
||||
"sha2",
|
||||
"subtle",
|
||||
@ -387,7 +398,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -522,6 +533,9 @@ name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
@ -624,7 +638,7 @@ dependencies = [
|
||||
"bytemuck",
|
||||
"clap",
|
||||
"clap-num",
|
||||
"rand",
|
||||
"rand 0.9.0-alpha.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
@ -642,12 +656,48 @@ dependencies = [
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint-dig"
|
||||
version = "0.8.2"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/num-bigint-dig.git?branch=alnyan%2Fyggdrasil-0.8.2#e0ff3fcf8e9f5612be8ede9df7458bd762ac525f"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"lazy_static",
|
||||
"libm",
|
||||
"num-integer",
|
||||
"num-iter",
|
||||
"num-traits",
|
||||
"rand 0.8.5",
|
||||
"smallvec",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-iter"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
@ -717,6 +767,15 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pem-rfc7468"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
|
||||
dependencies = [
|
||||
"base64ct",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
@ -735,6 +794,17 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkcs1"
|
||||
version = "0.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
|
||||
dependencies = [
|
||||
"der",
|
||||
"pkcs8",
|
||||
"spki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkcs8"
|
||||
version = "0.10.2"
|
||||
@ -757,7 +827,7 @@ version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -767,7 +837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -800,22 +870,40 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil#9fac921fcc405a936b9a88b6bb9f2ced264bc0ec"
|
||||
version = "0.8.5"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4#27d8b41f68e239bf5b2e5079554f1b861966672f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core 0.7.0",
|
||||
"zerocopy",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4 (git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.0-alpha.1"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil#d78efe056f23f1896b0e4f03a62d4b6adc37ea07"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0-alpha.1",
|
||||
"rand_core 0.9.0-alpha.1",
|
||||
"zerocopy 0.8.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.4.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil#9fac921fcc405a936b9a88b6bb9f2ced264bc0ec"
|
||||
version = "0.3.1"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4#27d8b41f68e239bf5b2e5079554f1b861966672f"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.7.0",
|
||||
"rand_core 0.6.4 (git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0-alpha.1"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil#d78efe056f23f1896b0e4f03a62d4b6adc37ea07"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.0-alpha.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -829,11 +917,19 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.7.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil#9fac921fcc405a936b9a88b6bb9f2ced264bc0ec"
|
||||
version = "0.6.4"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4#27d8b41f68e239bf5b2e5079554f1b861966672f"
|
||||
dependencies = [
|
||||
"getrandom 0.2.12",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.0-alpha.1"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil#d78efe056f23f1896b0e4f03a62d4b6adc37ea07"
|
||||
dependencies = [
|
||||
"getrandom 0.2.12",
|
||||
"zerocopy 0.8.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -892,6 +988,25 @@ dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.6"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rsa.git?branch=alnyan%2Fyggdrasil#1ebb9403b0ad1ca7eab5dffbb0837a53d68c4ca3"
|
||||
dependencies = [
|
||||
"const-oid",
|
||||
"digest",
|
||||
"num-bigint-dig",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"pkcs1",
|
||||
"pkcs8",
|
||||
"rand_core 0.6.4 (git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4)",
|
||||
"signature 2.2.0 (git+https://git.alnyan.me/yggdrasil/rustcrypto-traits.git?branch=alnyan%2Fyggdrasil-2.2.0)",
|
||||
"spki",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rsh"
|
||||
version = "0.1.0"
|
||||
@ -899,7 +1014,6 @@ dependencies = [
|
||||
"bytemuck",
|
||||
"clap",
|
||||
"cross",
|
||||
"ed25519-dalek",
|
||||
"flexbuffers",
|
||||
"libterm",
|
||||
"serde",
|
||||
@ -980,7 +1094,7 @@ checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1060,7 +1174,16 @@ version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||
dependencies = [
|
||||
"rand_core 0.6.4",
|
||||
"rand_core 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signature"
|
||||
version = "2.2.0"
|
||||
source = "git+https://git.alnyan.me/yggdrasil/rustcrypto-traits.git?branch=alnyan%2Fyggdrasil-2.2.0#ac3771039858e20b812450ff7b6bf67e29436208"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"rand_core 0.6.4 (git+https://git.alnyan.me/yggdrasil/rand.git?branch=alnyan%2Fyggdrasil-rng_core-0.6.4)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1081,6 +1204,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "spki"
|
||||
version = "0.7.3"
|
||||
@ -1122,9 +1251,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.85"
|
||||
version = "2.0.86"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56"
|
||||
checksum = "e89275301d38033efb81a6e60e3497e734dfcc62571f2854bf4b16690398824c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -1152,7 +1281,7 @@ dependencies = [
|
||||
"humansize",
|
||||
"init",
|
||||
"libterm",
|
||||
"rand",
|
||||
"rand 0.9.0-alpha.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
@ -1186,22 +1315,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.65"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5"
|
||||
checksum = "5d171f59dbaa811dbbb1aee1e73db92ec2b122911a48e1390dfe327a821ddede"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.65"
|
||||
version = "1.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602"
|
||||
checksum = "b08be0f17bd307950653ce45db00cd31200d82b624b36e181337d9c7d92765b5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1548,7 +1677,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a4e33e6dce36f2adba29746927f8e848ba70989fdb61c772773bbdda8b5d6a7"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1559,7 +1697,18 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.85",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cd137b4cc21bde6ecce3bbbb3350130872cda0be2c6888874279ea76e17d4c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.86",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -16,7 +16,8 @@ members = [
|
||||
"rdb",
|
||||
"lib/yasync",
|
||||
"rsh",
|
||||
"lib/cross"
|
||||
"lib/cross",
|
||||
"crypt"
|
||||
]
|
||||
exclude = ["dynload-program", "test-kernel-module"]
|
||||
|
||||
@ -27,9 +28,16 @@ serde_json = "1.0.132"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
bytemuck = "1.19.0"
|
||||
thiserror = "1.0.64"
|
||||
rand = { git = "https://git.alnyan.me/yggdrasil/rand.git", branch = "alnyan/yggdrasil" }
|
||||
flexbuffers = "2.0.0"
|
||||
|
||||
# Vendored/patched dependencies
|
||||
rand = { git = "https://git.alnyan.me/yggdrasil/rand.git", branch = "alnyan/yggdrasil" }
|
||||
ring = { git = "https://git.alnyan.me/yggdrasil/ring.git", branch = "alnyan/yggdrasil" }
|
||||
rsa = { git = "https://git.alnyan.me/yggdrasil/rsa.git", branch = "alnyan/yggdrasil" }
|
||||
curve25519-dalek = { git = "https://git.alnyan.me/yggdrasil/curve25519-dalek.git", branch = "alnyan/yggdrasil" }
|
||||
x25519-dalek = { git = "https://git.alnyan.me/yggdrasil/curve25519-dalek.git", branch = "alnyan/yggdrasil" }
|
||||
ed25519-dalek = { git = "https://git.alnyan.me/yggdrasil/curve25519-dalek.git", branch = "alnyan/yggdrasil" }
|
||||
|
||||
# Internal crates
|
||||
serde-ipc.path = "lib/serde-ipc"
|
||||
libterm.path = "lib/libterm"
|
||||
|
12
userspace/crypt/Cargo.toml
Normal file
12
userspace/crypt/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "crypt"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
rsa.workspace = true
|
||||
ed25519-dalek = { workspace = true, features = ["rand_core", "pem"] }
|
||||
clap.workspace = true
|
||||
thiserror.workspace = true
|
||||
|
||||
rand = { git = "https://git.alnyan.me/yggdrasil/rand.git", branch = "alnyan/yggdrasil-rng_core-0.6.4" }
|
113
userspace/crypt/src/lib.rs
Normal file
113
userspace/crypt/src/lib.rs
Normal file
@ -0,0 +1,113 @@
|
||||
use std::{
|
||||
fs::File,
|
||||
io::{self, stdin, stdout, BufRead, BufReader, BufWriter, Read, Stdin, Stdout, Write},
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
pub mod rsa;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error("{0}")]
|
||||
Io(#[from] io::Error),
|
||||
#[error("RSA error: {0}")]
|
||||
Rsa(#[from] ::rsa::Error),
|
||||
#[error("PKCS#1 error: {0}")]
|
||||
Pkcs1(#[from] ::rsa::pkcs1::Error),
|
||||
#[error("PKCS#8 error: {0}")]
|
||||
Pkcs8(#[from] ::rsa::pkcs8::Error),
|
||||
#[error("PKCS#8 error: {0}")]
|
||||
Pkcs8Spki(#[from] ::rsa::pkcs8::spki::Error),
|
||||
#[error("incompatible options: {0}")]
|
||||
IncompatibleOptions(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
pub struct AsymmetricEncryptOptions {
|
||||
#[clap(short, long, help = "Ciphertext output (default: stdout)")]
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(short = 'k', long, help = "Public key to use")]
|
||||
pub public_key: PathBuf,
|
||||
#[clap(help = "Plaintext input (default: stdin)")]
|
||||
pub input: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
pub struct AsymmetricDecryptOptions {
|
||||
#[clap(short, long, help = "Plaintext output (default: stdout)")]
|
||||
pub output: Option<PathBuf>,
|
||||
#[clap(short = 'k', long, help = "Private key to use")]
|
||||
pub private_key: PathBuf,
|
||||
#[clap(help = "Ciphertext input (default: stdin)")]
|
||||
pub input: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
pub struct AsymmetricKeyOptions {
|
||||
#[clap(short = 'o', long, help = "Public key output file (default: stdout)")]
|
||||
pub public_key: Option<PathBuf>,
|
||||
#[clap(help = "Private key output file")]
|
||||
pub private_key: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Input {
|
||||
Stdin(Stdin),
|
||||
File(BufReader<File>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Output {
|
||||
Stdout(Stdout),
|
||||
File(BufWriter<File>),
|
||||
}
|
||||
|
||||
impl Input {
|
||||
pub fn from_path_option<P: AsRef<Path>>(option: Option<P>) -> Result<Self, io::Error> {
|
||||
match option {
|
||||
Some(path) => File::open(path).map(BufReader::new).map(Self::File),
|
||||
None => Ok(Self::Stdin(stdin())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_line(&mut self, buf: &mut String) -> io::Result<usize> {
|
||||
match self {
|
||||
Self::Stdin(stdin) => stdin.read_line(buf),
|
||||
Self::File(file) => file.read_line(buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Read for Input {
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
match self {
|
||||
Self::Stdin(stdin) => stdin.read(buf),
|
||||
Self::File(file) => file.read(buf),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Output {
|
||||
pub fn from_path_option<P: AsRef<Path>>(option: Option<P>) -> Result<Self, io::Error> {
|
||||
match option {
|
||||
Some(path) => File::create(path).map(BufWriter::new).map(Self::File),
|
||||
None => Ok(Self::Stdout(stdout())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Output {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
match self {
|
||||
Self::Stdout(stdout) => stdout.write(buf),
|
||||
Self::File(file) => file.write(buf),
|
||||
}
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
match self {
|
||||
Self::Stdout(stdout) => stdout.flush(),
|
||||
Self::File(file) => file.flush(),
|
||||
}
|
||||
}
|
||||
}
|
122
userspace/crypt/src/main.rs
Normal file
122
userspace/crypt/src/main.rs
Normal file
@ -0,0 +1,122 @@
|
||||
use std::process::ExitCode;
|
||||
|
||||
use clap::Parser;
|
||||
use crypt::{
|
||||
rsa::RsaKeyOptions, AsymmetricDecryptOptions, AsymmetricEncryptOptions, AsymmetricKeyOptions,
|
||||
Error,
|
||||
};
|
||||
use rsa::pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding};
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
struct Args {
|
||||
#[clap(subcommand)]
|
||||
command: Command,
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
enum Command {
|
||||
#[clap(subcommand, about = "Generate a key/keypair")]
|
||||
Generate(GenerateCommand),
|
||||
#[clap(subcommand, about = "Encrypt data using a public key")]
|
||||
Encrypt(EncryptCommand),
|
||||
#[clap(subcommand, about = "Decrypt data using a private key")]
|
||||
Decrypt(DecryptCommand),
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
enum GenerateCommand {
|
||||
Rsa {
|
||||
#[clap(short = 'b', long, help = "Key bitness")]
|
||||
bits: usize,
|
||||
#[clap(flatten)]
|
||||
options: AsymmetricKeyOptions,
|
||||
#[clap(flatten)]
|
||||
rsa_options: RsaKeyOptions,
|
||||
},
|
||||
Ed25519 {
|
||||
#[clap(flatten)]
|
||||
options: AsymmetricKeyOptions,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
enum EncryptCommand {
|
||||
Rsa {
|
||||
#[clap(flatten)]
|
||||
options: AsymmetricEncryptOptions,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Subcommand)]
|
||||
enum DecryptCommand {
|
||||
Rsa {
|
||||
#[clap(flatten)]
|
||||
options: AsymmetricDecryptOptions,
|
||||
},
|
||||
}
|
||||
|
||||
fn generate_ed25519(options: &AsymmetricKeyOptions) -> Result<(), Error> {
|
||||
let mut rng = rand::thread_rng();
|
||||
let signing_key = ed25519_dalek::SigningKey::generate(&mut rng);
|
||||
|
||||
println!("Generating a new ed25519 keypair");
|
||||
signing_key.write_pkcs8_pem_file(&options.private_key, LineEnding::LF)?;
|
||||
println!("Done, deriving a verifying key");
|
||||
|
||||
if let Some(public_key) = options.public_key.as_ref() {
|
||||
signing_key
|
||||
.verifying_key()
|
||||
.write_public_key_pem_file(public_key, LineEnding::LF)?;
|
||||
} else {
|
||||
let key_string = signing_key
|
||||
.verifying_key()
|
||||
.to_public_key_pem(LineEnding::LF)?;
|
||||
println!("Public key:");
|
||||
println!("{key_string}");
|
||||
}
|
||||
println!("Done!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate(command: GenerateCommand) -> Result<(), Error> {
|
||||
match command {
|
||||
GenerateCommand::Rsa {
|
||||
options,
|
||||
rsa_options,
|
||||
bits,
|
||||
} => crypt::rsa::generate_rsa(&options, &rsa_options, bits),
|
||||
GenerateCommand::Ed25519 { options } => generate_ed25519(&options),
|
||||
}
|
||||
}
|
||||
|
||||
fn encrypt(command: EncryptCommand) -> Result<(), Error> {
|
||||
match command {
|
||||
EncryptCommand::Rsa { options } => crypt::rsa::encrypt_rsa(&options),
|
||||
}
|
||||
}
|
||||
|
||||
fn decrypt(command: DecryptCommand) -> Result<(), Error> {
|
||||
match command {
|
||||
DecryptCommand::Rsa { options } => crypt::rsa::decrypt_rsa(&options),
|
||||
}
|
||||
}
|
||||
|
||||
fn run(command: Command) -> Result<(), Error> {
|
||||
match command {
|
||||
Command::Generate(command) => generate(command),
|
||||
Command::Encrypt(command) => encrypt(command),
|
||||
Command::Decrypt(command) => decrypt(command),
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> ExitCode {
|
||||
let args = Args::parse();
|
||||
|
||||
match run(args.command) {
|
||||
Ok(_) => ExitCode::SUCCESS,
|
||||
Err(error) => {
|
||||
eprintln!("Error: {error}");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
126
userspace/crypt/src/rsa/mod.rs
Normal file
126
userspace/crypt/src/rsa/mod.rs
Normal file
@ -0,0 +1,126 @@
|
||||
use std::{
|
||||
io::{Read, Write},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use rsa::{
|
||||
pkcs1::{DecodeRsaPrivateKey, DecodeRsaPublicKey, EncodeRsaPrivateKey, EncodeRsaPublicKey},
|
||||
pkcs8::LineEnding,
|
||||
Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
AsymmetricDecryptOptions, AsymmetricEncryptOptions, AsymmetricKeyOptions, Error, Input, Output,
|
||||
};
|
||||
|
||||
#[derive(Default, Debug, Clone, Copy, PartialEq, clap::ValueEnum)]
|
||||
pub enum KeyFormat {
|
||||
#[default]
|
||||
#[clap(alias("pem"), help = "PKCS#1 PEM")]
|
||||
Pkcs1Pem,
|
||||
#[clap(alias("der"), help = "PKCS#1 DER")]
|
||||
Pkcs1Der,
|
||||
}
|
||||
|
||||
#[derive(Debug, clap::Parser)]
|
||||
pub struct RsaKeyOptions {
|
||||
#[clap(short = 'f', long, help = "Key output format", default_value = "pem")]
|
||||
pub format: KeyFormat,
|
||||
}
|
||||
|
||||
pub fn read_private_key<P: AsRef<Path>>(keyfile: P) -> Result<RsaPrivateKey, Error> {
|
||||
let keyfile = keyfile.as_ref();
|
||||
if let Ok(key) = RsaPrivateKey::read_pkcs1_pem_file(keyfile) {
|
||||
return Ok(key);
|
||||
}
|
||||
let key = RsaPrivateKey::read_pkcs1_der_file(keyfile)?;
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
pub fn read_public_key<P: AsRef<Path>>(keyfile: P) -> Result<RsaPublicKey, Error> {
|
||||
let keyfile = keyfile.as_ref();
|
||||
if let Ok(key) = RsaPublicKey::read_pkcs1_pem_file(keyfile) {
|
||||
return Ok(key);
|
||||
}
|
||||
let key = RsaPublicKey::read_pkcs1_der_file(keyfile)?;
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
pub fn generate_rsa(
|
||||
options: &AsymmetricKeyOptions,
|
||||
rsa: &RsaKeyOptions,
|
||||
bits: usize,
|
||||
) -> Result<(), Error> {
|
||||
if rsa.format == KeyFormat::Pkcs1Der && options.public_key.is_none() {
|
||||
return Err(Error::IncompatibleOptions(format!(
|
||||
"DER output format requires -o/--public-key"
|
||||
)));
|
||||
}
|
||||
|
||||
println!("Generating a new RSA keypair, bits={}", bits);
|
||||
println!("This will take a while");
|
||||
let mut rng = rand::thread_rng();
|
||||
let private_key = RsaPrivateKey::new(&mut rng, bits)?;
|
||||
|
||||
println!("Done, deriving a public key");
|
||||
let public_key = private_key.to_public_key();
|
||||
|
||||
match rsa.format {
|
||||
KeyFormat::Pkcs1Pem => {
|
||||
private_key.write_pkcs1_pem_file(&options.private_key, LineEnding::LF)?;
|
||||
|
||||
if let Some(public_key_path) = options.public_key.as_ref() {
|
||||
public_key.write_pkcs1_pem_file(public_key_path, LineEnding::LF)?;
|
||||
} else {
|
||||
let output = public_key.to_pkcs1_pem(LineEnding::LF)?;
|
||||
println!("Public key:");
|
||||
println!("{output}");
|
||||
}
|
||||
}
|
||||
KeyFormat::Pkcs1Der => {
|
||||
private_key.write_pkcs1_der_file(&options.private_key)?;
|
||||
|
||||
if let Some(public_key_path) = options.public_key.as_ref() {
|
||||
public_key.write_pkcs1_der_file(public_key_path)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Done!");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn encrypt_rsa(options: &AsymmetricEncryptOptions) -> Result<(), Error> {
|
||||
let key = read_public_key(&options.public_key)?;
|
||||
let mut input = Input::from_path_option(options.input.as_ref())?;
|
||||
let mut output = Output::from_path_option(options.output.as_ref())?;
|
||||
let mut buf = [0; 2048];
|
||||
let mut rng = rand::thread_rng();
|
||||
loop {
|
||||
let len = input.read(&mut buf)?;
|
||||
if len == 0 {
|
||||
break;
|
||||
}
|
||||
let ciphertext = key.encrypt(&mut rng, Pkcs1v15Encrypt, &buf[..len])?;
|
||||
output.write_all(&ciphertext)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn decrypt_rsa(options: &AsymmetricDecryptOptions) -> Result<(), Error> {
|
||||
let key = read_private_key(&options.private_key)?;
|
||||
let mut input = Input::from_path_option(options.input.as_ref())?;
|
||||
let mut output = Output::from_path_option(options.output.as_ref())?;
|
||||
let mut buf = [0; 2048];
|
||||
loop {
|
||||
let len = input.read(&mut buf)?;
|
||||
if len == 0 {
|
||||
break;
|
||||
}
|
||||
let plaintext = key.decrypt(Pkcs1v15Encrypt, &buf[..len])?;
|
||||
output.write_all(&plaintext)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
9
userspace/lib/yasync/Cargo.toml
Normal file
9
userspace/lib/yasync/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "yasync"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
cross.workspace = true
|
||||
futures-util = "0.3.31"
|
||||
spmc = "0.3.0"
|
219
userspace/lib/yasync/src/lib.rs
Normal file
219
userspace/lib/yasync/src/lib.rs
Normal file
@ -0,0 +1,219 @@
|
||||
#![cfg_attr(target_os = "yggdrasil", feature(yggdrasil_os, rustc_private))]
|
||||
use std::{
|
||||
cell::OnceCell,
|
||||
collections::HashMap,
|
||||
future::Future,
|
||||
os::fd::{AsRawFd, RawFd},
|
||||
pin::Pin,
|
||||
sync::{Arc, Mutex},
|
||||
task::{Context, Poll, Waker},
|
||||
thread::JoinHandle,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use cross::io::{Poll as PollChannel, TimerFd};
|
||||
use futures_util::task::{waker_ref, ArcWake};
|
||||
use spmc::{Receiver, Sender};
|
||||
|
||||
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
|
||||
|
||||
pub struct Executor {
|
||||
_id: usize,
|
||||
queue: Arc<Receiver<Arc<Task>>>,
|
||||
}
|
||||
|
||||
pub struct Task {
|
||||
future: Mutex<Option<BoxFuture<'static, ()>>>,
|
||||
runtime: Arc<RuntimeInner>,
|
||||
}
|
||||
|
||||
struct ReactorInner {
|
||||
poll: PollChannel,
|
||||
event_map: HashMap<RawFd, Waker>,
|
||||
}
|
||||
|
||||
pub struct Reactor {
|
||||
// TODO this lock will become very contended
|
||||
inner: Mutex<ReactorInner>,
|
||||
}
|
||||
|
||||
struct RuntimeInner {
|
||||
// TODO this lock will become very contended
|
||||
sender: Mutex<Sender<Arc<Task>>>,
|
||||
reactor: Arc<Reactor>
|
||||
}
|
||||
|
||||
pub struct Runtime {
|
||||
inner: Arc<RuntimeInner>,
|
||||
executors: Vec<JoinHandle<()>>,
|
||||
reactor: JoinHandle<()>,
|
||||
}
|
||||
|
||||
// TODO use global timer instead of creating a timer for each sleep
|
||||
pub struct Sleep {
|
||||
timer: TimerFd,
|
||||
}
|
||||
|
||||
impl Future for Sleep {
|
||||
type Output = ();
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
let expired = self.timer.is_expired().unwrap();
|
||||
if expired {
|
||||
return Poll::Ready(());
|
||||
}
|
||||
let reactor = &RuntimeInner::get().reactor;
|
||||
reactor.register(&self.timer, cx.waker().clone());
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
pub fn new(id: usize, queue: Arc<Receiver<Arc<Task>>>) -> Self {
|
||||
Self { _id: id, queue }
|
||||
}
|
||||
|
||||
pub fn run(self) {
|
||||
loop {
|
||||
let task = self.queue.recv().unwrap();
|
||||
let mut slot = task.future.lock().unwrap();
|
||||
|
||||
if let Some(mut future) = slot.take() {
|
||||
let waker = waker_ref(&task);
|
||||
let context = &mut Context::from_waker(&waker);
|
||||
|
||||
if future.as_mut().poll(context).is_pending() {
|
||||
*slot = Some(future);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ArcWake for Task {
|
||||
fn wake_by_ref(arc_self: &Arc<Self>) {
|
||||
arc_self
|
||||
.runtime
|
||||
.sender
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send(arc_self.clone())
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
static RUNTIME: OnceCell<Arc<RuntimeInner>> = OnceCell::new();
|
||||
}
|
||||
|
||||
impl RuntimeInner {
|
||||
fn try_get() -> Option<Arc<RuntimeInner>> {
|
||||
RUNTIME.with(|r| r.get().cloned())
|
||||
}
|
||||
|
||||
fn get() -> Arc<RuntimeInner> {
|
||||
Self::try_get().expect("Runtime::get() called from a thread with no runtime")
|
||||
}
|
||||
}
|
||||
|
||||
impl Reactor {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
inner: Mutex::new(ReactorInner {
|
||||
poll: PollChannel::new().unwrap(),
|
||||
event_map: HashMap::new(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn run(self: Arc<Self>) {
|
||||
loop {
|
||||
// TODO this is a hack to prevent the lock from becoming fully contended by Reactor
|
||||
std::thread::sleep(Duration::from_millis(100));
|
||||
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
let event = inner.poll.wait(Some(Duration::from_millis(100))).unwrap();
|
||||
if let Some(fd) = event {
|
||||
inner.poll.remove(&fd).ok();
|
||||
if let Some(task) = inner.event_map.remove(&fd) {
|
||||
task.wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn register<F: AsRawFd>(&self, interest: &F, waker: Waker) {
|
||||
let mut inner = self.inner.lock().unwrap();
|
||||
let fd = interest.as_raw_fd();
|
||||
// TODO have multiple tasks be able to poll the same fd?
|
||||
assert!(inner.event_map.insert(fd, waker).is_none());
|
||||
inner.poll.add(interest).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
impl Runtime {
|
||||
pub fn new(threads: usize) -> Self {
|
||||
let mut executors = vec![];
|
||||
let (sender, receiver) = spmc::channel();
|
||||
let reactor = Arc::new(Reactor::new());
|
||||
let inner = Arc::new(RuntimeInner {
|
||||
reactor: reactor.clone(),
|
||||
sender: Mutex::new(sender),
|
||||
});
|
||||
let receiver = Arc::new(receiver);
|
||||
|
||||
// TODO add an option to run reactor on main thread?
|
||||
let reactor = std::thread::spawn(move || reactor.run());
|
||||
|
||||
for id in 0..threads {
|
||||
let receiver = receiver.clone();
|
||||
let inner = inner.clone();
|
||||
executors.push(std::thread::spawn(move || {
|
||||
// Initialize local runtime ref
|
||||
RUNTIME.with(|r| {
|
||||
if r.set(inner).is_err() {
|
||||
panic!("Couldn't initialize thread runtime");
|
||||
}
|
||||
});
|
||||
|
||||
Executor::new(id, receiver).run();
|
||||
}));
|
||||
}
|
||||
|
||||
Self {
|
||||
inner,
|
||||
executors,
|
||||
reactor,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn spawn<F: Future<Output = ()> + Send + 'static>(&self, future: F) {
|
||||
spawn_into(self.inner.clone(), future)
|
||||
}
|
||||
|
||||
pub fn join(self) {
|
||||
for executor in self.executors {
|
||||
executor.join().ok();
|
||||
}
|
||||
self.reactor.join().ok();
|
||||
}
|
||||
}
|
||||
|
||||
fn spawn_into<F: Future<Output = ()> + Send + 'static>(runtime: Arc<RuntimeInner>, future: F) {
|
||||
let task = Arc::new(Task {
|
||||
future: Mutex::new(Some(Box::pin(future))),
|
||||
runtime: runtime.clone(),
|
||||
});
|
||||
runtime.sender.lock().unwrap().send(task).unwrap();
|
||||
}
|
||||
|
||||
pub fn spawn<F: Future<Output = ()> + Send + 'static>(future: F) {
|
||||
let runtime = RuntimeInner::get();
|
||||
spawn_into(runtime, future)
|
||||
}
|
||||
|
||||
pub fn sleep(timeout: Duration) -> Sleep {
|
||||
let mut timer = TimerFd::new().unwrap();
|
||||
timer.start(timeout).unwrap();
|
||||
Sleep { timer }
|
||||
}
|
23
userspace/lib/yasync/src/main.rs
Normal file
23
userspace/lib/yasync/src/main.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use yasync::Runtime;
|
||||
|
||||
fn main() {
|
||||
let runtime = Runtime::new(4);
|
||||
|
||||
runtime.spawn(async move {
|
||||
loop {
|
||||
println!("a");
|
||||
yasync::sleep(Duration::from_secs(1)).await;
|
||||
}
|
||||
});
|
||||
|
||||
runtime.spawn(async move {
|
||||
loop {
|
||||
println!("b");
|
||||
yasync::sleep(Duration::from_millis(500)).await;
|
||||
}
|
||||
});
|
||||
|
||||
runtime.join();
|
||||
}
|
@ -17,4 +17,3 @@ cross.workspace = true
|
||||
bytemuck.workspace = true
|
||||
|
||||
smallvec = { version = "1.13.2", features = ["serde"] }
|
||||
ed25519-dalek = "2.1.1"
|
||||
|
@ -52,6 +52,8 @@ const PROGRAMS: &[(&str, &str)] = &[
|
||||
// rsh
|
||||
("rsh", "bin/rsh"),
|
||||
("rshd", "sbin/rshd"),
|
||||
// crypt
|
||||
("crypt", "bin/rc"),
|
||||
// ("dyn-loader", "libexec/dyn-loader"),
|
||||
];
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user