diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01ed2688b..bdb6a7317 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -117,6 +117,18 @@ jobs: cargo fmt --check -p mbedtls cargo fmt --check -p mbedtls-platform-support cargo fmt --check -p mbedtls-sys-auto + + bench: + name: Cargo bench + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + - name: Run cargo bench + run: cargo bench + ci-success: name: ci if: always() diff --git a/Cargo.lock b/Cargo.lock index 0152a19ff..440d1c6b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,18 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + [[package]] name = "async-stream" version = "0.3.4" @@ -96,6 +108,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + [[package]] name = "byteorder" version = "1.3.2" @@ -108,6 +126,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cbc" version = "0.1.2" @@ -159,6 +183,33 @@ dependencies = [ "time", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -180,6 +231,31 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + [[package]] name = "cmake" version = "0.1.50" @@ -189,6 +265,73 @@ dependencies = [ "cc", ] +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-common" version = "0.1.6" @@ -213,7 +356,7 @@ checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -337,6 +480,16 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +[[package]] +name = "half" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" +dependencies = [ + "cfg-if 1.0.0", + "crunchy", +] + [[package]] name = "hermit-abi" version = "0.1.17" @@ -346,6 +499,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" + [[package]] name = "hex" version = "0.3.2" @@ -358,7 +517,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -407,6 +566,41 @@ dependencies = [ "generic-array", ] +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi 0.3.5", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "language-tags" version = "0.2.2" @@ -485,7 +679,7 @@ checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" [[package]] name = "mbedtls" -version = "0.12.2" +version = "0.12.3" dependencies = [ "async-stream", "bit-vec", @@ -495,6 +689,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "chrono", + "criterion", "futures", "hex", "hyper", @@ -626,11 +821,11 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.8" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ - "autocfg 0.1.6", + "autocfg 1.1.0", ] [[package]] @@ -639,7 +834,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.17", "libc", ] @@ -649,6 +844,12 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "peeking_take_while" version = "0.1.2" @@ -679,6 +880,34 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72d5370d90f49f70bd033c3d75e87fc529fbfff9d6f7cccef07d6170079d91ea" +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + [[package]] name = "prettyplease" version = "0.2.15" @@ -753,6 +982,26 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "rc2" version = "0.8.1" @@ -817,20 +1066,38 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + [[package]] name = "safemem" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" +dependencies = [ + "serde_derive", +] [[package]] name = "serde_bytes" @@ -863,6 +1130,17 @@ dependencies = [ "syn 0.14.9", ] +[[package]] +name = "serde_json" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "shlex" version = "1.3.0" @@ -928,6 +1206,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.1.0" @@ -1094,6 +1382,80 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log 0.4.8", + "once_cell", + "proc-macro2 1.0.66", + "quote 1.0.33", + "syn 2.0.32", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote 1.0.33", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.33", + "syn 2.0.32", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "web-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "which" version = "4.4.2" @@ -1122,6 +1484,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1134,7 +1505,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -1143,13 +1523,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1158,42 +1553,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "yasna" version = "0.2.2" diff --git a/mbedtls/Cargo.toml b/mbedtls/Cargo.toml index 31c8e0db6..882383c8f 100644 --- a/mbedtls/Cargo.toml +++ b/mbedtls/Cargo.toml @@ -2,7 +2,7 @@ name = "mbedtls" # We jumped from v0.9 to v0.12 because v0.10 and v0.11 were based on mbedtls 3.X, which # we decided not to support. -version = "0.12.2" +version = "0.12.3" authors = ["Jethro Beekman "] build = "build.rs" edition = "2018" @@ -57,6 +57,7 @@ async-stream = "0.3.0" futures = "0.3" tracing = "0.1" pin-project-lite = "0.2" +criterion = { version = "0.5.1", features = ["html_reports"] } [build-dependencies] cc = "1.0" @@ -138,3 +139,7 @@ required-features = ["std", "ssl"] name = "async_session" path = "tests/async_session.rs" required-features = ["async-rt", "ssl"] + +[[bench]] +name = "ecp_eq_test" +harness = false \ No newline at end of file diff --git a/mbedtls/benches/ecp_eq_test.rs b/mbedtls/benches/ecp_eq_test.rs new file mode 100644 index 000000000..ab21a6719 --- /dev/null +++ b/mbedtls/benches/ecp_eq_test.rs @@ -0,0 +1,41 @@ +use criterion::{black_box, criterion_main, Criterion}; +use mbedtls::{bignum::Mpi, ecp::EcPoint}; + +fn ecp_equal(a: &EcPoint, b: &EcPoint) { + assert!(!a.eq(&b).unwrap()); +} + +fn ecp_equal_const_time(a: &EcPoint, b: &EcPoint) { + assert!(!a.eq_const_time(&b)); +} + +fn criterion_benchmark(c: &mut Criterion) { + let one = Mpi::new(1).unwrap(); + let zero = Mpi::new(0).unwrap(); + let p_0_1_1 = EcPoint::from_components(zero.clone(), one.clone()).unwrap(); + let p_1_0_1 = EcPoint::from_components(one.clone(), zero.clone()).unwrap(); + let p_1_1_0 = EcPoint::new().unwrap(); + let p_1_1_1 = EcPoint::from_components(one.clone(), one.clone()).unwrap(); + + let mut group = c.benchmark_group("EcpPoint equal"); + + group.bench_function("X not equal", |b| b.iter(|| ecp_equal(black_box(&p_0_1_1), &p_1_1_1))); + group.bench_function("Y not equal", |b| b.iter(|| ecp_equal(black_box(&p_1_0_1), &p_1_1_1))); + group.bench_function("Z not equal", |b| b.iter(|| ecp_equal(black_box(&p_1_1_0), &p_1_1_1))); + + group.bench_function("X not equal const_time", |b| { + b.iter(|| ecp_equal_const_time(black_box(&p_0_1_1), &p_1_1_1)) + }); + group.bench_function("Y not equal const_time", |b| { + b.iter(|| ecp_equal_const_time(black_box(&p_1_0_1), &p_1_1_1)) + }); + group.bench_function("Z not equal const_time", |b| { + b.iter(|| ecp_equal_const_time(black_box(&p_1_1_0), &p_1_1_1)) + }); +} + +pub fn benches() { + let mut criterion = Criterion::default().sample_size(10_000).configure_from_args(); + criterion_benchmark(&mut criterion); +} +criterion_main!(benches); diff --git a/mbedtls/src/ecp/mod.rs b/mbedtls/src/ecp/mod.rs index ab01002bc..6e7d6e23b 100644 --- a/mbedtls/src/ecp/mod.rs +++ b/mbedtls/src/ecp/mod.rs @@ -309,6 +309,10 @@ impl EcPoint { Mpi::copy(&self.inner.Y) } + pub fn z(&self) -> Result { + Mpi::copy(&self.inner.Z) + } + pub fn is_zero(&self) -> Result { /* mbedtls_ecp_is_zero takes arg as non-const for no particular reason @@ -321,8 +325,15 @@ impl EcPoint { } } + /// This function performs a scalar multiplication of a point by an integer: R = m * P. + /// + /// This function does not accept a RNG so there is no blinding applied. + #[deprecated( + since = "0.12.3", + note = "This function does not accept an RNG so it's vulnerable to side channel attacks. +Please use `mul_with_rng` instead." + )] pub fn mul(&self, group: &mut EcGroup, k: &Mpi) -> Result { - // TODO provide random number generator for blinding // Note: mbedtls_ecp_mul performs point validation itself so we skip that here let mut ret = Self::init(); @@ -342,6 +353,49 @@ impl EcPoint { Ok(ret) } + /// This function performs a scalar multiplication of a point by an integer: `R = k * self`. + /// + /// It uses the group's base field operations to prevent timing attacks, executing the same sequence regardless of `k`. + /// Some intermediate results are randomized using the provided RNG function for blinding. + /// + /// + /// # Arguments + /// + /// * `group` - The elliptic curve group to use. + /// * `k` - The integer scalar by which to multiply. + /// * `rng` - The RNG used for blinding (randomizing some intermediate results) to defend side channel attacks. + /// + /// # Returns + /// + /// * `Result` - The resulting point after multiplication on success. + /// + /// # Errors + /// + /// This function will return an error if: + /// + /// * `k` is not a valid private key, or `self` is not a valid public key. + /// * Memory allocation fails. + /// * Any other kind of failure occurs during the execution of the underlying `mbedtls_ecp_mul` function. + pub fn mul_with_rng(&self, group: &mut EcGroup, k: &Mpi, rng: &mut F) -> Result { + // Note: mbedtls_ecp_mul performs point validation itself so we skip that here + + let mut ret = Self::init(); + + unsafe { + ecp_mul( + &mut group.inner, + &mut ret.inner, + k.handle(), + &self.inner, + Some(F::call), + rng.data_ptr(), + ) + } + .into_result()?; + + Ok(ret) + } + /// Compute pt1*k1 + pt2*k2 -- not const time pub fn muladd(group: &mut EcGroup, pt1: &EcPoint, k1: &Mpi, pt2: &EcPoint, k2: &Mpi) -> Result { let mut ret = Self::init(); @@ -379,6 +433,16 @@ impl EcPoint { } } + /// This function compares two points in const time. + pub fn eq_const_time(&self, other: &EcPoint) -> bool { + unsafe { + let x = mpi_cmp_mpi(&self.inner.X, &other.inner.X) == 0; + let y = mpi_cmp_mpi(&self.inner.Y, &other.inner.Y) == 0; + let z = mpi_cmp_mpi(&self.inner.Z, &other.inner.Z) == 0; + x & y & z + } + } + pub fn to_binary(&self, group: &EcGroup, compressed: bool) -> Result> { /* We know biggest group supported is P-521 so just allocate a @@ -472,7 +536,9 @@ mod tests { for i in 0..32 { k += i; - let pt = generator.mul(&mut group, &k).unwrap(); + let pt = generator + .mul_with_rng(&mut group, &k, &mut crate::test_support::rand::test_rng()) + .unwrap(); let uncompressed_pt = pt.to_binary(&group, false).unwrap(); assert_eq!(uncompressed_pt.len(), 1 + p_len * 2); @@ -502,7 +568,9 @@ mod tests { assert_eq!(g.is_zero().unwrap(), false); let k = Mpi::new(0xC3FF2).unwrap(); - let pt = g.mul(&mut secp256k1, &k).unwrap(); + let pt = g + .mul_with_rng(&mut secp256k1, &k, &mut crate::test_support::rand::test_rng()) + .unwrap(); let pt_uncompressed = pt.to_binary(&secp256k1, false).unwrap(); assert_eq!(pt_uncompressed.len(), 1 + 2 * (bitlen / 8)); @@ -581,7 +649,9 @@ mod tests { let d = Mpi::from_str("0x7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE1D19CE9891EC3B28").unwrap(); - let pubkey = gost_g.mul(&mut gost, &d).unwrap(); + let pubkey = gost_g + .mul_with_rng(&mut gost, &d, &mut crate::test_support::rand::test_rng()) + .unwrap(); let pubkey_x = pubkey.x().unwrap(); let pubkey_y = pubkey.y().unwrap(); @@ -594,7 +664,9 @@ mod tests { let k = Mpi::from_str("0x77105C9B20BCD3122823C8CF6FCC7B956DE33814E95B7FE64FED924594DCEAB3").unwrap(); - let gk = gost_g.mul(&mut gost, &k).unwrap(); + let gk = gost_g + .mul_with_rng(&mut gost, &k, &mut crate::test_support::rand::test_rng()) + .unwrap(); let exp_gk_x = Mpi::from_str("0x41AA28D2F1AB148280CD9ED56FEDA41974053554A42767B83AD043FD39DC0493"); let exp_gk_y = Mpi::from_str("0x489C375A9941A3049E33B34361DD204172AD98C3E5916DE27695D22A61FAE46E"); @@ -638,6 +710,19 @@ mod tests { assert_eq!(xr, r); } + #[test] + fn test_ecp_const_eq() { + let secp256r1 = EcGroup::new(EcGroupId::SecP256R1).unwrap(); + let g = secp256r1.generator().unwrap(); + let zero = EcPoint::new().unwrap(); + assert!(g.eq(&g).unwrap()); + assert!(zero.eq(&zero).unwrap()); + assert!(!g.eq(&zero).unwrap()); + assert!(g.eq_const_time(&g)); + assert!(zero.eq_const_time(&zero)); + assert!(!g.eq_const_time(&zero)); + } + #[test] fn test_ecp_mul() { let mut secp256r1 = EcGroup::new(EcGroupId::SecP256R1).unwrap(); @@ -651,14 +736,20 @@ mod tests { /* Basic sanity check - multiplying twice by k is same as multiply by k**2 */ - let pt1 = g.mul(&mut secp256r1, &k).unwrap(); + let pt1 = g + .mul_with_rng(&mut secp256r1, &k, &mut crate::test_support::rand::test_rng()) + .unwrap(); assert_eq!(pt1.is_zero().unwrap(), false); - let pt2 = g.mul(&mut secp256r1, &half_k).unwrap(); + let pt2 = g + .mul_with_rng(&mut secp256r1, &half_k, &mut crate::test_support::rand::test_rng()) + .unwrap(); assert_eq!(pt2.is_zero().unwrap(), false); assert_eq!(pt1.eq(&pt2).unwrap(), false); - let pt3 = pt2.mul(&mut secp256r1, &half_k).unwrap(); + let pt3 = pt2 + .mul_with_rng(&mut secp256r1, &half_k, &mut crate::test_support::rand::test_rng()) + .unwrap(); assert_eq!(pt1.eq(&pt3).unwrap(), true); assert_eq!(pt3.eq(&pt1).unwrap(), true); diff --git a/mbedtls/src/pk/mod.rs b/mbedtls/src/pk/mod.rs index 77e6bb76f..a96719471 100644 --- a/mbedtls/src/pk/mod.rs +++ b/mbedtls/src/pk/mod.rs @@ -305,9 +305,15 @@ impl Pk { Ok(ret) } + #[deprecated( + since = "0.12.3", + note = "This function does not accept an RNG so it's vulnerable to side channel attacks. +Please use `private_from_ec_components_with_rng` instead." + )] pub fn private_from_ec_components(mut curve: EcGroup, private_key: Mpi) -> Result { let mut ret = Self::init(); let curve_generator = curve.generator()?; + #[allow(deprecated)] let public_point = curve_generator.mul(&mut curve, &private_key)?; unsafe { pk_setup(&mut ret.inner, pk_info_from_type(Type::Eckey.into())).into_result()?; @@ -319,6 +325,46 @@ impl Pk { Ok(ret) } + /// Constructs a private key from elliptic curve components. + /// + /// This function requires a random number generator (RNG) because it uses the `EcPoint::mul` + /// function which requires an RNG for blinding. + /// + /// It initializes a `Pk` context, generates the public key point by multiplying the curve generator + /// with the private key, and sets up the private key context with the generated curve, private key, + /// and public point. + /// + /// # Arguments + /// + /// * `rng` - The RNG used for blinding in the `EcPoint::mul` function. + /// * `curve` - The elliptic curve group to use for key generation. + /// * `private_key` - The private key as an MPI (Multiple Precision Integer). + /// + /// # Returns + /// + /// * `Result` - A `Pk` context filled with the generated private key on success. + /// + /// # Errors + /// + /// This function will return an error if: + /// + /// * Fails to genearte `EcPoint` from given EcGroup in `curve`. + /// * The underlying C `mbedtls_pk_setup` function fails to set up the `Pk` context. + /// * The `EcPoint::mul` function fails to generate the public key point. + pub fn private_from_ec_components_with_rng(mut curve: EcGroup, private_key: Mpi, rng: &mut F) -> Result { + let mut ret = Self::init(); + let curve_generator = curve.generator()?; + let public_point = curve_generator.mul_with_rng(&mut curve, &private_key, rng)?; + unsafe { + pk_setup(&mut ret.inner, pk_info_from_type(Type::Eckey.into())).into_result()?; + let ctx = ret.inner.pk_ctx as *mut ecp_keypair; + (*ctx).grp = curve.into_inner(); + (*ctx).d = private_key.into_inner(); + (*ctx).Q = public_point.into_inner(); + } + Ok(ret) + } + pub fn public_from_ec_components(curve: EcGroup, public_point: EcPoint) -> Result { let mut ret = Self::init(); unsafe { @@ -1159,7 +1205,12 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi assert_eq!(pem1, pem2); - let mut key_from_components = Pk::private_from_ec_components(secp256r1.clone(), key1.ec_private().unwrap()).unwrap(); + let mut key_from_components = Pk::private_from_ec_components_with_rng( + secp256r1.clone(), + key1.ec_private().unwrap(), + &mut crate::test_support::rand::test_rng(), + ) + .unwrap(); let pem3 = key_from_components.write_private_pem_string().unwrap(); assert_eq!(pem3, pem2);