Browse Source

crates.io hates developers

master
jahway603 2 years ago
parent
commit
6a4558ea5c
  1. 1
      aes-0.2.0/.cargo-ok
  2. 32
      aes-0.2.0/Cargo.toml
  3. 24
      aes-0.2.0/Cargo.toml.orig
  4. 201
      aes-0.2.0/LICENSE-APACHE
  5. 25
      aes-0.2.0/LICENSE-MIT
  6. 68
      aes-0.2.0/benches/aes128.rs
  7. 69
      aes-0.2.0/benches/aes192.rs
  8. 68
      aes-0.2.0/benches/aes256.rs
  9. 66
      aes-0.2.0/src/lib.rs
  10. BIN
      aes-0.2.0/tests/data/aes128.ciphertexts.bin
  11. BIN
      aes-0.2.0/tests/data/aes128.index.bin
  12. BIN
      aes-0.2.0/tests/data/aes128.keys.bin
  13. BIN
      aes-0.2.0/tests/data/aes128.plaintexts.bin
  14. BIN
      aes-0.2.0/tests/data/aes192.ciphertexts.bin
  15. BIN
      aes-0.2.0/tests/data/aes192.index.bin
  16. BIN
      aes-0.2.0/tests/data/aes192.keys.bin
  17. BIN
      aes-0.2.0/tests/data/aes192.plaintexts.bin
  18. BIN
      aes-0.2.0/tests/data/aes256.ciphertexts.bin
  19. BIN
      aes-0.2.0/tests/data/aes256.index.bin
  20. BIN
      aes-0.2.0/tests/data/aes256.keys.bin
  21. BIN
      aes-0.2.0/tests/data/aes256.plaintexts.bin
  22. 10
      aes-0.2.0/tests/lib.rs
  23. 1
      aes-soft-0.2.0/.cargo-ok
  24. 33
      aes-soft-0.2.0/Cargo.toml
  25. 18
      aes-soft-0.2.0/Cargo.toml.orig
  26. 201
      aes-soft-0.2.0/LICENSE-APACHE
  27. 27
      aes-soft-0.2.0/LICENSE-MIT
  28. 68
      aes-soft-0.2.0/benches/aes128.rs
  29. 69
      aes-soft-0.2.0/benches/aes192.rs
  30. 68
      aes-soft-0.2.0/benches/aes256.rs
  31. 869
      aes-soft-0.2.0/src/bitslice.rs
  32. 10
      aes-soft-0.2.0/src/consts.rs
  33. 79
      aes-soft-0.2.0/src/expand.rs
  34. 113
      aes-soft-0.2.0/src/impls.rs
  35. 47
      aes-soft-0.2.0/src/lib.rs
  36. 47
      aes-soft-0.2.0/src/simd.rs
  37. BIN
      aes-soft-0.2.0/tests/data/aes128.ciphertexts.bin
  38. BIN
      aes-soft-0.2.0/tests/data/aes128.index.bin
  39. BIN
      aes-soft-0.2.0/tests/data/aes128.keys.bin
  40. BIN
      aes-soft-0.2.0/tests/data/aes128.plaintexts.bin
  41. BIN
      aes-soft-0.2.0/tests/data/aes192.ciphertexts.bin
  42. BIN
      aes-soft-0.2.0/tests/data/aes192.index.bin
  43. BIN
      aes-soft-0.2.0/tests/data/aes192.keys.bin
  44. BIN
      aes-soft-0.2.0/tests/data/aes192.plaintexts.bin
  45. BIN
      aes-soft-0.2.0/tests/data/aes256.ciphertexts.bin
  46. BIN
      aes-soft-0.2.0/tests/data/aes256.index.bin
  47. BIN
      aes-soft-0.2.0/tests/data/aes256.keys.bin
  48. BIN
      aes-soft-0.2.0/tests/data/aes256.plaintexts.bin
  49. BIN
      aes-soft-0.2.0/tests/data/ctr_aes128.ciphertext.bin
  50. 1
      aes-soft-0.2.0/tests/data/ctr_aes128.iv.bin
  51. 1
      aes-soft-0.2.0/tests/data/ctr_aes128.key.bin
  52. BIN
      aes-soft-0.2.0/tests/data/ctr_aes128.plaintext.bin
  53. BIN
      aes-soft-0.2.0/tests/data/ctr_aes256.ciphertext.bin
  54. 1
      aes-soft-0.2.0/tests/data/ctr_aes256.iv.bin
  55. 1
      aes-soft-0.2.0/tests/data/ctr_aes256.key.bin
  56. BIN
      aes-soft-0.2.0/tests/data/ctr_aes256.plaintext.bin
  57. 10
      aes-soft-0.2.0/tests/lib.rs
  58. 1
      aesni-0.6.0/.cargo-ok
  59. 5
      aesni-0.6.0/.cargo_vcs_info.json
  60. 46
      aesni-0.6.0/Cargo.toml
  61. 30
      aesni-0.6.0/Cargo.toml.orig
  62. 201
      aesni-0.6.0/LICENSE-APACHE
  63. 25
      aesni-0.6.0/LICENSE-MIT
  64. 56
      aesni-0.6.0/benches/aes128.rs
  65. 6
      aesni-0.6.0/benches/aes128_ctr.rs
  66. 56
      aesni-0.6.0/benches/aes192.rs
  67. 6
      aesni-0.6.0/benches/aes192_ctr.rs
  68. 56
      aesni-0.6.0/benches/aes256.rs
  69. 6
      aesni-0.6.0/benches/aes256_ctr.rs
  70. 50
      aesni-0.6.0/src/aes128/expand.rs
  71. 132
      aesni-0.6.0/src/aes128/mod.rs
  72. 104
      aesni-0.6.0/src/aes128/test_expand.rs
  73. 107
      aesni-0.6.0/src/aes192/expand.rs
  74. 140
      aesni-0.6.0/src/aes192/mod.rs
  75. 91
      aesni-0.6.0/src/aes192/test_expand.rs
  76. 88
      aesni-0.6.0/src/aes256/expand.rs
  77. 148
      aesni-0.6.0/src/aes256/mod.rs
  78. 101
      aesni-0.6.0/src/aes256/test_expand.rs
  79. 240
      aesni-0.6.0/src/ctr.rs
  80. 98
      aesni-0.6.0/src/lib.rs
  81. 23
      aesni-0.6.0/src/target_checks.rs
  82. 112
      aesni-0.6.0/src/utils.rs
  83. 11
      aesni-0.6.0/tests/ctr.rs
  84. BIN
      aesni-0.6.0/tests/data/aes128-ctr.blb
  85. BIN
      aesni-0.6.0/tests/data/aes128.blb
  86. BIN
      aesni-0.6.0/tests/data/aes192.blb
  87. BIN
      aesni-0.6.0/tests/data/aes256-ctr.blb
  88. BIN
      aesni-0.6.0/tests/data/aes256.blb
  89. 11
      aesni-0.6.0/tests/mod.rs
  90. 1
      block-cipher-trait-0.5.3/.cargo-ok
  91. 32
      block-cipher-trait-0.5.3/Cargo.toml
  92. 23
      block-cipher-trait-0.5.3/Cargo.toml.orig
  93. 201
      block-cipher-trait-0.5.3/LICENSE-APACHE
  94. 25
      block-cipher-trait-0.5.3/LICENSE-MIT
  95. 147
      block-cipher-trait-0.5.3/src/dev.rs
  96. 20
      block-cipher-trait-0.5.3/src/errors.rs
  97. 73
      block-cipher-trait-0.5.3/src/lib.rs

1
aes-0.2.0/.cargo-ok

@ -0,0 +1 @@
ok

32
aes-0.2.0/Cargo.toml

@ -0,0 +1,32 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "aes"
version = "0.2.0"
authors = ["RustCrypto Developers"]
description = "Facade for AES (Rijndael) block ciphers implementations"
documentation = "https://docs.rs/aes"
keywords = ["crypto", "aes", "rijndael", "block-cipher"]
categories = ["cryptography", "no-std"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/RustCrypto/block-ciphers"
[dependencies.block-cipher-trait]
version = "0.5"
[dev-dependencies.block-cipher-trait]
version = "0.5"
features = ["dev"]
[target."cfg(all(target_feature=\"aes\", target_feature = \"sse2\", any(target_arch = \"x86_64\", target_arch = \"x86\")))".dependencies.aesni]
version = "0.4"
default-features = false
[target."cfg(not(all(target_feature=\"aes\", target_feature = \"sse2\", any(target_arch = \"x86_64\", target_arch = \"x86\"))))".dependencies.aes-soft]
version = "0.2"

24
aes-0.2.0/Cargo.toml.orig

@ -0,0 +1,24 @@
[package]
name = "aes"
version = "0.2.0"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
description = "Facade for AES (Rijndael) block ciphers implementations"
documentation = "https://docs.rs/aes"
repository = "https://github.com/RustCrypto/block-ciphers"
keywords = ["crypto", "aes", "rijndael", "block-cipher"]
categories = ["cryptography", "no-std"]
[dependencies]
block-cipher-trait = "0.5"
[target.'cfg(not(all(target_feature="aes", target_feature = "sse2", any(target_arch = "x86_64", target_arch = "x86"))))'.dependencies]
aes-soft = "0.2"
[target.'cfg(all(target_feature="aes", target_feature = "sse2", any(target_arch = "x86_64", target_arch = "x86")))'.dependencies]
aesni = { version = "0.4", default-features = false }
[dev-dependencies]
block-cipher-trait = { version = "0.5", features = ["dev"] }
[workspace]

201
aes-0.2.0/LICENSE-APACHE

@ -0,0 +1,201 @@
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.

25
aes-0.2.0/LICENSE-MIT

@ -0,0 +1,25 @@
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.

68
aes-0.2.0/benches/aes128.rs

@ -0,0 +1,68 @@
#![no_std]
#![feature(test)]
extern crate aes;
extern crate test;
use aes::{Aes128, BlockCipher};
#[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;
}
/*
#[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;
}
*/

69
aes-0.2.0/benches/aes192.rs

@ -0,0 +1,69 @@
#![no_std]
#![feature(test)]
extern crate aes;
extern crate test;
use aes::{Aes192, BlockCipher};
#[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;
}
/*
#[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;
}
*/

68
aes-0.2.0/benches/aes256.rs

@ -0,0 +1,68 @@
#![no_std]
#![feature(test)]
extern crate aes;
extern crate test;
use aes::{Aes256, BlockCipher};
#[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;
}
/*
#[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;
}
*/

66
aes-0.2.0/src/lib.rs

@ -0,0 +1,66 @@
//! This crate is a wrapper around different implementations of AES block ciphers.
//!
//! 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).
//!
//! Crate switches between implementations automatically at compile time.
//! (i.e. it does not use run-time feature detection)
//!
//! # Usage example
//! ```
//! use aes::block_cipher_trait::generic_array::GenericArray;
//! use aes::block_cipher_trait::BlockCipher;
//! use aes::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 = 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);
//! ```
//!
//! For implementations of block cipher modes of operation see
//! [`block-modes`](https://docs.rs/block-modes) crate.
#![no_std]
pub extern crate block_cipher_trait;
#[cfg(not(all(
target_feature="aes", target_feature = "sse2",
any(target_arch = "x86_64", target_arch = "x86"),
)))]
extern crate aes_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};
#[cfg(all(
target_feature="aes", target_feature = "sse2",
any(target_arch = "x86_64", target_arch = "x86"),
))]
extern crate aesni;
#[cfg(all(
target_feature="aes", target_feature = "sse2",
any(target_arch = "x86_64", target_arch = "x86"),
))]
pub use aesni::{Aes128, Aes192, Aes256};

BIN
aes-0.2.0/tests/data/aes128.ciphertexts.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes128.index.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes128.keys.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes128.plaintexts.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes192.ciphertexts.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes192.index.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes192.keys.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes192.plaintexts.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes256.ciphertexts.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes256.index.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes256.keys.bin

Binary file not shown.

BIN
aes-0.2.0/tests/data/aes256.plaintexts.bin

Binary file not shown.

10
aes-0.2.0/tests/lib.rs

@ -0,0 +1,10 @@
//! Test vectors are from NESSIE:
//! https://www.cosic.esat.kuleuven.be/nessie/testvectors/
#![no_std]
extern crate aes;
#[macro_use]
extern crate block_cipher_trait;
new_test!(aes128_test, "aes128", aes::Aes128);
new_test!(aes192_test, "aes192", aes::Aes192);
new_test!(aes256_test, "aes256", aes::Aes256);

1
aes-soft-0.2.0/.cargo-ok

@ -0,0 +1 @@
ok

33
aes-soft-0.2.0/Cargo.toml

@ -0,0 +1,33 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "aes-soft"
version = "0.2.0"
authors = ["RustCrypto Developers"]
description = "AES (Rijndael) block ciphers bit-sliced implementation"
documentation = "https://docs.rs/aes-soft"
keywords = ["crypto", "aes", "rijndael", "block-cipher"]
categories = ["cryptography", "no-std"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/RustCrypto/block-ciphers"
[dependencies.block-cipher-trait]
version = "0.5"
[dependencies.byte-tools]
version = "0.2"
[dependencies.opaque-debug]
version = "0.1"
[dev-dependencies.block-cipher-trait]
version = "0.5"
features = ["dev"]

18
aes-soft-0.2.0/Cargo.toml.orig

@ -0,0 +1,18 @@
[package]
name = "aes-soft"
version = "0.2.0"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
description = "AES (Rijndael) block ciphers bit-sliced implementation"
documentation = "https://docs.rs/aes-soft"
repository = "https://github.com/RustCrypto/block-ciphers"
keywords = ["crypto", "aes", "rijndael", "block-cipher"]
categories = ["cryptography", "no-std"]
[dependencies]
block-cipher-trait = "0.5"
opaque-debug = "0.1"
byte-tools = "0.2"
[dev-dependencies]
block-cipher-trait = { version = "0.5", features = ["dev"] }

201
aes-soft-0.2.0/LICENSE-APACHE

@ -0,0 +1,201 @@
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.

27
aes-soft-0.2.0/LICENSE-MIT

@ -0,0 +1,27 @@
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.

68
aes-soft-0.2.0/benches/aes128.rs

@ -0,0 +1,68 @@
#![no_std]
#![feature(test)]
extern crate aes_soft;
extern crate test;
use aes_soft::{Aes128, BlockCipher};
#[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;
}
/*
#[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;
}
*/

69
aes-soft-0.2.0/benches/aes192.rs

@ -0,0 +1,69 @@
#![no_std]
#![feature(test)]
extern crate aes_soft;
extern crate test;
use aes_soft::{Aes192, BlockCipher};
#[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;
}
/*
#[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;
}
*/

68
aes-soft-0.2.0/benches/aes256.rs

@ -0,0 +1,68 @@
#![no_std]
#![feature(test)]
extern crate aes_soft;
extern crate test;
use aes_soft::{Aes256, BlockCipher};
#[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;
}
/*
#[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;
}
*/

869
aes-soft-0.2.0/src/bitslice.rs

