diff options
-rw-r--r-- | .gitlab-ci.yml | 16 | ||||
-rw-r--r-- | Cargo.lock | 238 | ||||
-rw-r--r-- | openpgp/Cargo.toml | 34 | ||||
-rw-r--r-- | openpgp/NEWS | 2 | ||||
-rw-r--r-- | openpgp/README.md | 7 | ||||
-rw-r--r-- | openpgp/build.rs | 6 | ||||
-rw-r--r-- | openpgp/src/crypto/aead.rs | 8 | ||||
-rw-r--r-- | openpgp/src/crypto/backend.rs | 5 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust.rs | 64 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/aead.rs | 134 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/asymmetric.rs | 473 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/ecdh.rs | 99 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/hash.rs | 80 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/symmetric.rs | 199 |
14 files changed, 1358 insertions, 7 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 76218ecc..c30c5476 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -72,6 +72,22 @@ bullseye: RUSTFLAGS: -D warnings -A unused-parens after_script: [] +bullseye-crypto-rust: + tags: + - linux + stage: build + image: registry.gitlab.com/sequoia-pgp/build-docker-image/bullseye-prebuild:latest + dependencies: + - codespell + script: + - cargo run --manifest-path openpgp/Cargo.toml --no-default-features --features crypto-rust,compression,allow-experimental-crypto,allow-variable-time-crypto --example supported-algorithms + - cargo test --release --manifest-path openpgp/Cargo.toml --no-default-features --features crypto-rust,compression,allow-experimental-crypto,allow-variable-time-crypto + variables: + CARGO_TARGET_DIR: /target + CARGO_HOME: /cargo + RUSTFLAGS: -D warnings -A unused-parens + after_script: [] + bullseye:arm64: tags: - docker-arm64 @@ -25,6 +25,37 @@ dependencies = [ ] [[package]] +name = "aes" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" +dependencies = [ + "aes-soft", + "aesni", + "cipher", +] + +[[package]] +name = "aes-soft" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" +dependencies = [ + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aesni" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +dependencies = [ + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] name = "ahash" version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -189,7 +220,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding", + "block-padding 0.1.5", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -205,6 +236,16 @@ dependencies = [ ] [[package]] +name = "block-modes" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +dependencies = [ + "block-padding 0.2.1", + "cipher", +] + +[[package]] name = "block-padding" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -214,6 +255,23 @@ dependencies = [ ] [[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "blowfish" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32fa6a061124e37baba002e496d203e23ba3d7b73750be82dbfbc92913048a5b" +dependencies = [ + "byteorder", + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] name = "bstr" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -331,6 +389,17 @@ dependencies = [ ] [[package]] +name = "cast5" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1285caf81ea1f1ece6b24414c521e625ad0ec94d880625c20f2e65d8d3f78823" +dependencies = [ + "byteorder", + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] name = "cc" version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -449,6 +518,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" [[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] name = "cpuid-bool" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -625,6 +703,17 @@ dependencies = [ ] [[package]] +name = "des" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b24e7c748888aa2fa8bce21d8c64a52efc810663285315ac7476f7197a982fae" +dependencies = [ + "byteorder", + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] name = "diff" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1150,6 +1239,16 @@ dependencies = [ ] [[package]] +name = "idea" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdd4b114cf2265123bbdc5d32a39f96a343fbdf141267d2b5232b7e14caacb3" +dependencies = [ + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] name = "idna" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1271,9 +1370,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.92" +version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714" +checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" [[package]] name = "libm" @@ -1308,6 +1407,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] +name = "md-5" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] name = "memchr" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1470,6 +1580,17 @@ dependencies = [ ] [[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg 1.0.1", + "num-integer", + "num-traits", +] + +[[package]] name = "num-bigint-dig" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1482,7 +1603,10 @@ dependencies = [ "num-integer", "num-iter", "num-traits", + "rand 0.7.3", + "serde", "smallvec", + "zeroize", ] [[package]] @@ -1595,6 +1719,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] +name = "pem" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +dependencies = [ + "base64", + "once_cell", + "regex", +] + +[[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1917,6 +2052,17 @@ dependencies = [ ] [[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] name = "rpassword" version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1927,6 +2073,28 @@ dependencies = [ ] [[package]] +name = "rsa" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3648b669b10afeab18972c105e284a7b953a669b0be3514c27f9b17acab2f9cd" +dependencies = [ + "byteorder", + "digest 0.9.0", + "lazy_static", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pem", + "rand 0.7.3", + "sha2 0.9.3", + "simple_asn1", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] name = "rusqlite" version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2141,22 +2309,33 @@ dependencies = [ name = "sequoia-openpgp" version = "1.3.0" dependencies = [ + "aes", "anyhow", "backtrace", "base64", + "block-modes", + "block-padding 0.2.1", + "blowfish", "buffered-reader", "bzip2", + "cast5", "chrono", + "cipher", "criterion", + "des", + "digest 0.9.0", "dyn-clone", "eax", "ed25519-dalek", "flate2", + "generic-array 0.14.4", + "idea", "idna", "lalrpop", "lalrpop-util", "lazy_static", "libc", + "md-5", "memsec", "nettle", "num-bigint-dig", @@ -2164,12 +2343,19 @@ dependencies = [ "rand 0.7.3", "regex", "regex-syntax", + "ripemd160", "rpassword", + "rsa", + "sha-1", "sha1collisiondetection", + "sha2 0.9.3", "thiserror", + "twofish", + "typenum", "unicode-normalization", "win-crypto-ng", "winapi 0.3.9", + "x25519-dalek", ] [[package]] @@ -2262,6 +2448,19 @@ dependencies = [ ] [[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] name = "sha1collisiondetection" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2319,6 +2518,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0242b8e50dd9accdd56170e94ca1ebd223b098eb9c83539a6e367d0f36ae68" [[package]] +name = "simple_asn1" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" +dependencies = [ + "chrono", + "num-bigint", + "num-traits", +] + +[[package]] name = "siphasher" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2613,6 +2823,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] +name = "twofish" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0028f5982f23ecc9a1bc3008ead4c664f843ed5d78acd3d213b99ff50c441bc2" +dependencies = [ + "byteorder", + "cipher", + "opaque-debug 0.3.0", +] + +[[package]] name = "typenum" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2842,6 +3063,17 @@ dependencies = [ ] [[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] name = "zbase32" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index 1d1fa3de..cd285ebe 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -45,12 +45,33 @@ thiserror = "1.0.2" backtrace = "0.3.3" unicode-normalization = "0.1.9" +# RustCrypto crates. +aes = { version = "0.6.0", optional = true } +block-modes = { version = "0.7.0", optional = true } +block-padding = { version = "0.2.1", optional = true } +blowfish = { version = "0.7.0", optional = true } +cast5 = { version = "0.9.0", optional = true } +cipher = { version = "0.2.5", optional = true, features = ["std"] } +des = { version = "0.6.0", optional = true } +digest = { version = "0.9.0", optional = true } +eax = { version = "0.3.0", optional = true } +ed25519-dalek = { version = "1", default-features = false, features = ["rand", "u64_backend"], optional = true } +generic-array = { version = "0.14.4", optional = true } +idea = { version = "0.3.0", optional = true } +md-5 = { version = "0.9.1", optional = true } +num-bigint-dig = { version = "0.6", default-features = false, optional = true } +rand = { version = "0.7.3", optional = true } +ripemd160 = { version = "0.9.1", optional = true } +rsa = { version = "0.3.0", optional = true } +sha-1 = { version = "0.9.2", optional = true } +sha2 = { version = "0.9.2", optional = true } +twofish = { version = "0.5.0", optional = true } +typenum = { version = "1.12.0", optional = true } +x25519-dalek = { version = "1.1.0", optional = true } + [target.'cfg(windows)'.dependencies] win-crypto-ng = { version = "0.4", features = ["rand", "block-cipher"], optional = true } -num-bigint-dig = { version = "0.6", default-features = false, optional = true } -ed25519-dalek = { version = "1", default-features = false, features = ["rand", "u64_backend"], optional = true } winapi = { version = "0.3.8", default-features = false, features = ["bcrypt"], optional = true } -eax = "0.3" [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] chrono = { version = "0.4.10", default-features = false, features = ["std"] } @@ -68,7 +89,12 @@ criterion = { version = "0.3.4", features = ["html_reports"] } default = ["compression", "crypto-nettle"] # TODO(#333): Allow for/implement more backends crypto-nettle = ["nettle"] -crypto-cng = ["winapi", "win-crypto-ng", "ed25519-dalek", "num-bigint-dig"] +crypto-rust = [ + "aes", "block-modes", "block-padding", "blowfish", "cast5", "cipher", "des", + "digest", "eax", "ed25519-dalek", "generic-array", "idea", "md-5", "num-bigint-dig", "rand", + "ripemd160", "rsa", "sha-1", "sha2", "twofish", "typenum", "x25519-dalek" +] +crypto-cng = ["eax", "winapi", "win-crypto-ng", "ed25519-dalek", "num-bigint-dig"] # Experimental and variable-time cryptographic backends opt-ins allow-experimental-crypto = [] diff --git a/openpgp/NEWS b/openpgp/NEWS index d17c9c08..739f53ec 100644 --- a/openpgp/NEWS +++ b/openpgp/NEWS @@ -3,6 +3,8 @@ #+STARTUP: content hidestars * Changes in 1.4.0 +** New cryptographic backends + - We added a backend based on the RustCrypto crates. ** New functionality - CipherSuite::is_supported - MPI::value_padded diff --git a/openpgp/README.md b/openpgp/README.md index 3e0c81c2..c4bfa9e8 100644 --- a/openpgp/README.md +++ b/openpgp/README.md @@ -81,6 +81,13 @@ at compile time. Currently, these libraries are available: include the `crypto-cng` feature to enable it. Currently, the CNG backend requires at least Windows 10. + - The RustCrypto crates. To select this backend, use + `default-features = false`, and explicitly include the + `crypto-rust` feature to enable it. As of this writing, the + RustCrypto crates are not recommended for general use as they + cannot offer the same security guarantees as more mature + cryptographic libraries. + ### Experimental and variable-time cryptographic backends Some cryptographic backends are not yet considered mature enough for diff --git a/openpgp/build.rs b/openpgp/build.rs index 210483e5..aabf157d 100644 --- a/openpgp/build.rs +++ b/openpgp/build.rs @@ -62,6 +62,12 @@ fn crypto_backends_sanity_check() { production_ready: true, constant_time: true, }), + (cfg!(feature = "crypto-rust"), + Backend { + name: "RustCrypto", + production_ready: false, + constant_time: false, + }), ].into_iter().filter_map(|(selected, backend)| { if selected { Some(backend) } else { None } }).collect::<Vec<_>>(); diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs index 3d55b0ab..95c172c1 100644 --- a/openpgp/src/crypto/aead.rs +++ b/openpgp/src/crypto/aead.rs @@ -815,6 +815,14 @@ mod tests { SymmetricAlgorithm::Camellia256] .iter() .filter(|algo| algo.is_supported()) { + + if cfg!(feature = "crypto-rust") + && sym_algo == &SymmetricAlgorithm::Twofish { + eprintln!("XXX: Skipping Twofish until Twofish \ + implements Clone"); + continue; + } + for aead in [ AEADAlgorithm::EAX, AEADAlgorithm::OCB, diff --git a/openpgp/src/crypto/backend.rs b/openpgp/src/crypto/backend.rs index 11727d74..c0fd883f 100644 --- a/openpgp/src/crypto/backend.rs +++ b/openpgp/src/crypto/backend.rs @@ -8,6 +8,11 @@ mod nettle; #[cfg(feature = "crypto-nettle")] pub use self::nettle::*; +#[cfg(feature = "crypto-rust")] +mod rust; +#[cfg(feature = "crypto-rust")] +pub use self::rust::*; + #[cfg(feature = "crypto-cng")] mod cng; #[cfg(feature = "crypto-cng")] diff --git a/openpgp/src/crypto/backend/rust.rs b/openpgp/src/crypto/backend/rust.rs new file mode 100644 index 00000000..a661c14e --- /dev/null +++ b/openpgp/src/crypto/backend/rust.rs @@ -0,0 +1,64 @@ +//! Implementation of Sequoia crypto API using pure Rust cryptographic +//! libraries. + +use crate::types::*; + +pub mod aead; +pub mod asymmetric; +pub mod ecdh; +pub mod hash; +pub mod symmetric; + +/// Fills the given buffer with random data. +/// +/// Fills the given buffer with random data produced by a +/// cryptographically secure pseudorandom number generator (CSPRNG). +/// The output may be used as session keys or to derive long-term +/// cryptographic keys from. +pub fn random<B: AsMut<[u8]>>(mut buf: B) { + use rand::rngs::OsRng; + use rand::RngCore; + + OsRng.fill_bytes(buf.as_mut()) +} + +impl PublicKeyAlgorithm { + pub(crate) fn is_supported_by_backend(&self) -> bool { + use PublicKeyAlgorithm::*; + #[allow(deprecated)] + match &self { + RSAEncryptSign | RSAEncrypt | RSASign | ECDH | EdDSA + => true, + DSA | ECDSA + => false, + ElGamalEncrypt | ElGamalEncryptSign | Private(_) | Unknown(_) + => false, + } + } +} + +impl Curve { + pub(crate) fn is_supported_by_backend(&self) -> bool { + use self::Curve::*; + match &self { + NistP256 | NistP384 | NistP521 + => false, + Ed25519 | Cv25519 + => true, + BrainpoolP256 | BrainpoolP512 | Unknown(_) + => false, + } + } +} + +impl AEADAlgorithm { + pub(crate) fn is_supported_by_backend(&self) -> bool { + use self::AEADAlgorithm::*; + match &self { + EAX + => true, + OCB | Private(_) | Unknown(_) + => false, + } + } +} diff --git a/openpgp/src/crypto/backend/rust/aead.rs b/openpgp/src/crypto/backend/rust/aead.rs new file mode 100644 index 00000000..ab2ca208 --- /dev/null +++ b/openpgp/src/crypto/backend/rust/aead.rs @@ -0,0 +1,134 @@ +//! Implementation of AEAD using pure Rust cryptographic libraries. + +use std::cmp; + +use cipher::{BlockCipher, NewBlockCipher}; +use cipher::block::Block; +use cipher::consts::U16; +use eax::online::{Eax, Encrypt, Decrypt}; +use generic_array::{ArrayLength, GenericArray}; + +use crate::{Error, Result}; +use crate::crypto::aead::{Aead, CipherOp}; +use crate::seal; +use crate::types::{AEADAlgorithm, SymmetricAlgorithm}; + +trait GenericArrayExt { + const LEN: usize; +} + +impl<T, N: ArrayLength<T>> GenericArrayExt for GenericArray<T, N> { + const LEN: usize = N::USIZE; +} + +impl<Cipher> Aead for Eax<Cipher, Encrypt> +where + Cipher: BlockCipher<BlockSize = U16> + NewBlockCipher + Clone, + Cipher::ParBlocks: ArrayLength<Block<Cipher>>, +{ + fn update(&mut self, ad: &[u8]) { + self.update_assoc(ad) + } + + fn digest_size(&self) -> usize { + eax::Tag::LEN + } + + fn digest(&mut self, digest: &mut [u8]) { + let tag = self.tag_clone(); + digest[..tag.len()].copy_from_slice(&tag[..]); + } + + fn encrypt(&mut self, dst: &mut [u8], src: &[u8]) { + let len = cmp::min(dst.len(), src.len()); + dst[..len].copy_from_slice(&src[..len]); + Self::encrypt(self, &mut dst[..len]) + } + + fn decrypt(&mut self, _dst: &mut [u8], _src: &[u8]) { + panic!("AEAD decryption called in the encryption context") + } +} + +impl<Cipher> Aead for Eax<Cipher, Decrypt> +where + Cipher: BlockCipher<BlockSize = U16> + NewBlockCipher + Clone, + Cipher::ParBlocks: ArrayLength<Block<Cipher>>, +{ + fn update(&mut self, ad: &[u8]) { + self.update_assoc(ad) + } + + fn digest_size(&self) -> usize { + eax::Tag::LEN + } + + fn digest(&mut self, digest: &mut [u8]) { + let tag = self.tag_clone(); + digest[..tag.len()].copy_from_slice(&tag[..]); + } + + fn encrypt(&mut self, _dst: &mut [u8], _src: &[u8]) { + panic!("AEAD encryption called in the decryption context") + } + + fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) { + let len = core::cmp::min(dst.len(), src.len()); + dst[..len].copy_from_slice(&src[..len]); + self.decrypt_unauthenticated_hazmat(&mut dst[..len]) + } +} + +impl<Cipher, Op> seal::Sealed for Eax<Cipher, Op> +where + Cipher: BlockCipher<BlockSize = U16> + NewBlockCipher + Clone, + Cipher::ParBlocks: ArrayLength<Block<Cipher>>, + Op: eax::online::CipherOp, +{} + +impl AEADAlgorithm { + pub(crate) fn context( + &self, + sym_algo: SymmetricAlgorithm, + key: &[u8], + nonce: &[u8], + op: CipherOp, + ) -> Result<Box<dyn Aead>> { + match self { + AEADAlgorithm::EAX => match sym_algo { + SymmetricAlgorithm::AES128 => match op { + CipherOp::Encrypt => Ok(Box::new( + Eax::<aes::Aes128, Encrypt>::with_key_and_nonce(key.into(), nonce.into()))), + CipherOp::Decrypt => Ok(Box::new( + Eax::<aes::Aes128, Decrypt>::with_key_and_nonce(key.into(), nonce.into()))), + } + SymmetricAlgorithm::AES192 => match op { + CipherOp::Encrypt => Ok(Box::new( + Eax::<aes::Aes192, Encrypt>::with_key_and_nonce(key.into(), nonce.into()))), + CipherOp::Decrypt => Ok(Box::new( + Eax::<aes::Aes192, Decrypt>::with_key_and_nonce(key.into(), nonce.into()))), + } + SymmetricAlgorithm::AES256 => match op { + CipherOp::Encrypt => Ok(Box::new( + Eax::<aes::Aes256, Encrypt>::with_key_and_nonce(key.into(), nonce.into()))), + CipherOp::Decrypt => Ok(Box::new( + Eax::<aes::Aes256, Decrypt>::with_key_and_nonce(key.into(), nonce.into()))), + } + | SymmetricAlgorithm::IDEA + | SymmetricAlgorithm::TripleDES + | SymmetricAlgorithm::CAST5 + | SymmetricAlgorithm::Blowfish + | SymmetricAlgorithm::Twofish + | SymmetricAlgorithm::Camellia128 + | SymmetricAlgorithm::Camellia192 + | SymmetricAlgorithm::Camellia256 + | SymmetricAlgorithm::Private(_) + | SymmetricAlgorithm::Unknown(_) + | SymmetricAlgorithm::Unencrypted => + Err(Error::UnsupportedSymmetricAlgorithm(sym_algo).into()), + }, + AEADAlgorithm::OCB | AEADAlgorithm::Private(_) | AEADAlgorithm::Unknown(_) => + Err(Error::UnsupportedAEADAlgorithm(*self).into()), + } + } |