From fc0f22d5fc552831178070cc86620b7637b7a6cb Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Mon, 16 Nov 2020 14:02:08 -0800 Subject: [PATCH 1/6] Unify the `aes`, `aesni`, and `aes-soft` crates Combines all three crates into a single `aes` crate. The optional `ctr` feature exposes a consistent set of `Aes*Ctr` types as well. --- .github/workflows/aes-soft.yml | 100 --------- .github/workflows/aes.yml | 109 ++++++++-- .github/workflows/aesni.yml | 37 ---- Cargo.lock | 27 +-- Cargo.toml | 2 - aes/Cargo.toml | 20 +- aes/aes-soft/CHANGELOG.md | 83 -------- aes/aes-soft/Cargo.toml | 21 -- aes/aes-soft/LICENSE-APACHE | 201 ------------------ aes/aes-soft/LICENSE-MIT | 27 --- aes/aes-soft/benches/aes128.rs | 61 ------ aes/aes-soft/benches/aes192.rs | 61 ------ aes/aes-soft/benches/aes256.rs | 61 ------ aes/aes-soft/src/lib.rs | 60 ------ aes/aes-soft/tests/data/aes128.blb | Bin 27418 -> 0 bytes aes/aes-soft/tests/data/aes192.blb | Bin 41322 -> 0 bytes aes/aes-soft/tests/data/aes256.blb | Bin 49594 -> 0 bytes aes/aes-soft/tests/lib.rs | 6 - aes/aesni/CHANGELOG.md | 87 -------- aes/aesni/Cargo.toml | 27 --- aes/aesni/LICENSE-APACHE | 201 ------------------ aes/aesni/LICENSE-MIT | 25 --- aes/aesni/benches/aes128.rs | 54 ----- aes/aesni/benches/aes128_ctr.rs | 5 - aes/aesni/benches/aes192.rs | 54 ----- aes/aesni/benches/aes192_ctr.rs | 5 - aes/aesni/benches/aes256.rs | 54 ----- aes/aesni/benches/aes256_ctr.rs | 5 - aes/aesni/tests/data/aes128.blb | Bin 27418 -> 0 bytes aes/aesni/tests/data/aes192.blb | Bin 41322 -> 0 bytes aes/aesni/tests/data/aes256.blb | Bin 49594 -> 0 bytes aes/aesni/tests/lib.rs | 6 - aes/benches/aes128.rs | 26 +-- aes/benches/aes192.rs | 27 +-- aes/benches/aes256.rs | 26 +-- aes/src/lib.rs | 67 ++++-- aes/{aesni/src/lib.rs => src/ni.rs} | 52 +---- aes/{aesni/src => src/ni}/aes128.rs | 4 +- aes/{aesni/src => src/ni}/aes128/expand.rs | 2 +- .../src => src/ni}/aes128/test_expand.rs | 2 +- aes/{aesni/src => src/ni}/aes192.rs | 4 +- aes/{aesni/src => src/ni}/aes192/expand.rs | 2 +- .../src => src/ni}/aes192/test_expand.rs | 2 +- aes/{aesni/src => src/ni}/aes256.rs | 4 +- aes/{aesni/src => src/ni}/aes256/expand.rs | 2 +- .../src => src/ni}/aes256/test_expand.rs | 2 +- aes/{aesni/src => src/ni}/ctr.rs | 5 +- aes/{aesni/src => src/ni}/target_checks.rs | 0 aes/{aesni/src => src/ni}/utils.rs | 2 +- aes/src/soft.rs | 20 ++ aes/src/soft/ctr.rs | 15 ++ aes/{aes-soft/src => src/soft}/fixslice32.rs | 0 aes/{aes-soft/src => src/soft}/fixslice64.rs | 0 aes/{aes-soft/src => src/soft}/impls.rs | 9 +- aes/{aesni => }/tests/ctr.rs | 2 +- aes/{aesni => }/tests/data/aes128-ctr.blb | Bin aes/{aesni => }/tests/data/aes256-ctr.blb | Bin 57 files changed, 268 insertions(+), 1406 deletions(-) delete mode 100644 .github/workflows/aes-soft.yml delete mode 100644 .github/workflows/aesni.yml delete mode 100644 aes/aes-soft/CHANGELOG.md delete mode 100644 aes/aes-soft/Cargo.toml delete mode 100644 aes/aes-soft/LICENSE-APACHE delete mode 100644 aes/aes-soft/LICENSE-MIT delete mode 100644 aes/aes-soft/benches/aes128.rs delete mode 100644 aes/aes-soft/benches/aes192.rs delete mode 100644 aes/aes-soft/benches/aes256.rs delete mode 100644 aes/aes-soft/src/lib.rs delete mode 100644 aes/aes-soft/tests/data/aes128.blb delete mode 100644 aes/aes-soft/tests/data/aes192.blb delete mode 100644 aes/aes-soft/tests/data/aes256.blb delete mode 100644 aes/aes-soft/tests/lib.rs delete mode 100644 aes/aesni/CHANGELOG.md delete mode 100644 aes/aesni/Cargo.toml delete mode 100644 aes/aesni/LICENSE-APACHE delete mode 100644 aes/aesni/LICENSE-MIT delete mode 100644 aes/aesni/benches/aes128.rs delete mode 100644 aes/aesni/benches/aes128_ctr.rs delete mode 100644 aes/aesni/benches/aes192.rs delete mode 100644 aes/aesni/benches/aes192_ctr.rs delete mode 100644 aes/aesni/benches/aes256.rs delete mode 100644 aes/aesni/benches/aes256_ctr.rs delete mode 100644 aes/aesni/tests/data/aes128.blb delete mode 100644 aes/aesni/tests/data/aes192.blb delete mode 100644 aes/aesni/tests/data/aes256.blb delete mode 100644 aes/aesni/tests/lib.rs rename aes/{aesni/src/lib.rs => src/ni.rs} (67%) rename aes/{aesni/src => src/ni}/aes128.rs (98%) rename aes/{aesni/src => src/ni}/aes128/expand.rs (98%) rename aes/{aesni/src => src/ni}/aes128/test_expand.rs (99%) rename aes/{aesni/src => src/ni}/aes192.rs (98%) rename aes/{aesni/src => src/ni}/aes192/expand.rs (99%) rename aes/{aesni/src => src/ni}/aes192/test_expand.rs (99%) rename aes/{aesni/src => src/ni}/aes256.rs (98%) rename aes/{aesni/src => src/ni}/aes256/expand.rs (99%) rename aes/{aesni/src => src/ni}/aes256/test_expand.rs (99%) rename aes/{aesni/src => src/ni}/ctr.rs (98%) rename aes/{aesni/src => src/ni}/target_checks.rs (100%) rename aes/{aesni/src => src/ni}/utils.rs (99%) create mode 100644 aes/src/soft.rs create mode 100644 aes/src/soft/ctr.rs rename aes/{aes-soft/src => src/soft}/fixslice32.rs (100%) rename aes/{aes-soft/src => src/soft}/fixslice64.rs (100%) rename aes/{aes-soft/src => src/soft}/impls.rs (91%) rename aes/{aesni => }/tests/ctr.rs (90%) rename aes/{aesni => }/tests/data/aes128-ctr.blb (100%) rename aes/{aesni => }/tests/data/aes256-ctr.blb (100%) diff --git a/.github/workflows/aes-soft.yml b/.github/workflows/aes-soft.yml deleted file mode 100644 index 0f65372e..00000000 --- a/.github/workflows/aes-soft.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: aes-soft - -on: - pull_request: - paths: - - "aes/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: aes/aes-soft - -env: - CARGO_INCREMENTAL: 0 - RUSTFLAGS: "-Dwarnings" - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - target: - - thumbv7em-none-eabi - - wasm32-unknown-unknown - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - profile: minimal - override: true - - run: cargo build --release --target ${{ matrix.target }} - - test: - runs-on: ubuntu-latest - strategy: - matrix: - include: - # 32-bit Linux - - target: i686-unknown-linux-gnu - rust: 1.41.0 # MSRV - deps: sudo apt install gcc-multilib - - target: i686-unknown-linux-gnu - rust: stable - deps: sudo apt install gcc-multilib - - # 64-bit Linux - - target: x86_64-unknown-linux-gnu - rust: 1.41.0 # MSRV - - target: x86_64-unknown-linux-gnu - rust: stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - profile: minimal - override: true - - run: ${{ matrix.deps }} - - run: cargo check --target ${{ matrix.target }} --all-features - - run: cargo test --release --target ${{ matrix.target }} - - run: cargo test --release --target ${{ matrix.target }} --features semi_fixslice - - # Cross-compiled tests - cross: - strategy: - matrix: - include: - # ARM64 - - target: aarch64-unknown-linux-gnu - rust: 1.41.0 # MSRV - - target: aarch64-unknown-linux-gnu - rust: stable - - # PPC32 - - target: powerpc-unknown-linux-gnu - rust: 1.41.0 # MSRV - - target: powerpc-unknown-linux-gnu - rust: stable - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v1 - - run: ${{ matrix.deps }} - - uses: actions-rs/toolchain@v1 - with: - toolchain: ${{ matrix.rust }} - target: ${{ matrix.target }} - profile: minimal - override: true - - run: cargo install cross - - run: cross test --release --target ${{ matrix.target }} - - run: cross test --release --target ${{ matrix.target }} --features semi_fixslice diff --git a/.github/workflows/aes.yml b/.github/workflows/aes.yml index efbbd385..5466bda0 100644 --- a/.github/workflows/aes.yml +++ b/.github/workflows/aes.yml @@ -31,25 +31,106 @@ jobs: - uses: actions/checkout@v1 - uses: actions-rs/toolchain@v1 with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} profile: minimal + override: true + - run: cargo build --release --target ${{ matrix.target }} + + # Tests for the portable software backend + soft: + runs-on: ubuntu-latest + strategy: + matrix: + include: + # 32-bit Linux + - target: i686-unknown-linux-gnu + rust: 1.41.0 # MSRV + deps: sudo apt install gcc-multilib + - target: i686-unknown-linux-gnu + rust: stable + deps: sudo apt install gcc-multilib + + # 64-bit Linux + - target: x86_64-unknown-linux-gnu + rust: 1.41.0 # MSRV + - target: x86_64-unknown-linux-gnu + rust: stable + steps: + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: toolchain: ${{ matrix.rust }} target: ${{ matrix.target }} + profile: minimal override: true - - run: cargo build --no-default-features --release --target ${{ matrix.target }} - test: + - run: ${{ matrix.deps }} + - run: cargo check --target ${{ matrix.target }} --all-features + - run: cargo test --release --target ${{ matrix.target }} + - run: cargo test --release --target ${{ matrix.target }} --features semi_fixslice + + # Tests for the AES-NI backend + aesni: runs-on: ubuntu-latest + env: + CARGO_INCREMENTAL: 0 + RUSTDOCFLAGS: "-Ctarget-feature=+aes,+ssse3" + RUSTFLAGS: "-Dwarnings -Ctarget-feature=+aes,+ssse3" strategy: matrix: - rust: - - 1.41.0 # MSRV - - stable + include: + # 32-bit Linux + - target: i686-unknown-linux-gnu + rust: 1.41.0 # MSRV + deps: sudo apt install gcc-multilib + - target: i686-unknown-linux-gnu + rust: stable + deps: sudo apt install gcc-multilib + + # 64-bit Linux + - target: x86_64-unknown-linux-gnu + rust: 1.41.0 # MSRV + - target: x86_64-unknown-linux-gnu + rust: stable steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - - run: cargo check --all-features - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --all-features + - uses: actions/checkout@v1 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + - run: ${{ matrix.deps }} + - run: cargo check --all-features + - run: cargo test --no-default-features + - run: cargo test + - run: cargo test --all-features + + # Cross-compiled tests + cross: + strategy: + matrix: + include: + # ARM64 + - target: aarch64-unknown-linux-gnu + rust: 1.41.0 # MSRV + - target: aarch64-unknown-linux-gnu + rust: stable + + # PPC32 + - target: powerpc-unknown-linux-gnu + rust: 1.41.0 # MSRV + - target: powerpc-unknown-linux-gnu + rust: stable + + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - run: ${{ matrix.deps }} + - uses: actions-rs/toolchain@v1 + with: + toolchain: ${{ matrix.rust }} + target: ${{ matrix.target }} + profile: minimal + override: true + - run: cargo install cross + - run: cross test --release --target ${{ matrix.target }} + - run: cross test --release --target ${{ matrix.target }} --features semi_fixslice diff --git a/.github/workflows/aesni.yml b/.github/workflows/aesni.yml deleted file mode 100644 index 7b4080b9..00000000 --- a/.github/workflows/aesni.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: aesni - -on: - pull_request: - paths: - - "aes/**" - - "Cargo.*" - push: - branches: master - -defaults: - run: - working-directory: aes/aesni - -env: - CARGO_INCREMENTAL: 0 - RUSTDOCFLAGS: "-C target-feature=+aes,+ssse3" - RUSTFLAGS: "-Dwarnings -C target-feature=+aes,+ssse3" - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - rust: - - 1.41.0 # MSRV - - stable - steps: - - uses: actions/checkout@v1 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.rust }} - - run: cargo check --all-features - - run: cargo test --no-default-features - - run: cargo test - - run: cargo test --all-features diff --git a/Cargo.lock b/Cargo.lock index 93421756..2aa80e20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,25 +3,9 @@ [[package]] name = "aes" version = "0.6.0" -dependencies = [ - "aes-soft", - "aesni", - "cipher", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -dependencies = [ - "cipher", - "opaque-debug", -] - -[[package]] -name = "aesni" -version = "0.10.0" dependencies = [ "cipher", + "ctr", "opaque-debug", ] @@ -82,6 +66,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "ctr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" +dependencies = [ + "cipher", +] + [[package]] name = "des" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index 27a72414..3cc9549c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,6 @@ [workspace] members = [ "aes", - "aes/aes-soft", - "aes/aesni", "blowfish", "block-modes", "gost-modes", diff --git a/aes/Cargo.toml b/aes/Cargo.toml index e3028d84..39d2ed09 100644 --- a/aes/Cargo.toml +++ b/aes/Cargo.toml @@ -1,7 +1,10 @@ [package] name = "aes" version = "0.6.0" -description = "Facade for AES (Rijndael) block ciphers implementations" +description = """ +Pure Rust implementation of the Advanced Encryption Standard (a.k.a. Rijndael) +including support for AES in counter mode (a.k.a. AES-CTR) +""" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" readme = "README.md" @@ -13,12 +16,15 @@ categories = ["cryptography", "no-std"] [dependencies] cipher = "0.2" - -[target.'cfg(not(all(target_feature="aes", target_feature = "sse2", any(target_arch = "x86_64", target_arch = "x86"))))'.dependencies] -aes-soft = { version = "0.6", path = "aes-soft" } - -[target.'cfg(all(target_feature="aes", target_feature = "sse2", any(target_arch = "x86_64", target_arch = "x86")))'.dependencies] -aesni = { version = "0.10", default-features = false, path = "aesni" } +ctr = { version = "0.6", optional = true } +opaque-debug = "0.3" [dev-dependencies] cipher = { version = "0.2", features = ["dev"] } + +[features] +semi_fixslice = [] + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] diff --git a/aes/aes-soft/CHANGELOG.md b/aes/aes-soft/CHANGELOG.md deleted file mode 100644 index 4f0b80a3..00000000 --- a/aes/aes-soft/CHANGELOG.md +++ /dev/null @@ -1,83 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.6.4 (2020-11-16) -### Changed -- Rework of xor_columns ([#197]) -- Implement semi-fixsliced support under `semi_fixslice` Cargo feature ([#195]) - -[#197]: https://github.com/RustCrypto/block-ciphers/pull/197 -[#195]: https://github.com/RustCrypto/block-ciphers/pull/195 - -## 0.6.3 (2020-11-01) -### Changed -- Comprehensive refactoring of fixslice code ([#192]) -- Forbid `unsafe` ([#190]) -- Re-order (`inv`)`_sbox` using custom scheduler ([#189]) - -[#192]: https://github.com/RustCrypto/block-ciphers/pull/192 -[#190]: https://github.com/RustCrypto/block-ciphers/pull/190 -[#189]: https://github.com/RustCrypto/block-ciphers/pull/189 - -## 0.6.2 (2020-10-28) -### Added -- 64-bit fixsliced AES implementation ([#180]) - -### Changed -- Fixsliced AES decryption ([#185]) -- Improved AES fixsliced MixColumns algorithms ([#184]) - -[#185]: https://github.com/RustCrypto/block-ciphers/pull/185 -[#184]: https://github.com/RustCrypto/block-ciphers/pull/184 -[#180]: https://github.com/RustCrypto/block-ciphers/pull/180 - -## 0.6.1 (2020-10-26) -### Changed -- Use fixslicing for AES encryption - 3X performance boost ([#174], [#176], [#177]) -- Additional bitslicing performance optimizations ([#171], [#175]) - -[#177]: https://github.com/RustCrypto/block-ciphers/pull/177 -[#176]: https://github.com/RustCrypto/block-ciphers/pull/176 -[#175]: https://github.com/RustCrypto/block-ciphers/pull/175 -[#174]: https://github.com/RustCrypto/block-ciphers/pull/174 -[#171]: https://github.com/RustCrypto/block-ciphers/pull/171 - -## 0.6.0 (2020-10-16) -### Changed -- Replace `block-cipher`/`stream-cipher` with `cipher` crate ([#167]) -- Performance improvements ([#166]) - -[#167]: https://github.com/RustCrypto/block-ciphers/pull/167 -[#166]: https://github.com/RustCrypto/block-ciphers/pull/166 - -## 0.5.0 (2020-08-07) -### Changed -- Bump `block-cipher` dependency to v0.8 ([#138]) -- Bump `opaque-debug` dependency to v0.3 ([#140]) - -[#138]: https://github.com/RustCrypto/block-ciphers/pull/138 -[#140]: https://github.com/RustCrypto/block-ciphers/pull/140 - -## 0.4.0 (2020-06-05) -### Changed -- Bump `block-cipher` dependency to v0.7 ([#86], [#122]) -- Update to Rust 2018 edition ([#86]) - -[#122]: https://github.com/RustCrypto/block-ciphers/pull/122 -[#86]: https://github.com/RustCrypto/block-ciphers/pull/86 - -## 0.3.3 (2018-12-23) - -## 0.3.2 (2018-10-04) - -## 0.3.1 (2018-10-03) - -## 0.3.0 (2018-10-03) - -## 0.2.0 (2018-07-27) - -## 0.1.0 (2018-03-04) diff --git a/aes/aes-soft/Cargo.toml b/aes/aes-soft/Cargo.toml deleted file mode 100644 index 5c351c26..00000000 --- a/aes/aes-soft/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "aes-soft" -version = "0.6.4" -description = "AES (Rijndael) block ciphers bit-sliced implementation" -authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -edition = "2018" -documentation = "https://docs.rs/aes-soft" -repository = "https://github.com/RustCrypto/block-ciphers" -keywords = ["crypto", "aes", "rijndael", "block-cipher"] -categories = ["cryptography", "no-std"] - -[dependencies] -cipher = "0.2" -opaque-debug = "0.3" - -[dev-dependencies] -cipher = { version = "0.2", features = ["dev"] } - -[features] -semi_fixslice = [] diff --git a/aes/aes-soft/LICENSE-APACHE b/aes/aes-soft/LICENSE-APACHE deleted file mode 100644 index 78173fa2..00000000 --- a/aes/aes-soft/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/aes/aes-soft/LICENSE-MIT b/aes/aes-soft/LICENSE-MIT deleted file mode 100644 index 95d1222e..00000000 --- a/aes/aes-soft/LICENSE-MIT +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2006-2009 Graydon Hoare -Copyright (c) 2009-2013 Mozilla Foundation -Copyright (c) 2018 Artyom Pavlov - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/aes/aes-soft/benches/aes128.rs b/aes/aes-soft/benches/aes128.rs deleted file mode 100644 index fa562669..00000000 --- a/aes/aes-soft/benches/aes128.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![feature(test)] -extern crate test; - -use aes_soft::cipher::{BlockCipher, NewBlockCipher}; -use aes_soft::Aes128; - -#[bench] -pub fn aes128_new(bh: &mut test::Bencher) { - bh.iter(|| { - let cipher = Aes128::new(&Default::default()); - test::black_box(&cipher); - }); -} - -#[bench] -pub fn aes128_encrypt(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes128_decrypt(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes128_encrypt8(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} - -#[bench] -pub fn aes128_decrypt8(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} diff --git a/aes/aes-soft/benches/aes192.rs b/aes/aes-soft/benches/aes192.rs deleted file mode 100644 index c6b28112..00000000 --- a/aes/aes-soft/benches/aes192.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![feature(test)] -extern crate test; - -use aes_soft::cipher::{BlockCipher, NewBlockCipher}; -use aes_soft::Aes192; - -#[bench] -pub fn aes192_new(bh: &mut test::Bencher) { - bh.iter(|| { - let cipher = Aes192::new(&Default::default()); - test::black_box(&cipher); - }); -} - -#[bench] -pub fn aes192_encrypt(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes192_decrypt(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes192_encrypt8(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} - -#[bench] -pub fn aes192_decrypt8(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} diff --git a/aes/aes-soft/benches/aes256.rs b/aes/aes-soft/benches/aes256.rs deleted file mode 100644 index c10e44a3..00000000 --- a/aes/aes-soft/benches/aes256.rs +++ /dev/null @@ -1,61 +0,0 @@ -#![feature(test)] -extern crate test; - -use aes_soft::cipher::{BlockCipher, NewBlockCipher}; -use aes_soft::Aes256; - -#[bench] -pub fn aes256_new(bh: &mut test::Bencher) { - bh.iter(|| { - let cipher = Aes256::new(&Default::default()); - test::black_box(&cipher); - }); -} - -#[bench] -pub fn aes256_encrypt(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes256_decrypt(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes256_encrypt8(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} - -#[bench] -pub fn aes256_decrypt8(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} diff --git a/aes/aes-soft/src/lib.rs b/aes/aes-soft/src/lib.rs deleted file mode 100644 index 2d30ab1d..00000000 --- a/aes/aes-soft/src/lib.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! AES block cipher constant-time implementation. -//! -//! The `aes-soft` crate implements the AES algorithm completely in software -//! without using any table lookups or other timing dependant mechanisms. -//! -//! The encryption implementation is based on a technique called [fixslicing][1], -//! while the decryption implementation is heavily based on `aessafe` [module][2], -//! from the original `rust-crypto` crate. -//! -//! # Usage example -//! ``` -//! use aes_soft::cipher::generic_array::GenericArray; -//! use aes_soft::cipher::{BlockCipher, NewBlockCipher}; -//! use aes_soft::Aes128; -//! -//! let key = GenericArray::from_slice(&[0u8; 16]); -//! let mut block = GenericArray::clone_from_slice(&[0u8; 16]); -//! let mut block8 = GenericArray::clone_from_slice(&[block; 8]); -//! // Initialize cipher -//! let cipher = aes_soft::Aes128::new(&key); -//! -//! let block_copy = block.clone(); -//! // Encrypt block in-place -//! cipher.encrypt_block(&mut block); -//! // And decrypt it back -//! cipher.decrypt_block(&mut block); -//! assert_eq!(block, block_copy); -//! -//! // We can encrypt 8 blocks simultaneously using -//! // instruction-level parallelism -//! let block8_copy = block8.clone(); -//! cipher.encrypt_blocks(&mut block8); -//! cipher.decrypt_blocks(&mut block8); -//! assert_eq!(block8, block8_copy); -//! ``` -//! -//! [1]: https://eprint.iacr.org/2020/1123.pdf -//! [2]: https://github.com/DaGenix/rust-crypto/blob/master/src/aessafe.rs - -#![no_std] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![forbid(unsafe_code)] -#![warn(missing_docs, rust_2018_idioms)] - -#[cfg_attr(not(target_pointer_width = "64"), path = "fixslice32.rs")] -#[cfg_attr(target_pointer_width = "64", path = "fixslice64.rs")] -mod fixslice; -mod impls; - -pub use crate::impls::{Aes128, Aes192, Aes256}; -pub use cipher; - -/// 128-bit AES block -pub type Block = cipher::generic_array::GenericArray; - -/// 8 x 128-bit AES blocks to be processed in parallel -pub type ParBlocks = cipher::generic_array::GenericArray; diff --git a/aes/aes-soft/tests/data/aes128.blb b/aes/aes-soft/tests/data/aes128.blb deleted file mode 100644 index 0accb99eb444c47207eebd13422e0505c3052994..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27418 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�#whGFaOQqMXc`x5# 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 diff --git a/aes/aes-soft/tests/data/aes192.blb b/aes/aes-soft/tests/data/aes192.blb deleted file mode 100644 index b5f70fa00ce7ed9f68fdc43b979fc5fba5b3142d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41322 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 RSD2B=VX++Wu?{1c{tv)^Sl0jm diff --git a/aes/aes-soft/tests/lib.rs b/aes/aes-soft/tests/lib.rs deleted file mode 100644 index 874ef06a..00000000 --- a/aes/aes-soft/tests/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Test vectors are from NESSIE: -//! https://www.cosic.esat.kuleuven.be/nessie/testvectors/ - -cipher::block_cipher_test!(aes128_test, "aes128", aes_soft::Aes128); -cipher::block_cipher_test!(aes192_test, "aes192", aes_soft::Aes192); -cipher::block_cipher_test!(aes256_test, "aes256", aes_soft::Aes256); diff --git a/aes/aesni/CHANGELOG.md b/aes/aesni/CHANGELOG.md deleted file mode 100644 index 4a055df6..00000000 --- a/aes/aesni/CHANGELOG.md +++ /dev/null @@ -1,87 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## 0.10.0 (2020-10-16) -### Added -- `target_feature` annotations to allow intrinsic inlining ([#165]) - -### Changed -- Replace `block-cipher`/`stream-cipher` with `cipher` crate ([#167]) - -[#167]: https://github.com/RustCrypto/block-ciphers/pull/167 -[#165]: https://github.com/RustCrypto/block-ciphers/pull/165 - -## 0.9.0 (2020-08-25) -### Changed -- Bump `stream-cipher` dependency to v0.7 ([#158]) - -### Fixed -- Incorrect values returned by the `SyncStreamCipherSeek::current_pos` method ([#71]) - -[#71]: https://github.com/RustCrypto/block-ciphers/issues/71 -[#158]: https://github.com/RustCrypto/block-ciphers/pull/158 - -## 0.8.0 (2020-08-07) -### Changed -- Bump `block-cipher` dependency to v0.8 and `stream-cipher` to v0.6 ([#138]) -- Bump `opaque-debug` dependency to v0.3 ([#140]) - -[#138]: https://github.com/RustCrypto/block-ciphers/pull/138 -[#140]: https://github.com/RustCrypto/block-ciphers/pull/140 - -## 0.7.0 (2020-06-05) -### Added -- Impl `FromBlockCipher` for AES-CTR types ([#121]) - -### Changed -- Bump `block-cipher` dependency to v0.7 ([#86], [#122]) -- Update to Rust 2018 edition ([#86]) -- Use `mem::zeroed` instead of `mem::uninitialized` on XMM registers ([#109], [#110]) - -[#122]: https://github.com/RustCrypto/block-ciphers/pull/122 -[#121]: https://github.com/RustCrypto/block-ciphers/pull/121 -[#110]: https://github.com/RustCrypto/block-ciphers/pull/110 -[#109]: https://github.com/RustCrypto/block-ciphers/pull/109 -[#86]: https://github.com/RustCrypto/block-ciphers/pull/86 - -## 0.6.0 (2018-11-01) - -## 0.5.1 (2018-10-04) - -## 0.5.0 (2018-10-03) - -## 0.4.1 (2018-08-07) - -## 0.4.0 (2018-07-27) - -## 0.3.5 (2018-06-22) - -## 0.3.4 (2018-06-13) - -## 0.3.3 (2018-06-13) - -## 0.3.2 (2018-06-13) - -## 0.3.1 (2018-03-06) - -## 0.3.0 (2018-03-06) - -## 0.2.2 (2018-03-06) - -## 0.2.1 (2017-12-01) - -## 0.2.0 (2017-11-26) - -## 0.1.4 (2017-08-06) - -## 0.1.3 (2017-08-06) - -## 0.1.2 (2017-08-02) - -## 0.1.1 (2017-07-31) - -## 0.1.0 (2017-07-21)~~~~ diff --git a/aes/aesni/Cargo.toml b/aes/aesni/Cargo.toml deleted file mode 100644 index 99a7f4ff..00000000 --- a/aes/aesni/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -[package] -name = "aesni" -version = "0.10.0" -description = "AES (Rijndael) block ciphers implementation using AES-NI" -authors = ["RustCrypto Developers"] -license = "MIT OR Apache-2.0" -edition = "2018" -documentation = "https://docs.rs/aesni" -repository = "https://github.com/RustCrypto/block-ciphers" -keywords = ["crypto", "aes", "rijndael", "block-cipher"] -categories = ["cryptography", "no-std"] - -[dependencies] -cipher = "0.2" -opaque-debug = "0.3" - -[dev-dependencies] -cipher = { version = "0.2", features = ["dev"] } - -[features] -default = ["ctr"] -ctr = [] -nocheck = [] - -[package.metadata.docs.rs] -rustc-args = ["-C", "target-feature=+aes,+ssse3"] -rustdoc-args = ["-C", "target-feature=+aes,+ssse3"] diff --git a/aes/aesni/LICENSE-APACHE b/aes/aesni/LICENSE-APACHE deleted file mode 100644 index 78173fa2..00000000 --- a/aes/aesni/LICENSE-APACHE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - -2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - -3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - -4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - -5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - -6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - -8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - -Copyright [yyyy] [name of copyright owner] - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/aes/aesni/LICENSE-MIT b/aes/aesni/LICENSE-MIT deleted file mode 100644 index 8dcb85b3..00000000 --- a/aes/aesni/LICENSE-MIT +++ /dev/null @@ -1,25 +0,0 @@ -Copyright (c) 2017 Artyom Pavlov - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/aes/aesni/benches/aes128.rs b/aes/aesni/benches/aes128.rs deleted file mode 100644 index 3c921c6e..00000000 --- a/aes/aesni/benches/aes128.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![feature(test)] - -extern crate test; - -use aesni::cipher::{BlockCipher, NewBlockCipher}; -use aesni::Aes128; - -#[bench] -pub fn aes128_encrypt(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes128_decrypt(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes128_encrypt8(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} - -#[bench] -pub fn aes128_decrypt8(bh: &mut test::Bencher) { - let cipher = Aes128::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} diff --git a/aes/aesni/benches/aes128_ctr.rs b/aes/aesni/benches/aes128_ctr.rs deleted file mode 100644 index 3b7b1514..00000000 --- a/aes/aesni/benches/aes128_ctr.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![cfg(feature = "ctr")] -#![feature(test)] - -#[cfg(feature = "ctr")] -cipher::stream_cipher_sync_bench!(aesni::Aes128Ctr); diff --git a/aes/aesni/benches/aes192.rs b/aes/aesni/benches/aes192.rs deleted file mode 100644 index e6ce55d1..00000000 --- a/aes/aesni/benches/aes192.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![feature(test)] - -extern crate test; - -use aesni::cipher::{BlockCipher, NewBlockCipher}; -use aesni::Aes192; - -#[bench] -pub fn aes192_encrypt(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes192_decrypt(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes192_encrypt8(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} - -#[bench] -pub fn aes192_decrypt8(bh: &mut test::Bencher) { - let cipher = Aes192::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} diff --git a/aes/aesni/benches/aes192_ctr.rs b/aes/aesni/benches/aes192_ctr.rs deleted file mode 100644 index 683e98ec..00000000 --- a/aes/aesni/benches/aes192_ctr.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![cfg(feature = "ctr")] -#![feature(test)] - -#[cfg(feature = "ctr")] -cipher::stream_cipher_sync_bench!(aesni::Aes192Ctr); diff --git a/aes/aesni/benches/aes256.rs b/aes/aesni/benches/aes256.rs deleted file mode 100644 index 222c7392..00000000 --- a/aes/aesni/benches/aes256.rs +++ /dev/null @@ -1,54 +0,0 @@ -#![feature(test)] - -extern crate test; - -use aesni::cipher::{BlockCipher, NewBlockCipher}; -use aesni::Aes256; - -#[bench] -pub fn aes256_encrypt(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes256_decrypt(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_block(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} - -#[bench] -pub fn aes256_encrypt8(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.encrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} - -#[bench] -pub fn aes256_decrypt8(bh: &mut test::Bencher) { - let cipher = Aes256::new(&Default::default()); - let mut input = Default::default(); - - bh.iter(|| { - cipher.decrypt_blocks(&mut input); - test::black_box(&input); - }); - bh.bytes = (input[0].len() * input.len()) as u64; -} diff --git a/aes/aesni/benches/aes256_ctr.rs b/aes/aesni/benches/aes256_ctr.rs deleted file mode 100644 index c16079c8..00000000 --- a/aes/aesni/benches/aes256_ctr.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![cfg(feature = "ctr")] -#![feature(test)] - -#[cfg(feature = "ctr")] -cipher::stream_cipher_sync_bench!(aesni::Aes256Ctr); diff --git a/aes/aesni/tests/data/aes128.blb b/aes/aesni/tests/data/aes128.blb deleted file mode 100644 index 0accb99eb444c47207eebd13422e0505c3052994..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27418 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�#whGFaOQqMXc`x5# z=I|5ijY5h$eSDQS-Y-r&|of=Q`&_g7yW0Qc~0EFSc-PrqsBOQ})uu;{3xTZK$+va)bg{3iF-_z%z0 zH<~b)idJ1s`_Y}>&MoYxKBm~m_7QWbl-k#xdYAo;+-;lps`lDaB<50?U^(Svr4Luz zIF84<6fvB_Tq=z$l8bH}JmpH^$zRcfOARD+eD=>&RaxAYeL0ck($}yvjf}Ze;>^dH zBX(WZrHUi>TV#BTBnv^{3rp{<31=;b38}X=D>3p>m`f$kJbHZKVaH}DhGpt_!r*a) z54CLovqVCONvdU!#MqKf@m|cOqNlX4+uS5T_tOuZ)R+t@St1%1oT4WpU@macLg)NL zD}D7tm`laz1h=N%bt-z{yr-2b*P3fEmr6$@W0k>y1nKsL&}$><2d6QY%B*&z$~l^ZG2@hbgQo)!bjnjC>}!4+E^nHa{!mL+ZoH7>j&9T4V|ibfB>7|Q zPL|ckFba68Cu0|zS%iQ-MGtP8TdkP!e9^@gG7zV_)0=?y z)bWug1@>>6Wa_P3Hg<1II*z$ic9$>@#B-cfsMm7Kf4wiN9doIi+Ol`8|Mq@<{(WjY zc@8f>(trTF@KfuBixI(fUUHN9o9XsqE)`v>D2u20A3eK0L%7>pgAFj3%3bekmqlD( z)eYoK69E?7P>h{J&9N##}1>_r}iNJtC0vGvQwM7C`9lKh(E%D% z$>~hem`ml@;rQXL+0r+U%%8boT-Uf4bE#w{G({whl=$6$malO`gOM6@snkkN4{fvC zk>vSAexd)Am$T4$9-L_AftdlYZBMxm3ta98|(R*_~aRzOKe}k}hE`6;eg1Mt@z>+k#c2^JJ#v z2F#`6>+&t?(X7sP#)`P0d&A;aF_%iKPC;1j+0DJL52QLuJd2~oTq@hjA`;-<=NUj< zP$T*LYdy@RG8B{Wm5P0Fq;srjsB0y5PD9r-cS6N(9`WlZ@jKbYkqZ&o*W$x+GTfeHN=`MtozVO z+bXd{g`?*b^MyhlUT{)M5w2^P6gNJQk0=q)#}Lu@?Uo_z^*MGlv?!U6$eomJ*Rl)kf-r#Uj_RbxVL(yS%#MsOb`Z!qFOsr_U;|6t zL%0}25Jt}_CVfb2*|sdsHu=?h+CqTs9?=y&r#KhyQyOn(M=aUIBRPJDZvs8MNDFQ* zhwJjBBvTH`(<7?c9b;r#^qk^Qd`K%&@qBH5e^~!DwrhPvS$)uXH3xRh)$$nLX|~wz z8&0k73|P02u4$coG3fkaVe6CKeTmNKIYmnH3l;uA%2&)`r=Ii9i(Do#Aq>FyLx*+H zPLt1@#zT_jhx&sM27(s28rUCZ_Qi;Y`JfM3^nug}dU%l*gmI}Qo$@NJ4SiA3w))*Z zmq3f2Q{1dGvCJm!C?Eaq#d8O)Dk{W~AOMsMpEnsQOh4iGjB2#cQr92|NP-;uySv&l z8tLX9FF0@gJ{Ta0o>Sy6cv9D1UmGbVsCu&-QB_B@95o1M(5LCNuY-pxk2W`y`1067BooNuRSYARf`dB z^qgXt`TtdL-~U*DZydlyvR4v9jvbPso1`*tBW{sBGqN|`GQxWik<5&bWR+5itTMAR zGeaawib9bn$@hGJJ%7MC*Wcs4#SjHys9(>qa@ekC#My zWiCx<5{l3%F6c9weUC5O-9D9(FZ7&c0Fy#bfX98Bxdht@q3P=b_tZi+=Ft(9*P#8MJ7%jt7oYa4uq`aL3@9e09 z*a_$qEB=->F%LEFB}cFaUd{i~i2Gx_V12W zL_Icmfi+kp3#G?g!LQ8|ALuQjS@pneoi%HZEzA`<#UHk=9HiQ&$Imvys&V(B<-60pP$>afvSTM z=d1a6Azq{h>V`e9QwIqRSmoXPR5Qp9@uDo~y?U!`hVGB;%kAXeVVi$}xGZ#v+osOc zTIY=tb_;iltp>GHh!?3qEWo)nQ9R(AwT;0g9zG2^f*J{G+Ke~^FB7kf=lHoL`!ACs zF>VmW!Fusnw(YOwpAp7{IrjsM8y5iC@3f^t%&bx+V!dtF3(BK#0q7Kmgy_HhQ6V8c z@i{#0sWN@U2_BH6ptoGowmL(~bqtmCOPS&!M1cRH;8(txanzn+_5bj*ENg@abc)|D zsV3&tN0wyll%SH&Kb%KRp;H_PY~@;c-KJf?{V_J@QeOJ58|EnClt`A_6?`Hq5i2t3gV6&2~KvG5LrHbc&OS>awwf zTVI>^L#08l31+?1aeRr_n*XMrnIz}X#96_@XKF6z}d*-4J9@ll{t%n>X7S#`fTVmOaF z`G)0C8^nu&z_4;vyntfn*ZI)ommwlrg9RdrK$yj1%D%DA=psxjGlHdi5Jebju#2A~ zhqiRyKCL_xRvMcUCaEF8#9mH}%QrQ{HR2~u5$OZ5^ z%I2D;NhY&&>2v4rm+dN$3%DuJq4}KVQFdB>1#Oba^BB;@O`%hac$^T_5L0um$-b_` zH(L;acu@@ogiHL^dc$twBIDw<=gQj%HPjzWI14SQ=GSRa)la(zeqnD!{V{&fNkjWW z$9dR-ng8GR%p;iQ}MPf2e~47UVV)nH$_F;K#~^vH>sM*X|(C4l8QBvCgJm;)DL*DJIM9 zq3#K=TK~?O$BN4xNFvw}IUlY6XZF&w}YW`UTJ6cbwN5ml&&D zj>#ftp;L_Sviq}=Ai{H8xI#;s%6<(OM%94Me+_>Ryh9A%59AK86h^&6|L+v#ip^d7 zgwxvbk`;H~{>f-e4LZd~>|N`8P5Xakpr%YaFM`zxAzT+Ey95gcOfG7g^l0{u7x3Q3 zb-BU9(qxrtW5&n$Rmuv}6YJKfq-0bq3j@EKr*W#(hB$gG-BR>?mnYSS%>|oTV%73!P%U=C#l<7n%DzA^JAy z@2M1o44tB3EMMyHiseo1<0UMmyJNK&3v`NpwWVL@ZT~6mu+liJN-C@pSKUF&uAzCO z`2;`d@{heqEE~P3C?E49J#OkD4Tc4>HgmS&$mBN%!dl2N5J~PrI(4gcmf(>uR+G2 z{Jg_I`c571FGoC~Q+zw@|FJ2`_}l|83#A7`q9+MDL<%sp-0|^Y_}F?yeb+`fO}ZG7 z!q@;s%}v-R=DtV4tHk5=5lgo*Hs}=7I++d!P=^CFgMvAR4Yr;@ych{2TR0QkR(eNb zKeFvL>r?haBfY_&_p}b{e!uOLKyqv$m?P>LLOXI8_8#SSXwRbahQYB zN~0eZONOo`J$*(=xI)jq8__C57@*vskaVrW`xc*DDychl<@%pR zlpBix)8_j^(#Ko^CbfB|QtF?)gm_U11ZnS^AKLZ4>0=?5j-9(ahY2BEK(MfLv0P6h zuJFj=;wkO&D*ya=?Et16g>t$IiQ7~V#Vg;1p=ZOw=fmx z6mO*Ui4+`^>AvCmDF5?dLK1F*K&R+sBj5G)8>#SSU=s7$Hx0-oj06lR%hy)q(%Wgp z+|GBCco{Gfbc%HW_2~xV4{PTGFipnMxhJ?5!UUfAOy_LVnN^Y1%cor4MqWmk*g(ra zr(C7)pTv|(u03fCzL3cVouaI>w%7RH)@X*ki>E{*vTP7n%pF{xKH^%vanegjHh#r= zfT+XVFM%)Nu~OnY;n%4zE?4+oJMi@q9gs9EE#>B9miWgoHUMmMGU%XFys=Ajj&>t# zsIE9tQ0KyK7Q~CZfWAOPUC6rUw?K&8YN@x{ca#@8#hSZ7GjctDXRXMJ_poWy6+#|5 z#jc_cDY9pi+K*R>FSWhztHxOfC(s{#WP0o7j-61O?}cZzJC1}CZVy(lq&Tgebzcbw zHfB9P&OzLs1a$Qs<#URSj05D$>#MvN$s`u=%S8V};QD(RnZ+6NJk_R?EYK;w&fL2( zd-Ld!uAf`j|4-fX#T@Y#av@TJ@n#0sD-`r z2b{zYjB*d!OYauUkJvD7KGVHl!H~n^X)5xk=`daB6el0BwtP!0Ogk@p zFu{9^)CTcl7?5C;dxcz#7N0R34^ZK;I|K0|oKiCTZ?zOo2As3}^d~qtz7OI>TacS9 zgcL5HvNqlbmP#V79l`(a6lvG%t}p!9GCS-MIVF>L1|A_)KwEVodAs{6waE`;2Fd^> zgbJPF$QPow^z*dST%F^Vw$s87lnk9BZ&s?_-A1|M&&QcWy)7-eF>~k?GX(7q2|0~f zzj^$k^kSu@2QG~Y0iPyMqlj};V;?qKr;HLPfv6C4is8oNawMA&^2@$X^`4To5rhXi zMO6N|NAxk46#b~guQXKV9V`qw#h@(Fn$yuod7|TVL~6uV-B{ zEKUD`hzoRzdiy=t3}w18G3BJfYMp)yj7t`L!?^xYB!Z_uzcryWP1pREg-#I?rT63i z?e3u*Dk~SMVZn(#2EcZ!Jg1Si!10)qON{#uDK`V?6!omORDj0f-iqvv{m!I*1wsOg z1ol~me5R@6l}mHy13x^IZ^t4n!M(}k>sI8NwaN}-S5+CFLzcK4hLZ?Wx%K|IfgN(h} z&p%d$to0CFs4DPM)DD@@PkXaf>~)M^>4Gn+stC3fClXKW>#dASyFak_^Lv9L<_S#d zT5p6^^354aV(s+3nl+dwdKD-wR(z6496BaJj#3Koh&zm4g--FhyLAGiD*rtNvqn43 z>pLcd96|xsEH`&4r{7n_iY>a$*&G!?C}P0W_;7%CC7n^;9`#+dUpa@x^g-k;28+5} zdncaw%!rP`worZO6bntORPT4T^4if&92b2NxevLDp9QI%>0EpiX_+~DPE|@cEu@Rk zDc0B8HP4YEjzTilVppu2iz-5=_$|)Gf6J<@2EE2Kpk=`;4DliZsB8=g{?XQxz@L)4 zbo0jVYJ>qg#R5BTy}hq9=4buch6FQ~ZlW$Y8L&QT`X2Tl^PMN&myX|WJfMP;CBSx9 zsH1I3_@Blc+NK|8nwTUoGN}G-D|M2^S1Zq%xNla;LksaD9VpneAdArolB19NQ0b@aE=SD~>Max`OX^1uTD@K7%asHufZ0eZL$=f={N7#elDinW2 z8lZ@iNYe!Y#u+~^w$<4VQA8R##kG}$H%8k>i_&R^9bZ~axzrT8GU|PJ_$k=(Ez*K z+kKfrf-Og0u1pb2X7PvyCJ&lfx`xYV8B=CSGC4HrvqvFbz$J{!Xr(by&B%2Vu%FD_|F9KQ-4(JjB7xI^OOyjC4KBuUe*2_HRfR;k zaXRP}U+l1Z)~i=jOyj36eLTmwL`dOI0DKl{&oMO45B_VovpQ$vgF8W|=-PNV_Lfc8 za$rEx(b?JMUql3Sigp?12ZIXknVFoTEfC@faY6#2Q*>#ZF=`1sQq!_5P-}bdQ#j5G zoucE&;+0Bc&%Zl$rzXre}H}ZV$ zNy*Qb9!DWw6ac|w1H)$Ca6#{oZv)iNGy4evW#FbGq)ktiSf)|9Cvi1|4NTOrSew)bFz8PnV!4L8@E~kd@O)9Vfg{t| zx~4kr$>PmVx2e!69(r6Vzp_CNtc`WIe6;g66*VyhBPq%uQPQU}_YtvoufC{wWEulw sX&IYpCTYIh)v0VP-Q?1V82T6nu$UINGJ0r&{-%?2`D-2bg&4a30qj8EGXMYp diff --git a/aes/aesni/tests/data/aes192.blb b/aes/aesni/tests/data/aes192.blb deleted file mode 100644 index b5f70fa00ce7ed9f68fdc43b979fc5fba5b3142d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41322 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 RSD2B=VX++Wu?{1c{tv)^Sl0jm diff --git a/aes/aesni/tests/lib.rs b/aes/aesni/tests/lib.rs deleted file mode 100644 index f0610d68..00000000 --- a/aes/aesni/tests/lib.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Test vectors are from NESSIE: -//! https://www.cosic.esat.kuleuven.be/nessie/testvectors/ - -cipher::block_cipher_test!(aes128_test, "aes128", aesni::Aes128); -cipher::block_cipher_test!(aes192_test, "aes192", aesni::Aes192); -cipher::block_cipher_test!(aes256_test, "aes256", aesni::Aes256); diff --git a/aes/benches/aes128.rs b/aes/benches/aes128.rs index eccb0b1c..ee62bf00 100644 --- a/aes/benches/aes128.rs +++ b/aes/benches/aes128.rs @@ -1,8 +1,16 @@ #![feature(test)] - extern crate test; -use aes::{Aes128, BlockCipher, NewBlockCipher}; +use aes::cipher::{BlockCipher, NewBlockCipher}; +use aes::Aes128; + +#[bench] +pub fn aes128_new(bh: &mut test::Bencher) { + bh.iter(|| { + let cipher = Aes128::new(&Default::default()); + test::black_box(&cipher); + }); +} #[bench] pub fn aes128_encrypt(bh: &mut test::Bencher) { @@ -51,17 +59,3 @@ pub fn aes128_decrypt8(bh: &mut test::Bencher) { }); bh.bytes = (input[0].len() * input.len()) as u64; } -/* -#[bench] -pub fn ctr_aes128(bh: &mut test::Bencher) { - let mut cipher = aes::CtrAes128::new(&[0; 16], &[0; 16]); - let mut input = [0u8; 10000]; - - - bh.iter(|| { - cipher.xor(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} -*/ diff --git a/aes/benches/aes192.rs b/aes/benches/aes192.rs index 23ec688b..9f869d9b 100644 --- a/aes/benches/aes192.rs +++ b/aes/benches/aes192.rs @@ -1,8 +1,16 @@ #![feature(test)] - extern crate test; -use aes::{Aes192, BlockCipher, NewBlockCipher}; +use aes::cipher::{BlockCipher, NewBlockCipher}; +use aes::Aes192; + +#[bench] +pub fn aes192_new(bh: &mut test::Bencher) { + bh.iter(|| { + let cipher = Aes192::new(&Default::default()); + test::black_box(&cipher); + }); +} #[bench] pub fn aes192_encrypt(bh: &mut test::Bencher) { @@ -51,18 +59,3 @@ pub fn aes192_decrypt8(bh: &mut test::Bencher) { }); bh.bytes = (input[0].len() * input.len()) as u64; } - -/* -#[bench] -pub fn ctr_aes192(bh: &mut test::Bencher) { - let mut cipher = aes::CtrAes192::new(&[0; 24], &[0; 16]); - let mut input = [0u8; 10000]; - - - bh.iter(|| { - cipher.xor(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} -*/ diff --git a/aes/benches/aes256.rs b/aes/benches/aes256.rs index fddd33e9..2e0b1f8f 100644 --- a/aes/benches/aes256.rs +++ b/aes/benches/aes256.rs @@ -1,8 +1,16 @@ #![feature(test)] - extern crate test; -use aes::{Aes256, BlockCipher, NewBlockCipher}; +use aes::cipher::{BlockCipher, NewBlockCipher}; +use aes::Aes256; + +#[bench] +pub fn aes256_new(bh: &mut test::Bencher) { + bh.iter(|| { + let cipher = Aes256::new(&Default::default()); + test::black_box(&cipher); + }); +} #[bench] pub fn aes256_encrypt(bh: &mut test::Bencher) { @@ -51,17 +59,3 @@ pub fn aes256_decrypt8(bh: &mut test::Bencher) { }); bh.bytes = (input[0].len() * input.len()) as u64; } -/* -#[bench] -pub fn ctr_aes256(bh: &mut test::Bencher) { - let mut cipher = aes::CtrAes256::new(&[0; 32], &[0; 16]); - let mut input = [0u8; 10000]; - - - bh.iter(|| { - cipher.xor(&mut input); - test::black_box(&input); - }); - bh.bytes = input.len() as u64; -} -*/ diff --git a/aes/src/lib.rs b/aes/src/lib.rs index e0a55d18..e063b3be 100644 --- a/aes/src/lib.rs +++ b/aes/src/lib.rs @@ -1,12 +1,12 @@ -//! This crate is a wrapper around different implementations of AES block ciphers. +//! Pure Rust implementation of the Advanced Encryption Standard +//! (a.k.a. Rijndael) //! -//! Currently it uses: -//! - [`aes-soft`](https://docs.rs/aes-soft) hardware independent bit-sliced -//! implementation -//! - [`aesni`](https://docs.rs/aesni) implementation using -//! [AES-NI](https://en.wikipedia.org/wiki/AES_instruction_set) instruction set. -//! Used for x86-64 and x86 target architectures with enabled `aes` and `sse2` -//! target features (the latter is usually enabled by default). +//! It provides two different backends based on what target features +//! are specified: +//! - "soft" portable constant-time implementation based on [fixslicing]. +//! - [AES-NI] accelerated implementation for `i686`/`x86_64` target +//! architectures with enabled `aes` and `sse2` target features +//! (the latter is usually enabled by default). //! //! Crate switches between implementations automatically at compile time. //! (i.e. it does not use run-time feature detection) @@ -39,9 +39,14 @@ //! ``` //! //! For implementations of block cipher modes of operation see -//! [`block-modes`](https://docs.rs/block-modes) crate. +//! [`block-modes`] crate. +//! +//! [fixslicing]: https://eprint.iacr.org/2020/1123.pdf +//! [AES-NI]: https://en.wikipedia.org/wiki/AES_instruction_set +//! [`block-modes`]: https://docs.rs/block-modes #![no_std] +#![cfg_attr(docsrs, feature(doc_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" @@ -49,18 +54,56 @@ #![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] -pub use cipher::{self, BlockCipher, NewBlockCipher}; +#[cfg(all( + target_feature = "aes", + target_feature = "sse2", + any(target_arch = "x86_64", target_arch = "x86"), +))] +mod ni; + +#[cfg(not(all( + target_feature = "aes", + target_feature = "sse2", + any(target_arch = "x86_64", target_arch = "x86"), +)))] +mod soft; #[cfg(not(all( target_feature = "aes", target_feature = "sse2", any(target_arch = "x86_64", target_arch = "x86"), )))] -pub use aes_soft::{Aes128, Aes192, Aes256}; +pub use soft::{Aes128, Aes192, Aes256}; #[cfg(all( target_feature = "aes", target_feature = "sse2", any(target_arch = "x86_64", target_arch = "x86"), ))] -pub use aesni::{Aes128, Aes192, Aes256}; +pub use ni::{Aes128, Aes192, Aes256}; + +#[cfg(all( + feature = "ctr", + not(all( + target_feature = "aes", + target_feature = "sse2", + any(target_arch = "x86_64", target_arch = "x86"), + )) +))] +pub use soft::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; + +#[cfg(all( + feature = "ctr", + target_feature = "aes", + target_feature = "sse2", + any(target_arch = "x86_64", target_arch = "x86"), +))] +pub use ni::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; + +pub use cipher::{self, BlockCipher, NewBlockCipher}; + +/// 128-bit AES block +pub type Block = cipher::generic_array::GenericArray; + +/// 8 x 128-bit AES blocks to be processed in parallel +pub type ParBlocks = cipher::generic_array::GenericArray; diff --git a/aes/aesni/src/lib.rs b/aes/src/ni.rs similarity index 67% rename from aes/aesni/src/lib.rs rename to aes/src/ni.rs index 73c49c47..c2b5c87c 100644 --- a/aes/aesni/src/lib.rs +++ b/aes/src/ni.rs @@ -32,33 +32,6 @@ //! - [Intel advisory](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00145.html) //! - [Wikipedia](https://en.wikipedia.org/wiki/Lazy_FP_state_restore) //! -//! # Usage example -//! ``` -//! use aesni::cipher::generic_array::GenericArray; -//! use aesni::cipher::{BlockCipher, NewBlockCipher}; -//! use aesni::Aes128; -//! -//! let key = GenericArray::from_slice(&[0u8; 16]); -//! let mut block = GenericArray::clone_from_slice(&[0u8; 16]); -//! let mut block8 = GenericArray::clone_from_slice(&[block; 8]); -//! // Initialize cipher -//! let cipher = aesni::Aes128::new(&key); -//! -//! let block_copy = block.clone(); -//! // Encrypt block in-place -//! cipher.encrypt_block(&mut block); -//! // And decrypt it back -//! cipher.decrypt_block(&mut block); -//! assert_eq!(block, block_copy); -//! -//! // We can encrypt 8 blocks simultaneously using -//! // instruction-level parallelism -//! let block8_copy = block8.clone(); -//! cipher.encrypt_blocks(&mut block8); -//! cipher.decrypt_blocks(&mut block8); -//! assert_eq!(block8, block8_copy); -//! ``` -//! //! # Runtime detection //! If you plan to use AES with runtime detection (e.g. via //! `is_x86_feature_detected!("aes")`), then you'll need to enable `nocheck` @@ -71,36 +44,27 @@ //! - [Intel AES-NI whitepaper](https://software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf) //! - [Use of the AES Instruction Set](https://www.cosic.esat.kuleuven.be/ecrypt/AESday/slides/Use_of_the_AES_Instruction_Set.pdf) -#![no_std] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" -)] -#![warn(missing_docs, rust_2018_idioms)] - -pub use cipher; - -#[cfg(feature = "ctr")] -pub use cipher::stream; +#![allow(unsafe_code)] -#[cfg(not(feature = "nocheck"))] -mod target_checks; #[macro_use] mod utils; + mod aes128; mod aes192; mod aes256; + #[cfg(feature = "ctr")] mod ctr; +#[cfg(not(feature = "nocheck"))] +mod target_checks; + #[cfg(target_arch = "x86")] use core::arch::x86 as arch; #[cfg(target_arch = "x86_64")] use core::arch::x86_64 as arch; -pub use crate::aes128::Aes128; -pub use crate::aes192::Aes192; -pub use crate::aes256::Aes256; +pub use self::{aes128::Aes128, aes192::Aes192, aes256::Aes256}; #[cfg(feature = "ctr")] -pub use crate::ctr::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; +pub use self::ctr::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; diff --git a/aes/aesni/src/aes128.rs b/aes/src/ni/aes128.rs similarity index 98% rename from aes/aesni/src/aes128.rs rename to aes/src/ni/aes128.rs index 4339b564..9aac60d1 100644 --- a/aes/aesni/src/aes128.rs +++ b/aes/src/ni/aes128.rs @@ -1,11 +1,11 @@ -use crate::arch::*; +use crate::ni::arch::*; use cipher::{ consts::{U16, U8}, generic_array::GenericArray, BlockCipher, NewBlockCipher, }; -use crate::utils::{Block128, Block128x8}; +use crate::ni::utils::{Block128, Block128x8}; mod expand; #[cfg(test)] diff --git a/aes/aesni/src/aes128/expand.rs b/aes/src/ni/aes128/expand.rs similarity index 98% rename from aes/aesni/src/aes128/expand.rs rename to aes/src/ni/aes128/expand.rs index 12f70375..5334b032 100644 --- a/aes/aesni/src/aes128/expand.rs +++ b/aes/src/ni/aes128/expand.rs @@ -1,4 +1,4 @@ -use crate::arch::*; +use crate::ni::arch::*; use core::mem; diff --git a/aes/aesni/src/aes128/test_expand.rs b/aes/src/ni/aes128/test_expand.rs similarity index 99% rename from aes/aesni/src/aes128/test_expand.rs rename to aes/src/ni/aes128/test_expand.rs index bdbdf061..38744e65 100644 --- a/aes/aesni/src/aes128/test_expand.rs +++ b/aes/src/ni/aes128/test_expand.rs @@ -1,5 +1,5 @@ use super::expand::expand; -use crate::utils::check; +use crate::ni::utils::check; #[test] fn test() { diff --git a/aes/aesni/src/aes192.rs b/aes/src/ni/aes192.rs similarity index 98% rename from aes/aesni/src/aes192.rs rename to aes/src/ni/aes192.rs index 75826b6d..88c71acc 100644 --- a/aes/aesni/src/aes192.rs +++ b/aes/src/ni/aes192.rs @@ -1,11 +1,11 @@ -use crate::arch::*; +use crate::ni::arch::*; use cipher::{ consts::{U16, U24, U8}, generic_array::GenericArray, BlockCipher, NewBlockCipher, }; -use crate::utils::{Block128, Block128x8}; +use crate::ni::utils::{Block128, Block128x8}; mod expand; #[cfg(test)] diff --git a/aes/aesni/src/aes192/expand.rs b/aes/src/ni/aes192/expand.rs similarity index 99% rename from aes/aesni/src/aes192/expand.rs rename to aes/src/ni/aes192/expand.rs index dbcf4859..553a7930 100644 --- a/aes/aesni/src/aes192/expand.rs +++ b/aes/src/ni/aes192/expand.rs @@ -1,4 +1,4 @@ -use crate::arch::*; +use crate::ni::arch::*; use core::{mem, ptr}; diff --git a/aes/aesni/src/aes192/test_expand.rs b/aes/src/ni/aes192/test_expand.rs similarity index 99% rename from aes/aesni/src/aes192/test_expand.rs rename to aes/src/ni/aes192/test_expand.rs index 1462724f..7811d4c8 100644 --- a/aes/aesni/src/aes192/test_expand.rs +++ b/aes/src/ni/aes192/test_expand.rs @@ -1,5 +1,5 @@ use super::expand::expand; -use crate::utils::check; +use crate::ni::utils::check; #[test] fn test() { diff --git a/aes/aesni/src/aes256.rs b/aes/src/ni/aes256.rs similarity index 98% rename from aes/aesni/src/aes256.rs rename to aes/src/ni/aes256.rs index 9448b20b..c03ffd0d 100644 --- a/aes/aesni/src/aes256.rs +++ b/aes/src/ni/aes256.rs @@ -1,11 +1,11 @@ -use crate::arch::*; +use crate::ni::arch::*; use cipher::{ consts::{U16, U32, U8}, generic_array::GenericArray, BlockCipher, NewBlockCipher, }; -use crate::utils::{Block128, Block128x8}; +use crate::ni::utils::{Block128, Block128x8}; mod expand; #[cfg(test)] diff --git a/aes/aesni/src/aes256/expand.rs b/aes/src/ni/aes256/expand.rs similarity index 99% rename from aes/aesni/src/aes256/expand.rs rename to aes/src/ni/aes256/expand.rs index c8bb0999..48dab854 100644 --- a/aes/aesni/src/aes256/expand.rs +++ b/aes/src/ni/aes256/expand.rs @@ -1,4 +1,4 @@ -use crate::arch::*; +use crate::ni::arch::*; use core::mem; diff --git a/aes/aesni/src/aes256/test_expand.rs b/aes/src/ni/aes256/test_expand.rs similarity index 99% rename from aes/aesni/src/aes256/test_expand.rs rename to aes/src/ni/aes256/test_expand.rs index 598b654f..52e728ff 100644 --- a/aes/aesni/src/aes256/test_expand.rs +++ b/aes/src/ni/aes256/test_expand.rs @@ -1,5 +1,5 @@ use super::expand::expand; -use crate::utils::check; +use crate::ni::utils::check; #[test] fn test() { diff --git a/aes/aesni/src/ctr.rs b/aes/src/ni/ctr.rs similarity index 98% rename from aes/aesni/src/ctr.rs rename to aes/src/ni/ctr.rs index 47726f08..6e7a0ea2 100644 --- a/aes/aesni/src/ctr.rs +++ b/aes/src/ni/ctr.rs @@ -1,6 +1,8 @@ +//! AES in counter mode (a.k.a. AES-CTR) + #![allow(clippy::unreadable_literal)] -use crate::arch::*; +use crate::ni::arch::*; use core::mem; use super::{Aes128, Aes192, Aes256}; @@ -64,6 +66,7 @@ macro_rules! impl_ctr { ($name:ident, $cipher:ty, $doc:expr) => { #[doc=$doc] #[derive(Clone)] + #[cfg_attr(docsrs, doc(cfg(feature = "ctr")))] pub struct $name { nonce: __m128i, ctr: __m128i, diff --git a/aes/aesni/src/target_checks.rs b/aes/src/ni/target_checks.rs similarity index 100% rename from aes/aesni/src/target_checks.rs rename to aes/src/ni/target_checks.rs diff --git a/aes/aesni/src/utils.rs b/aes/src/ni/utils.rs similarity index 99% rename from aes/aesni/src/utils.rs rename to aes/src/ni/utils.rs index 4ef30bbd..4cec25dd 100644 --- a/aes/aesni/src/utils.rs +++ b/aes/src/ni/utils.rs @@ -1,5 +1,5 @@ #[cfg(test)] -use crate::arch::__m128i; +use crate::ni::arch::__m128i; #[cfg(test)] use core::mem; diff --git a/aes/src/soft.rs b/aes/src/soft.rs new file mode 100644 index 00000000..a58f9b81 --- /dev/null +++ b/aes/src/soft.rs @@ -0,0 +1,20 @@ +//! AES block cipher constant-time implementation. +//! +//! The implementation uses a technique called [fixslicing][1], an improved +//! form of bitslicing which represents ciphers in a way which enables +//! very efficient constant-time implementations in software. +//! +//! [1]: https://eprint.iacr.org/2020/1123.pdf + +#[cfg_attr(not(target_pointer_width = "64"), path = "soft/fixslice32.rs")] +#[cfg_attr(target_pointer_width = "64", path = "soft/fixslice64.rs")] +mod fixslice; +mod impls; + +#[cfg(feature = "ctr")] +mod ctr; + +pub use self::impls::{Aes128, Aes192, Aes256}; + +#[cfg(feature = "ctr")] +pub use self::ctr::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; diff --git a/aes/src/soft/ctr.rs b/aes/src/soft/ctr.rs new file mode 100644 index 00000000..e29c5b0d --- /dev/null +++ b/aes/src/soft/ctr.rs @@ -0,0 +1,15 @@ +//! AES in counter mode (a.k.a. AES-CTR) + +use super::{Aes128, Aes192, Aes256}; + +/// AES-128 in CTR mode +#[cfg_attr(docsrs, doc(cfg(feature = "ctr")))] +pub type Aes128Ctr = ::ctr::Ctr128; + +/// AES-192 in CTR mode +#[cfg_attr(docsrs, doc(cfg(feature = "ctr")))] +pub type Aes192Ctr = ::ctr::Ctr128; + +/// AES-256 in CTR mode +#[cfg_attr(docsrs, doc(cfg(feature = "ctr")))] +pub type Aes256Ctr = ::ctr::Ctr128; diff --git a/aes/aes-soft/src/fixslice32.rs b/aes/src/soft/fixslice32.rs similarity index 100% rename from aes/aes-soft/src/fixslice32.rs rename to aes/src/soft/fixslice32.rs diff --git a/aes/aes-soft/src/fixslice64.rs b/aes/src/soft/fixslice64.rs similarity index 100% rename from aes/aes-soft/src/fixslice64.rs rename to aes/src/soft/fixslice64.rs diff --git a/aes/aes-soft/src/impls.rs b/aes/src/soft/impls.rs similarity index 91% rename from aes/aes-soft/src/impls.rs rename to aes/src/soft/impls.rs index 901f4b10..33952b1d 100644 --- a/aes/aes-soft/src/impls.rs +++ b/aes/src/soft/impls.rs @@ -1,14 +1,13 @@ -pub use cipher::{BlockCipher, NewBlockCipher}; +//! Macros for implementing `Aes*` structs and the `BlockCipher` interface use cipher::{ consts::{U16, U24, U32, U8}, generic_array::GenericArray, + BlockCipher, NewBlockCipher, }; -use crate::{ - fixslice::{self, FixsliceKeys128, FixsliceKeys192, FixsliceKeys256, FIXSLICE_BLOCKS}, - Block, ParBlocks, -}; +use super::fixslice::{self, FixsliceKeys128, FixsliceKeys192, FixsliceKeys256, FIXSLICE_BLOCKS}; +use crate::{Block, ParBlocks}; macro_rules! define_aes_impl { ( diff --git a/aes/aesni/tests/ctr.rs b/aes/tests/ctr.rs similarity index 90% rename from aes/aesni/tests/ctr.rs rename to aes/tests/ctr.rs index 6a8d6b48..70a3f9f6 100644 --- a/aes/aesni/tests/ctr.rs +++ b/aes/tests/ctr.rs @@ -1,6 +1,6 @@ #![cfg(feature = "ctr")] -use aesni::{Aes128Ctr, Aes256Ctr}; +use aes::{Aes128Ctr, Aes256Ctr}; // Random tests generated by OpenSSL cipher::stream_cipher_sync_test!(aes128_ctr_core, Aes128Ctr, "aes128-ctr"); diff --git a/aes/aesni/tests/data/aes128-ctr.blb b/aes/tests/data/aes128-ctr.blb similarity index 100% rename from aes/aesni/tests/data/aes128-ctr.blb rename to aes/tests/data/aes128-ctr.blb diff --git a/aes/aesni/tests/data/aes256-ctr.blb b/aes/tests/data/aes256-ctr.blb similarity index 100% rename from aes/aesni/tests/data/aes256-ctr.blb rename to aes/tests/data/aes256-ctr.blb From 18a2f0c95fb66844315c73fa9c539208ef347636 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 18 Nov 2020 05:46:47 -0800 Subject: [PATCH 2/6] aes: remove `deny(unsafe_code)` from toplevel Hardware accelerated backends will need unsafe code --- aes/src/lib.rs | 1 - aes/src/ni.rs | 2 -- aes/src/soft.rs | 2 ++ 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/aes/src/lib.rs b/aes/src/lib.rs index e063b3be..33dc87ee 100644 --- a/aes/src/lib.rs +++ b/aes/src/lib.rs @@ -51,7 +51,6 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] -#![deny(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(all( diff --git a/aes/src/ni.rs b/aes/src/ni.rs index c2b5c87c..8cf3a478 100644 --- a/aes/src/ni.rs +++ b/aes/src/ni.rs @@ -44,8 +44,6 @@ //! - [Intel AES-NI whitepaper](https://software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf) //! - [Use of the AES Instruction Set](https://www.cosic.esat.kuleuven.be/ecrypt/AESday/slides/Use_of_the_AES_Instruction_Set.pdf) -#![allow(unsafe_code)] - #[macro_use] mod utils; diff --git a/aes/src/soft.rs b/aes/src/soft.rs index a58f9b81..192c2ab5 100644 --- a/aes/src/soft.rs +++ b/aes/src/soft.rs @@ -6,6 +6,8 @@ //! //! [1]: https://eprint.iacr.org/2020/1123.pdf +#![deny(unsafe_code)] + #[cfg_attr(not(target_pointer_width = "64"), path = "soft/fixslice32.rs")] #[cfg_attr(target_pointer_width = "64", path = "soft/fixslice64.rs")] mod fixslice; From 2ea345f614b8796b3874fbace33924ea60990250 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 18 Nov 2020 05:57:53 -0800 Subject: [PATCH 3/6] aes: use `super` when importing `ni`-related modules --- aes/src/ni/aes128.rs | 4 ++-- aes/src/ni/aes192.rs | 4 ++-- aes/src/ni/aes256.rs | 4 ++-- aes/src/ni/ctr.rs | 2 +- aes/src/ni/utils.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/aes/src/ni/aes128.rs b/aes/src/ni/aes128.rs index 9aac60d1..85db802a 100644 --- a/aes/src/ni/aes128.rs +++ b/aes/src/ni/aes128.rs @@ -1,11 +1,11 @@ -use crate::ni::arch::*; +use super::arch::*; use cipher::{ consts::{U16, U8}, generic_array::GenericArray, BlockCipher, NewBlockCipher, }; -use crate::ni::utils::{Block128, Block128x8}; +use super::utils::{Block128, Block128x8}; mod expand; #[cfg(test)] diff --git a/aes/src/ni/aes192.rs b/aes/src/ni/aes192.rs index 88c71acc..b7b27c32 100644 --- a/aes/src/ni/aes192.rs +++ b/aes/src/ni/aes192.rs @@ -1,11 +1,11 @@ -use crate::ni::arch::*; +use super::arch::*; use cipher::{ consts::{U16, U24, U8}, generic_array::GenericArray, BlockCipher, NewBlockCipher, }; -use crate::ni::utils::{Block128, Block128x8}; +use super::utils::{Block128, Block128x8}; mod expand; #[cfg(test)] diff --git a/aes/src/ni/aes256.rs b/aes/src/ni/aes256.rs index c03ffd0d..19dc769f 100644 --- a/aes/src/ni/aes256.rs +++ b/aes/src/ni/aes256.rs @@ -1,11 +1,11 @@ -use crate::ni::arch::*; +use super::arch::*; use cipher::{ consts::{U16, U32, U8}, generic_array::GenericArray, BlockCipher, NewBlockCipher, }; -use crate::ni::utils::{Block128, Block128x8}; +use super::utils::{Block128, Block128x8}; mod expand; #[cfg(test)] diff --git a/aes/src/ni/ctr.rs b/aes/src/ni/ctr.rs index 6e7a0ea2..e72eecae 100644 --- a/aes/src/ni/ctr.rs +++ b/aes/src/ni/ctr.rs @@ -2,7 +2,7 @@ #![allow(clippy::unreadable_literal)] -use crate::ni::arch::*; +use super::arch::*; use core::mem; use super::{Aes128, Aes192, Aes256}; diff --git a/aes/src/ni/utils.rs b/aes/src/ni/utils.rs index 4cec25dd..d7f49e2c 100644 --- a/aes/src/ni/utils.rs +++ b/aes/src/ni/utils.rs @@ -1,5 +1,5 @@ #[cfg(test)] -use crate::ni::arch::__m128i; +use super::arch::__m128i; #[cfg(test)] use core::mem; From fa79e6086a395a88ccfc75d5489e373cb07d18d3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 18 Nov 2020 06:51:45 -0800 Subject: [PATCH 4/6] aes: remove obsolete target_checks module --- aes/src/ni.rs | 11 ----------- aes/src/ni/target_checks.rs | 27 --------------------------- 2 files changed, 38 deletions(-) delete mode 100644 aes/src/ni/target_checks.rs diff --git a/aes/src/ni.rs b/aes/src/ni.rs index 8cf3a478..b8d3c262 100644 --- a/aes/src/ni.rs +++ b/aes/src/ni.rs @@ -32,15 +32,7 @@ //! - [Intel advisory](https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00145.html) //! - [Wikipedia](https://en.wikipedia.org/wiki/Lazy_FP_state_restore) //! -//! # Runtime detection -//! If you plan to use AES with runtime detection (e.g. via -//! `is_x86_feature_detected!("aes")`), then you'll need to enable `nocheck` -//! feature to disable compile-time target checks. Note that techincally -//! doing so will make API of this crate unsafe, so you MUST ensure that -//! this crate will be used in contexts with enabled necessary target features! -//! //! # Related documents -//! //! - [Intel AES-NI whitepaper](https://software.intel.com/sites/default/files/article/165683/aes-wp-2012-09-22-v01.pdf) //! - [Use of the AES Instruction Set](https://www.cosic.esat.kuleuven.be/ecrypt/AESday/slides/Use_of_the_AES_Instruction_Set.pdf) @@ -54,9 +46,6 @@ mod aes256; #[cfg(feature = "ctr")] mod ctr; -#[cfg(not(feature = "nocheck"))] -mod target_checks; - #[cfg(target_arch = "x86")] use core::arch::x86 as arch; #[cfg(target_arch = "x86_64")] diff --git a/aes/src/ni/target_checks.rs b/aes/src/ni/target_checks.rs deleted file mode 100644 index 9d3a568f..00000000 --- a/aes/src/ni/target_checks.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! Check all target requirements. Note that SSE2 should be enabled by default. -#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))] -compile_error!("crate can only be used on x86 and x86_64 architectures"); - -#[cfg(all( - feature = "ctr", - not(all( - target_feature = "aes", - target_feature = "sse2", - target_feature = "ssse3" - )), -))] -compile_error!( - "enable aes and ssse3 target features, e.g. with \ - RUSTFLAGS=\"-C target-feature=+aes,+ssse3\" environment variable. \ - For x86 target arch additionally enable sse2 target feature." -); - -#[cfg(all( - not(feature = "ctr"), - not(all(target_feature = "aes", target_feature = "sse2")), -))] -compile_error!( - "enable aes target feature, e.g. with \ - RUSTFLAGS=\"-C target-feature=+aes\" environment variable. \ - For x86 target arch additionally enable sse2 target feature." -); From f005a97e2bd8fb04cbda16978172fdba27516b5e Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 18 Nov 2020 06:56:13 -0800 Subject: [PATCH 5/6] aes: remove docs for sse2, add them for ssse3 --- aes/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aes/src/lib.rs b/aes/src/lib.rs index 33dc87ee..8eef6451 100644 --- a/aes/src/lib.rs +++ b/aes/src/lib.rs @@ -5,8 +5,8 @@ //! are specified: //! - "soft" portable constant-time implementation based on [fixslicing]. //! - [AES-NI] accelerated implementation for `i686`/`x86_64` target -//! architectures with enabled `aes` and `sse2` target features -//! (the latter is usually enabled by default). +//! architectures with `target-feature=+aes`, as well as an accelerated +//! AES-CTR implementation with `target-feature=+aes,+ssse3` //! //! Crate switches between implementations automatically at compile time. //! (i.e. it does not use run-time feature detection) From 62ef2bb40ceebfd2c4a1e9d8702388e4db0fe6db Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Wed, 18 Nov 2020 06:58:52 -0800 Subject: [PATCH 6/6] aes: add target-feature=+ssse3 gating for AES-CTR impl --- aes/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aes/src/lib.rs b/aes/src/lib.rs index 8eef6451..a351c75d 100644 --- a/aes/src/lib.rs +++ b/aes/src/lib.rs @@ -86,6 +86,7 @@ pub use ni::{Aes128, Aes192, Aes256}; not(all( target_feature = "aes", target_feature = "sse2", + target_feature = "ssse3", any(target_arch = "x86_64", target_arch = "x86"), )) ))] @@ -95,6 +96,7 @@ pub use soft::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; feature = "ctr", target_feature = "aes", target_feature = "sse2", + target_feature = "ssse3", any(target_arch = "x86_64", target_arch = "x86"), ))] pub use ni::{Aes128Ctr, Aes192Ctr, Aes256Ctr};