@ -0,0 +1,869 @@
use core::ops::{BitAnd, BitXor, Not};
use byte_tools::{read_u32v_le, write_u32_le};
use simd::u32x4;
use consts::U32X4_1;
// This trait defines all of the operations needed for a type to be processed as part of an AES
// encryption or decryption operation.
pub trait AesOps {
fn sub_bytes(self) -> Self;
fn inv_sub_bytes(self) -> Self;
fn shift_rows(self) -> Self;
fn inv_shift_rows(self) -> Self;
fn mix_columns(self) -> Self;
fn inv_mix_columns(self) -> Self;
fn add_round_key(self, rk: &Self) -> Self;
}
pub fn encrypt_core<S: AesOps + Copy>(state: &S, sk: &[S]) -> S {
// Round 0 - add round key
let mut tmp = state.add_round_key(&sk[0]);
// Remaining rounds (except last round)
for i in 1..sk.len() - 1 {
tmp = tmp.sub_bytes();
tmp = tmp.shift_rows();
tmp = tmp.mix_columns();
tmp = tmp.add_round_key(&sk[i]);
}
// Last round
tmp = tmp.sub_bytes();
tmp = tmp.shift_rows();
tmp = tmp.add_round_key(&sk[sk.len() - 1]);
tmp
}
pub fn decrypt_core<S: AesOps + Copy>(state: &S, sk: &[S]) -> S {
// Round 0 - add round key
let mut tmp = state.add_round_key(&sk[sk.len() - 1]);
// Remaining rounds (except last round)
for i in 1..sk.len() - 1 {
tmp = tmp.inv_sub_bytes();
tmp = tmp.inv_shift_rows();
tmp = tmp.inv_mix_columns();
tmp = tmp.add_round_key(&sk[sk.len() - 1 - i]);
}
// Last round
tmp = tmp.inv_sub_bytes();
tmp = tmp.inv_shift_rows();
tmp = tmp.add_round_key(&sk[0]);
tmp
}
#[derive(Clone, Copy)]
pub struct Bs8State<T>(pub T, pub T, pub T, pub T, pub T, pub T, pub T, pub T);
impl<T: Copy> Bs8State<T> {
fn split(self) -> (Bs4State<T>, Bs4State<T>) {
let Bs8State(x0, x1, x2, x3, x4, x5, x6, x7) = self;
(Bs4State(x0, x1, x2, x3), Bs4State(x4, x5, x6, x7))
}
}
impl<T: BitXor<Output = T> + Copy> Bs8State<T> {
fn xor(self, rhs: Bs8State<T>) -> Bs8State<T> {
let Bs8State(a0, a1, a2, a3, a4, a5, a6, a7) = self;
let Bs8State(b0, b1, b2, b3, b4, b5, b6, b7) = rhs;
Bs8State(
a0 ^ b0,
a1 ^ b1,
a2 ^ b2,
a3 ^ b3,
a4 ^ b4,
a5 ^ b5,
a6 ^ b6,
a7 ^ b7,
)
}
// We need to be able to convert a Bs8State to and from a polynomial basis and a normal
// basis. That transformation could be done via pseudocode that roughly looks like the
// following:
//
// for x in 0..8 {
// for y in 0..8 {
// result.x ^= input.y & MATRIX[7 - y][x]
// }
// }
//
// Where the MATRIX is one of the following depending on the conversion being done.
// (The affine transformation step is included in all of these matrices):
//
// A2X = [
// [ 0, 0, 0, -1, -1, 0, 0, -1],
// [-1, -1, 0, 0, -1, -1, -1, -1],
// [ 0, -1, 0, 0, -1, -1, -1, -1],
// [ 0, 0, 0, -1, 0, 0, -1, 0],
// [-1, 0, 0, -1, 0, 0, 0, 0],
// [-1, 0, 0, 0, 0, 0, 0, -1],
// [-1, 0, 0, -1, 0, -1, 0, -1],
// [-1, -1, -1, -1, -1, -1, -1, -1]
// ];
//
// X2A = [
// [ 0, 0, -1, 0, 0, -1, -1, 0],
// [ 0, 0, 0, -1, -1, -1, -1, 0],
// [ 0, -1, -1, -1, 0, -1, -1, 0],
// [ 0, 0, -1, -1, 0, 0, 0, -1],
// [ 0, 0, 0, -1, 0, -1, -1, 0],
// [-1, 0, 0, -1, 0, -1, 0, 0],
// [ 0, -1, -1, -1, -1, 0, -1, -1],
// [ 0, 0, 0, 0, 0, -1, -1, 0],
// ];
//
// X2S = [
// [ 0, 0, 0, -1, -1, 0, -1, 0],
// [-1, 0, -1, -1, 0, -1, 0, 0],
// [ 0, -1, -1, -1, -1, 0, 0, -1],
// [-1, -1, 0, -1, 0, 0, 0, 0],
// [ 0, 0, -1, -1, -1, 0, -1, -1],
// [ 0, 0, -1, 0, 0, 0, 0, 0],
// [-1, -1, 0, 0, 0, 0, 0, 0],
// [ 0, 0, -1, 0, 0, -1, 0, 0],
// ];
//
// S2X = [
// [ 0, 0, -1, -1, 0, 0, 0, -1],
// [-1, 0, 0, -1, -1, -1, -1, 0],
// [-1, 0, -1, 0, 0, 0, 0, 0],
// [-1, -1, 0, -1, 0, -1, -1, -1],
// [ 0, -1, 0, 0, -1, 0, 0, 0],
// [ 0, 0, -1, 0, 0, 0, 0, 0],
// [-1, 0, 0, 0, -1, 0, -1, 0],
// [-1, -1, 0, 0, -1, 0, -1, 0],
// ];
//
// Looking at the pseudocode implementation, we see that there is no point
// in processing any of the elements in those matrices that have zero values
// since a logical AND with 0 will produce 0 which will have no effect when it
// is XORed into the result.
//
// LLVM doesn't appear to be able to fully unroll the loops in the pseudocode
// above and to eliminate processing of the 0 elements. So, each transformation is
// implemented independently directly in fully unrolled form with the 0 elements
// removed.
//
// As an optimization, elements that are XORed together multiple times are
// XORed just once and then used multiple times. I wrote a simple program that
// greedily looked for terms to combine to create the implementations below.
// It is likely that this could be optimized more.
fn change_basis_a2x(&self) -> Bs8State<T> {
let t06 = self.6 ^ self.0;
let t056 = self.5 ^ t06;
let t0156 = t056 ^ self.1;
let t13 = self.1 ^ self.3;
let x0 = self.2 ^ t06 ^ t13;
let x1 = t056;
let x2 = self.0;
let x3 = self.0 ^ self.4 ^ self.7 ^ t13;
let x4 = self.7 ^ t056;
let x5 = t0156;
let x6 = self.4 ^ t056;
let x7 = self.2 ^ self.7 ^ t0156;
Bs8State(x0, x1, x2, x3, x4, x5, x6, x7)
}
fn change_basis_x2s(&self) -> Bs8State<T> {
let t46 = self.4 ^ self.6;
let t35 = self.3 ^ self.5;
let t06 = self.0 ^ self.6;
let t357 = t35 ^ self.7;
let x0 = self.1 ^ t46;
let x1 = self.1 ^ self.4 ^ self.5;
let x2 = self.2 ^ t35 ^ t06;
let x3 = t46 ^ t357;
let x4 = t357;
let x5 = t06;
let x6 = self.3 ^ self.7;
let x7 = t35;
Bs8State(x0, x1, x2, x3, x4, x5, x6, x7)
}
fn change_basis_x2a(&self) -> Bs8State<T> {
let t15 = self.1 ^ self.5;
let t36 = self.3 ^ self.6;
let t1356 = t15 ^ t36;
let t07 = self.0 ^ self.7;
let x0 = self.2;
let x1 = t15;
let x2 = self.4 ^ self.7 ^ t15;
let x3 = self.2 ^ self.4 ^ t1356;
let x4 = self.1 ^ self.6;
let x5 = self.2 ^ self.5 ^ t36 ^ t07;
let x6 = t1356 ^ t07;
let x7 = self.1 ^ self.4;
Bs8State(x0, x1, x2, x3, x4, x5, x6, x7)
}
fn change_basis_s2x(&self) -> Bs8State<T> {
let t46 = self.4 ^ self.6;
let t01 = self.0 ^ self.1;
let t0146 = t01 ^ t46;
let x0 = self.5 ^ t0146;
let x1 = self.0 ^ self.3 ^ self.4;
let x2 = self.2 ^ self.5 ^ self.7;
let x3 = self.7 ^ t46;
let x4 = self.3 ^ self.6 ^ t01;
let x5 = t46;
let x6 = t0146;
let x7 = self.4 ^ self.7;
Bs8State(x0, x1, x2, x3, x4, x5, x6, x7)
}
}
impl<T: Not<Output = T> + Copy> Bs8State<T> {
// The special value "x63" is used as part of the sub_bytes and inv_sub_bytes
// steps. It is conceptually a Bs8State value where the 0th, 1st, 5th, and 6th
// elements are all 1s and the other elements are all 0s. The only thing that
// we do with the "x63" value is to XOR a Bs8State with it. We optimize that XOR
// below into just inverting 4 of the elements and leaving the other 4 elements
// untouched.
fn xor_x63(self) -> Bs8State<T> {
Bs8State(
!self.0,
!self.1,
self.2,
self.3,
self.4,
!self.5,
!self.6,
self.7,
)
}
}
#[derive(Clone, Copy)]
struct Bs4State<T>(T, T, T, T);
impl<T: Copy> Bs4State<T> {
fn split(self) -> (Bs2State<T>, Bs2State<T>) {
let Bs4State(x0, x1, x2, x3) = self;
(Bs2State(x0, x1), Bs2State(x2, x3))
}
fn join(self, rhs: Bs4State<T>) -> Bs8State<T> {
let Bs4State(a0, a1, a2, a3) = self;
let Bs4State(b0, b1, b2, b3) = rhs;
Bs8State(a0, a1, a2, a3, b0, b1, b2, b3)
}
}
impl<T: BitXor<Output = T> + Copy> Bs4State<T> {
fn xor(self, rhs: Bs4State<T>) -> Bs4State<T> {
let Bs4State(a0, a1, a2, a3) = self;
let Bs4State(b0, b1, b2, b3) = rhs;
Bs4State(a0 ^ b0, a1 ^ b1, a2 ^ b2, a3 ^ b3)
}
}
#[derive(Clone, Copy)]
struct Bs2State<T>(T, T);
impl<T> Bs2State<T> {
fn split(self) -> (T, T) {
let Bs2State(x0, x1) = self;
(x0, x1)
}
fn join(self, rhs: Bs2State<T>) -> Bs4State<T> {
let Bs2State(a0, a1) = self;
let Bs2State(b0, b1) = rhs;
Bs4State(a0, a1, b0, b1)
}
}
impl<T: BitXor<Output = T> + Copy> Bs2State<T> {
fn xor(self, rhs: Bs2State<T>) -> Bs2State<T> {
let Bs2State(a0, a1) = self;
let Bs2State(b0, b1) = rhs;
Bs2State(a0 ^ b0, a1 ^ b1)
}
}
// Bit Slice data in the form of 4 u32s in column-major order
#[inline(always)]
pub fn bit_slice_4x4_with_u16(a: u32, b: u32, c: u32, d: u32) -> Bs8State<u16> {
fn pb(x: u32, bit: u32, shift: u32) -> u16 {
(((x >> bit) & 1) as u16) << shift
}
fn construct(a: u32, b: u32, c: u32, d: u32, bit: u32) -> u16 {
pb(a, bit, 0) | pb(b, bit, 1) | pb(c, bit, 2) | pb(d, bit, 3)
| pb(a, bit + 8, 4) | pb(b, bit + 8, 5) | pb(c, bit + 8, 6)
| pb(d, bit + 8, 7) | pb(a, bit + 16, 8)
| pb(b, bit + 16, 9) | pb(c, bit + 16, 10)
| pb(d, bit + 16, 11) | pb(a, bit + 24, 12)
| pb(b, bit + 24, 13) | pb(c, bit + 24, 14)
| pb(d, bit + 24, 15)
}
let x0 = construct(a, b, c, d, 0);
let x1 = construct(a, b, c, d, 1);
let x2 = construct(a, b, c, d, 2);
let x3 = construct(a, b, c, d, 3);
let x4 = construct(a, b, c, d, 4);
let x5 = construct(a, b, c, d, 5);
let x6 = construct(a, b, c, d, 6);
let x7 = construct(a, b, c, d, 7);
Bs8State(x0, x1, x2, x3, x4, x5, x6, x7)
}
// Bit slice a single u32 value - this is used to calculate the SubBytes step when creating the
// round keys.
pub fn bit_slice_4x1_with_u16(a: u32) -> Bs8State<u16> {
bit_slice_4x4_with_u16(a, 0, 0, 0)
}
// Bit slice a 16 byte array in column major order
pub fn bit_slice_1x16_with_u16(data: &[u8]) -> Bs8State<u16> {
let mut n = [0u32; 4];
read_u32v_le(&mut n, data);
let a = n[0];
let b = n[1];
let c = n[2];
let d = n[3];
bit_slice_4x4_with_u16(a, b, c, d)
}
// Un Bit Slice into a set of 4 u32s
pub fn un_bit_slice_4x4_with_u16(bs: &Bs8State<u16>) -> (u32, u32, u32, u32) {
fn pb(x: u16, bit: u32, shift: u32) -> u32 {
(((x >> bit) & 1) as u32) << shift
}
fn deconstruct(bs: &Bs8State<u16>, bit: u32) -> u32 {
let Bs8State(x0, x1, x2, x3, x4, x5, x6, x7) = *bs;
pb(x0, bit, 0) | pb(x1, bit, 1) | pb(x2, bit, 2) | pb(x3, bit, 3)
| pb(x4, bit, 4) | pb(x5, bit, 5) | pb(x6, bit, 6)
| pb(x7, bit, 7) | pb(x0, bit + 4, 8) | pb(x1, bit + 4, 9)
| pb(x2, bit + 4, 10) | pb(x3, bit + 4, 11)
| pb(x4, bit + 4, 12) | pb(x5, bit + 4, 13)
| pb(x6, bit + 4, 14) | pb(x7, bit + 4, 15)
| pb(x0, bit + 8, 16) | pb(x1, bit + 8, 17)
| pb(x2, bit + 8, 18) | pb(x3, bit + 8, 19)
| pb(x4, bit + 8, 20) | pb(x5, bit + 8, 21)
| pb(x6, bit + 8, 22) | pb(x7, bit + 8, 23)
| pb(x0, bit + 12, 24) | pb(x1, bit + 12, 25)
| pb(x2, bit + 12, 26) | pb(x3, bit + 12, 27)
| pb(x4, bit + 12, 28) | pb(x5, bit + 12, 29)
| pb(x6, bit + 12, 30) | pb(x7, bit + 12, 31)
}
let a = deconstruct(bs, 0);
let b = deconstruct(bs, 1);
let c = deconstruct(bs, 2);
let d = deconstruct(bs, 3);
(a, b, c, d)
}
// Un Bit Slice into a single u32. This is used when creating the round keys.
pub fn un_bit_slice_4x1_with_u16(bs: &Bs8State<u16>) -> u32 {
let (a, _, _, _) = un_bit_slice_4x4_with_u16(bs);
a
}
// Un Bit Slice into a 16 byte array
pub fn un_bit_slice_1x16_with_u16(bs: &Bs8State<u16>, output: &mut [u8]) {
let (a, b, c, d) = un_bit_slice_4x4_with_u16(bs);
write_u32_le(&mut output[0..4], a);
write_u32_le(&mut output[4..8], b);
write_u32_le(&mut output[8..12], c);
write_u32_le(&mut output[12..16], d);
}
// Bit Slice a 128 byte array of eight 16 byte blocks. Each block is in column major order.
pub fn bit_slice_1x128_with_u32x4(data: &[u8]) -> Bs8State<u32x4> {
let bit0 = u32x4(0x01010101, 0x01010101, 0x01010101, 0x01010101);
let bit1 = u32x4(0x02020202, 0x02020202, 0x02020202, 0x02020202);
let bit2 = u32x4(0x04040404, 0x04040404, 0x04040404, 0x04040404);
let bit3 = u32x4(0x08080808, 0x08080808, 0x08080808, 0x08080808);
let bit4 = u32x4(0x10101010, 0x10101010, 0x10101010, 0x10101010);
let bit5 = u32x4(0x20202020, 0x20202020, 0x20202020, 0x20202020);
let bit6 = u32x4(0x40404040, 0x40404040, 0x40404040, 0x40404040);
let bit7 = u32x4(0x80808080, 0x80808080, 0x80808080, 0x80808080);
fn read_row_major(data: &[u8]) -> u32x4 {
u32x4(
(data[0] as u32) | ((data[4] as u32) << 8)
| ((data[8] as u32) << 16)
| ((data[12] as u32) << 24),
(data[1] as u32) | ((data[5] as u32) << 8)
| ((data[9] as u32) << 16)
| ((data[13] as u32) << 24),
(data[2] as u32) | ((data[6] as u32) << 8)
| ((data[10] as u32) << 16)
| ((data[14] as u32) << 24),
(data[3] as u32) | ((data[7] as u32) << 8)
| ((data[11] as u32) << 16)
| ((data[15] as u32) << 24),
)
}
let t0 = read_row_major(&data[0..16]);
let t1 = read_row_major(&data[16..32]);
let t2 = read_row_major(&data[32..48]);
let t3 = read_row_major(&data[48..64]);
let t4 = read_row_major(&data[64..80]);
let t5 = read_row_major(&data[80..96]);
let t6 = read_row_major(&data[96..112]);
let t7 = read_row_major(&data[112..128]);
let x0 = (t0 & bit0) | (t1.lsh(1) & bit1) | (t2.lsh(2) & bit2)
| (t3.lsh(3) & bit3) | (t4.lsh(4) & bit4)
| (t5.lsh(5) & bit5) | (t6.lsh(6) & bit6)
| (t7.lsh(7) & bit7);
let x1 = (t0.rsh(1) & bit0) | (t1 & bit1) | (t2.lsh(1) & bit2)
| (t3.lsh(2) & bit3) | (t4.lsh(3) & bit4)
| (t5.lsh(4) & bit5) | (t6.lsh(5) & bit6)
| (t7.lsh(6) & bit7);
let x2 = (t0.rsh(2) & bit0) | (t1.rsh(1) & bit1) | (t2 & bit2)
| (t3.lsh(1) & bit3) | (t4.lsh(2) & bit4)
| (t5.lsh(3) & bit5) | (t6.lsh(4) & bit6)
| (t7.lsh(5) & bit7);
let x3 = (t0.rsh(3) & bit0) | (t1.rsh(2) & bit1) | (t2.rsh(1) & bit2)
| (t3 & bit3) | (t4.lsh(1) & bit4) | (t5.lsh(2) & bit5)
| (t6.lsh(3) & bit6) | (t7.lsh(4) & bit7);
let x4 = (t0.rsh(4) & bit0) | (t1.rsh(3) & bit1) | (t2.rsh(2) & bit2)
| (t3.rsh(1) & bit3) | (t4 & bit4) | (t5.lsh(1) & bit5)
| (t6.lsh(2) & bit6) | (t7.lsh(3) & bit7);
let x5 = (t0.rsh(5) & bit0) | (t1.rsh(4) & bit1) | (t2.rsh(3) & bit2)
| (t3.rsh(2) & bit3) | (t4.rsh(1) & bit4) | (t5 & bit5)
| (t6.lsh(1) & bit6) | (t7.lsh(2) & bit7);
let x6 = (t0.rsh(6) & bit0) | (t1.rsh(5) & bit1) | (t2.rsh(4) & bit2)
| (t3.rsh(3) & bit3) | (t4.rsh(2) & bit4)
| (t5.rsh(1) & bit5) | (t6 & bit6) | (t7.lsh(1) & bit7);
let x7 = (t0.rsh(7) & bit0) | (t1.rsh(6) & bit1) | (t2.rsh(5) & bit2)
| (t3.rsh(4) & bit3) | (t4.rsh(3) & bit4)
| (t5.rsh(2) & bit5) | (t6.rsh(1) & bit6) | (t7 & bit7);
Bs8State(x0, x1, x2, x3, x4, x5, x6, x7)
}
// Bit slice a set of 4 u32s by filling a full 128 byte data block with those repeated values. This
// is used as part of bit slicing the round keys.
pub fn bit_slice_fill_4x4_with_u32x4(
a: u32, b: u32, c: u32, d: u32
) -> Bs8State<u32x4> {
let mut tmp = [0u8; 128];
for i in 0..8 {
write_u32_le(&mut tmp[i * 16..i * 16 + 4], a);
write_u32_le(&mut tmp[i * 16 + 4..i * 16 + 8], b);
write_u32_le(&mut tmp[i * 16 + 8..i * 16 + 12], c);
write_u32_le(&mut tmp[i * 16 + 12..i * 16 + 16], d);
}
bit_slice_1x128_with_u32x4(&tmp)
}
// Un bit slice into a 128 byte buffer.
pub fn un_bit_slice_1x128_with_u32x4(bs: Bs8State<u32x4>, output: &mut [u8]) {
let Bs8State(t0, t1, t2, t3, t4, t5, t6, t7) = bs;
let bit0 = u32x4(0x01010101, 0x01010101, 0x01010101, 0x01010101);
let bit1 = u32x4(0x02020202, 0x02020202, 0x02020202, 0x02020202);
let bit2 = u32x4(0x04040404, 0x04040404, 0x04040404, 0x04040404);
let bit3 = u32x4(0x08080808, 0x08080808, 0x08080808, 0x08080808);
let bit4 = u32x4(0x10101010, 0x10101010, 0x10101010, 0x10101010);
let bit5 = u32x4(0x20202020, 0x20202020, 0x20202020, 0x20202020);
let bit6 = u32x4(0x40404040, 0x40404040, 0x40404040, 0x40404040);
let bit7 = u32x4(0x80808080, 0x80808080, 0x80808080, 0x80808080);
// decode the individual blocks, in row-major order
// TODO: this is identical to the same block in bit_slice_1x128_with_u32x4
let x0 = (t0 & bit0) | (t1.lsh(1) & bit1) | (t2.lsh(2) & bit2)
| (t3.lsh(3) & bit3) | (t4.lsh(4) & bit4)
| (t5.lsh(5) & bit5) | (t6.lsh(6) & bit6)
| (t7.lsh(7) & bit7);
let x1 = (t0.rsh(1) & bit0) | (t1 & bit1) | (t2.lsh(1) & bit2)
| (t3.lsh(2) & bit3) | (t4.lsh(3) & bit4)
| (t5.lsh(4) & bit5) | (t6.lsh(5) & bit6)
| (t7.lsh(6) & bit7);
let x2 = (t0.rsh(2) & bit0) | (t1.rsh(1) & bit1) | (t2 & bit2)
| (t3.lsh(1) & bit3) | (t4.lsh(2) & bit4)
| (t5.lsh(3) & bit5) | (t6.lsh(4) & bit6)
| (t7.lsh(5) & bit7);
let x3 = (t0.rsh(3) & bit0) | (t1.rsh(2) & bit1) | (t2.rsh(1) & bit2)
| (t3 & bit3) | (t4.lsh(1) & bit4) | (t5.lsh(2) & bit5)
| (t6.lsh(3) & bit6) | (t7.lsh(4) & bit7);
let x4 = (t0.rsh(4) & bit0) | (t1.rsh(3) & bit1) | (t2.rsh(2) & bit2)
| (t3.rsh(1) & bit3) | (t4 & bit4) | (t5.lsh(1) & bit5)
| (t6.lsh(2) & bit6) | (t7.lsh(3) & bit7);
let x5 = (t0.rsh(5) & bit0) | (t1.rsh(4) & bit1) | (t2.rsh(3) & bit2)
| (t3.rsh(2) & bit3) | (t4.rsh(1) & bit4) | (t5 & bit5)
| (t6.lsh(1) & bit6) | (t7.lsh(2) & bit7);
let x6 = (t0.rsh(6) & bit0) | (t1.rsh(5) & bit1) | (t2.rsh(4) & bit2)
| (t3.rsh(3) & bit3) | (t4.rsh(2) & bit4)
| (t5.rsh(1) & bit5) | (t6 & bit6) | (t7.lsh(1) & bit7);
let x7 = (t0.rsh(7) & bit0) | (t1.rsh(6) & bit1) | (t2.rsh(5) & bit2)
| (t3.rsh(4) & bit3) | (t4.rsh(3) & bit4)
| (t5.rsh(2) & bit5) | (t6.rsh(1) & bit6) | (t7 & bit7);
fn write_row_major(block: u32x4, output: &mut [u8]) {
let u32x4(a0, a1, a2, a3) = block;
output[0] = a0 as u8;
output[1] = a1 as u8;
output[2] = a2 as u8;
output[3] = a3 as u8;
output[4] = (a0 >> 8) as u8;
output[5] = (a1 >> 8) as u8;
output[6] = (a2 >> 8) as u8;
output[7] = (a3 >> 8) as u8;
output[8] = (a0 >> 16) as u8;
output[9] = (a1 >> 16) as u8;
output[10] = (a2 >> 16) as u8;
output[11] = (a3 >> 16) as u8;
output[12] = (a0 >> 24) as u8;
output[13] = (a1 >> 24) as u8;
output[14] = (a2 >> 24) as u8;
output[15] = (a3 >> 24) as u8;
}
write_row_major(x0, &mut output[0..16]);
write_row_major(x1, &mut output[16..32]);
write_row_major(x2, &mut output[32..48]);
write_row_major(x3, &mut output[48..64]);
write_row_major(x4, &mut output[64..80]);
write_row_major(x5, &mut output[80..96]);
write_row_major(x6, &mut output[96..112]);
write_row_major(x7, &mut output[112..128])
}
// The Gf2Ops, Gf4Ops, and Gf8Ops traits specify the functions needed to calculate the AES S-Box
// values. This particuar implementation of those S-Box values is taken from [7], so that is where
// to look for details on how all that all works. This includes the transformations matrices defined
// below for the change_basis operation on the u32 and u32x4 types.
// Operations in GF(2^2) using normal basis (Omega^2,Omega)
trait Gf2Ops {
// multiply
fn mul(self, y: Self) -> Self;
// scale by N = Omega^2
fn scl_n(self) -> Self;
// scale by N^2 = Omega
fn scl_n2(self) -> Self;
// square
fn sq(self) -> Self;
// Same as sqaure
fn inv(self) -> Self;
}
impl<T: BitXor<Output = T> + BitAnd<Output = T> + Copy> Gf2Ops for Bs2State<T> {
fn mul(self, y: Bs2State<T>) -> Bs2State<T> {
let (b, a) = self.split();
let (d, c) = y.split();
let e = (a ^ b) & (c ^ d);
let p = (a & c) ^ e;
let q = (b & d) ^ e;
Bs2State(q, p)
}
fn scl_n(self) -> Bs2State<T> {
let (b, a) = self.split();
let q = a ^ b;
Bs2State(q, b)
}
fn scl_n2(self) -> Bs2State<T> {
let (b, a) = self.split();
let p = a ^ b;
let q = a;
Bs2State(q, p)
}
fn sq(self) -> Bs2State<T> {
let (b, a) = self.split();
Bs2State(a, b)
}
fn inv(self) -> Bs2State<T> { self.sq() }
}
// Operations in GF(2^4) using normal basis (alpha^8,alpha^2)
trait Gf4Ops {
// multiply
fn mul(self, y: Self) -> Self;
// square & scale by nu
// nu = beta^8 = N^2*alpha^2, N = w^2
fn sq_scl(self) -> Self;
// inverse
fn inv(self) -> Self;
}
impl<T: BitXor<Output = T> + BitAnd<Output = T> + Copy> Gf4Ops for Bs4State<T> {
fn mul(self, y: Bs4State<T>) -> Bs4State<T> {
let (b, a) = self.split();
let (d, c) = y.split();
let f = c.xor(d);
let e = a.xor(b).mul(f).scl_n();
let p = a.mul(c).xor(e);
let q = b.mul(d).xor(e);
q.join(p)
}
fn sq_scl(self) -> Bs4State<T> {
let (b, a) = self.split();
let p = a.xor(b).sq();
let q = b.sq().scl_n2();
q.join(p)
}
fn inv(self) -> Bs4State<T> {
let (b, a) = self.split();
let c = a.xor(b).sq().scl_n();
let d = a.mul(b);
let e = c.xor(d).inv();
let p = e.mul(b);
let q = e.mul(a);
q.join(p)
}
}
// Operations in GF(2^8) using normal basis (d^16,d)
trait Gf8Ops {
// inverse
fn inv(&self) -> Self;
}
impl<T: BitXor<Output = T> + BitAnd<Output = T> + Copy + Default> Gf8Ops
for Bs8State<T>
{
fn inv(&self) -> Bs8State<T> {
let (b, a) = self.split();
let c = a.xor(b).sq_scl();
let d = a.mul(b);
let e = c.xor(d).inv();
let p = e.mul(b);
let q = e.mul(a);
q.join(p)
}
}
impl<T: AesBitValueOps + Copy + 'static> AesOps for Bs8State<T> {
fn sub_bytes(self) -> Bs8State<T> {
let nb: Bs8State<T> = self.change_basis_a2x();
let inv = nb.inv();
let nb2: Bs8State<T> = inv.change_basis_x2s();
nb2.xor_x63()
}
fn inv_sub_bytes(self) -> Bs8State<T> {
let t = self.xor_x63();
let nb: Bs8State<T> = t.change_basis_s2x();
let inv = nb.inv();
inv.change_basis_x2a()
}
fn shift_rows(self) -> Bs8State<T> {
let Bs8State(x0, x1, x2, x3, x4, x5, x6, x7) = self;
Bs8State(
x0.shift_row(),
x1.shift_row(),
x2.shift_row(),
x3.shift_row(),
x4.shift_row(),
x5.shift_row(),
x6.shift_row(),
x7.shift_row(),
)
}
fn inv_shift_rows(self) -> Bs8State<T> {
let Bs8State(x0, x1, x2, x3, x4, x5, x6, x7) = self;
Bs8State(
x0.inv_shift_row(),
x1.inv_shift_row(),
x2.inv_shift_row(),
x3.inv_shift_row(),
x4.inv_shift_row(),
x5.inv_shift_row(),
x6.inv_shift_row(),
x7.inv_shift_row(),
)
}
// Formula from [5]
fn mix_columns(self) -> Bs8State<T> {
let Bs8State(x0, x1, x2, x3, x4, x5, x6, x7) = self;
let x0out = x7 ^ x7.ror1() ^ x0.ror1() ^ (x0 ^ x0.ror1()).ror2();
let x1out = x0 ^ x0.ror1() ^ x7 ^ x7.ror1() ^ x1.ror1()
^ (x1 ^ x1.ror1()).ror2();
let x2out = x1 ^ x1.ror1() ^ x2.ror1() ^ (x2 ^ x2.ror1()).ror2();
let x3out = x2 ^ x2.ror1() ^ x7 ^ x7.ror1() ^ x3.ror1()
^ (x3 ^ x3.ror1()).ror2();
let x4out = x3 ^ x3.ror1() ^ x7 ^ x7.ror1() ^ x4.ror1()
^ (x4 ^ x4.ror1()).ror2();
let x5out = x4 ^ x4.ror1() ^ x5.ror1() ^ (x5 ^ x5.ror1()).ror2();
let x6out = x5 ^ x5.ror1() ^ x6.ror1() ^ (x6 ^ x6.ror1()).ror2();
let x7out = x6 ^ x6.ror1() ^ x7.ror1() ^ (x7 ^ x7.ror1()).ror2();
Bs8State(x0out, x1out, x2out, x3out, x4out, x5out, x6out, x7out)
}
// Formula from [6]
fn inv_mix_columns(self) -> Bs8State<T> {
let Bs8State(x0, x1, x2, x3, x4, x5, x6, x7) = self;
let x0out = x5 ^ x6 ^ x7 ^ (x5 ^ x7 ^ x0).ror1() ^ (x0 ^ x5 ^ x6).ror2()
^ (x5 ^ x0).ror3();
let x1out = x5 ^ x0 ^ (x6 ^ x5 ^ x0 ^ x7 ^ x1).ror1()
^ (x1 ^ x7 ^ x5).ror2() ^ (x6 ^ x5 ^ x1).ror3();
let x2out = x6 ^ x0 ^ x1 ^ (x7 ^ x6 ^ x1 ^ x2).ror1()
^ (x0 ^ x2 ^ x6).ror2() ^ (x7 ^ x6 ^ x2).ror3();
let x3out = x0 ^ x5 ^ x1 ^ x6 ^ x2 ^ (x0 ^ x5 ^ x2 ^ x3).ror1()
^ (x0 ^ x1 ^ x3 ^ x5 ^ x6 ^ x7).ror2()
^ (x0 ^ x5 ^ x7 ^ x3).ror3();
let x4out = x1 ^ x5 ^ x2 ^ x3 ^ (x1 ^ x6 ^ x5 ^ x3 ^ x7 ^ x4).ror1()
^ (x1 ^ x2 ^ x4 ^ x5 ^ x7).ror2()
^ (x1 ^ x5 ^ x6 ^ x4).ror3();
let x5out = x2 ^ x6 ^ x3 ^ x4 ^ (x2 ^ x7 ^ x6 ^ x4 ^ x5).ror1()
^ (x2 ^ x3 ^ x5 ^ x6).ror2()
^ (x2 ^ x6 ^ x7 ^ x5).ror3();
let x6out = x3 ^ x7 ^ x4 ^ x5 ^ (x3 ^ x7 ^ x5 ^ x6).ror1()
^ (x3 ^ x4 ^ x6 ^ x7).ror2()
^ (x3 ^ x7 ^ x6).ror3();
let x7out = x4 ^ x5 ^ x6 ^ (x4 ^ x6 ^ x7).ror1() ^ (x4 ^ x5 ^ x7).ror2()
^ (x4 ^ x7).ror3();
Bs8State(x0out, x1out, x2out, x3out, x4out, x5out, x6out, x7out)
}
fn add_round_key(self, rk: &Bs8State<T>) -> Bs8State<T> { self.xor(*rk) }
}
pub trait AesBitValueOps
: BitXor<Output = Self>
+ BitAnd<Output = Self>
+ Not<Output = Self>
+ Default
+ Sized {
fn shift_row(self) -> Self;
fn inv_shift_row(self) -> Self;
fn ror1(self) -> Self;
fn ror2(self) -> Self;
fn ror3(self) -> Self;
}
impl AesBitValueOps for u16 {
fn shift_row(self) -> u16 {
// first 4 bits represent first row - don't shift
(self & 0x000f) |
// next 4 bits represent 2nd row - left rotate 1 bit
((self & 0x00e0) >> 1) | ((self & 0x0010) << 3) |
// next 4 bits represent 3rd row - left rotate 2 bits
((self & 0x0c00) >> 2) | ((self & 0x0300) << 2) |
// next 4 bits represent 4th row - left rotate 3 bits
((self & 0x8000) >> 3) | ((self & 0x7000) << 1)
}
fn inv_shift_row(self) -> u16 {
// first 4 bits represent first row - don't shift
(self & 0x000f) |
// next 4 bits represent 2nd row - right rotate 1 bit
((self & 0x0080) >> 3) | ((self & 0x0070) << 1) |
// next 4 bits represent 3rd row - right rotate 2 bits
((self & 0x0c00) >> 2) | ((self & 0x0300) << 2) |
// next 4 bits represent 4th row - right rotate 3 bits
((self & 0xe000) >> 1) | ((self & 0x1000) << 3)
}
fn ror1(self) -> u16 { self >> 4 | self << 12 }
fn ror2(self) -> u16 { self >> 8 | self << 8 }
fn ror3(self) -> u16 { self >> 12 | self << 4 }
}
impl u32x4 {
fn lsh(self, s: u32) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(
a0 << s,
(a1 << s) | (a0 >> (32 - s)),
(a2 << s) | (a1 >> (32 - s)),
(a3 << s) | (a2 >> (32 - s)),
)
}
fn rsh(self, s: u32) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(
(a0 >> s) | (a1 << (32 - s)),
(a1 >> s) | (a2 << (32 - s)),
(a2 >> s) | (a3 << (32 - s)),
a3 >> s,
)
}
}
impl Not for u32x4 {
type Output = u32x4;
fn not(self) -> u32x4 { self ^ U32X4_1 }
}
impl Default for u32x4 {
fn default() -> u32x4 { u32x4(0, 0, 0, 0) }
}
impl AesBitValueOps for u32x4 {
fn shift_row(self) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(
a0,
a1 >> 8 | a1 << 24,
a2 >> 16 | a2 << 16,
a3 >> 24 | a3 << 8,
)
}
fn inv_shift_row(self) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(
a0,
a1 >> 24 | a1 << 8,
a2 >> 16 | a2 << 16,
a3 >> 8 | a3 << 24,
)
}
fn ror1(self) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(a1, a2, a3, a0)
}
fn ror2(self) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(a2, a3, a0, a1)
}
fn ror3(self) -> u32x4 {
let u32x4(a0, a1, a2, a3) = self;
u32x4(a3, a0, a1, a2)
}
}

