From 4ec75df65e1e8646ede928dd8475ed0b681cfdae Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Fri, 28 Apr 2023 12:32:23 +0200 Subject: [PATCH] openpgp: Update rust-crypto dependencies - Note: `x25519-dalek` is broken. It depends on zeroize `=1.3`, but crates like rsa depend on newer versions of zeroize. - See https://github.com/WebAssembly/wasi-crypto/issues/63 , https://github.com/dalek-cryptography/x25519-dalek/issues/92 . - Resolve this by using `x25519-dalek-ng`, which fixes this issue. This is a common workaround, and is also used by, for instance OpenMLS: https://github.com/openmls/openmls/blob/3ff090fd4881cb796d4688f7f174929a7521dbf1/openmls_rust_crypto/README.md?plain=1#L3 - Fixes #910. --- .gitlab-ci.yml | 10 +- Cargo.lock | 664 ++++++++---------- openpgp/Cargo.toml | 64 +- openpgp/NEWS | 1 + openpgp/src/crypto/backend/rust.rs | 35 + openpgp/src/crypto/backend/rust/aead.rs | 45 +- openpgp/src/crypto/backend/rust/asymmetric.rs | 120 ++-- openpgp/src/crypto/backend/rust/ecdh.rs | 21 +- openpgp/src/crypto/backend/rust/hash.rs | 4 +- openpgp/src/crypto/backend/rust/symmetric.rs | 426 +++++++++-- 10 files changed, 828 insertions(+), 562 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c8d6fb0d..875e6cab 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -61,12 +61,18 @@ bookworm: CARGO_TARGET_DIR: /target CARGO_HOME: /cargo -bookworm-crypto-rust: +# XXX: Our MSRV is 1.63 except with rust-crypto, which requires +# 1.65. Switch back to bookworm, when rustc is >= 1.65. +# +# bookworm-crypto-rust: +# image: 192.168.122.1:5000/sequoia-pgp/build-docker-image/bookworm-prebuild:latest +rust-stable-crypto-rust: tags: - linux stage: build interruptible: true - image: 192.168.122.1:5000/sequoia-pgp/build-docker-image/bookworm-prebuild:latest + + image: 192.168.122.1:5000/sequoia-pgp/build-docker-image/rust-stable-prebuild:latest dependencies: - codespell script: diff --git a/Cargo.lock b/Cargo.lock index 37f47906..64b01ebb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,42 +10,23 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" -version = "0.3.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ + "crypto-common", "generic-array", ] [[package]] name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher 0.2.5", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug", -] - -[[package]] -name = "aesni" -version = "0.10.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" dependencies = [ - "cipher 0.2.5", - "opaque-debug", + "cfg-if", + "cipher", + "cpufeatures", ] [[package]] @@ -57,15 +38,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anyhow" version = "1.0.56" @@ -105,18 +77,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "0.1.8" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.1.0", -] +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] -name = "autocfg" -version = "1.1.0" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -124,6 +93,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bindgen" version = "0.63.0" @@ -165,18 +140,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitvec" -version = "0.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7774144344a4faa177370406a7ff5f1da24303817368584c6206c8303eb07848" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -187,30 +150,31 @@ dependencies = [ ] [[package]] -name = "block-modes" -version = "0.7.0" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "block-padding", - "cipher 0.2.5", + "generic-array", ] [[package]] name = "block-padding" -version = "0.2.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] [[package]] name = "blowfish" -version = "0.7.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fa6a061124e37baba002e496d203e23ba3d7b73750be82dbfbc92913048a5b" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ "byteorder", - "cipher 0.2.5", - "opaque-debug", + "cipher", ] [[package]] @@ -327,13 +291,11 @@ dependencies = [ [[package]] name = "cast5" -version = "0.9.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1285caf81ea1f1ece6b24414c521e625ad0ec94d880625c20f2e65d8d3f78823" +checksum = "26b07d673db1ccf000e90f54b819db9e75a8348d6eb056e9b8ab53231b7a9911" dependencies = [ - "byteorder", - "cipher 0.2.5", - "opaque-debug", + "cipher", ] [[package]] @@ -351,6 +313,15 @@ dependencies = [ "nom", ] +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -363,22 +334,10 @@ version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ - "iana-time-zone", "js-sys", "num-integer", "num-traits", - "time 0.1.43", "wasm-bindgen", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array", ] [[package]] @@ -439,29 +398,20 @@ dependencies = [ [[package]] name = "cmac" -version = "0.5.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73d4de4f7724e5fe70addfb2bd37c2abd2f95084a429d7773b0b9645499b4272" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" dependencies = [ - "crypto-mac 0.10.1", + "cipher", "dbl", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", + "digest 0.10.6", ] [[package]] name = "const-oid" -version = "0.5.2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279bc8fc53f788a75c7804af68237d1fce02cde1e275a886a4b320604dc2aeda" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "core-foundation" @@ -560,7 +510,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cfg-if", "crossbeam-utils", "lazy_static", @@ -585,34 +535,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.10.1" +name = "crypto-bigint" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" dependencies = [ - "cipher 0.2.5", "generic-array", + "rand_core 0.6.4", "subtle", + "zeroize", ] [[package]] -name = "crypto-mac" -version = "0.11.1" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "subtle", + "rand_core 0.6.4", + "typenum", ] [[package]] @@ -649,68 +591,37 @@ dependencies = [ [[package]] name = "ctr" -version = "0.6.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.2.5", + "cipher", ] [[package]] name = "curve25519-dalek" -version = "3.2.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" dependencies = [ "byteorder", - "digest", + "digest 0.9.0", "rand_core 0.5.1", "subtle", "zeroize", ] [[package]] -name = "cxx" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d3488e7665a7a483b57e25bdd90d0aeb2bc7608c8d0346acf2ad3f1caf1d62" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fcaf066a053a41a81dfb14d57d99738b767febb8b735c3016e469fac5da690" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.91" +name = "curve25519-dalek-ng" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2ef98b8b717a829ca5603af80e1f9e2e48013ab227b68ef37872ef84ee479bf" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "086c685979a698443656e5cf7856c95c642295a38599f12fb1ff76fb28d19892" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" dependencies = [ - "proc-macro2", - "quote", - "syn", + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", ] [[package]] @@ -730,23 +641,22 @@ dependencies = [ [[package]] name = "der" -version = "0.3.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eeb9d92785d1facb50567852ce75d0858630630e7eabea59cf7eb7474051087" +checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" dependencies = [ "const-oid", - "typenum", + "pem-rfc7468", + "zeroize", ] [[package]] name = "des" -version = "0.6.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b24e7c748888aa2fa8bce21d8c64a52efc810663285315ac7476f7197a982fae" +checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" dependencies = [ - "byteorder", - "cipher 0.2.5", - "opaque-debug", + "cipher", ] [[package]] @@ -764,6 +674,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + [[package]] name = "dirs" version = "4.0.0" @@ -819,36 +741,46 @@ checksum = "21e50f3adc76d6a43f5ed73b698a87d0760ca74617f60f7c3b879003536fdd28" [[package]] name = "eax" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1f76e7a5e594b299a0fa9a99de627530725e341df41376aa342aecb2c5eb76e" +checksum = "9954fabd903b82b9d7a68f65f97dc96dd9ad368e40ccc907a7c19d53e6bfac28" dependencies = [ "aead", - "cipher 0.2.5", + "cipher", "cmac", "ctr", "subtle", ] +[[package]] +name = "ecb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17fd84ba81a904351ee27bbccb4aa2461e1cca04176a63ab4f8ca087757681a2" +dependencies = [ + "cipher", +] + [[package]] name = "ecdsa" -version = "0.11.1" +version = "0.16.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d33b390ab82f2e1481e331dbd0530895640179d2128ef9a79cc690b78d1eba" +checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" dependencies = [ "der", + "digest 0.10.6", "elliptic-curve", - "hmac", - "signature", + "rfc6979", + "signature 2.1.0", ] [[package]] name = "ed25519" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d5c4b5e5959dc2c2b89918d8e2cc40fcdd623cef026ed09d2f0ee05199dc8e4" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", ] [[package]] @@ -860,7 +792,7 @@ dependencies = [ "curve25519-dalek", "ed25519", "rand 0.7.3", - "sha2", + "sha2 0.9.9", "zeroize", ] @@ -872,16 +804,21 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.9.12" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c13e9b0c3c4170dcc2a12783746c4205d98e18957f57854251eea3f9750fe005" +checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" dependencies = [ - "bitvec", + "base16ct", + "crypto-bigint", + "digest 0.10.6", "ff", "generic-array", "group", + "hkdf", + "pem-rfc7468", "pkcs8", - "rand_core 0.6.3", + "rand_core 0.6.4", + "sec1", "subtle", "zeroize", ] @@ -945,12 +882,11 @@ dependencies = [ [[package]] name = "ff" -version = "0.9.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a4d941a5b7c2a75222e2d44fcdf634a67133d9db31e177ae5ff6ecda852bfe" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "bitvec", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -1013,12 +949,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - [[package]] name = "futures" version = "0.3.21" @@ -1110,12 +1040,13 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.5" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1152,12 +1083,12 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "group" -version = "0.9.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3c1e8b4f1ca07e6605ea1be903a5f6956aec5c8a67fd44d56076631675ed8" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core 0.6.3", + "rand_core 0.6.4", "subtle", ] @@ -1213,14 +1144,22 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crypto-mac 0.11.1", - "digest", + "digest 0.10.6", ] [[package]] @@ -1305,38 +1244,13 @@ dependencies = [ "tokio-native-tls", ] -[[package]] -name = "iana-time-zone" -version = "0.1.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "winapi", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" -dependencies = [ - "cxx", - "cxx-build", -] - [[package]] name = "idea" -version = "0.3.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdd4b114cf2265123bbdc5d32a39f96a343fbdf141267d2b5232b7e14caacb3" +checksum = "075557004419d7f2031b8bb7f44bb43e55a83ca7b63076a8fb8fe75753836477" dependencies = [ - "cipher 0.2.5", - "opaque-debug", + "cipher", ] [[package]] @@ -1356,7 +1270,7 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ - "autocfg 1.1.0", + "autocfg", "hashbrown", ] @@ -1366,6 +1280,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array", ] @@ -1514,15 +1429,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33a33a362ce288760ec6a508b94caaec573ae7d3bbbd91b87aa0bad4456839db" -[[package]] -name = "link-cplusplus" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] - [[package]] name = "linked-hash-map" version = "0.5.4" @@ -1541,7 +1447,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ - "autocfg 1.1.0", + "autocfg", "scopeguard", ] @@ -1577,13 +1483,11 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "md-5" -version = "0.9.1" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" +checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" dependencies = [ - "block-buffer", - "digest", - "opaque-debug", + "digest 0.10.6", ] [[package]] @@ -1598,7 +1502,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 1.1.0", + "autocfg", ] [[package]] @@ -1723,32 +1627,19 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg 1.1.0", - "num-integer", - "num-traits", -] - [[package]] name = "num-bigint-dig" -version = "0.6.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d51546d704f52ef14b3c962b5776e53d5b862e5790e40a350d366c209bd7f7a" +checksum = "2399c9463abc5f909349d8aa9ba080e0b88b3ce2885389b60b993f39b1a56905" dependencies = [ - "autocfg 0.1.8", "byteorder", "lazy_static", "libm", "num-integer", "num-iter", "num-traits", - "rand 0.7.3", - "serde", + "rand 0.8.5", "smallvec", "zeroize", ] @@ -1759,7 +1650,7 @@ version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-traits", ] @@ -1769,7 +1660,7 @@ version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" dependencies = [ - "autocfg 1.1.0", + "autocfg", "num-integer", "num-traits", ] @@ -1780,7 +1671,8 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg 1.1.0", + "autocfg", + "libm", ] [[package]] @@ -1858,7 +1750,7 @@ version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" dependencies = [ - "autocfg 1.1.0", + "autocfg", "cc", "libc", "pkg-config", @@ -1873,13 +1765,14 @@ checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" [[package]] name = "p256" -version = "0.8.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f05f5287453297c4c16af5e2b04df8fd2a3008d70f252729650bc6d7ace5844" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" dependencies = [ "ecdsa", "elliptic-curve", - "sha2", + "primeorder", + "sha2 0.10.6", ] [[package]] @@ -1912,14 +1805,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] -name = "pem" -version = "0.8.3" +name = "pem-rfc7468" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" dependencies = [ - "base64", - "once_cell", - "regex", + "base64ct", ] [[package]] @@ -1959,11 +1850,22 @@ 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.6.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c2f795bc591cb3384cb64082a578b89207ac92bb89c9d98c1ea2ace7cd8110" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -2015,6 +1917,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "primeorder" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.56" @@ -2048,12 +1959,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" - [[package]] name = "radix_trie" version = "0.2.1" @@ -2085,7 +1990,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -2105,7 +2010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.3", + "rand_core 0.6.4", ] [[package]] @@ -2119,9 +2024,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom 0.2.6", ] @@ -2141,7 +2046,7 @@ version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" dependencies = [ - "autocfg 1.1.0", + "autocfg", "crossbeam-deque", "either", "rayon-core", @@ -2222,14 +2127,22 @@ dependencies = [ ] [[package]] -name = "ripemd160" -version = "0.9.1" +name = "rfc6979" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "block-buffer", - "digest", - "opaque-debug", + "hmac", + "subtle", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.6", ] [[package]] @@ -2246,23 +2159,22 @@ dependencies = [ [[package]] name = "rsa" -version = "0.3.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3648b669b10afeab18972c105e284a7b953a669b0be3514c27f9b17acab2f9cd" +checksum = "3dd2017d3e6d67384f301f8b06fbf4567afc576430a61624d845eb04d2b30a72" dependencies = [ "byteorder", - "digest", - "lazy_static", + "const-oid", + "digest 0.10.6", "num-bigint-dig", "num-integer", "num-iter", "num-traits", - "pem", - "rand 0.7.3", - "sha2", - "simple_asn1", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature 2.1.0", "subtle", - "thiserror", "zeroize", ] @@ -2333,10 +2245,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] -name = "scratch" -version = "1.0.3" +name = "sec1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] [[package]] name = "security-framework" @@ -2443,21 +2363,23 @@ dependencies = [ "aes", "anyhow", "base64", - "block-modes", "block-padding", "blowfish", "botan", "buffered-reader", "bzip2", "cast5", + "cfb-mode", "chrono", - "cipher 0.2.5", + "cipher", "criterion", "des", - "digest", + "digest 0.10.6", "dyn-clone", "eax", + "ecb", "ecdsa", + "ed25519", "ed25519-dalek", "flate2", "foreign-types-shared", @@ -2480,21 +2402,21 @@ dependencies = [ "quickcheck", "rand 0.7.3", "rand 0.8.5", - "rand_core 0.6.3", + "rand_core 0.6.4", "regex", "regex-syntax", - "ripemd160", + "ripemd", "rpassword", "rsa", "sha-1", "sha1collisiondetection", - "sha2", + "sha2 0.10.6", "thiserror", "twofish", "typenum", "win-crypto-ng", "winapi", - "x25519-dalek", + "x25519-dalek-ng", "xxhash-rust", ] @@ -2541,15 +2463,13 @@ dependencies = [ [[package]] name = "sha-1" -version = "0.9.8" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" dependencies = [ - "block-buffer", "cfg-if", "cpufeatures", - "digest", - "opaque-debug", + "digest 0.10.6", ] [[package]] @@ -2558,7 +2478,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f31bf4e9fe5cd8cea8e0887e2e4eb1b4d736ff11b776c8537bf0912a4b381285" dependencies = [ - "digest", + "digest 0.9.0", "generic-array", ] @@ -2568,13 +2488,24 @@ version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "block-buffer", + "block-buffer 0.9.0", "cfg-if", "cpufeatures", - "digest", + "digest 0.9.0", "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.6", +] + [[package]] name = "shlex" version = "1.1.0" @@ -2583,23 +2514,18 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signature" -version = "1.3.2" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2807892cfa58e081aa1f1111391c7a0649d4fa127a4ffbe34bcbfb35a1171a4" -dependencies = [ - "digest", - "rand_core 0.6.3", -] +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] -name = "simple_asn1" -version = "0.4.1" +name = "signature" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "chrono", - "num-bigint", - "num-traits", + "digest 0.10.6", + "rand_core 0.6.4", ] [[package]] @@ -2616,9 +2542,9 @@ checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" [[package]] name = "smallvec" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" @@ -2638,10 +2564,11 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.3.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dae7e047abc519c96350e9484a96c6bf1492348af912fd3446dd2dc323f6268" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" dependencies = [ + "base64ct", "der", ] @@ -2670,6 +2597,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + [[package]] name = "syn" version = "1.0.109" @@ -2693,12 +2626,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tempfile" version = "3.3.0" @@ -2768,16 +2695,6 @@ dependencies = [ "syn", ] -[[package]] -name = "time" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "time" version = "0.3.9" @@ -2928,7 +2845,7 @@ dependencies = [ "radix_trie", "rand 0.8.5", "thiserror", - "time 0.3.9", + "time", "tokio", "tracing", "trust-dns-proto", @@ -2988,13 +2905,11 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "twofish" -version = "0.5.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0028f5982f23ecc9a1bc3008ead4c664f843ed5d78acd3d213b99ff50c441bc2" +checksum = "a78e83a30223c757c3947cd144a31014ff04298d8719ae10d03c31c0448c8013" dependencies = [ - "byteorder", - "cipher 0.2.5", - "opaque-debug", + "cipher", ] [[package]] @@ -3175,7 +3090,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aea60789d46dc8aa7d41758143c1b7dc2d6101a421712f88716a9646da2a4e39" dependencies = [ - "cipher 0.4.4", + "cipher", "doc-comment", "rand_core 0.5.1", "winapi", @@ -3332,19 +3247,14 @@ dependencies = [ ] [[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - -[[package]] -name = "x25519-dalek" -version = "1.2.0" +name = "x25519-dalek-ng" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2392b6b94a576b4e2bf3c5b2757d63f10ada8020a2e4d08ac849ebcf6ea8e077" +checksum = "bf7074de8999662970c3c4c8f7f30925028dd8f4ca31ad4c055efa9cdf2ec326" dependencies = [ - "curve25519-dalek", - "rand_core 0.5.1", + "curve25519-dalek-ng", + "rand 0.8.5", + "rand_core 0.6.4", "zeroize", ] @@ -3362,9 +3272,9 @@ checksum = "0f9079049688da5871a7558ddacb7f04958862c703e68258594cb7a862b5e33f" [[package]] name = "zeroize" -version = "1.3.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] diff --git a/openpgp/Cargo.toml b/openpgp/Cargo.toml index 7cb210a6..634f3131 100644 --- a/openpgp/Cargo.toml +++ b/openpgp/Cargo.toml @@ -58,31 +58,48 @@ foreign-types-shared = { version = "0.1.1", optional = true } botan = { version = "0.10", optional = true } # 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 } -ecdsa = { version = "0.11", optional = true, features = ["hazmat", "arithmetic"] } # XXX +aes = { version = "0.8", optional = true } +block-padding = { version = "0.3", optional = true } +blowfish = { version = "0.9", optional = true } +cast5 = { version = "0.11", optional = true } +cipher = { version = "0.4", optional = true, features = ["std"] } +cfb-mode = { version = "0.8", optional = true } +des = { version = "0.8", optional = true } +digest = { version = "0.10", optional = true } +eax = { version = "0.5", optional = true } +ecb = { version = "0.1", optional = true } +ecdsa = { version = "0.16", optional = true, features = ["hazmat", "arithmetic"] } # XXX +# We don't directly use ed25519, but ed25519-dalek reexports it and we need the std feature. +ed25519 = { version = "1", default-features = false, features = ["std"], 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 } -p256 = { version = "0.8", optional = true, features = ["ecdh", "ecdsa"] } +idea = { version = "0.5", optional = true } +md-5 = { version = "0.10", features = ["oid"], optional = true } +num-bigint-dig = { version = "0.8", default-features = false, optional = true } +p256 = { version = "0.13", optional = true, features = ["ecdh", "ecdsa"] } +# XXX: ed25519-dalek 1.0.1 depends on rand 0.7 and doesn't reexport it. +# https://github.com/dalek-cryptography/ed25519-dalek/blob/1.0.1/Cargo.toml#L28 rand07 = { package = "rand", version = "0.7.3", optional = true } +rand = { package = "rand", version = "0.8", optional = true } rand_core = { version = "0.6", 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 } +ripemd = { version = "0.1", features = ["oid"], optional = true } +rsa = { version = "0.9.0", optional = true } +sha-1 = { version = "0.10", features = ["oid"], optional = true } +sha2 = { version = "0.10", features = ["oid"], optional = true } +twofish = { version = "0.7", optional = true } typenum = { version = "1.12.0", optional = true } -x25519-dalek = { version = "1.1.0", optional = true } +# XXX: x25519-dalek-ng is a fork of x25519-dalek shortly before its +# last release. The latest stable release of x25519-dalek depends on +# zeroize =1.3, which is a problem, because other crates, like rsa, +# depend on newer versions of zeroize. Thus, depending on +# x25519-dalek prevents us from updating those crates. Although this +# problem is known for over two years (as of April 2023), upstream +# hasn't fixed it. The x25519-dalek-ng fork, however, has. +# Unfortunately, it is not actively developed. So we use +# x25519-dalek-ng for now. Medium term, we should find a replacement +# for this crate, or switch back to x25519-dalek if it becomes after +# again. +x25519-dalek-ng = { version = "1", optional = true } [target.'cfg(windows)'.dependencies] win-crypto-ng = { version = ">=0.4, <0.6", features = ["rand", "block-cipher"], optional = true } @@ -107,9 +124,10 @@ default = ["compression", "crypto-nettle"] # TODO(#333): Allow for/implement more backends crypto-nettle = ["nettle"] crypto-rust = [ - "aes", "block-modes", "block-padding", "blowfish", "cast5", "cipher", "des", - "digest", "eax", "ed25519-dalek", "generic-array", "idea", "md-5", "num-bigint-dig", "rand07", - "ripemd160", "rsa", "sha-1", "sha2", "twofish", "typenum", "x25519-dalek", "p256", + "aes", "block-padding", "blowfish", "cast5", "cfb-mode", "cipher", "des", + "digest", "eax", "ecb", "ed25519", "ed25519-dalek", "generic-array", "idea", + "md-5", "num-bigint-dig", "rand", "rand07", "ripemd", "rsa", "sha-1", "sha2", + "twofish", "typenum", "x25519-dalek-ng", "p256", "rand_core", "rand_core/getrandom", "ecdsa" ] crypto-cng = [ diff --git a/openpgp/NEWS b/openpgp/NEWS index 5ee14de4..184383eb 100644 --- a/openpgp/NEWS +++ b/openpgp/NEWS @@ -7,6 +7,7 @@ ** New functionality - StandardPolicy::accept_hash_property * Notable changes + - Updated the crypto-rust backend. - Updated the crypto-cng backend. * Changes in 1.14.0 ** New cryptographic backends diff --git a/openpgp/src/crypto/backend/rust.rs b/openpgp/src/crypto/backend/rust.rs index 7fe567ef..0be0ea2e 100644 --- a/openpgp/src/crypto/backend/rust.rs +++ b/openpgp/src/crypto/backend/rust.rs @@ -1,6 +1,9 @@ //! Implementation of Sequoia crypto API using pure Rust cryptographic //! libraries. +use generic_array::{ArrayLength, GenericArray}; + +use crate::{Error, Result}; use crate::types::*; pub mod aead; @@ -9,6 +12,38 @@ pub mod ecdh; pub mod hash; pub mod symmetric; +trait GenericArrayExt> { + const LEN: usize; + + /// Like [`GenericArray::from_slice`], but fallible. + fn try_from_slice(slice: &[T]) -> Result<&GenericArray> { + if slice.len() == Self::LEN { + Ok(GenericArray::from_slice(slice)) + } else { + Err(Error::InvalidArgument( + format!("Invalid slice length, want {}, got {}", + Self::LEN, slice.len())).into()) + } + } + + /// Like [`GenericArray::clone_from_slice`], but fallible. + fn try_clone_from_slice(slice: &[T]) -> Result> + where T: Clone + { + if slice.len() == Self::LEN { + Ok(GenericArray::clone_from_slice(slice)) + } else { + Err(Error::InvalidArgument( + format!("Invalid slice length, want {}, got {}", + Self::LEN, slice.len())).into()) + } + } +} + +impl> GenericArrayExt for GenericArray { + const LEN: usize = N::USIZE; +} + /// Returns a short, human-readable description of the backend. pub fn backend() -> String { // XXX: can we include features and the version? diff --git a/openpgp/src/crypto/backend/rust/aead.rs b/openpgp/src/crypto/backend/rust/aead.rs index 90b62a91..e306c8a1 100644 --- a/openpgp/src/crypto/backend/rust/aead.rs +++ b/openpgp/src/crypto/backend/rust/aead.rs @@ -3,11 +3,10 @@ use std::cmp; use std::cmp::Ordering; -use cipher::{BlockCipher, NewBlockCipher}; -use cipher::block::Block; +use cipher::{BlockCipher, BlockEncrypt, KeyInit, Unsigned}; use cipher::consts::U16; use eax::online::{Eax, Encrypt, Decrypt}; -use generic_array::{ArrayLength, GenericArray}; +use generic_array::GenericArray; use crate::{Error, Result}; use crate::crypto::aead::{Aead, CipherOp}; @@ -15,38 +14,22 @@ use crate::crypto::mem::secure_cmp; use crate::seal; use crate::types::{AEADAlgorithm, SymmetricAlgorithm}; +use super::GenericArrayExt; + /// Disables authentication checks. /// /// This is DANGEROUS, and is only useful for debugging problems with /// malformed AEAD-encrypted messages. const DANGER_DISABLE_AUTHENTICATION: bool = false; -trait GenericArrayExt> { - const LEN: usize; - - /// Like [`GenericArray::from_slice`], but fallible. - fn try_from_slice(slice: &[T]) -> Result<&GenericArray> { - if slice.len() == Self::LEN { - Ok(GenericArray::from_slice(slice)) - } else { - Err(Error::InvalidArgument( - format!("Invalid slice length, want {}, got {}", - Self::LEN, slice.len())).into()) - } - } -} - -impl> GenericArrayExt for GenericArray { - const LEN: usize = N::USIZE; -} +type TagLen = U16; -impl Aead for Eax +impl Aead for Eax where - Cipher: BlockCipher + NewBlockCipher + Clone, - Cipher::ParBlocks: ArrayLength>, + Cipher: BlockCipher + BlockEncrypt + Clone + KeyInit, { fn digest_size(&self) -> usize { - eax::Tag::LEN + TagLen::USIZE } fn encrypt_seal(&mut self, dst: &mut [u8], src: &[u8]) -> Result<()> { @@ -64,13 +47,12 @@ where } } -impl Aead for Eax +impl Aead for Eax where - Cipher: BlockCipher + NewBlockCipher + Clone, - Cipher::ParBlocks: ArrayLength>, + Cipher: BlockCipher + BlockEncrypt + Clone + KeyInit, { fn digest_size(&self) -> usize { - eax::Tag::LEN + TagLen::USIZE } fn encrypt_seal(&mut self, _dst: &mut [u8], _src: &[u8]) -> Result<()> { @@ -99,10 +81,9 @@ where } } -impl seal::Sealed for Eax +impl seal::Sealed for Eax where - Cipher: BlockCipher + NewBlockCipher + Clone, - Cipher::ParBlocks: ArrayLength>, + Cipher: BlockCipher + BlockEncrypt + Clone + KeyInit, Op: eax::online::CipherOp, {} diff --git a/openpgp/src/crypto/backend/rust/asymmetric.rs b/openpgp/src/crypto/backend/rust/asymmetric.rs index c20363dd..38789926 100644 --- a/openpgp/src/crypto/backend/rust/asymmetric.rs +++ b/openpgp/src/crypto/backend/rust/asymmetric.rs @@ -7,9 +7,10 @@ use std::convert::TryFrom; use std::time::SystemTime; +use x25519_dalek_ng as x25519_dalek; use num_bigint_dig::{traits::ModInverse, BigUint}; -use rand07::rngs::OsRng; -use rsa::{PaddingScheme, RSAPublicKey, RSAPrivateKey, PublicKey, PublicKeyParts, Hash}; +use rsa::traits::{PrivateKeyParts, PublicKeyParts}; +use rsa::{Pkcs1v15Encrypt, RsaPublicKey, RsaPrivateKey, Pkcs1v15Sign}; use crate::{Error, Result}; use crate::crypto::asymmetric::{KeyPair, Decryptor, Signer}; @@ -21,41 +22,41 @@ use crate::packet::{key, Key}; use crate::packet::key::{Key4, SecretParts}; use crate::types::{Curve, HashAlgorithm, PublicKeyAlgorithm}; +use super::GenericArrayExt; + const CURVE25519_SIZE: usize = 32; -fn pkcs1_padding(hash_algo: HashAlgorithm) -> Result { +fn pkcs1_padding(hash_algo: HashAlgorithm) -> Result { let hash = match hash_algo { - HashAlgorithm::MD5 => Hash::MD5, - HashAlgorithm::SHA1 => Hash::SHA1, - HashAlgorithm::SHA224 => Hash::SHA2_224, - HashAlgorithm::SHA256 => Hash::SHA2_256, - HashAlgorithm::SHA384 => Hash::SHA2_384, - HashAlgorithm::SHA512 => Hash::SHA2_512, - HashAlgorithm::RipeMD => Hash::RIPEMD160, + HashAlgorithm::MD5 => Pkcs1v15Sign::new::(), + HashAlgorithm::SHA1 => Pkcs1v15Sign::new::(), + HashAlgorithm::SHA224 => Pkcs1v15Sign::new::(), + HashAlgorithm::SHA256 => Pkcs1v15Sign::new::(), + HashAlgorithm::SHA384 => Pkcs1v15Sign::new::(), + HashAlgorithm::SHA512 => Pkcs1v15Sign::new::(), + HashAlgorithm::RipeMD => Pkcs1v15Sign::new::(), _ => return Err(Error::InvalidArgument(format!( "Algorithm {:?} not representable", hash_algo)).into()), }; - Ok(PaddingScheme::PKCS1v15Sign { - hash: Some(hash) - }) + Ok(hash) } -fn rsa_public_key(e: &MPI, n: &MPI) -> Result { +fn rsa_public_key(e: &MPI, n: &MPI) -> Result { let n = BigUint::from_bytes_be(n.value()); let e = BigUint::from_bytes_be(e.value()); - Ok(RSAPublicKey::new(n, e)?) + Ok(RsaPublicKey::new(n, e)?) } #[allow(clippy::many_single_char_names)] fn rsa_private_key(e: &MPI, n: &MPI, p: &ProtectedMPI, q: &ProtectedMPI, d: &ProtectedMPI) - -> RSAPrivateKey + -> Result { let n = BigUint::from_bytes_be(n.value()); let e = BigUint::from_bytes_be(e.value()); let p = BigUint::from_bytes_be(p.value()); let q = BigUint::from_bytes_be(q.value()); let d = BigUint::from_bytes_be(d.value()); - RSAPrivateKey::from_components(n, e, d, vec![p, q]) + Ok(RsaPrivateKey::from_components(n, e, d, vec![p, q])?) } impl Signer for KeyPair { @@ -75,7 +76,7 @@ impl Signer for KeyPair { (RSASign, mpi::PublicKey::RSA { e, n }, mpi::SecretKeyMaterial::RSA { p, q, d, .. }) => { - let key = rsa_private_key(e, n, p, q, d); + let key = rsa_private_key(e, n, p, q, d)?; let padding = pkcs1_padding(hash_algo)?; let sig = key.sign(padding, digest)?; Ok(mpi::Signature::RSA { @@ -97,6 +98,7 @@ impl Signer for KeyPair { use p256::{ elliptic_curve::{ generic_array::GenericArray as GA, + ops::Reduce, }, Scalar, }; @@ -105,18 +107,18 @@ impl Signer for KeyPair { }; const LEN: usize = 32; - let key = Scalar::from_bytes_reduced( - GA::from_slice(&scalar.value_padded(LEN))); - let dig = Scalar::from_bytes_reduced( - GA::from_slice(&pad_truncating(digest, LEN))); + let key = scalar.value_padded(LEN); + let key = Scalar::reduce_bytes(GA::try_from_slice(&key)?); + let dig = pad_truncating(digest, LEN); + let dig = GA::try_from_slice(&dig)?; let sig = loop { let mut k: Protected = vec![0; LEN].into(); crate::crypto::random(&mut k); - let k = Scalar::from_bytes_reduced( - GA::from_slice(&k)); - if let Ok(s) = key.try_sign_prehashed(&k, &dig) { - break s; + let k = Scalar::reduce_bytes( + GA::try_from_slice(&k)?); + if let Ok(s) = key.try_sign_prehashed(k, &dig) { + break s.0; } }; @@ -193,9 +195,8 @@ impl Decryptor for KeyPair { (mpi::PublicKey::RSA { e, n }, mpi::SecretKeyMaterial::RSA { p, q, d, .. }, mpi::Ciphertext::RSA { c }) => { - let key = rsa_private_key(e, n, p, q, d); - let padding = PaddingScheme::PKCS1v15Encrypt; - let decrypted = key.decrypt(padding, c.value())?; + let key = rsa_private_key(e, n, p, q, d)?; + let decrypted = key.decrypt(Pkcs1v15Encrypt, c.value())?; Ok(SessionKey::from(decrypted)) } @@ -234,8 +235,9 @@ impl Key { "Plaintext data too large".into()).into()); } let key = rsa_public_key(e, n)?; - let padding = PaddingScheme::PKCS1v15Encrypt; - let ciphertext = key.encrypt(&mut OsRng, padding, data.as_ref())?; + let ciphertext = key.encrypt( + &mut rsa::rand_core::OsRng, + Pkcs1v15Encrypt, data.as_ref())?; Ok(mpi::Ciphertext::RSA { c: mpi::MPI::new(&ciphertext) }) @@ -268,7 +270,22 @@ impl Key { (mpi::PublicKey::RSA { e, n }, mpi::Signature::RSA { s }) => { let key = rsa_public_key(e, n)?; let padding = pkcs1_padding(hash_algo)?; - key.verify(padding, digest, s.value())?; + // Originally, we had: + // + // key.verify(padding, digest, s.value())?; + // + // Since version 0.9.0 of the rsa crate, this no + // longer works, because the verify function checks + // that the signature length in bytes is the same as + // the key length. No other crypto backend appears + // care (including older version of the rsa crate), + // but would happily left pad it with zeros. We now + // do that manually: + // + // See + // https://docs.rs/rsa/0.9.0/src/rsa/pkcs1v15.rs.html#212 + // and https://github.com/RustCrypto/RSA/issues/322. + key.verify(padding, digest, &s.value_padded(key.size())?)?; Ok(()) } (mpi::PublicKey::DSA { .. }, @@ -286,7 +303,6 @@ impl Key { generic_array::GenericArray as GA, sec1::FromEncodedPoint, }, - Scalar, }; use ecdsa::{ EncodedPoint, @@ -295,17 +311,22 @@ impl Key { const LEN: usize = 32; let key = AffinePoint::from_encoded_point( - &EncodedPoint::from_bytes(q.value())?) - .ok_or_else(|| Error::InvalidKey( - "Point is not on the curve".into()))?; + &EncodedPoint::::from_bytes(q.value())?); + let key = if key.is_some().into() { + key.unwrap() + } else { + return Err(Error::InvalidKey( + "Point is not on the curve".into()).into()); + }; + let sig = Signature::from_scalars( - Scalar::from_bytes_reduced( - GA::from_slice(&r.value_padded(LEN).map_err(bad)?)), - Scalar::from_bytes_reduced( - GA::from_slice(&s.value_padded(LEN).map_err(bad)?))) + GA::try_clone_from_slice( + &r.value_padded(LEN).map_err(bad)?)?, + GA::try_clone_from_slice( + &s.value_padded(LEN).map_err(bad)?)?) .map_err(bad)?; - let dig = Scalar::from_bytes_reduced( - GA::from_slice(&pad_truncating(digest, LEN))); + let dig = pad_truncating(digest, LEN); + let dig = GA::try_from_slice(&dig)?; key.verify_prehashed(&dig, &sig).map_err(bad) }, _ => Err(Error::UnsupportedEllipticCurve(curve.clone()).into()), @@ -441,7 +462,7 @@ impl Key4 /// Generates a new RSA key with a public modulos of size `bits`. pub fn generate_rsa(bits: usize) -> Result { - let key = RSAPrivateKey::new(&mut OsRng, bits)?; + let key = RsaPrivateKey::new(&mut rsa::rand_core::OsRng, bits)?; let (p, q) = match key.primes() { [p, q] => (p, q), _ => panic!("RSA key generation resulted in wrong number of primes"), @@ -484,7 +505,12 @@ impl Key4 (Curve::Ed25519, true) => { use ed25519_dalek::Keypair; - let Keypair { public, secret } = Keypair::generate(&mut OsRng); + // ed25519_dalek v1.0.1 doesn't reexport OsRng. It + // depends on 0.7. + use rand07::rngs::OsRng as OsRng; + + let Keypair { public, secret } + = Keypair::generate(&mut OsRng); let secret: Protected = secret.as_bytes().as_ref().into(); @@ -504,7 +530,11 @@ impl Key4 (Curve::Cv25519, false) => { use x25519_dalek::{StaticSecret, PublicKey}; - let private_key = StaticSecret::new(OsRng); + // x25519_dalek v1.1 doesn't reexport OsRng. It + // depends on rand 0.8. + use rand::rngs::OsRng; + + let private_key = StaticSecret::new(&mut OsRng); let public_key = PublicKey::from(&private_key); let mut private_key = Vec::from(private_key.to_bytes()); diff --git a/openpgp/src/crypto/backend/rust/ecdh.rs b/openpgp/src/crypto/backend/rust/ecdh.rs index 8531013d..fdec57f0 100644 --- a/openpgp/src/crypto/backend/rust/ecdh.rs +++ b/openpgp/src/crypto/backend/rust/ecdh.rs @@ -2,7 +2,7 @@ use std::convert::TryInto; -use rand07::rngs::OsRng; +use x25519_dalek_ng as x25519_dalek; use crate::{Error, Result}; use crate::crypto::SessionKey; @@ -12,6 +12,8 @@ use crate::crypto::mpi::{self, Ciphertext, SecretKeyMaterial, MPI}; use crate::packet::{key, Key}; use crate::types::Curve; +use super::GenericArrayExt; + const CURVE25519_SIZE: usize = 32; /// Wraps a session key using Elliptic Curve Diffie-Hellman. @@ -28,6 +30,9 @@ pub fn encrypt(recipient: &Key, let (VB, shared) = match curve { Curve::Cv25519 => { + // x25519_dalek v1.1 doesn't reexport OsRng. It + // depends on rand 0.8. + use rand::rngs::OsRng; use x25519_dalek::{EphemeralSecret, PublicKey}; // Decode the recipient's public key. @@ -68,7 +73,7 @@ pub fn encrypt(recipient: &Key, let VB = MPI::new(public.as_bytes()); // Encode the shared secret. - let shared: &[u8] = shared.as_bytes(); + let shared: &[u8] = shared.raw_secret_bytes(); let shared = Protected::from(shared); (VB, shared) @@ -115,7 +120,10 @@ pub fn decrypt(recipient: &Key, use p256::{ SecretKey, PublicKey, - elliptic_curve::ecdh::diffie_hellman, + elliptic_curve::{ + ecdh::diffie_hellman, + generic_array::GenericArray as GA, + }, }; const NISTP256_SIZE: usize = 32; @@ -125,10 +133,11 @@ pub fn decrypt(recipient: &Key, let scalar: [u8; NISTP256_SIZE] = scalar.value_padded(NISTP256_SIZE).as_ref().try_into()?; - let r = SecretKey::from_bytes(scalar)?; + let scalar = GA::try_from_slice(&scalar)?; + let r = SecretKey::from_bytes(&scalar)?; - let secret = diffie_hellman(r.secret_scalar(), V.as_affine()); - Vec::from(secret.as_bytes().as_slice()).into() + let secret = diffie_hellman(r.to_nonzero_scalar(), V.as_affine()); + Vec::from(secret.raw_secret_bytes().as_slice()).into() }, _ => { return Err(Error::UnsupportedEllipticCurve(curve.clone()).into()); diff --git a/openpgp/src/crypto/backend/rust/hash.rs b/openpgp/src/crypto/backend/rust/hash.rs index fa3b9f2c..42c6050a 100644 --- a/openpgp/src/crypto/backend/rust/hash.rs +++ b/openpgp/src/crypto/backend/rust/hash.rs @@ -32,7 +32,7 @@ macro_rules! impl_digest_for { } impl_digest_for!(md5::Md5, MD5); -impl_digest_for!(ripemd160::Ripemd160, RipeMD); +impl_digest_for!(ripemd::Ripemd160, RipeMD); impl_digest_for!(sha1::Sha1, SHA1); impl_digest_for!(sha2::Sha224, SHA224); impl_digest_for!(sha2::Sha256, SHA256); @@ -71,7 +71,7 @@ impl HashAlgorithm { HashAlgorithm::SHA256 => Ok(Box::new(sha2::Sha256::new())), HashAlgorithm::SHA384 => Ok(Box::new(sha2::Sha384::new())), HashAlgorithm::SHA512 => Ok(Box::new(sha2::Sha512::new())), - HashAlgorithm::RipeMD => Ok(Box::new(ripemd160::Ripemd160::new())), + HashAlgorithm::RipeMD => Ok(Box::new(ripemd::Ripemd160::new())), HashAlgorithm::MD5 => Ok(Box::new(md5::Md5::new())), HashAlgorithm::Private(_) | HashAlgorithm::Unknown(_) => Err(Error::UnsupportedHashAlgorithm(self).into()), diff --git a/openpgp/src/crypto/backend/rust/symmetric.rs b/openpgp/src/crypto/backend/rust/symmetric.rs index 160cdb4f..30bf7274 100644 --- a/openpgp/src/crypto/backend/rust/symmetric.rs +++ b/openpgp/src/crypto/backend/rust/symmetric.rs @@ -1,24 +1,103 @@ use std::slice; -use block_modes::{BlockMode, Cfb, Ecb}; -use block_padding::ZeroPadding; -use cipher::{BlockCipher, NewBlockCipher}; +use cipher::BlockDecryptMut; +use cipher::BlockEncryptMut; +use cipher::KeyInit; +use cipher::KeyIvInit; use generic_array::{ArrayLength, GenericArray}; -use typenum::Unsigned; use crate::{Error, Result}; use crate::crypto::symmetric::Mode; use crate::types::SymmetricAlgorithm; -macro_rules! impl_mode { +use super::GenericArrayExt; + +enum CfbEncrypt { + Idea(cfb_mode::Encryptor), + TripleDES(cfb_mode::Encryptor), + Cast5(cfb_mode::Encryptor), + Blowfish(cfb_mode::Encryptor), + Aes128(cfb_mode::Encryptor), + Aes192(cfb_mode::Encryptor), + Aes256(cfb_mode::Encryptor), + Twofish(cfb_mode::Encryptor), + //Camellia128 + //Camellia192 + //Camellia256 +} + +enum CfbDecrypt { + Idea(cfb_mode::Decryptor), + TripleDES(cfb_mode::Decryptor), + Cast5(cfb_mode::Decryptor), + Blowfish(cfb_mode::Decryptor), + Aes128(cfb_mode::Decryptor), + Aes192(cfb_mode::Decryptor), + Aes256(cfb_mode::Decryptor), + Twofish(cfb_mode::Decryptor), + //Camellia128 + //Camellia192 + //Camellia256 +} + +enum EcbEncrypt { + Idea(ecb::Encryptor), + TripleDES(ecb::Encryptor), + Cast5(ecb::Encryptor), + Blowfish(ecb::Encryptor), + Aes128(ecb::Encryptor), + Aes192(ecb::Encryptor), + Aes256(ecb::Encryptor), + Twofish(ecb::Encryptor), + //Camellia128 + //Camellia192 + //Camellia256 +} + +enum EcbDecrypt { + Idea(ecb::Decryptor), + TripleDES(ecb::Decryptor), + Cast5(ecb::Decryptor), + Blowfish(ecb::Decryptor), + Aes128(ecb::Decryptor), + Aes192(ecb::Decryptor), + Aes256(ecb::Decryptor), + Twofish(ecb::Decryptor), + //Camellia128 + //Camellia192 + //Camellia256 +} + +macro_rules! impl_block_size { ($mode:ident) => { - impl Mode for $mode - where - C: BlockCipher + NewBlockCipher + Send + Sync, - { - fn block_size(&self) -> usize { - C::BlockSize::to_usize() + fn block_size(&self) -> usize { + match self { + $mode::Idea(_) => + ::block_size(), + $mode::TripleDES(_) => + ::block_size(), + $mode::Cast5(_) => + ::block_size(), + $mode::Blowfish(_) => + ::block_size(), + $mode::Aes128(_) => + ::block_size(), + $mode::Aes192(_) => + ::block_size(), + $mode::Aes256(_) => + ::block_size(), + $mode::Twofish(_) => + ::block_size(), } + } + } +} + +macro_rules! impl_enc_mode { + ($mode:ident) => { + impl Mode for $mode + { + impl_block_size!($mode); fn encrypt( &mut self, @@ -31,15 +110,108 @@ macro_rules! impl_mode { if missing > 0 { let mut buf = vec![0u8; src.len() + missing]; buf[..src.len()].copy_from_slice(src); - self.encrypt_blocks(to_blocks(&mut buf)); + match self { + $mode::Idea(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::TripleDES(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::Cast5(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::Blowfish(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::Aes128(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::Aes192(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::Aes256(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + $mode::Twofish(m) => { + let blocks = to_blocks(&mut buf); + m.encrypt_blocks_mut(blocks) + } + } dst.copy_from_slice(&buf[..dst.len()]); } else { dst.copy_from_slice(src); - self.encrypt_blocks(to_blocks(dst)); + match self { + $mode::Idea(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::TripleDES(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::Cast5(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::Blowfish(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::Aes128(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::Aes192(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::Aes256(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + $mode::Twofish(m) => { + let blocks = to_blocks(dst); + m.encrypt_blocks_mut(blocks) + } + } } Ok(()) } + fn decrypt( + &mut self, + _dst: &mut [u8], + _src: &[u8], + ) -> Result<()> { + Err(anyhow::anyhow!( + "decryption not supported in encryption mode")) + } + } + } +} + +macro_rules! impl_dec_mode { + ($mode:ident) => { + impl Mode for $mode + { + impl_block_size!($mode); + + fn encrypt( + &mut self, + _dst: &mut [u8], + _src: &[u8], + ) -> Result<()> { + Err(anyhow::anyhow!( + "encryption not supported in decryption mode")) + } + fn decrypt( &mut self, dst: &mut [u8], @@ -51,11 +223,77 @@ macro_rules! impl_mode { if missing > 0 { let mut buf = vec![0u8; src.len() + missing]; buf[..src.len()].copy_from_slice(src); - self.decrypt_blocks(to_blocks(&mut buf)); + match self { + $mode::Idea(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::TripleDES(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::Cast5(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::Blowfish(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::Aes128(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::Aes192(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::Aes256(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + $mode::Twofish(m) => { + let blocks = to_blocks(&mut buf); + m.decrypt_blocks_mut(blocks) + } + } dst.copy_from_slice(&buf[..dst.len()]); } else { dst.copy_from_slice(src); - self.decrypt_blocks(to_blocks(dst)); + match self { + $mode::Idea(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::TripleDES(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::Cast5(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::Blowfish(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::Aes128(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::Aes192(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::Aes256(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + $mode::Twofish(m) => { + let blocks = to_blocks(dst); + m.decrypt_blocks_mut(blocks) + } + } } Ok(()) } @@ -63,8 +301,10 @@ macro_rules! impl_mode { } } -impl_mode!(Cfb); -impl_mode!(Ecb); +impl_enc_mode!(CfbEncrypt); +impl_dec_mode!(CfbDecrypt); +impl_enc_mode!(EcbEncrypt); +impl_dec_mode!(EcbDecrypt); fn to_blocks(data: &mut [u8]) -> &mut [GenericArray] where @@ -77,6 +317,81 @@ where } } +/// Creates a context for encrypting/decrypting in CFB/ECB mode. +macro_rules! make_mode { + ($fn:ident, $enum:ident, $mode:ident::$mode2:ident $(, $iv:ident:$ivt:ty)?) => { + pub(crate) fn $fn(self, key: &[u8], $($iv: $ivt)?) -> Result> { + use cipher::generic_array::GenericArray as GA; + + use SymmetricAlgorithm::*; + + match self { + IDEA => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Idea( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + TripleDES => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::TripleDES( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + CAST5 => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Cast5( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + Blowfish => { + // Right... the blowfish constructor expects a 56 + // byte key, but in OpenPGP the key is only 16 + // bytes. + assert_eq!(key.len(), 16); + let mut key = key.to_vec(); + while key.len() < 56 { + key.push(0); + } + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Blowfish( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + AES128 => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Aes128( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + AES192 => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Aes192( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + AES256 => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Aes256( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + Twofish => { + let key = GA::try_from_slice(&key)?; + $( let $iv = &GA::try_from_slice(&$iv)?; )? + Ok(Box::new($enum::Twofish( + $mode::$mode2::::new(key $(, $iv)?)))) + }, + Camellia128 | Camellia192 | Camellia256 + | Private(_) | Unknown(_) | Unencrypted => + { + Err(Error::UnsupportedSymmetricAlgorithm(self).into()) + } + } + } + } +} + impl SymmetricAlgorithm { /// Returns whether this algorithm is supported by the crypto backend. pub(crate) fn is_supported_by_backend(&self) -> bool { @@ -99,49 +414,10 @@ impl SymmetricAlgorithm { } } - /// Creates a context for encrypting in CFB mode. - pub(crate) fn make_encrypt_cfb(self, key: &[u8], iv: Vec) -> Result> { - use SymmetricAlgorithm::*; - match self { - IDEA => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - TripleDES => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - CAST5 => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - Blowfish => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - AES128 => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - AES192 => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - AES256 => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - Twofish => Ok(Box::new(Cfb::::new_var(key, &iv)?)), - Camellia128 | Camellia192 | Camellia256 | Private(_) | Unknown(_) | Unencrypted => - Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - - /// Creates a context for decrypting in CFB mode. - pub(crate) fn make_decrypt_cfb(self, key: &[u8], iv: Vec) -> Result> { - self.make_encrypt_cfb(key, iv) - } - - /// Creates a context for encrypting in ECB mode. - pub(crate) fn make_encrypt_ecb(self, key: &[u8]) -> Result> { - use SymmetricAlgorithm::*; - match self { - IDEA => Ok(Box::new(Ecb::::new_var(key, &[])?)), - TripleDES => Ok(Box::new(Ecb::::new_var(key, &[])?)), - CAST5 => Ok(Box::new(Ecb::::new_var(key, &[])?)), - Blowfish => Ok(Box::new(Ecb::::new_var(key, &[])?)), - AES128 => Ok(Box::new(Ecb::::new_var(key, &[])?)), - AES192 => Ok(Box::new(Ecb::::new_var(key, &[])?)), - AES256 => Ok(Box::new(Ecb::::new_var(key, &[])?)), - Twofish => Ok(Box::new(Ecb::::new_var(key, &[])?)), - Camellia128 | Camellia192 | Camellia256 | Private(_) | Unknown(_) | Unencrypted => - Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - - /// Creates a context for decrypting in ECB mode. - pub(crate) fn make_decrypt_ecb(self, key: &[u8]) -> Result> { - self.make_encrypt_ecb(key) - } + make_mode!(make_encrypt_cfb, CfbEncrypt, cfb_mode::Encryptor, iv: Vec); + make_mode!(make_decrypt_cfb, CfbDecrypt, cfb_mode::Decryptor, iv: Vec); + make_mode!(make_encrypt_ecb, EcbEncrypt, ecb::Encryptor); + make_mode!(make_decrypt_ecb, EcbDecrypt, ecb::Decryptor); } #[cfg(test)] @@ -153,21 +429,21 @@ mod tests { #[test] fn key_size() -> Result<()> { assert_eq!(SymmetricAlgorithm::IDEA.key_size()?, - ::KeySize::to_usize()); + ::key_size()); assert_eq!(SymmetricAlgorithm::TripleDES.key_size()?, - ::KeySize::to_usize()); + ::key_size()); assert_eq!(SymmetricAlgorithm::CAST5.key_size()?, - ::KeySize::to_usize()); + ::key_size()); // RFC4880, Section 9.2: Blowfish (128 bit key, 16 rounds) assert_eq!(SymmetricAlgorithm::Blowfish.key_size()?, 16); assert_eq!(SymmetricAlgorithm::AES128.key_size()?, - ::KeySize::to_usize()); + ::key_size()); assert_eq!(SymmetricAlgorithm::AES192.key_size()?, - ::KeySize::to_usize()); + ::key_size()); assert_eq!(SymmetricAlgorithm::AES256.key_size()?, - ::KeySize::to_usize()); + ::key_size()); assert_eq!(SymmetricAlgorithm::Twofish.key_size()?, - ::KeySize::to_usize()); + ::key_size()); Ok(()) } @@ -176,21 +452,21 @@ mod tests { #[test] fn block_size() -> Result<()> { assert_eq!(SymmetricAlgorithm::IDEA.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::TripleDES.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::CAST5.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::Blowfish.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::AES128.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::AES192.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::AES256.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); assert_eq!(SymmetricAlgorithm::Twofish.block_size()?, - ::BlockSize::to_usize()); + ::block_size()); Ok(()) } }