on the way to a usable version

This commit is contained in:
ddidderr 2024-02-14 22:23:57 +01:00
parent 668e726c21
commit ad03e176c3
Signed by: ddidderr
GPG Key ID: 3841F1C27E6F0E14
7 changed files with 437 additions and 201 deletions

343
Cargo.lock generated
View File

@ -4,35 +4,61 @@ version = 3
[[package]] [[package]]
name = "aead" name = "aead"
version = "0.4.3" version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
dependencies = [ dependencies = [
"crypto-common",
"generic-array", "generic-array",
] ]
[[package]] [[package]]
name = "atty" name = "anstream"
version = "0.2.14" version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
dependencies = [ dependencies = [
"hermit-abi", "anstyle",
"libc", "anstyle-parse",
"winapi", "anstyle-query",
"anstyle-wincon",
"colorchoice",
"utf8parse",
] ]
[[package]] [[package]]
name = "autocfg" name = "anstyle"
version = "1.1.0" version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
[[package]] [[package]]
name = "bitflags" name = "anstyle-parse"
version = "1.3.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -42,21 +68,20 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "chacha20" name = "chacha20"
version = "0.8.1" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cipher", "cipher",
"cpufeatures", "cpufeatures",
"zeroize",
] ]
[[package]] [[package]]
name = "chacha20poly1305" name = "chacha20poly1305"
version = "0.9.0" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35"
dependencies = [ dependencies = [
"aead", "aead",
"chacha20", "chacha20",
@ -67,37 +92,81 @@ dependencies = [
[[package]] [[package]]
name = "cipher" name = "cipher"
version = "0.3.0" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [ dependencies = [
"generic-array", "crypto-common",
"inout",
"zeroize",
] ]
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.1.8" version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f"
dependencies = [ dependencies = [
"atty", "clap_builder",
"bitflags", "clap_derive",
"indexmap",
"os_str_bytes",
"strsim",
"termcolor",
"textwrap",
] ]
[[package]] [[package]]
name = "cpufeatures" name = "clap_builder"
version = "0.2.2" version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "307bc0538d5f0f83b8248db3087aa92fe504e4691294d0c96c0eabc33f47ba47"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "clap_lex"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "cpufeatures"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"rand_core",
"typenum",
]
[[package]] [[package]]
name = "fcry" name = "fcry"
version = "0.9.0" version = "0.9.0"
@ -109,9 +178,9 @@ dependencies = [
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.5" version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [ dependencies = [
"typenum", "typenum",
"version_check", "version_check",
@ -119,9 +188,9 @@ dependencies = [
[[package]] [[package]]
name = "getrandom" name = "getrandom"
version = "0.2.6" version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
@ -129,41 +198,25 @@ dependencies = [
] ]
[[package]] [[package]]
name = "hashbrown" name = "heck"
version = "0.11.2" version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "hermit-abi" name = "inout"
version = "0.1.19" version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
dependencies = [ dependencies = [
"libc", "generic-array",
]
[[package]]
name = "indexmap"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee"
dependencies = [
"autocfg",
"hashbrown",
] ]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.122" version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec647867e2bf0772e28c8bcde4f0d19a9216916e890543b5a03ed8ef27b8f259" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "memchr"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]] [[package]]
name = "opaque-debug" name = "opaque-debug"
@ -171,20 +224,11 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "poly1305" name = "poly1305"
version = "0.7.2" version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf"
dependencies = [ dependencies = [
"cpufeatures", "cpufeatures",
"opaque-debug", "opaque-debug",
@ -193,9 +237,27 @@ dependencies = [
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.16" version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "proc-macro2"
version = "1.0.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
dependencies = [
"proc-macro2",
]
[[package]] [[package]]
name = "rand" name = "rand"
@ -220,56 +282,64 @@ dependencies = [
[[package]] [[package]]
name = "rand_core" name = "rand_core"
version = "0.6.3" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [ dependencies = [
"getrandom", "getrandom",
] ]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.10.0" version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
[[package]] [[package]]
name = "subtle" name = "subtle"
version = "2.4.1" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
[[package]] [[package]]
name = "termcolor" name = "syn"
version = "1.1.3" version = "2.0.48"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
dependencies = [ dependencies = [
"winapi-util", "proc-macro2",
"quote",
"unicode-ident",
] ]
[[package]]
name = "textwrap"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "typenum" name = "typenum"
version = "1.15.0" version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "universal-hash" name = "universal-hash"
version = "0.4.1" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea"
dependencies = [ dependencies = [
"generic-array", "crypto-common",
"subtle", "subtle",
] ]
[[package]]
name = "utf8parse"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -278,43 +348,78 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.10.2+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]] [[package]]
name = "winapi" name = "windows-sys"
version = "0.3.9" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu", "windows-targets",
"winapi-x86_64-pc-windows-gnu",
] ]
[[package]] [[package]]
name = "winapi-i686-pc-windows-gnu" name = "windows-targets"
version = "0.4.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [ dependencies = [
"winapi", "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]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "windows_aarch64_gnullvm"
version = "0.4.0" version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
[[package]]
name = "windows_i686_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
[[package]]
name = "windows_i686_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.4.3" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d68d9dcec5f9b43a30d38c49f91dfedfaac384cb8f085faca366c26207dd1619" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"

View File

@ -5,12 +5,13 @@ name = "fcry"
version = "0.9.0" version = "0.9.0"
[dependencies] [dependencies]
chacha20poly1305 = {version = "0.9.0", features = ["stream"]} chacha20poly1305 = {version = "0.10", features = ["stream"]}
clap = "3" clap = {version = "4", features = ["derive"]}
rand = {version = "0.8"} rand = {version = "0.8"}
[profile.release] [profile.release]
codegen-units = 1
debug = false
lto = true lto = true
debug = false
strip = true
panic = "unwind" panic = "unwind"
codegen-units = 1

View File

@ -1,54 +1,61 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use chacha20poly1305::{
aead::{stream, NewAead}, use chacha20poly1305::{aead::stream, KeyInit, XChaCha20Poly1305};
ChaCha20Poly1305,
};
use rand::{rngs::OsRng, RngCore}; use rand::{rngs::OsRng, RngCore};
use crate::error::*; use crate::error::*;
use crate::reader::ReadInfo;
use crate::utils::BUFSIZE;
use crate::utils::*; use crate::utils::*;
const BUFSIZE: usize = 64 * 1024; // 64 KiB
fn new_random_nonce() -> Result<[u8; 7], FcryError> {
let mut nonce = [0u8; 7];
OsRng.try_fill_bytes(&mut nonce)?;
Ok(nonce)
}
pub fn encrypt<S: AsRef<str>>( pub fn encrypt<S: AsRef<str>>(
input_file: Option<S>, input_file: Option<S>,
output_file: Option<S>, output_file: Option<S>,
key: [u8; 32], key: [u8; 32],
) -> Result<(), FcryError> { ) -> Result<(), FcryError> {
let mut f_plain = read_from_file_or_stdin(input_file); let mut f_plain = read_from_file_or_stdin(input_file, BUFSIZE);
let mut f_encrypted = write_to_file_or_stdout(output_file); let mut f_encrypted = write_to_file_or_stdout(output_file);
let nonce = new_random_nonce()?; let mut nonce = [0u8; 19];
OsRng.fill_bytes(&mut nonce);
// let key = XChaCha20Poly1305::generate_key(&mut OsRng);
f_encrypted.write_all(&nonce)?; f_encrypted.write_all(&nonce)?;
let aead = ChaCha20Poly1305::new(&key.into()); let aead = XChaCha20Poly1305::new(&key.into());
let mut stream_encryptor = stream::EncryptorBE32::from_aead(aead, &nonce.into()); let mut stream_encryptor = stream::EncryptorBE32::from_aead(aead, &nonce.into());
let mut buf = vec![0; BUFSIZE]; let mut buf = vec![0; BUFSIZE];
let mut read_bytes;
loop { loop {
read_bytes = f_plain.read(&mut buf)?; let read_result = f_plain.read_ahead(&mut buf)?;
if read_bytes < BUFSIZE { match read_result {
break; ReadInfo::NormalChunk(n) => {
assert_eq!(n, BUFSIZE);
assert_eq!(buf.len(), BUFSIZE);
println!("[encrypt]: read normal chunk");
stream_encryptor.encrypt_next_in_place(&[], &mut buf)?;
f_encrypted.write_all(&buf)?;
// buf grows after encrypt_next_in_place because of tag that is added
// we shrink it to the BUFSIZE in order to read the correct size
buf.truncate(BUFSIZE);
}
ReadInfo::LastChunk(n) => {
println!("[encrypt]: read last chunk");
buf.truncate(n);
stream_encryptor.encrypt_last_in_place(&[], &mut buf)?;
f_encrypted.write_all(&buf)?;
break;
}
ReadInfo::EmptyChunk => {
println!("[encrypt]: read empty chunk");
panic!("[ERROR] Empty Chunk while reading");
}
} }
stream_encryptor.encrypt_next_in_place(&[], &mut buf)?;
f_encrypted.write_all(&buf)?;
buf.truncate(BUFSIZE);
} }
buf.truncate(read_bytes);
stream_encryptor.encrypt_last_in_place(&[], &mut buf)?;
f_encrypted.write_all(&buf)?;
Ok(()) Ok(())
} }
@ -57,33 +64,41 @@ pub fn decrypt<S: AsRef<str>>(
output_file: Option<S>, output_file: Option<S>,
key: [u8; 32], key: [u8; 32],
) -> Result<(), FcryError> { ) -> Result<(), FcryError> {
let mut f_encrypted = read_from_file_or_stdin(input_file); let mut f_encrypted = read_from_file_or_stdin(input_file, BUFSIZE + 16);
let mut f_plain = write_to_file_or_stdout(output_file); let mut f_plain = write_to_file_or_stdout(output_file);
let mut nonce = [0u8; 7]; let mut nonce = [0u8; 19];
f_encrypted.read_exact(&mut nonce)?; f_encrypted.read_exact(&mut nonce)?;
let aead = ChaCha20Poly1305::new(&key.into()); let aead = XChaCha20Poly1305::new(&key.into());
let mut stream_decryptor = stream::DecryptorBE32::from_aead(aead, &nonce.into()); let mut stream_decryptor = stream::DecryptorBE32::from_aead(aead, &nonce.into());
let mut buf = vec![0; BUFSIZE + 16]; let mut buf = vec![0; BUFSIZE + 16];
let mut read_bytes;
loop { loop {
read_bytes = f_encrypted.read(&mut buf)?; let read_result = f_encrypted.read_ahead(&mut buf)?;
if read_bytes < BUFSIZE + 16 { match read_result {
break; ReadInfo::NormalChunk(n) => {
assert_eq!(n, BUFSIZE + 16);
println!("[decrypt]: read normal chunk");
stream_decryptor.decrypt_next_in_place(&[], &mut buf)?;
f_plain.write_all(&buf)?;
buf.resize(BUFSIZE + 16, 0);
}
ReadInfo::LastChunk(n) => {
println!("[decrypt]: read last chunk");
buf.truncate(n);
stream_decryptor.decrypt_last_in_place(&[], &mut buf)?;
f_plain.write_all(&buf)?;
break;
}
ReadInfo::EmptyChunk => {
println!("[decrypt]: read empty chunk");
panic!("Empty Chunk while reading");
}
} }
stream_decryptor.decrypt_next_in_place(&[], &mut buf)?;
f_plain.write_all(&buf)?;
buf.resize(BUFSIZE + 16, 0);
} }
buf.truncate(read_bytes);
stream_decryptor.decrypt_last_in_place(&[], &mut buf)?;
f_plain.write_all(&buf)?;
Ok(()) Ok(())
} }