10
aes-soft-0.2.0/src/consts.rs

@ -0,0 +1,10 @@
use simd::u32x4;
pub const U32X4_0: u32x4 = u32x4(0, 0, 0, 0);
pub const U32X4_1: u32x4 =
u32x4(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
// This array is not accessed in any key-dependant way, so there are no timing problems inherent in
// using it.
pub static RCON: [u32; 10] =
[0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];

79
aes-soft-0.2.0/src/expand.rs

@ -0,0 +1,79 @@
use block_cipher_trait::generic_array::{ArrayLength, GenericArray};
use bitslice::{AesOps, bit_slice_4x1_with_u16, un_bit_slice_4x1_with_u16};
use consts::RCON;
fn ffmulx(x: u32) -> u32 {
let m1: u32 = 0x80808080;
let m2: u32 = 0x7f7f7f7f;
let m3: u32 = 0x0000001b;
((x & m2) << 1) ^ (((x & m1) >> 7) * m3)
}
fn inv_mcol(x: u32) -> u32 {
let f2 = ffmulx(x);
let f4 = ffmulx(f2);
let f8 = ffmulx(f4);
let f9 = x ^ f8;
f2 ^ f4 ^ f8 ^ (f2 ^ f9).rotate_right(8) ^ (f4 ^ f9).rotate_right(16)
^ f9.rotate_right(24)
}
fn sub_word(x: u32) -> u32 {
let bs = bit_slice_4x1_with_u16(x).sub_bytes();
un_bit_slice_4x1_with_u16(&bs)
}
// The round keys are created without bit-slicing the key data. The individual implementations bit
// slice the round keys returned from this function. This function, and the few functions above, are
// derived from the BouncyCastle AES implementation.
pub fn expand_key<KeySize: ArrayLength<u8>, Rounds: ArrayLength<[u32; 4]>>(
key: &GenericArray<u8, KeySize>
) -> (
GenericArray<[u32; 4], Rounds>,
GenericArray<[u32; 4], Rounds>,
) {
let rounds = Rounds::to_usize();
let key_len = KeySize::to_usize();
let key_words = match key_len {
16 => 4,
24 => 6,
32 => 8,
_ => panic!("Invalid AES key size."),
};
let mut ek = GenericArray::<[u32; 4], Rounds>::default();
// The key is copied directly into the first few round keys
let mut j = 0;
for i in 0..key_len / 4 {
ek[j / 4][j % 4] = (key[4 * i] as u32) | ((key[4 * i + 1] as u32) << 8)
| ((key[4 * i + 2] as u32) << 16)
| ((key[4 * i + 3] as u32) << 24);
j += 1;
}
// Calculate the rest of the round keys
for i in key_words..rounds * 4 {
let mut tmp = ek[(i - 1) / 4][(i - 1) % 4];
if (i % key_words) == 0 {
tmp = sub_word(tmp.rotate_right(8)) ^ RCON[(i / key_words) - 1];
} else if (key_words == 8) && ((i % key_words) == 4) {
// This is only necessary for AES-256 keys
tmp = sub_word(tmp);
}
ek[i / 4][i % 4] = ek[(i - key_words) / 4][(i - key_words) % 4] ^ tmp;
}
// Decryption round keys require extra processing
let mut dk = GenericArray::<[u32; 4], Rounds>::default();
dk[0] = ek[0];
for j in 1..rounds - 1 {
for i in 0..4 {
dk[j][i] = inv_mcol(ek[j][i]);
}
}
dk[rounds - 1] = ek[rounds - 1];
(ek, dk)
}

113
aes-soft-0.2.0/src/impls.rs

@ -0,0 +1,113 @@
use core::{fmt, mem};
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::{U16, U8};
use block_cipher_trait::generic_array::typenum::{U11, U13, U15, U24, U32};
pub use block_cipher_trait::BlockCipher;
use expand::expand_key;
use simd::u32x4;
use consts::U32X4_0;
use bitslice::{
decrypt_core, encrypt_core, Bs8State, bit_slice_1x128_with_u32x4,
bit_slice_1x16_with_u16, bit_slice_4x4_with_u16,
bit_slice_fill_4x4_with_u32x4, un_bit_slice_1x128_with_u32x4,
un_bit_slice_1x16_with_u16,
};
pub type Block128 = GenericArray<u8, U16>;
pub type Block128x8 = GenericArray<GenericArray<u8, U16>, U8>;
macro_rules! define_aes_impl {
(
$name:ident,
$key_size:ty,
$rounds:expr,
$rounds2:ty,
$doc:expr
) => {
#[doc=$doc]
pub struct $name {
enc_keys: [Bs8State<u16>; $rounds],
dec_keys: [Bs8State<u16>; $rounds],
enc_keys8: [Bs8State<u32x4>; $rounds],
dec_keys8: [Bs8State<u32x4>; $rounds],
}
impl BlockCipher for $name {
type KeySize = $key_size;
type BlockSize = U16;
type ParBlocks = U8;
#[inline]
fn new(key: &GenericArray<u8, $key_size>) -> Self {
let (ek, dk) = expand_key::<$key_size, $rounds2>(key);
let k8 = Bs8State(
U32X4_0, U32X4_0, U32X4_0, U32X4_0,
U32X4_0, U32X4_0, U32X4_0, U32X4_0
);
let mut c = Self {
enc_keys: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0); $rounds],
dec_keys: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0); $rounds],
enc_keys8: [k8; $rounds],
dec_keys8: [k8; $rounds],
};
for i in 0..$rounds {
c.enc_keys[i] = bit_slice_4x4_with_u16(
ek[i][0], ek[i][1], ek[i][2], ek[i][3],
);
c.dec_keys[i] = bit_slice_4x4_with_u16(
dk[i][0], dk[i][1], dk[i][2], dk[i][3],
);
c.enc_keys8[i] = bit_slice_fill_4x4_with_u32x4(
ek[i][0], ek[i][1], ek[i][2], ek[i][3],
);
c.dec_keys8[i] = bit_slice_fill_4x4_with_u32x4(
dk[i][0], dk[i][1], dk[i][2], dk[i][3],
);
}
c
}
#[inline]
fn encrypt_block(&self, block: &mut Block128) {
let mut bs = bit_slice_1x16_with_u16(block);
bs = encrypt_core(&bs, &self.enc_keys);
un_bit_slice_1x16_with_u16(&bs, block);
}
#[inline]
fn decrypt_block(&self, block: &mut Block128) {
let mut bs = bit_slice_1x16_with_u16(block);
bs = decrypt_core(&bs, &self.dec_keys);
un_bit_slice_1x16_with_u16(&bs, block);
}
#[inline]
fn encrypt_blocks(&self, blocks: &mut Block128x8) {
let blocks: &mut [u8; 16*8] = unsafe {
mem::transmute(blocks)
};
let bs = bit_slice_1x128_with_u32x4(blocks);
let bs2 = encrypt_core(&bs, &self.enc_keys8);
un_bit_slice_1x128_with_u32x4(bs2, blocks);
}
#[inline]
fn decrypt_blocks(&self, blocks: &mut Block128x8) {
let blocks: &mut [u8; 16*8] = unsafe {
mem::transmute(blocks)
};
let bs = bit_slice_1x128_with_u32x4(blocks);
let bs2 = decrypt_core(&bs, &self.dec_keys8);
un_bit_slice_1x128_with_u32x4(bs2, blocks);
}
}
impl_opaque_debug!($name);
}
}
define_aes_impl!(Aes128, U16, 11, U11, "AES-128 block cipher instance");
define_aes_impl!(Aes192, U24, 13, U13, "AES-192 block cipher instance");
define_aes_impl!(Aes256, U32, 15, U15, "AES-256 block cipher instance");

