summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.yml16
-rw-r--r--Cargo.lock238
-rw-r--r--openpgp/Cargo.toml34
-rw-r--r--openpgp/NEWS2
-rw-r--r--openpgp/README.md7
-rw-r--r--openpgp/build.rs6
-rw-r--r--openpgp/src/crypto/aead.rs8
-rw-r--r--openpgp/src/crypto/backend.rs5
-rw-r--r--openpgp/src/crypto/backend/rust.rs64
-rw-r--r--openpgp/src/crypto/backend/rust/aead.rs134
-rw-r--r--openpgp/src/crypto/backend/rust/asymmetric.rs473
-rw-r--r--openpgp/src/crypto/backend/rust/ecdh.rs99
-rw-r--r--openpgp/src/crypto/backend/rust/hash.rs80
-rw-r--r--openpgp/src/crypto/backend/rust/symmetric.rs199
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
diff --git a/Cargo.lock b/Cargo.lock
index 50b3468c..efcea173 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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()))),
+ }