View File

@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use chacha20poly1305::aead; use chacha20poly1305::aead;
use std::io; use std::io;

View File

@ -1,47 +1,48 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
mod crypto; mod crypto;
mod error; mod error;
mod reader;
mod utils; mod utils;
use clap::{Arg, ArgMatches, Command};
use crypto::*; use crypto::*;
use error::FcryError; use error::FcryError;
fn build_cmdline_args() -> ArgMatches { use clap::Parser;
Command::new("fcry - [f]ile[cry]pt").version(env!("CARGO_PKG_VERSION"))
.about("A file en-/decryption tool for easy use.") /// fcry - [f]ile[cry]pt: A file en-/decryption tool for easy use
.arg(Arg::new("decrypt") #[derive(Parser, Debug)]
.short('d') #[clap(author, version, about)]
.long("decrypt") struct Cli {
.help("Decrypt instead of encrypt. Encrypting is the default.") /// decrypt instead of encrypt (encryption is the default)
.takes_value(false)) #[clap(short, long)]
.arg(Arg::new("input_file") decrypt: bool,
.short('i')
.long("input-file") /// The input file to en-/decrypt
.help("The input file to en-/decrypt") #[clap(short, long)]
.takes_value(true)) input_file: Option<String>,
.arg(Arg::new("output_file")
.short('o') /// The output file.
.long("output-file") /// If not specified, en-/decrypted bytes will be sent to stdout
.help("The output file. If not specified, en-/decrypted bytes will be sent to stdout.") #[clap(short, long)]
.takes_value(true)) output_file: Option<String>,
.arg(Arg::new("raw-key")
.required(true) /// The raw bytes of the crypto key.
.long("raw-key") /// Has to be exactly 32 bytes
.help("The raw bytes of the crypto key. Has to be exactly 32 bytes.\n*** DANGEROUS, use for testing purposes only! ***") /// *** DANGEROUS, use for testing purposes only! ***
.takes_value(true)) #[clap(short, long)]
.get_matches() raw_key: String,
} }
fn run(args: ArgMatches) -> Result<(), FcryError> { fn run(cli: Cli) -> Result<(), FcryError> {
let input_file = args.value_of("input_file"); let input_file = cli.input_file;
let output_file = args.value_of("output_file"); let output_file = cli.output_file;
let mut key = [0u8; 32]; let mut key = [0u8; 32];
key.clone_from_slice(args.value_of("raw-key").unwrap().as_bytes()); dbg!(&cli.raw_key);
key.clone_from_slice(cli.raw_key.as_bytes());
if args.is_present("decrypt") { if cli.decrypt {
decrypt(input_file, output_file, key)? decrypt(input_file, output_file, key)?
} else { } else {
encrypt(input_file, output_file, key)? encrypt(input_file, output_file, key)?
@ -51,7 +52,8 @@ fn run(args: ArgMatches) -> Result<(), FcryError> {
} }
fn main() { fn main() {
if let Err(e) = run(build_cmdline_args()) { let cli = Cli::parse();
if let Err(e) = run(cli) {
println!("Error: {:?}", e); println!("Error: {:?}", e);
} }
} }

100
src/reader.rs Normal file
View File

@ -0,0 +1,100 @@
// SPDX-License-Identifier: GPL-3.0-only
use std::io;
use std::io::{BufRead, Read};
pub enum ReadInfo {
NormalChunk(usize),
LastChunk(usize),
EmptyChunk,
}
pub struct AheadReader {
inner: Box<dyn BufRead>,
buf: Vec<u8>,
bufsz: usize,
capacity: usize,
}
impl AheadReader {
pub fn from(reader: Box<dyn BufRead>, capacity: usize) -> Self {
Self {
inner: reader,
buf: vec![0; capacity],
bufsz: 0,
capacity,
}
}
fn read_until_full(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
let mut total = 0;
loop {
match self.inner.read(buf) {
Ok(0) => break,
Ok(n) => {
total += n;
let tmp = buf;
buf = &mut tmp[n..];
}
Err(e) => match e.kind() {
io::ErrorKind::Interrupted => continue,
_ => return Err(e),
},
}
}
Ok(total)
}
pub fn read_ahead(&mut self, userbuf: &mut [u8]) -> io::Result<ReadInfo> {
// 1st read
if self.bufsz == 0 {
println!("[reader] first read");
return self.first_read(userbuf);
}
println!("[reader] normal read");
// normal read (not the 1st one)
self.normal_read(userbuf)
}
pub fn read_exact(&mut self, userbuf: &mut [u8]) -> io::Result<()> {
self.inner.read_exact(userbuf)
}
fn first_read(&mut self, userbuf: &mut [u8]) -> io::Result<ReadInfo> {
// 1st read directly to userbuf (we have no cached data yet)
let n = self.read_until_full(userbuf)?;
if n == 0 {
return Ok(ReadInfo::EmptyChunk);
}
// 2nd read directly into our internal buf
let mut tmp = vec![0u8; self.capacity];
let n2 = self.read_until_full(&mut tmp)?;
self.buf = tmp;
self.bufsz = n2;
if n2 == 0 {
return Ok(ReadInfo::LastChunk(n));
}
Ok(ReadInfo::NormalChunk(n))
}
fn normal_read(&mut self, userbuf: &mut [u8]) -> io::Result<ReadInfo> {
// copy internal buf to userbuf
userbuf.copy_from_slice(&self.buf);
let userbuf_sz = self.bufsz;
// 2nd read directly into our internal buf
let mut tmp = vec![0u8; self.capacity];
let n2 = self.read_until_full(&mut tmp)?;
self.buf = tmp;
self.bufsz = n2;
if n2 == 0 {
return Ok(ReadInfo::LastChunk(userbuf_sz));
}
Ok(ReadInfo::NormalChunk(userbuf_sz))
}
}

View File

@ -1,13 +1,25 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
use crate::reader::AheadReader;
use std::io::BufReader;
use std::{ use std::{
fs::File, fs::File,
io::{self, Read, Write}, io::{self, Write},
}; };
pub(crate) fn read_from_file_or_stdin<S: AsRef<str>>(input_file: Option<S>) -> Box<dyn Read> { pub const BUFSIZE: usize = 64 * 1024; // 64 KiB
pub(crate) fn read_from_file_or_stdin<S: AsRef<str>>(
input_file: Option<S>,
bufsz: usize,
) -> AheadReader {
match input_file { match input_file {
Some(f) => Box::new(File::open(f.as_ref()).unwrap()), Some(f) => AheadReader::from(
None => Box::new(io::stdin()), Box::new(BufReader::new(File::open(f.as_ref()).unwrap())),
bufsz,
),
None => AheadReader::from(Box::new(io::stdin().lock()), bufsz),
} }
} }