47
aes-soft-0.2.0/src/lib.rs

@ -0,0 +1,47 @@
//! 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 implementation is heavily based on `aessafe` [module][1]
//! from `rust-crypto` crate.
//!
//! # Usage example
//! ```
//! use aes_soft::block_cipher_trait::generic_array::GenericArray;
//! use aes_soft::block_cipher_trait::BlockCipher;
//! 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://github.com/DaGenix/rust-crypto/blob/master/src/aessafe.rs
#![no_std]
pub extern crate block_cipher_trait;
extern crate byte_tools;
#[macro_use]
extern crate opaque_debug;
mod simd;
mod bitslice;
mod expand;
mod consts;
mod impls;
pub use impls::{Aes128, Aes192, Aes256};

47
aes-soft-0.2.0/src/simd.rs

@ -0,0 +1,47 @@
use core::ops::{BitAnd, BitOr, BitXor};
#[derive(Clone, Copy, PartialEq, Eq)]
#[allow(non_camel_case_types)]
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
impl BitXor for u32x4 {
type Output = u32x4;
#[inline(always)]
fn bitxor(self, rhs: u32x4) -> u32x4 {
u32x4(
self.0 ^ rhs.0,
self.1 ^ rhs.1,
self.2 ^ rhs.2,
self.3 ^ rhs.3,
)
}
}
impl BitAnd for u32x4 {
type Output = u32x4;
#[inline(always)]
fn bitand(self, rhs: u32x4) -> u32x4 {
u32x4(
self.0 & rhs.0,
self.1 & rhs.1,
self.2 & rhs.2,
self.3 & rhs.3,
)
}
}
impl BitOr for u32x4 {
type Output = u32x4;
#[inline(always)]
fn bitor(self, rhs: u32x4) -> u32x4 {
u32x4(
self.0 | rhs.0,
self.1 | rhs.1,
self.2 | rhs.2,
self.3 | rhs.3,
)
}
}

BIN
aes-soft-0.2.0/tests/data/aes128.ciphertexts.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes128.index.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes128.keys.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes128.plaintexts.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes192.ciphertexts.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes192.index.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes192.keys.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes192.plaintexts.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes256.ciphertexts.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes256.index.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes256.keys.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/aes256.plaintexts.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/ctr_aes128.ciphertext.bin

Binary file not shown.

1
aes-soft-0.2.0/tests/data/ctr_aes128.iv.bin

@ -0,0 +1 @@
‹ÙÚI01Ÿ±'ÑÏ`Å,

1
aes-soft-0.2.0/tests/data/ctr_aes128.key.bin

@ -0,0 +1 @@
肌 +0`[b顎#lD枸}

BIN
aes-soft-0.2.0/tests/data/ctr_aes128.plaintext.bin

Binary file not shown.

BIN
aes-soft-0.2.0/tests/data/ctr_aes256.ciphertext.bin

Binary file not shown.

1
aes-soft-0.2.0/tests/data/ctr_aes256.iv.bin

@ -0,0 +1 @@
���= ����+�3}�

1
aes-soft-0.2.0/tests/data/ctr_aes256.key.bin

@ -0,0 +1 @@
�ÔšMRÁÆR—ôÁÍÞå<1�A¤§¶/‚

BIN
aes-soft-0.2.0/tests/data/ctr_aes256.plaintext.bin

Binary file not shown.

10
aes-soft-0.2.0/tests/lib.rs

@ -0,0 +1,10 @@
//! Test vectors are from NESSIE:
//! https://www.cosic.esat.kuleuven.be/nessie/testvectors/
#![no_std]
extern crate aes_soft;
#[macro_use]
extern crate block_cipher_trait;
new_test!(aes128_test, "aes128", aes_soft::Aes128);
new_test!(aes192_test, "aes192", aes_soft::Aes192);
new_test!(aes256_test, "aes256", aes_soft::Aes256);

1
aesni-0.6.0/.cargo-ok

@ -0,0 +1 @@
ok

5
aesni-0.6.0/.cargo_vcs_info.json

@ -0,0 +1,5 @@
{
"git": {
"sha1": "ca170bbe8c0e40013d8ffdf8b055450bbeb448dc"
}
}

46
aesni-0.6.0/Cargo.toml

@ -0,0 +1,46 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "aesni"
version = "0.6.0"
authors = ["RustCrypto Developers"]
description = "AES (Rijndael) block ciphers implementation using AES-NI"
documentation = "https://docs.rs/aesni"
keywords = ["crypto", "aes", "rijndael", "block-cipher"]
categories = ["cryptography", "no-std"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/RustCrypto/block-ciphers"
[package.metadata.docs.rs]
rustc-args = ["-C", "target-feature=+aes,+ssse3"]
rustdoc-args = ["-C", "target-feature=+aes,+ssse3"]
[dependencies.block-cipher-trait]
version = "0.6"
[dependencies.opaque-debug]
version = "0.2"
[dependencies.stream-cipher]
version = "0.3"
optional = true
[dev-dependencies.block-cipher-trait]
version = "0.6"
features = ["dev"]
[dev-dependencies.stream-cipher]
version = "0.3"
features = ["dev"]
[features]
ctr = ["stream-cipher"]
default = ["ctr"]
nocheck = []

30
aesni-0.6.0/Cargo.toml.orig

@ -0,0 +1,30 @@
[package]
name = "aesni"
version = "0.6.0"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
description = "AES (Rijndael) block ciphers implementation using AES-NI"
documentation = "https://docs.rs/aesni"
repository = "https://github.com/RustCrypto/block-ciphers"
keywords = ["crypto", "aes", "rijndael", "block-cipher"]
categories = ["cryptography", "no-std"]
[dependencies]
block-cipher-trait = "0.6"
opaque-debug = "0.2"
stream-cipher = { version = "0.3", optional = true }
[dev-dependencies]
block-cipher-trait = { version = "0.6", features = ["dev"] }
stream-cipher = { version = "0.3", features = ["dev"] }
[features]
default = ["ctr"]
ctr = ["stream-cipher"]
nocheck = []
[workspace]
[package.metadata.docs.rs]
rustc-args = ["-C", "target-feature=+aes,+ssse3"]
rustdoc-args = ["-C", "target-feature=+aes,+ssse3"]

201
aesni-0.6.0/LICENSE-APACHE

@ -0,0 +1,201 @@
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.

25
aesni-0.6.0/LICENSE-MIT

@ -0,0 +1,25 @@
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.

56
aesni-0.6.0/benches/aes128.rs

@ -0,0 +1,56 @@
#![no_std]
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#![feature(test)]
extern crate aesni;
extern crate test;
use aesni::Aes128;
use aesni::block_cipher_trait::BlockCipher;
#[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;
}

6
aesni-0.6.0/benches/aes128_ctr.rs

@ -0,0 +1,6 @@
#![cfg(feature = "ctr")]
#![feature(test)]
#[macro_use] extern crate stream_cipher;
extern crate aesni;
bench_sync!(aesni::Aes128Ctr);

56
aesni-0.6.0/benches/aes192.rs

@ -0,0 +1,56 @@
#![no_std]
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#![feature(test)]
extern crate aesni;
extern crate test;
use aesni::Aes192;
use aesni::block_cipher_trait::BlockCipher;
#[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;
}

6
aesni-0.6.0/benches/aes192_ctr.rs

@ -0,0 +1,6 @@
#![cfg(feature = "ctr")]
#![feature(test)]
#[macro_use] extern crate stream_cipher;
extern crate aesni;
bench_sync!(aesni::Aes192Ctr);

56
aesni-0.6.0/benches/aes256.rs

@ -0,0 +1,56 @@
#![no_std]
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
#![feature(test)]
extern crate aesni;
extern crate test;
use aesni::Aes256;
use aesni::block_cipher_trait::BlockCipher;
#[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;
}

6
aesni-0.6.0/benches/aes256_ctr.rs

@ -0,0 +1,6 @@
#![cfg(feature = "ctr")]
#![feature(test)]
#[macro_use] extern crate stream_cipher;
extern crate aesni;
bench_sync!(aesni::Aes256Ctr);

50
aesni-0.6.0/src/aes128/expand.rs

@ -0,0 +1,50 @@
use arch::*;
use core::mem;
macro_rules! expand_round {
($enc_keys:expr, $dec_keys:expr, $pos:expr, $round:expr) => {
let mut t1 = _mm_load_si128($enc_keys.as_ptr().offset($pos - 1));
let mut t2;
let mut t3;
t2 = _mm_aeskeygenassist_si128(t1, $round);
t2 = _mm_shuffle_epi32(t2, 0xff);
t3 = _mm_slli_si128(t1, 0x4);
t1 = _mm_xor_si128(t1, t3);
t3 = _mm_slli_si128(t3, 0x4);
t1 = _mm_xor_si128(t1, t3);
t3 = _mm_slli_si128(t3, 0x4);
t1 = _mm_xor_si128(t1, t3);
t1 = _mm_xor_si128(t1, t2);
_mm_store_si128($enc_keys.as_mut_ptr().offset($pos), t1);
let t1 = if $pos != 10 { _mm_aesimc_si128(t1) } else { t1 };
_mm_store_si128($dec_keys.as_mut_ptr().offset($pos), t1);
}
}
#[inline(always)]
pub(super) fn expand(key: &[u8; 16]) -> ([__m128i; 11], [__m128i; 11]) {
unsafe {
let mut enc_keys: [__m128i; 11] = mem::uninitialized();
let mut dec_keys: [__m128i; 11] = mem::uninitialized();
let k = _mm_loadu_si128(key.as_ptr() as *const __m128i);
_mm_store_si128(enc_keys.as_mut_ptr(), k);
_mm_store_si128(dec_keys.as_mut_ptr(), k);
expand_round!(enc_keys, dec_keys, 1, 0x01);
expand_round!(enc_keys, dec_keys, 2, 0x02);
expand_round!(enc_keys, dec_keys, 3, 0x04);
expand_round!(enc_keys, dec_keys, 4, 0x08);
expand_round!(enc_keys, dec_keys, 5, 0x10);
expand_round!(enc_keys, dec_keys, 6, 0x20);
expand_round!(enc_keys, dec_keys, 7, 0x40);
expand_round!(enc_keys, dec_keys, 8, 0x80);
expand_round!(enc_keys, dec_keys, 9, 0x1B);
expand_round!(enc_keys, dec_keys, 10, 0x36);
(enc_keys, dec_keys)
}
}

132
aesni-0.6.0/src/aes128/mod.rs

@ -0,0 +1,132 @@
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::{U16, U8};
use block_cipher_trait::BlockCipher;
use arch::*;
use core::mem;
use utils::{Block128, Block128x8};
mod expand;
#[cfg(test)]
mod test_expand;
/// AES-128 block cipher
#[derive(Copy, Clone)]
pub struct Aes128 {
encrypt_keys: [__m128i; 11],
decrypt_keys: [__m128i; 11],
}
impl Aes128 {
#[inline(always)]
pub(crate) fn encrypt8(&self, mut blocks: [__m128i; 8]) -> [__m128i; 8] {
let keys = self.encrypt_keys;
unsafe {
xor8!(blocks, keys[0]);
aesenc8!(blocks, keys[1]);
aesenc8!(blocks, keys[2]);
aesenc8!(blocks, keys[3]);
aesenc8!(blocks, keys[4]);
aesenc8!(blocks, keys[5]);
aesenc8!(blocks, keys[6]);
aesenc8!(blocks, keys[7]);
aesenc8!(blocks, keys[8]);
aesenc8!(blocks, keys[9]);
aesenclast8!(blocks, keys[10]);
}
blocks
}
#[inline(always)]
pub(crate) fn encrypt(&self, mut block: __m128i) -> __m128i {
let keys = self.encrypt_keys;
unsafe {
block = _mm_xor_si128(block, keys[0]);
block = _mm_aesenc_si128(block, keys[1]);
block = _mm_aesenc_si128(block, keys[2]);
block = _mm_aesenc_si128(block, keys[3]);
block = _mm_aesenc_si128(block, keys[4]);
block = _mm_aesenc_si128(block, keys[5]);
block = _mm_aesenc_si128(block, keys[6]);
block = _mm_aesenc_si128(block, keys[7]);
block = _mm_aesenc_si128(block, keys[8]);
block = _mm_aesenc_si128(block, keys[9]);
_mm_aesenclast_si128(block, keys[10])
}
}
}
impl BlockCipher for Aes128 {
type KeySize = U16;
type BlockSize = U16;
type ParBlocks = U8;
#[inline]
fn new(key: &GenericArray<u8, U16>) -> Self {
let key = unsafe { mem::transmute(key) };
let (encrypt_keys, decrypt_keys) = expand::expand(key);
Self {
encrypt_keys,
decrypt_keys,
}
}
#[inline]
fn encrypt_block(&self, block: &mut Block128) {
unsafe {
let b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
let b = self.encrypt(b);
_mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
}
}
#[inline]
fn decrypt_block(&self, block: &mut Block128) {
let keys = self.decrypt_keys;
unsafe {
let mut b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
b = _mm_xor_si128(b, keys[10]);
b = _mm_aesdec_si128(b, keys[9]);
b = _mm_aesdec_si128(b, keys[8]);
b = _mm_aesdec_si128(b, keys[7]);
b = _mm_aesdec_si128(b, keys[6]);
b = _mm_aesdec_si128(b, keys[5]);
b = _mm_aesdec_si128(b, keys[4]);
b = _mm_aesdec_si128(b, keys[3]);
b = _mm_aesdec_si128(b, keys[2]);
b = _mm_aesdec_si128(b, keys[1]);
b = _mm_aesdeclast_si128(b, keys[0]);
_mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
}
}
#[inline]
fn encrypt_blocks(&self, blocks: &mut Block128x8) {
unsafe {
let b = self.encrypt8(load8!(blocks));
store8!(blocks, b);
}
}
#[inline]
fn decrypt_blocks(&self, blocks: &mut Block128x8) {
let keys = self.decrypt_keys;
unsafe {
let mut b = load8!(blocks);
xor8!(b, keys[10]);
aesdec8!(b, keys[9]);
aesdec8!(b, keys[8]);
aesdec8!(b, keys[7]);
aesdec8!(b, keys[6]);
aesdec8!(b, keys[5]);
aesdec8!(b, keys[4]);
aesdec8!(b, keys[3]);
aesdec8!(b, keys[2]);
aesdec8!(b, keys[1]);
aesdeclast8!(b, keys[0]);
store8!(blocks, b);
}
}
}
impl_opaque_debug!(Aes128);

104
aesni-0.6.0/src/aes128/test_expand.rs

@ -0,0 +1,104 @@
use super::expand::expand;
use utils::check;
#[test]
fn test() {
let enc_keys = expand(&[0x00; 16]).0;
check(
&enc_keys,
&[
[0x0000000000000000, 0x0000000000000000],
[0x6263636362636363, 0x6263636362636363],
[0x9b9898c9f9fbfbaa, 0x9b9898c9f9fbfbaa],
[0x90973450696ccffa, 0xf2f457330b0fac99],
[0xee06da7b876a1581, 0x759e42b27e91ee2b],
[0x7f2e2b88f8443e09, 0x8dda7cbbf34b9290],
[0xec614b851425758c, 0x99ff09376ab49ba7],
[0x217517873550620b, 0xacaf6b3cc61bf09b],
[0x0ef903333ba96138, 0x97060a04511dfa9f],
[0xb1d4d8e28a7db9da, 0x1d7bb3de4c664941],
[0xb4ef5bcb3e92e211, 0x23e951cf6f8f188e],
],
);
let enc_keys = expand(&[0xff; 16]).0;
check(
&enc_keys,
&[
[0xffffffffffffffff, 0xffffffffffffffff],
[0xe8e9e9e917161616, 0xe8e9e9e917161616],
[0xadaeae19bab8b80f, 0x525151e6454747f0],
[0x090e2277b3b69a78, 0xe1e7cb9ea4a08c6e],
[0xe16abd3e52dc2746, 0xb33becd8179b60b6],
[0xe5baf3ceb766d488, 0x045d385013c658e6],
[0x71d07db3c6b6a93b, 0xc2eb916bd12dc98d],
[0xe90d208d2fbb89b6, 0xed5018dd3c7dd150],
[0x96337366b988fad0, 0x54d8e20d68a5335d],
[0x8bf03f233278c5f3, 0x66a027fe0e0514a3],
[0xd60a3588e472f07b, 0x82d2d7858cd7c326],
],
);
let enc_keys = expand(&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
]).0;
check(
&enc_keys,
&[
[0x0001020304050607, 0x08090a0b0c0d0e0f],
[0xd6aa74fdd2af72fa, 0xdaa678f1d6ab76fe],
[0xb692cf0b643dbdf1, 0xbe9bc5006830b3fe],
[0xb6ff744ed2c2c9bf, 0x6c590cbf0469bf41],
[0x47f7f7bc95353e03, 0xf96c32bcfd058dfd],
[0x3caaa3e8a99f9deb, 0x50f3af57adf622aa],
[0x5e390f7df7a69296, 0xa7553dc10aa31f6b],
[0x14f9701ae35fe28c, 0x440adf4d4ea9c026],
[0x47438735a41c65b9, 0xe016baf4aebf7ad2],
[0x549932d1f0855768, 0x1093ed9cbe2c974e],
[0x13111d7fe3944a17, 0xf307a78b4d2b30c5],
],
);
let enc_keys = expand(&[
0x69, 0x20, 0xe2, 0x99, 0xa5, 0x20, 0x2a, 0x6d, 0x65, 0x6e, 0x63, 0x68,
0x69, 0x74, 0x6f, 0x2a,
]).0;
check(
&enc_keys,
&[
[0x6920e299a5202a6d, 0x656e636869746f2a],
[0xfa8807605fa82d0d, 0x3ac64e6553b2214f],
[0xcf75838d90ddae80, 0xaa1be0e5f9a9c1aa],
[0x180d2f1488d08194, 0x22cb6171db62a0db],
[0xbaed96ad323d1739, 0x10f67648cb94d693],
[0x881b4ab2ba265d8b, 0xaad02bc36144fd50],
[0xb34f195d096944d6, 0xa3b96f15c2fd9245],
[0xa7007778ae6933ae, 0x0dd05cbbcf2dcefe],
[0xff8bccf251e2ff5c, 0x5c32a3e7931f6d19],
[0x24b7182e7555e772, 0x29674495ba78298c],
[0xae127cdadb479ba8, 0xf220df3d4858f6b1],
],
);
let enc_keys = expand(&[
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88,
0x09, 0xcf, 0x4f, 0x3c,
]).0;
check(
&enc_keys,
&[
[0x2b7e151628aed2a6, 0xabf7158809cf4f3c],
[0xa0fafe1788542cb1, 0x23a339392a6c7605],
[0xf2c295f27a96b943, 0x5935807a7359f67f],
[0x3d80477d4716fe3e, 0x1e237e446d7a883b],
[0xef44a541a8525b7f, 0xb671253bdb0bad00],
[0xd4d1c6f87c839d87, 0xcaf2b8bc11f915bc],
[0x6d88a37a110b3efd, 0xdbf98641ca0093fd],
[0x4e54f70e5f5fc9f3, 0x84a64fb24ea6dc4f],
[0xead27321b58dbad2, 0x312bf5607f8d292f],
[0xac7766f319fadc21, 0x28d12941575c006e],
[0xd014f9a8c9ee2589, 0xe13f0cc8b6630ca6],
],
);
}

107
aesni-0.6.0/src/aes192/expand.rs

@ -0,0 +1,107 @@
use arch::*;
use core::{mem, ptr};
macro_rules! expand_round {
($t1:expr, $t3:expr, $round:expr) => {{
let mut t1 = $t1;
let mut t2;
let mut t3 = $t3;
let mut t4;
t2 = _mm_aeskeygenassist_si128(t3, $round);
t2 = _mm_shuffle_epi32(t2, 0x55);
t4 = _mm_slli_si128(t1, 0x4);
t1 = _mm_xor_si128(t1, t4);
t4 = _mm_slli_si128(t4, 0x4);
t1 = _mm_xor_si128(t1, t4);
t4 = _mm_slli_si128(t4, 0x4);
t1 = _mm_xor_si128(t1, t4);
t1 = _mm_xor_si128(t1, t2);
t2 = _mm_shuffle_epi32(t1, 0xff);
t4 = _mm_slli_si128(t3, 0x4);
t3 = _mm_xor_si128(t3, t4);
t3 = _mm_xor_si128(t3, t2);
(t1, t3)
}}
}
macro_rules! shuffle {
($a:expr, $b:expr, $imm:expr) => {
mem::transmute::<_, __m128i>(
_mm_shuffle_pd(mem::transmute($a), mem::transmute($b), $imm)
)
}
}
#[inline(always)]
pub(super) fn expand(key: &[u8; 24]) -> ([__m128i; 13], [__m128i; 13]) {
unsafe {
let mut enc_keys: [__m128i; 13] = mem::uninitialized();
let mut dec_keys: [__m128i; 13] = mem::uninitialized();
macro_rules! store {
($i:expr, $k:expr) => {
_mm_store_si128(enc_keys.as_mut_ptr().offset($i), $k);
_mm_store_si128(dec_keys.as_mut_ptr().offset($i),
_mm_aesimc_si128($k));
}
}
// we are being extra pedantic here to remove out-of-bound access.
// this should be optimized out into movups, movsd sequence
// note that unaligned load MUST be used here, even though we read
// from the array (compiler missoptimizes aligned load)
let (k0, k1l) = {
let mut t = [0u8; 32];
ptr::write(t.as_mut_ptr() as *mut [u8; 24], *key);
(
_mm_loadu_si128(t.as_ptr() as *const __m128i),
_mm_loadu_si128(t.as_ptr().offset(16) as *const __m128i),
)
};
_mm_store_si128(enc_keys.as_mut_ptr(), k0);
_mm_store_si128(dec_keys.as_mut_ptr(), k0);
let (k1_2, k2r) = expand_round!(k0, k1l, 0x01);
let k1 = shuffle!(k1l, k1_2, 0);
let k2 = shuffle!(k1_2, k2r, 1);
store!(1, k1);
store!(2, k2);
let (k3, k4l) = expand_round!(k1_2, k2r, 0x02);
store!(3, k3);
let (k4_5, k5r) = expand_round!(k3, k4l, 0x04);
let k4 = shuffle!(k4l, k4_5, 0);
let k5 = shuffle!(k4_5, k5r, 1);
store!(4, k4);
store!(5, k5);
let (k6, k7l) = expand_round!(k4_5, k5r, 0x08);
store!(6, k6);
let (k7_8, k8r) = expand_round!(k6, k7l, 0x10);
let k7 = shuffle!(k7l, k7_8, 0);
let k8 = shuffle!(k7_8, k8r, 1);
store!(7, k7);
store!(8, k8);
let (k9, k10l) = expand_round!(k7_8, k8r, 0x20);
store!(9, k9);
let (k10_11, k11r) = expand_round!(k9, k10l, 0x40);
let k10 = shuffle!(k10l, k10_11, 0);
let k11 = shuffle!(k10_11, k11r, 1);
store!(10, k10);
store!(11, k11);
let (k12, _) = expand_round!(k10_11, k11r, 0x80);
_mm_store_si128(enc_keys.as_mut_ptr().offset(12), k12);
_mm_store_si128(dec_keys.as_mut_ptr().offset(12), k12);
(enc_keys, dec_keys)
}
}

140
aesni-0.6.0/src/aes192/mod.rs

@ -0,0 +1,140 @@
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::{U16, U24, U8};
use block_cipher_trait::BlockCipher;
use arch::*;
use core::mem;
use utils::{Block128, Block128x8};
mod expand;
#[cfg(test)]
mod test_expand;
/// AES-192 block cipher
#[derive(Copy, Clone)]
pub struct Aes192 {
encrypt_keys: [__m128i; 13],
decrypt_keys: [__m128i; 13],
}
impl Aes192 {
#[inline(always)]
pub(crate) fn encrypt8(&self, mut blocks: [__m128i; 8]) -> [__m128i; 8] {
let keys = self.encrypt_keys;
unsafe {
xor8!(blocks, keys[0]);
aesenc8!(blocks, keys[1]);
aesenc8!(blocks, keys[2]);
aesenc8!(blocks, keys[3]);
aesenc8!(blocks, keys[4]);
aesenc8!(blocks, keys[5]);
aesenc8!(blocks, keys[6]);
aesenc8!(blocks, keys[7]);
aesenc8!(blocks, keys[8]);
aesenc8!(blocks, keys[9]);
aesenc8!(blocks, keys[10]);
aesenc8!(blocks, keys[11]);
aesenclast8!(blocks, keys[12]);
}
blocks
}
#[inline(always)]
pub(crate) fn encrypt(&self, mut block: __m128i) -> __m128i {
let keys = self.encrypt_keys;
unsafe {
block = _mm_xor_si128(block, keys[0]);
block = _mm_aesenc_si128(block, keys[1]);
block = _mm_aesenc_si128(block, keys[2]);
block = _mm_aesenc_si128(block, keys[3]);
block = _mm_aesenc_si128(block, keys[4]);
block = _mm_aesenc_si128(block, keys[5]);
block = _mm_aesenc_si128(block, keys[6]);
block = _mm_aesenc_si128(block, keys[7]);
block = _mm_aesenc_si128(block, keys[8]);
block = _mm_aesenc_si128(block, keys[9]);
block = _mm_aesenc_si128(block, keys[10]);
block = _mm_aesenc_si128(block, keys[11]);
_mm_aesenclast_si128(block, keys[12])
}
}
}
impl BlockCipher for Aes192 {
type KeySize = U24;
type BlockSize = U16;
type ParBlocks = U8;
#[inline]
fn new(key: &GenericArray<u8, U24>) -> Self {
let key = unsafe { mem::transmute(key) };
let (encrypt_keys, decrypt_keys) = expand::expand(key);
Self {
encrypt_keys,
decrypt_keys,
}
}
#[inline]
fn encrypt_block(&self, block: &mut Block128) {
unsafe {
let b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
let b = self.encrypt(b);
_mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
}
}
#[inline]
fn decrypt_block(&self, block: &mut Block128) {
let keys = self.decrypt_keys;
unsafe {
let mut b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
b = _mm_xor_si128(b, keys[12]);
b = _mm_aesdec_si128(b, keys[11]);
b = _mm_aesdec_si128(b, keys[10]);
b = _mm_aesdec_si128(b, keys[9]);
b = _mm_aesdec_si128(b, keys[8]);
b = _mm_aesdec_si128(b, keys[7]);
b = _mm_aesdec_si128(b, keys[6]);
b = _mm_aesdec_si128(b, keys[5]);
b = _mm_aesdec_si128(b, keys[4]);
b = _mm_aesdec_si128(b, keys[3]);
b = _mm_aesdec_si128(b, keys[2]);
b = _mm_aesdec_si128(b, keys[1]);
b = _mm_aesdeclast_si128(b, keys[0]);
_mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
}
}
#[inline]
fn encrypt_blocks(&self, blocks: &mut Block128x8) {
unsafe {
let b = self.encrypt8(load8!(blocks));
store8!(blocks, b);
}
}
#[inline]
fn decrypt_blocks(&self, blocks: &mut Block128x8) {
let keys = self.decrypt_keys;
unsafe {
let mut b = load8!(blocks);
xor8!(b, keys[12]);
aesdec8!(b, keys[11]);
aesdec8!(b, keys[10]);
aesdec8!(b, keys[9]);
aesdec8!(b, keys[8]);
aesdec8!(b, keys[7]);
aesdec8!(b, keys[6]);
aesdec8!(b, keys[5]);
aesdec8!(b, keys[4]);
aesdec8!(b, keys[3]);
aesdec8!(b, keys[2]);
aesdec8!(b, keys[1]);
aesdeclast8!(b, keys[0]);
store8!(blocks, b);
}
}
}
impl_opaque_debug!(Aes192);

91
aesni-0.6.0/src/aes192/test_expand.rs

@ -0,0 +1,91 @@
use super::expand::expand;
use utils::check;
#[test]
fn test() {
let enc_keys = expand(&[0x00; 24]).0;
check(
&enc_keys,
&[
[0x0000000000000000, 0x0000000000000000],
[0x0000000000000000, 0x6263636362636363],
[0x6263636362636363, 0x6263636362636363],
[0x9b9898c9f9fbfbaa, 0x9b9898c9f9fbfbaa],
[0x9b9898c9f9fbfbaa, 0x90973450696ccffa],
[0xf2f457330b0fac99, 0x90973450696ccffa],
[0xc81d19a9a171d653, 0x53858160588a2df9],
[0xc81d19a9a171d653, 0x7bebf49bda9a22c8],
[0x891fa3a8d1958e51, 0x198897f8b8f941ab],
[0xc26896f718f2b43f, 0x91ed1797407899c6],
[0x59f00e3ee1094f95, 0x83ecbc0f9b1e0830],
[0x0af31fa74a8b8661, 0x137b885ff272c7ca],
[0x432ac886d834c0b6, 0xd2c7df11984c5970],
],
);
let enc_keys = expand(&[0xff; 24]).0;
check(
&enc_keys,
&[
[0xffffffffffffffff, 0xffffffffffffffff],
[0xffffffffffffffff, 0xe8e9e9e917161616],
[0xe8e9e9e917161616, 0xe8e9e9e917161616],
[0xadaeae19bab8b80f, 0x525151e6454747f0],
[0xadaeae19bab8b80f, 0xc5c2d8ed7f7a60e2],
[0x2d2b3104686c76f4, 0xc5c2d8ed7f7a60e2],
[0x1712403f686820dd, 0x454311d92d2f672d],
[0xe8edbfc09797df22, 0x8f8cd3b7e7e4f36a],
[0xa2a7e2b38f88859e, 0x67653a5ef0f2e57c],
[0x2655c33bc1b13051, 0x6316d2e2ec9e577c],
[0x8bfb6d227b09885e, 0x67919b1aa620ab4b],
[0xc53679a929a82ed5, 0xa25343f7d95acba9],
[0x598e482fffaee364, 0x3a989acd1330b418],
],
);
let enc_keys = expand(&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
]).0;
check(
&enc_keys,
&[
[0x0001020304050607, 0x08090a0b0c0d0e0f],
[0x1011121314151617, 0x5846f2f95c43f4fe],
[0x544afef55847f0fa, 0x4856e2e95c43f4fe],
[0x40f949b31cbabd4d, 0x48f043b810b7b342],
[0x58e151ab04a2a555, 0x7effb5416245080c],
[0x2ab54bb43a02f8f6, 0x62e3a95d66410c08],
[0xf501857297448d7e, 0xbdf1c6ca87f33e3c],
[0xe510976183519b69, 0x34157c9ea351f1e0],
[0x1ea0372a99530916, 0x7c439e77ff12051e],
[0xdd7e0e887e2fff68, 0x608fc842f9dcc154],
[0x859f5f237a8d5a3d, 0xc0c02952beefd63a],
[0xde601e7827bcdf2c, 0xa223800fd8aeda32],
[0xa4970a331a78dc09, 0xc418c271e3a41d5d],
],
);
let enc_keys = expand(&[
0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b,
0x80, 0x90, 0x79, 0xe5, 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
]).0;
check(
&enc_keys,
&[
[0x8e73b0f7da0e6452, 0xc810f32b809079e5],
[0x62f8ead2522c6b7b, 0xfe0c91f72402f5a5],
[0xec12068e6c827f6b, 0x0e7a95b95c56fec2],
[0x4db7b4bd69b54118, 0x85a74796e92538fd],
[0xe75fad44bb095386, 0x485af05721efb14f],
[0xa448f6d94d6dce24, 0xaa326360113b30e6],
[0xa25e7ed583b1cf9a, 0x27f939436a94f767],
[0xc0a69407d19da4e1, 0xec1786eb6fa64971],
[0x485f703222cb8755, 0xe26d135233f0b7b3],
[0x40beeb282f18a259, 0x6747d26b458c553e],
[0xa7e1466c9411f1df, 0x821f750aad07d753],
[0xca4005388fcc5006, 0x282d166abc3ce7b5],
[0xe98ba06f448c773c, 0x8ecc720401002202],
],
);
}

88
aesni-0.6.0/src/aes256/expand.rs

@ -0,0 +1,88 @@
use arch::*;
use core::mem;
macro_rules! expand_round {
($enc_keys:expr, $dec_keys:expr, $pos:expr, $round:expr) => {
let mut t1 = _mm_load_si128($enc_keys.as_ptr().offset($pos - 2));;
let mut t2;
let mut t3 = _mm_load_si128($enc_keys.as_ptr().offset($pos - 1));;
let mut t4;
t2 = _mm_aeskeygenassist_si128(t3, $round);
t2 = _mm_shuffle_epi32(t2, 0xff);
t4 = _mm_slli_si128(t1, 0x4);
t1 = _mm_xor_si128(t1, t4);
t4 = _mm_slli_si128(t4, 0x4);
t1 = _mm_xor_si128(t1, t4);
t4 = _mm_slli_si128(t4, 0x4);
t1 = _mm_xor_si128(t1, t4);
t1 = _mm_xor_si128(t1, t2);
_mm_store_si128($enc_keys.as_mut_ptr().offset($pos), t1);
let t = _mm_aesimc_si128(t1);
_mm_store_si128($dec_keys.as_mut_ptr().offset($pos), t);
t4 = _mm_aeskeygenassist_si128(t1, 0x00);
t2 = _mm_shuffle_epi32(t4, 0xaa);
t4 = _mm_slli_si128(t3, 0x4);
t3 = _mm_xor_si128(t3, t4);
t4 = _mm_slli_si128(t4, 0x4);
t3 = _mm_xor_si128(t3, t4);
t4 = _mm_slli_si128(t4, 0x4);
t3 = _mm_xor_si128(t3, t4);
t3 = _mm_xor_si128(t3, t2);
_mm_store_si128($enc_keys.as_mut_ptr().offset($pos + 1), t3);
let t = _mm_aesimc_si128(t3);
_mm_store_si128($dec_keys.as_mut_ptr().offset($pos + 1), t);
}
}
macro_rules! expand_round_last {
($enc_keys:expr, $dec_keys:expr, $pos:expr, $round:expr) => {
let mut t1 = _mm_load_si128($enc_keys.as_ptr().offset($pos - 2));;
let mut t2;
let t3 = _mm_load_si128($enc_keys.as_ptr().offset($pos - 1));;
let mut t4;
t2 = _mm_aeskeygenassist_si128(t3, $round);
t2 = _mm_shuffle_epi32(t2, 0xff);
t4 = _mm_slli_si128(t1, 0x4);
t1 = _mm_xor_si128(t1, t4);
t4 = _mm_slli_si128(t4, 0x4);
t1 = _mm_xor_si128(t1, t4);
t4 = _mm_slli_si128(t4, 0x4);
t1 = _mm_xor_si128(t1, t4);
t1 = _mm_xor_si128(t1, t2);
_mm_store_si128($enc_keys.as_mut_ptr().offset($pos), t1);
_mm_store_si128($dec_keys.as_mut_ptr().offset($pos), t1);
}
}
#[inline(always)]
pub(super) fn expand(key: &[u8; 32]) -> ([__m128i; 15], [__m128i; 15]) {
unsafe {
let mut enc_keys: [__m128i; 15] = mem::uninitialized();
let mut dec_keys: [__m128i; 15] = mem::uninitialized();
let kp = key.as_ptr() as *const __m128i;
let k1 = _mm_loadu_si128(kp);
let k2 = _mm_loadu_si128(kp.offset(1));
_mm_store_si128(enc_keys.as_mut_ptr(), k1);
_mm_store_si128(dec_keys.as_mut_ptr(), k1);
_mm_store_si128(enc_keys.as_mut_ptr().offset(1), k2);
_mm_store_si128(dec_keys.as_mut_ptr().offset(1), _mm_aesimc_si128(k2));
expand_round!(enc_keys, dec_keys, 2, 0x01);
expand_round!(enc_keys, dec_keys, 4, 0x02);
expand_round!(enc_keys, dec_keys, 6, 0x04);
expand_round!(enc_keys, dec_keys, 8, 0x08);
expand_round!(enc_keys, dec_keys, 10, 0x10);
expand_round!(enc_keys, dec_keys, 12, 0x20);
expand_round_last!(enc_keys, dec_keys, 14, 0x40);
(enc_keys, dec_keys)
}
}

148
aesni-0.6.0/src/aes256/mod.rs

@ -0,0 +1,148 @@
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::{U16, U32, U8};
use block_cipher_trait::BlockCipher;
use arch::*;
use core::mem;
use utils::{Block128, Block128x8};
mod expand;
#[cfg(test)]
mod test_expand;
/// AES-256 block cipher
#[derive(Copy, Clone)]
pub struct Aes256 {
encrypt_keys: [__m128i; 15],
decrypt_keys: [__m128i; 15],
}
impl Aes256 {
#[inline(always)]
pub(crate) fn encrypt8(&self, mut blocks: [__m128i; 8]) -> [__m128i; 8] {
let keys = self.encrypt_keys;
unsafe {
xor8!(blocks, keys[0]);
aesenc8!(blocks, keys[1]);
aesenc8!(blocks, keys[2]);
aesenc8!(blocks, keys[3]);
aesenc8!(blocks, keys[4]);
aesenc8!(blocks, keys[5]);
aesenc8!(blocks, keys[6]);
aesenc8!(blocks, keys[7]);
aesenc8!(blocks, keys[8]);
aesenc8!(blocks, keys[9]);
aesenc8!(blocks, keys[10]);
aesenc8!(blocks, keys[11]);
aesenc8!(blocks, keys[12]);
aesenc8!(blocks, keys[13]);
aesenclast8!(blocks, keys[14]);
}
blocks
}
#[inline(always)]
pub(crate) fn encrypt(&self, mut block: __m128i) -> __m128i {
let keys = self.encrypt_keys;
unsafe {
block = _mm_xor_si128(block, keys[0]);
block = _mm_aesenc_si128(block, keys[1]);
block = _mm_aesenc_si128(block, keys[2]);
block = _mm_aesenc_si128(block, keys[3]);
block = _mm_aesenc_si128(block, keys[4]);
block = _mm_aesenc_si128(block, keys[5]);
block = _mm_aesenc_si128(block, keys[6]);
block = _mm_aesenc_si128(block, keys[7]);
block = _mm_aesenc_si128(block, keys[8]);
block = _mm_aesenc_si128(block, keys[9]);
block = _mm_aesenc_si128(block, keys[10]);
block = _mm_aesenc_si128(block, keys[11]);
block = _mm_aesenc_si128(block, keys[12]);
block = _mm_aesenc_si128(block, keys[13]);
_mm_aesenclast_si128(block, keys[14])
}
}
}
impl BlockCipher for Aes256 {
type KeySize = U32;
type BlockSize = U16;
type ParBlocks = U8;
#[inline]
fn new(key: &GenericArray<u8, U32>) -> Self {
let key = unsafe { mem::transmute(key) };
let (encrypt_keys, decrypt_keys) = expand::expand(key);
Self {
encrypt_keys,
decrypt_keys,
}
}
#[inline]
fn encrypt_block(&self, block: &mut Block128) {
unsafe {
let b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
let b = self.encrypt(b);
_mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
}
}
#[inline]
fn decrypt_block(&self, block: &mut Block128) {
let keys = self.decrypt_keys;
unsafe {
let mut b = _mm_loadu_si128(block.as_ptr() as *const __m128i);
b = _mm_xor_si128(b, keys[14]);
b = _mm_aesdec_si128(b, keys[13]);
b = _mm_aesdec_si128(b, keys[12]);
b = _mm_aesdec_si128(b, keys[11]);
b = _mm_aesdec_si128(b, keys[10]);
b = _mm_aesdec_si128(b, keys[9]);
b = _mm_aesdec_si128(b, keys[8]);
b = _mm_aesdec_si128(b, keys[7]);
b = _mm_aesdec_si128(b, keys[6]);
b = _mm_aesdec_si128(b, keys[5]);
b = _mm_aesdec_si128(b, keys[4]);
b = _mm_aesdec_si128(b, keys[3]);
b = _mm_aesdec_si128(b, keys[2]);
b = _mm_aesdec_si128(b, keys[1]);
b = _mm_aesdeclast_si128(b, keys[0]);
_mm_storeu_si128(block.as_mut_ptr() as *mut __m128i, b);
}
}
#[inline]
fn encrypt_blocks(&self, blocks: &mut Block128x8) {
unsafe {
let b = self.encrypt8(load8!(blocks));
store8!(blocks, b);
}
}
#[inline]
fn decrypt_blocks(&self, blocks: &mut Block128x8) {
let keys = self.decrypt_keys;
unsafe {
let mut b = load8!(blocks);
xor8!(b, keys[14]);
aesdec8!(b, keys[13]);
aesdec8!(b, keys[12]);
aesdec8!(b, keys[11]);
aesdec8!(b, keys[10]);
aesdec8!(b, keys[9]);
aesdec8!(b, keys[8]);
aesdec8!(b, keys[7]);
aesdec8!(b, keys[6]);
aesdec8!(b, keys[5]);
aesdec8!(b, keys[4]);
aesdec8!(b, keys[3]);
aesdec8!(b, keys[2]);
aesdec8!(b, keys[1]);
aesdeclast8!(b, keys[0]);
store8!(blocks, b);
}
}
}
impl_opaque_debug!(Aes256);

101
aesni-0.6.0/src/aes256/test_expand.rs

@ -0,0 +1,101 @@
use super::expand::expand;
use utils::check;
#[test]
fn test() {
let enc_keys = expand(&[0x00; 32]).0;
check(
&enc_keys,
&[
[0x0000000000000000, 0x0000000000000000],
[0x0000000000000000, 0x0000000000000000],
[0x6263636362636363, 0x6263636362636363],
[0xaafbfbfbaafbfbfb, 0xaafbfbfbaafbfbfb],
[0x6f6c6ccf0d0f0fac, 0x6f6c6ccf0d0f0fac],
[0x7d8d8d6ad7767691, 0x7d8d8d6ad7767691],
[0x5354edc15e5be26d, 0x31378ea23c38810e],
[0x968a81c141fcf750, 0x3c717a3aeb070cab],
[0x9eaa8f28c0f16d45, 0xf1c6e3e7cdfe62e9],
[0x2b312bdf6acddc8f, 0x56bca6b5bdbbaa1e],
[0x6406fd52a4f79017, 0x553173f098cf1119],
[0x6dbba90b07767584, 0x51cad331ec71792f],
[0xe7b0e89c4347788b, 0x16760b7b8eb91a62],
[0x74ed0ba1739b7e25, 0x2251ad14ce20d43b],
[0x10f80a1753bf729c, 0x45c979e7cb706385],
],
);
let enc_keys = expand(&[0xff; 32]).0;
check(
&enc_keys,
&[
[0xffffffffffffffff, 0xffffffffffffffff],
[0xffffffffffffffff, 0xffffffffffffffff],
[0xe8e9e9e917161616, 0xe8e9e9e917161616],
[0x0fb8b8b8f0474747, 0x0fb8b8b8f0474747],
[0x4a4949655d5f5f73, 0xb5b6b69aa2a0a08c],
[0x355858dcc51f1f9b, 0xcaa7a7233ae0e064],
[0xafa80ae5f2f75596, 0x4741e30ce5e14380],
[0xeca0421129bf5d8a, 0xe318faa9d9f81acd],
[0xe60ab7d014fde246, 0x53bc014ab65d42ca],
[0xa2ec6e658b5333ef, 0x684bc946b1b3d38b],
[0x9b6c8a188f91685e, 0xdc2d69146a702bde],
[0xa0bd9f782beeac97, 0x43a565d1f216b65a],
[0xfc22349173b35ccf, 0xaf9e35dbc5ee1e05],
[0x0695ed132d7b4184, 0x6ede24559cc8920f],
[0x546d424f27de1e80, 0x88402b5b4dae355e],
],
);
let enc_keys = expand(&[
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
]).0;
check(
&enc_keys,
&[
[0x0001020304050607, 0x08090a0b0c0d0e0f],
[0x1011121314151617, 0x18191a1b1c1d1e1f],
[0xa573c29fa176c498, 0xa97fce93a572c09c],
[0x1651a8cd0244beda, 0x1a5da4c10640bade],
[0xae87dff00ff11b68, 0xa68ed5fb03fc1567],
[0x6de1f1486fa54f92, 0x75f8eb5373b8518d],
[0xc656827fc9a79917, 0x6f294cec6cd5598b],
[0x3de23a75524775e7, 0x27bf9eb45407cf39],
[0x0bdc905fc27b0948, 0xad5245a4c1871c2f],
[0x45f5a66017b2d387, 0x300d4d33640a820a],
[0x7ccff71cbeb4fe54, 0x13e6bbf0d261a7df],
[0xf01afafee7a82979, 0xd7a5644ab3afe640],
[0x2541fe719bf50025, 0x8813bbd55a721c0a],
[0x4e5a6699a9f24fe0, 0x7e572baacdf8cdea],
[0x24fc79ccbf0979e9, 0x371ac23c6d68de36],
],
);
let enc_keys = expand(&[
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0,
0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
]).0;
check(
&enc_keys,
&[
[0x603deb1015ca71be, 0x2b73aef0857d7781],
[0x1f352c073b6108d7, 0x2d9810a30914dff4],
[0x9ba354118e6925af, 0xa51a8b5f2067fcde],
[0xa8b09c1a93d194cd, 0xbe49846eb75d5b9a],
[0xd59aecb85bf3c917, 0xfee94248de8ebe96],
[0xb5a9328a2678a647, 0x983122292f6c79b3],
[0x812c81addadf48ba, 0x24360af2fab8b464],
[0x98c5bfc9bebd198e, 0x268c3ba709e04214],
[0x68007bacb2df3316, 0x96e939e46c518d80],
[0xc814e20476a9fb8a, 0x5025c02d59c58239],
[0xde1369676ccc5a71, 0xfa2563959674ee15],
[0x5886ca5d2e2f31d7, 0x7e0af1fa27cf73c3],
[0x749c47ab18501dda, 0xe2757e4f7401905a],
[0xcafaaae3e4d59b34, 0x9adf6acebd10190d],
[0xfe4890d1e6188d0b, 0x046df344706c631e],
],
);
}

240
aesni-0.6.0/src/ctr.rs

@ -0,0 +1,240 @@
use core::{mem, cmp};
use arch::*;
use super::{Aes128, Aes192, Aes256};
use block_cipher_trait::BlockCipher;
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::U16;
use stream_cipher::{
SyncStreamCipher, SyncStreamCipherSeek, NewStreamCipher, LoopError,
};
const BLOCK_SIZE: usize = 16;
const PAR_BLOCKS: usize = 8;
const PAR_BLOCKS_SIZE: usize = PAR_BLOCKS*BLOCK_SIZE;
#[inline(always)]
pub fn xor(buf: &mut [u8], key: &[u8]) {
debug_assert_eq!(buf.len(), key.len());
for (a, b) in buf.iter_mut().zip(key) {
*a ^= *b;
}
}
#[inline(always)]
fn xor_block8(buf: &mut [u8], ctr: [__m128i; 8]) {
debug_assert_eq!(buf.len(), PAR_BLOCKS_SIZE);
unsafe {
// compiler should unroll this loop
for i in 0..8 {
let ptr = buf.as_mut_ptr().offset(16*i) as *mut __m128i;
let data = _mm_loadu_si128(ptr);
let data = _mm_xor_si128(data, ctr[i as usize]);
_mm_storeu_si128(ptr, data);
}
}
}
#[inline(always)]
fn swap_bytes(v: __m128i) -> __m128i {
unsafe {
let mask = _mm_set_epi64x(0x08090a0b0c0d0e0f, 0x0001020304050607);
_mm_shuffle_epi8(v, mask)
}
}
#[inline(always)]
fn inc_be(v: __m128i) -> __m128i {
unsafe { _mm_add_epi64(v, _mm_set_epi64x(1, 0)) }
}
#[inline(always)]
fn load(val: &GenericArray<u8, U16>) -> __m128i {
unsafe { _mm_loadu_si128(val.as_ptr() as *const __m128i) }
}
macro_rules! impl_ctr {
($name:ident, $cipher:ty, $doc:expr) => {
#[doc=$doc]
#[derive(Clone)]
pub struct $name {
nonce: __m128i,
ctr: __m128i,
cipher: $cipher,
// if `leftover_pos` is `None` it means that leftover_buf is not
// filled with data and current position of the stream cipher
// can be calculated as counter*BLOCK_SIZE. If it's equal to
// `Some(pos)`, then buffer is filled with leftover keystream data
// and current position of the cipher equals to:
// `(counter - 1)*BLOCK_SIZE + pos`
// In other words counter is set for the next block calculation
leftover_buf: [u8; BLOCK_SIZE],
leftover_pos: Option<u8>,
}
impl $name {
#[inline(always)]
fn next_block(&mut self) -> __m128i {
let block = swap_bytes(self.ctr);
self.ctr = inc_be(self.ctr);
self.cipher.encrypt(block)
}
#[inline(always)]
fn next_block8(&mut self) -> [__m128i; 8] {
let mut ctr = self.ctr;
let mut block8: [__m128i; 8] = unsafe { mem::uninitialized() };
for i in 0..8 {
block8[i] = swap_bytes(ctr);
ctr = inc_be(ctr);
}
self.ctr = ctr;
self.cipher.encrypt8(block8)
}
#[inline(always)]
fn get_u64_ctr(&self) -> u64 {
let (ctr, nonce) = unsafe {(
mem::transmute::<__m128i, [u64; 2]>(self.ctr)[0],
mem::transmute::<__m128i, [u64; 2]>(self.nonce)[0],
)};
ctr.wrapping_sub(nonce)
}
/// Check if provided data will not overflow counter
#[inline(always)]
fn check_data_len(&self, data: &[u8]) -> Result<(), LoopError> {
let dlen = data.len() - match self.leftover_pos {
Some(pos) => cmp::min(BLOCK_SIZE - pos as usize, data.len()),
None => 0,
};
let data_blocks = dlen/BLOCK_SIZE +
if data.len() % BLOCK_SIZE != 0 { 1 } else { 0 };
let counter = self.get_u64_ctr();
if counter.checked_add(data_blocks as u64).is_some() {
Ok(())
} else {
Err(LoopError)
}
}
}
impl NewStreamCipher for $name {
type KeySize = <$cipher as BlockCipher>::KeySize;
type NonceSize = U16;
fn new(
key: &GenericArray<u8, Self::KeySize>,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self {
let nonce = swap_bytes(load(nonce));
let cipher = <$cipher>::new(key);
Self {
nonce,
ctr: nonce,
cipher,
leftover_pos: None,
leftover_buf: [0u8; BLOCK_SIZE],
}
}
}
impl SyncStreamCipher for $name {
#[inline]
fn try_apply_keystream(&mut self, mut data: &mut [u8])
-> Result<(), LoopError>
{
self.check_data_len(data)?;
// process leftover bytes from the last call if any
if let Some(pos) = self.leftover_pos {
let pos = pos as usize;
// check if input buffer is large enough to be xor'ed
// with all leftover bytes
if data.len() >= BLOCK_SIZE - pos {
let buf = &self.leftover_buf[pos..];
let (r, l) = {data}.split_at_mut(buf.len());
data = l;
xor(r, buf);
self.leftover_pos = None;
} else {
let buf = &self.leftover_buf[pos..pos + data.len()];
xor(data, buf);
self.leftover_pos = Some((pos + data.len()) as u8);
return Ok(());
}
}
// process 8 blocks at a time
while data.len() >= PAR_BLOCKS_SIZE {
let (r, l) = {data}.split_at_mut(PAR_BLOCKS_SIZE);
data = l;
xor_block8(r, self.next_block8());
}
// process one block at a time
while data.len() >= BLOCK_SIZE {
let (r, l) = {data}.split_at_mut(BLOCK_SIZE);
data = l;
let block = self.next_block();
unsafe {
let t = _mm_loadu_si128(r.as_ptr() as *const __m128i);
let res = _mm_xor_si128(block, t);
_mm_storeu_si128(r.as_mut_ptr() as *mut __m128i, res);
}
}
// process leftover bytes
if data.len() != 0 {
let block = self.next_block();
self.leftover_buf = unsafe {
mem::transmute::<__m128i, [u8; BLOCK_SIZE]>(block)
};
let n = data.len();
self.leftover_pos = Some(n as u8);
for (a, b) in data.iter_mut().zip(&self.leftover_buf[..n]) {
*a ^= *b;
}
}
Ok(())
}
}
impl SyncStreamCipherSeek for $name {
fn current_pos(&self) -> u64 {
let bs = BLOCK_SIZE as u64;
let ctr = self.get_u64_ctr();
match self.leftover_pos {
Some(pos) => ctr.wrapping_sub(1)*bs + pos as u64,
None => ctr*bs,
}
}
fn seek(&mut self, pos: u64) {
let n = pos / BLOCK_SIZE as u64;
let l = pos % BLOCK_SIZE as u64;
self.ctr = unsafe {
_mm_add_epi64(self.nonce, _mm_set_epi64x(n as i64, 0))
};
if l == 0 {
self.leftover_pos = None;
} else {
self.leftover_buf = unsafe {
mem::transmute(self.next_block())
};
self.leftover_pos = Some(l as u8);
}
}
}
impl_opaque_debug!($name);
}
}
impl_ctr!(Aes128Ctr, Aes128, "AES-128 in CTR mode");
impl_ctr!(Aes192Ctr, Aes192, "AES-192 in CTR mode");
impl_ctr!(Aes256Ctr, Aes256, "AES-256 in CTR mode");

98
aesni-0.6.0/src/lib.rs

@ -0,0 +1,98 @@
//! AES block ciphers implementation using AES-NI instruction set.
//!
//! This crate does not implement any software fallback and does not
//! automatically check CPUID, so if you are using this crate make sure to run
//! software on an appropriate hardware or to use software fallback
//! (e.g. from [`aes-soft`](https://crates.io/crates/aes-soft) crate) with
//! runtime detection of AES-NI availability (e.g. by using
//! [`cupid`](https://crates.io/crates/cupid) crate).
//!
//! When using this crate do not forget to enable `aes` target feature,
//! otherwise you will get a compilation error. You can do it either by using
//! `RUSTFLAGS="-C target-feature=+aes"` or by editing your `.cargo/config`.
//!
//! Ciphers functionality is accessed using `BlockCipher` trait from
//! [`block-cipher-trait`](https://docs.rs/block-cipher-trait) crate.
//!
//! # CTR mode
//! In addition to core block cipher functionality this crate provides optimized
//! CTR mode implementation. This functionality requires additionall `ssse3`
//! target feature and feature-gated behind `ctr` feature flag, which is enabled
//! by default. If you only need block ciphers, disable default features with
//! `default-features = false` in your `Cargro.toml`.
//!
//! AES-CTR functionality is accessed using traits from
//! [`stream-cipher`](https://docs.rs/stream-cipher) crate.
//!
//! # Vulnerability
//! Lazy FP state restory vulnerability can allow local process to leak content
//! of the FPU register, in which round keys are stored. This vulnerability
//! can be mitigated at the operating system level by installing relevant
//! patches. (i.e. keep your OS updated!) More info:
//! - [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::block_cipher_trait::generic_array::GenericArray;
//! use aesni::block_cipher_trait::BlockCipher;
//! 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`
//! 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)
#![no_std]
pub extern crate block_cipher_trait;
#[macro_use] extern crate opaque_debug;
#[cfg(feature = "ctr")]
pub extern crate stream_cipher;
#[cfg(not(feature = "nocheck"))]
mod target_checks;
#[macro_use]
mod utils;
mod aes128;
mod aes192;
mod aes256;
#[cfg(feature = "ctr")]
mod ctr;
#[cfg(target_arch = "x86_64")]
use core::arch::x86_64 as arch;
#[cfg(target_arch = "x86")]
use core::arch::x86 as arch;
pub use aes128::Aes128;
pub use aes192::Aes192;
pub use aes256::Aes256;
#[cfg(feature = "ctr")]
pub use ctr::{Aes128Ctr, Aes192Ctr, Aes256Ctr};

23
aesni-0.6.0/src/target_checks.rs

@ -0,0 +1,23 @@
//! 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\" enviromental 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\" enviromental variable. \
For x86 target arch additionally enable sse2 target feature."
);

112
aesni-0.6.0/src/utils.rs

@ -0,0 +1,112 @@
#[cfg(test)]
use core::mem;
#[cfg(test)]
use arch::__m128i;
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::{U16, U8};
pub type Block128 = GenericArray<u8, U16>;
pub type Block128x8 = GenericArray<GenericArray<u8, U16>, U8>;
#[cfg(test)]
pub(crate) fn check(a: &[__m128i], b: &[[u64; 2]]) {
for (v1, v2) in a.iter().zip(b) {
let t1: [u64; 2] = unsafe { mem::transmute(*v1) };
let t2 = [v2[0].to_be(), v2[1].to_be()];
assert_eq!(t1, t2);
}
}
macro_rules! load8 {
($blocks:expr) => {
[
_mm_loadu_si128($blocks[0].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[1].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[2].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[3].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[4].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[5].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[6].as_ptr() as *const __m128i),
_mm_loadu_si128($blocks[7].as_ptr() as *const __m128i),
]
}
}
macro_rules! store8 {
($blocks:expr, $b:expr) => {
_mm_storeu_si128($blocks[0].as_mut_ptr() as *mut __m128i, $b[0]);
_mm_storeu_si128($blocks[1].as_mut_ptr() as *mut __m128i, $b[1]);
_mm_storeu_si128($blocks[2].as_mut_ptr() as *mut __m128i, $b[2]);
_mm_storeu_si128($blocks[3].as_mut_ptr() as *mut __m128i, $b[3]);
_mm_storeu_si128($blocks[4].as_mut_ptr() as *mut __m128i, $b[4]);
_mm_storeu_si128($blocks[5].as_mut_ptr() as *mut __m128i, $b[5]);
_mm_storeu_si128($blocks[6].as_mut_ptr() as *mut __m128i, $b[6]);
_mm_storeu_si128($blocks[7].as_mut_ptr() as *mut __m128i, $b[7]);
}
}
macro_rules! xor8 {
($b:expr, $key:expr) => {
$b[0] = _mm_xor_si128($b[0], $key);
$b[1] = _mm_xor_si128($b[1], $key);
$b[2] = _mm_xor_si128($b[2], $key);
$b[3] = _mm_xor_si128($b[3], $key);
$b[4] = _mm_xor_si128($b[4], $key);
$b[5] = _mm_xor_si128($b[5], $key);
$b[6] = _mm_xor_si128($b[6], $key);
$b[7] = _mm_xor_si128($b[7], $key);
}
}
macro_rules! aesenc8 {
($b:expr, $key:expr) => {
$b[0] = _mm_aesenc_si128($b[0], $key);
$b[1] = _mm_aesenc_si128($b[1], $key);
$b[2] = _mm_aesenc_si128($b[2], $key);
$b[3] = _mm_aesenc_si128($b[3], $key);
$b[4] = _mm_aesenc_si128($b[4], $key);
$b[5] = _mm_aesenc_si128($b[5], $key);
$b[6] = _mm_aesenc_si128($b[6], $key);
$b[7] = _mm_aesenc_si128($b[7], $key);
}
}
macro_rules! aesenclast8 {
($b:expr, $key:expr) => {
$b[0] = _mm_aesenclast_si128($b[0], $key);
$b[1] = _mm_aesenclast_si128($b[1], $key);
$b[2] = _mm_aesenclast_si128($b[2], $key);
$b[3] = _mm_aesenclast_si128($b[3], $key);
$b[4] = _mm_aesenclast_si128($b[4], $key);
$b[5] = _mm_aesenclast_si128($b[5], $key);
$b[6] = _mm_aesenclast_si128($b[6], $key);
$b[7] = _mm_aesenclast_si128($b[7], $key);
}
}
macro_rules! aesdec8 {
($b:expr, $key:expr) => {
$b[0] = _mm_aesdec_si128($b[0], $key);
$b[1] = _mm_aesdec_si128($b[1], $key);
$b[2] = _mm_aesdec_si128($b[2], $key);
$b[3] = _mm_aesdec_si128($b[3], $key);
$b[4] = _mm_aesdec_si128($b[4], $key);
$b[5] = _mm_aesdec_si128($b[5], $key);
$b[6] = _mm_aesdec_si128($b[6], $key);
$b[7] = _mm_aesdec_si128($b[7], $key);
}
}
macro_rules! aesdeclast8 {
($b:expr, $key:expr) => {
$b[0] = _mm_aesdeclast_si128($b[0], $key);
$b[1] = _mm_aesdeclast_si128($b[1], $key);
$b[2] = _mm_aesdeclast_si128($b[2], $key);
$b[3] = _mm_aesdeclast_si128($b[3], $key);
$b[4] = _mm_aesdeclast_si128($b[4], $key);
$b[5] = _mm_aesdeclast_si128($b[5], $key);
$b[6] = _mm_aesdeclast_si128($b[6], $key);
$b[7] = _mm_aesdeclast_si128($b[7], $key);
}
}

11
aesni-0.6.0/tests/ctr.rs

@ -0,0 +1,11 @@
#![cfg(feature = "ctr")]
extern crate aesni;
#[macro_use] extern crate stream_cipher;
use aesni::{Aes128Ctr, Aes256Ctr};
// Random tests generated by OpenSSL
new_sync_test!(aes128_ctr_core, Aes128Ctr, "aes128-ctr");
new_seek_test!(aes128_ctr_seek, Aes128Ctr, "aes128-ctr");
new_sync_test!(aes256_ctr_core, Aes256Ctr, "aes256-ctr");
new_seek_test!(aes256_ctr_seek, Aes256Ctr, "aes256-ctr");

BIN
aesni-0.6.0/tests/data/aes128-ctr.blb

Binary file not shown.

BIN
aesni-0.6.0/tests/data/aes128.blb

Binary file not shown.

BIN
aesni-0.6.0/tests/data/aes192.blb

Binary file not shown.

BIN
aesni-0.6.0/tests/data/aes256-ctr.blb

Binary file not shown.

BIN
aesni-0.6.0/tests/data/aes256.blb

Binary file not shown.

11
aesni-0.6.0/tests/mod.rs

@ -0,0 +1,11 @@
//! Test vectors are from NESSIE:
//! https://www.cosic.esat.kuleuven.be/nessie/testvectors/
#![no_std]
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
extern crate aesni;
#[macro_use]
extern crate block_cipher_trait;
new_test!(aes128_test, "aes128", aesni::Aes128);
new_test!(aes192_test, "aes192", aesni::Aes192);
new_test!(aes256_test, "aes256", aesni::Aes256);

1
block-cipher-trait-0.5.3/.cargo-ok

@ -0,0 +1 @@
ok

32
block-cipher-trait-0.5.3/Cargo.toml

@ -0,0 +1,32 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g. crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "block-cipher-trait"
version = "0.5.3"
authors = ["RustCrypto Developers"]
description = "Traits for description of block ciphers"
documentation = "https://docs.rs/block-cipher-trait"
keywords = ["crypto", "block-cipher", "trait"]
categories = ["cryptography", "no-std"]
license = "MIT/Apache-2.0"
repository = "https://github.com/RustCrypto/block-ciphers"
[package.metadata.docs.rs]
features = ["std"]
[dependencies.generic-array]
version = "0.9"
[features]
dev = []
std = []
[badges.travis-ci]
repository = "RustCrypto/traits"

23
block-cipher-trait-0.5.3/Cargo.toml.orig

@ -0,0 +1,23 @@
[package]
name = "block-cipher-trait"
version = "0.5.3"
authors = ["RustCrypto Developers"]
license = "MIT/Apache-2.0"
description = "Traits for description of block ciphers"
documentation = "https://docs.rs/block-cipher-trait"
repository = "https://github.com/RustCrypto/block-ciphers"
keywords = ["crypto", "block-cipher", "trait"]
categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.9"
[features]
dev = []
std = []
[badges]
travis-ci = { repository = "RustCrypto/traits" }
[package.metadata.docs.rs]
features = [ "std" ]

201
block-cipher-trait-0.5.3/LICENSE-APACHE

@ -0,0 +1,201 @@
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.

25
block-cipher-trait-0.5.3/LICENSE-MIT

@ -0,0 +1,25 @@
Copyright (c) 2016 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.

147
block-cipher-trait-0.5.3/src/dev.rs

@ -0,0 +1,147 @@
#[macro_export]
macro_rules! new_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use block_cipher_trait::BlockCipher;
use block_cipher_trait::generic_array::GenericArray;
use block_cipher_trait::generic_array::typenum::Unsigned;
fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as BlockCipher>::new_varkey(key).unwrap();
let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
if ct != block.as_slice() {
return false;
}
state.decrypt_block(&mut block);
if pt != block.as_slice() {
return false;
}
true
}
fn run_par_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
type ParBlocks = <$cipher as BlockCipher>::ParBlocks;
type BlockSize = <$cipher as BlockCipher>::BlockSize;
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;
let state = <$cipher as BlockCipher>::new_varkey(key).unwrap();
let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
for (i, b) in blocks1.iter_mut().enumerate() {
*b = block;
b[0] = b[0].wrapping_add(i as u8);
}
let mut blocks2 = blocks1.clone();
// check that `encrypt_blocks` and `encrypt_block`
// result in the same ciphertext
state.encrypt_blocks(&mut blocks1);
for b in blocks2.iter_mut() { state.encrypt_block(b); }
if blocks1 != blocks2 { return false; }
// check that `encrypt_blocks` and `encrypt_block`
// result in the same plaintext
state.decrypt_blocks(&mut blocks1);
for b in blocks2.iter_mut() { state.decrypt_block(b); }
if blocks1 != blocks2 { return false; }
true
}
let keys = include_bytes!(
concat!("data/", $test_name, ".keys.bin"));
let plaintexts = include_bytes!(
concat!("data/", $test_name, ".plaintexts.bin"));
let ciphertexts = include_bytes!(
concat!("data/", $test_name, ".ciphertexts.bin"));
let index = include_bytes!(
concat!("data/", $test_name, ".index.bin"));
// u32 (2 bytes); start + end (x2); key, plaintext, ciphertext (x3)
assert_eq!(index.len() % (2*3*2), 0, "invlaid index length");
for (i, chunk) in index.chunks(2*3*2).enumerate() {
// proper aligment is assumed here
let mut idx = unsafe {
*(chunk.as_ptr() as *const [[u16; 2]; 3])
};
// convert to LE for BE machine
for val in idx.iter_mut() {
for i in val.iter_mut() { *i = i.to_le(); }
}
let key = &keys[(idx[0][0] as usize)..(idx[0][1] as usize)];
let plaintext = &plaintexts[
(idx[1][0] as usize)..(idx[1][1] as usize)];
let ciphertext = &ciphertexts[
(idx[2][0] as usize)..(idx[2][1] as usize)];
if !run_test(key, plaintext, ciphertext) {
panic!("\n\
Failed test {}\n\
key: [{}..{}]\t{:?}\n\
plaintext: [{}..{}]\t{:?}\n\
ciphertext: [{}..{}]\t{:?}\n",
i, idx[0][0], idx[0][1], key,
idx[1][0], idx[1][1], plaintext,
idx[2][0], idx[2][1], ciphertext,
);
}
/// test parallel blocks encryption/decryption
let pb = <$cipher as BlockCipher>::ParBlocks::to_usize();
if pb != 1 {
if !run_par_test(key, plaintext, ciphertext) {
panic!("\n\
Failed parallel test {}\n\
key: [{}..{}]\t{:?}\n\
plaintext: [{}..{}]\t{:?}\n\
ciphertext: [{}..{}]\t{:?}\n",
i, idx[0][0], idx[0][1], key,
idx[1][0], idx[1][1], plaintext,
idx[2][0], idx[2][1], ciphertext,
);
}
}
}
}
}
}
#[macro_export]
macro_rules! bench {
($cipher:path, $key_len:expr) => {
extern crate test;
use test::Bencher;
use block_cipher_trait::BlockCipher;
#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let mut block = Default::default();
bh.iter(|| {
state.encrypt_block(&mut block);
test::black_box(&block);
});
bh.bytes = block.len() as u64;
}
#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let mut block = Default::default();
bh.iter(|| {
state.decrypt_block(&mut block);
test::black_box(&block);
});
bh.bytes = block.len() as u64;
}
}
}

20
block-cipher-trait-0.5.3/src/errors.rs

@ -0,0 +1,20 @@
use core::fmt;
#[cfg(feature = "std")]
use std::error;
/// Error struct which used with `NewVarKey`
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct InvalidKeyLength;
impl fmt::Display for InvalidKeyLength {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("invalid key length")
}
}
#[cfg(feature = "std")]
impl error::Error for InvalidKeyLength {
fn description(&self) -> &str {
"invalid key length"
}
}

73
block-cipher-trait-0.5.3/src/lib.rs

@ -0,0 +1,73 @@
//! This crate defines a set of simple traits used to define functionality of
//! block ciphers.
#![no_std]
pub extern crate generic_array;
#[cfg(feature = "std")]
extern crate std;
use generic_array::{GenericArray, ArrayLength};
use generic_array::typenum::Unsigned;
mod errors;
#[cfg(feature = "dev")]
pub mod dev;
pub use errors::InvalidKeyLength;
type ParBlocks<B, P> = GenericArray<GenericArray<u8, B>, P>;
/// The trait which defines in-place encryption and decryption
/// over single block or several blocks in parallel.
pub trait BlockCipher: core::marker::Sized {
/// Key size in bytes with which cipher guaranteed to be initialized
type KeySize: ArrayLength<u8>;
/// Size of the block in bytes
type BlockSize: ArrayLength<u8>;
/// Number of blocks which can be processed in parallel by
/// cipher implementation
type ParBlocks: ArrayLength<GenericArray<u8, Self::BlockSize>>;
/// Create new block cipher instance from key with fixed size.
fn new(key: &GenericArray<u8, Self::KeySize>) -> Self;
/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidKeyLength> {
if key.len() != Self::KeySize::to_usize() {
Err(InvalidKeyLength)
} else {
Ok(Self::new(GenericArray::from_slice(key)))
}
}
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut GenericArray<u8, Self::BlockSize>);
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut GenericArray<u8, Self::BlockSize>);
/// Encrypt several blocks in parallel using instruction level parallelism
/// if possible.
///
/// If `ParBlocks` equals to 1 it's equivalent to `encrypt_block`.
#[inline]
fn encrypt_blocks(&self,
blocks: &mut ParBlocks<Self::BlockSize, Self::ParBlocks>)
{
for block in blocks.iter_mut() { self.encrypt_block(block); }
}
/// Decrypt several blocks in parallel using instruction level parallelism
/// if possible.
///
/// If `ParBlocks` equals to 1 it's equivalent to `decrypt_block`.
#[inline]
fn decrypt_blocks(&self,
blocks: &mut ParBlocks<Self::BlockSize, Self::ParBlocks>)
{
for block in blocks.iter_mut() { self.decrypt_block(block); }
}
}
Loading…
Cancel
Save