ring-native 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +3 -0
- data/README.md +22 -0
- data/Rakefile +1 -0
- data/ext/ring/extconf.rb +29 -0
- data/lib/ring/native.rb +8 -0
- data/lib/ring/native/version.rb +5 -0
- data/ring-native.gemspec +25 -0
- data/vendor/ring/BUILDING.md +40 -0
- data/vendor/ring/Cargo.toml +43 -0
- data/vendor/ring/LICENSE +185 -0
- data/vendor/ring/Makefile +35 -0
- data/vendor/ring/PORTING.md +163 -0
- data/vendor/ring/README.md +113 -0
- data/vendor/ring/STYLE.md +197 -0
- data/vendor/ring/appveyor.yml +27 -0
- data/vendor/ring/build.rs +108 -0
- data/vendor/ring/crypto/aes/aes.c +1142 -0
- data/vendor/ring/crypto/aes/aes_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/aes/aes_test.cc +93 -0
- data/vendor/ring/crypto/aes/asm/aes-586.pl +2368 -0
- data/vendor/ring/crypto/aes/asm/aes-armv4.pl +1249 -0
- data/vendor/ring/crypto/aes/asm/aes-x86_64.pl +2246 -0
- data/vendor/ring/crypto/aes/asm/aesni-x86.pl +1318 -0
- data/vendor/ring/crypto/aes/asm/aesni-x86_64.pl +2084 -0
- data/vendor/ring/crypto/aes/asm/aesv8-armx.pl +675 -0
- data/vendor/ring/crypto/aes/asm/bsaes-armv7.pl +1364 -0
- data/vendor/ring/crypto/aes/asm/bsaes-x86_64.pl +1565 -0
- data/vendor/ring/crypto/aes/asm/vpaes-x86.pl +841 -0
- data/vendor/ring/crypto/aes/asm/vpaes-x86_64.pl +1116 -0
- data/vendor/ring/crypto/aes/internal.h +87 -0
- data/vendor/ring/crypto/aes/mode_wrappers.c +61 -0
- data/vendor/ring/crypto/bn/add.c +394 -0
- data/vendor/ring/crypto/bn/asm/armv4-mont.pl +694 -0
- data/vendor/ring/crypto/bn/asm/armv8-mont.pl +1503 -0
- data/vendor/ring/crypto/bn/asm/bn-586.pl +774 -0
- data/vendor/ring/crypto/bn/asm/co-586.pl +287 -0
- data/vendor/ring/crypto/bn/asm/rsaz-avx2.pl +1882 -0
- data/vendor/ring/crypto/bn/asm/x86-mont.pl +592 -0
- data/vendor/ring/crypto/bn/asm/x86_64-gcc.c +599 -0
- data/vendor/ring/crypto/bn/asm/x86_64-mont.pl +1393 -0
- data/vendor/ring/crypto/bn/asm/x86_64-mont5.pl +3507 -0
- data/vendor/ring/crypto/bn/bn.c +352 -0
- data/vendor/ring/crypto/bn/bn_asn1.c +74 -0
- data/vendor/ring/crypto/bn/bn_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/bn/bn_test.cc +1696 -0
- data/vendor/ring/crypto/bn/cmp.c +200 -0
- data/vendor/ring/crypto/bn/convert.c +433 -0
- data/vendor/ring/crypto/bn/ctx.c +311 -0
- data/vendor/ring/crypto/bn/div.c +594 -0
- data/vendor/ring/crypto/bn/exponentiation.c +1335 -0
- data/vendor/ring/crypto/bn/gcd.c +711 -0
- data/vendor/ring/crypto/bn/generic.c +1019 -0
- data/vendor/ring/crypto/bn/internal.h +316 -0
- data/vendor/ring/crypto/bn/montgomery.c +516 -0
- data/vendor/ring/crypto/bn/mul.c +888 -0
- data/vendor/ring/crypto/bn/prime.c +829 -0
- data/vendor/ring/crypto/bn/random.c +334 -0
- data/vendor/ring/crypto/bn/rsaz_exp.c +262 -0
- data/vendor/ring/crypto/bn/rsaz_exp.h +53 -0
- data/vendor/ring/crypto/bn/shift.c +276 -0
- data/vendor/ring/crypto/bytestring/bytestring_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/bytestring/bytestring_test.cc +421 -0
- data/vendor/ring/crypto/bytestring/cbb.c +399 -0
- data/vendor/ring/crypto/bytestring/cbs.c +227 -0
- data/vendor/ring/crypto/bytestring/internal.h +46 -0
- data/vendor/ring/crypto/chacha/chacha_generic.c +140 -0
- data/vendor/ring/crypto/chacha/chacha_vec.c +323 -0
- data/vendor/ring/crypto/chacha/chacha_vec_arm.S +1447 -0
- data/vendor/ring/crypto/chacha/chacha_vec_arm_generate.go +153 -0
- data/vendor/ring/crypto/cipher/cipher_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/cipher/e_aes.c +390 -0
- data/vendor/ring/crypto/cipher/e_chacha20poly1305.c +208 -0
- data/vendor/ring/crypto/cipher/internal.h +173 -0
- data/vendor/ring/crypto/cipher/test/aes_128_gcm_tests.txt +543 -0
- data/vendor/ring/crypto/cipher/test/aes_128_key_wrap_tests.txt +9 -0
- data/vendor/ring/crypto/cipher/test/aes_256_gcm_tests.txt +475 -0
- data/vendor/ring/crypto/cipher/test/aes_256_key_wrap_tests.txt +23 -0
- data/vendor/ring/crypto/cipher/test/chacha20_poly1305_old_tests.txt +422 -0
- data/vendor/ring/crypto/cipher/test/chacha20_poly1305_tests.txt +484 -0
- data/vendor/ring/crypto/cipher/test/cipher_test.txt +100 -0
- data/vendor/ring/crypto/constant_time_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/constant_time_test.c +304 -0
- data/vendor/ring/crypto/cpu-arm-asm.S +32 -0
- data/vendor/ring/crypto/cpu-arm.c +199 -0
- data/vendor/ring/crypto/cpu-intel.c +261 -0
- data/vendor/ring/crypto/crypto.c +151 -0
- data/vendor/ring/crypto/curve25519/asm/x25519-arm.S +2118 -0
- data/vendor/ring/crypto/curve25519/curve25519.c +4888 -0
- data/vendor/ring/crypto/curve25519/x25519_test.cc +128 -0
- data/vendor/ring/crypto/digest/md32_common.h +181 -0
- data/vendor/ring/crypto/ec/asm/p256-x86_64-asm.pl +2725 -0
- data/vendor/ring/crypto/ec/ec.c +193 -0
- data/vendor/ring/crypto/ec/ec_curves.c +61 -0
- data/vendor/ring/crypto/ec/ec_key.c +228 -0
- data/vendor/ring/crypto/ec/ec_montgomery.c +114 -0
- data/vendor/ring/crypto/ec/example_mul.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/ec/internal.h +243 -0
- data/vendor/ring/crypto/ec/oct.c +253 -0
- data/vendor/ring/crypto/ec/p256-64.c +1794 -0
- data/vendor/ring/crypto/ec/p256-x86_64-table.h +9548 -0
- data/vendor/ring/crypto/ec/p256-x86_64.c +509 -0
- data/vendor/ring/crypto/ec/simple.c +1007 -0
- data/vendor/ring/crypto/ec/util-64.c +183 -0
- data/vendor/ring/crypto/ec/wnaf.c +508 -0
- data/vendor/ring/crypto/ecdh/ecdh.c +155 -0
- data/vendor/ring/crypto/ecdsa/ecdsa.c +304 -0
- data/vendor/ring/crypto/ecdsa/ecdsa_asn1.c +193 -0
- data/vendor/ring/crypto/ecdsa/ecdsa_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/ecdsa/ecdsa_test.cc +327 -0
- data/vendor/ring/crypto/header_removed.h +17 -0
- data/vendor/ring/crypto/internal.h +495 -0
- data/vendor/ring/crypto/libring.Windows.vcxproj +101 -0
- data/vendor/ring/crypto/mem.c +98 -0
- data/vendor/ring/crypto/modes/asm/aesni-gcm-x86_64.pl +1045 -0
- data/vendor/ring/crypto/modes/asm/ghash-armv4.pl +517 -0
- data/vendor/ring/crypto/modes/asm/ghash-x86.pl +1393 -0
- data/vendor/ring/crypto/modes/asm/ghash-x86_64.pl +1741 -0
- data/vendor/ring/crypto/modes/asm/ghashv8-armx.pl +422 -0
- data/vendor/ring/crypto/modes/ctr.c +226 -0
- data/vendor/ring/crypto/modes/gcm.c +1206 -0
- data/vendor/ring/crypto/modes/gcm_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/modes/gcm_test.c +348 -0
- data/vendor/ring/crypto/modes/internal.h +299 -0
- data/vendor/ring/crypto/perlasm/arm-xlate.pl +170 -0
- data/vendor/ring/crypto/perlasm/readme +100 -0
- data/vendor/ring/crypto/perlasm/x86_64-xlate.pl +1164 -0
- data/vendor/ring/crypto/perlasm/x86asm.pl +292 -0
- data/vendor/ring/crypto/perlasm/x86gas.pl +263 -0
- data/vendor/ring/crypto/perlasm/x86masm.pl +200 -0
- data/vendor/ring/crypto/perlasm/x86nasm.pl +187 -0
- data/vendor/ring/crypto/poly1305/poly1305.c +331 -0
- data/vendor/ring/crypto/poly1305/poly1305_arm.c +301 -0
- data/vendor/ring/crypto/poly1305/poly1305_arm_asm.S +2015 -0
- data/vendor/ring/crypto/poly1305/poly1305_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/poly1305/poly1305_test.cc +80 -0
- data/vendor/ring/crypto/poly1305/poly1305_test.txt +52 -0
- data/vendor/ring/crypto/poly1305/poly1305_vec.c +892 -0
- data/vendor/ring/crypto/rand/asm/rdrand-x86_64.pl +75 -0
- data/vendor/ring/crypto/rand/internal.h +32 -0
- data/vendor/ring/crypto/rand/rand.c +189 -0
- data/vendor/ring/crypto/rand/urandom.c +219 -0
- data/vendor/ring/crypto/rand/windows.c +56 -0
- data/vendor/ring/crypto/refcount_c11.c +66 -0
- data/vendor/ring/crypto/refcount_lock.c +53 -0
- data/vendor/ring/crypto/refcount_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/refcount_test.c +58 -0
- data/vendor/ring/crypto/rsa/blinding.c +462 -0
- data/vendor/ring/crypto/rsa/internal.h +108 -0
- data/vendor/ring/crypto/rsa/padding.c +300 -0
- data/vendor/ring/crypto/rsa/rsa.c +450 -0
- data/vendor/ring/crypto/rsa/rsa_asn1.c +261 -0
- data/vendor/ring/crypto/rsa/rsa_impl.c +944 -0
- data/vendor/ring/crypto/rsa/rsa_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/rsa/rsa_test.cc +437 -0
- data/vendor/ring/crypto/sha/asm/sha-armv8.pl +436 -0
- data/vendor/ring/crypto/sha/asm/sha-x86_64.pl +2390 -0
- data/vendor/ring/crypto/sha/asm/sha256-586.pl +1275 -0
- data/vendor/ring/crypto/sha/asm/sha256-armv4.pl +735 -0
- data/vendor/ring/crypto/sha/asm/sha256-armv8.pl +14 -0
- data/vendor/ring/crypto/sha/asm/sha256-x86_64.pl +14 -0
- data/vendor/ring/crypto/sha/asm/sha512-586.pl +911 -0
- data/vendor/ring/crypto/sha/asm/sha512-armv4.pl +666 -0
- data/vendor/ring/crypto/sha/asm/sha512-armv8.pl +14 -0
- data/vendor/ring/crypto/sha/asm/sha512-x86_64.pl +14 -0
- data/vendor/ring/crypto/sha/sha1.c +271 -0
- data/vendor/ring/crypto/sha/sha256.c +204 -0
- data/vendor/ring/crypto/sha/sha512.c +355 -0
- data/vendor/ring/crypto/test/file_test.cc +326 -0
- data/vendor/ring/crypto/test/file_test.h +181 -0
- data/vendor/ring/crypto/test/malloc.cc +150 -0
- data/vendor/ring/crypto/test/scoped_types.h +95 -0
- data/vendor/ring/crypto/test/test.Windows.vcxproj +35 -0
- data/vendor/ring/crypto/test/test_util.cc +46 -0
- data/vendor/ring/crypto/test/test_util.h +41 -0
- data/vendor/ring/crypto/thread_none.c +55 -0
- data/vendor/ring/crypto/thread_pthread.c +165 -0
- data/vendor/ring/crypto/thread_test.Windows.vcxproj +25 -0
- data/vendor/ring/crypto/thread_test.c +200 -0
- data/vendor/ring/crypto/thread_win.c +282 -0
- data/vendor/ring/examples/checkdigest.rs +103 -0
- data/vendor/ring/include/openssl/aes.h +121 -0
- data/vendor/ring/include/openssl/arm_arch.h +129 -0
- data/vendor/ring/include/openssl/base.h +156 -0
- data/vendor/ring/include/openssl/bn.h +794 -0
- data/vendor/ring/include/openssl/buffer.h +18 -0
- data/vendor/ring/include/openssl/bytestring.h +235 -0
- data/vendor/ring/include/openssl/chacha.h +37 -0
- data/vendor/ring/include/openssl/cmac.h +76 -0
- data/vendor/ring/include/openssl/cpu.h +184 -0
- data/vendor/ring/include/openssl/crypto.h +43 -0
- data/vendor/ring/include/openssl/curve25519.h +88 -0
- data/vendor/ring/include/openssl/ec.h +225 -0
- data/vendor/ring/include/openssl/ec_key.h +129 -0
- data/vendor/ring/include/openssl/ecdh.h +110 -0
- data/vendor/ring/include/openssl/ecdsa.h +156 -0
- data/vendor/ring/include/openssl/err.h +201 -0
- data/vendor/ring/include/openssl/mem.h +101 -0
- data/vendor/ring/include/openssl/obj_mac.h +71 -0
- data/vendor/ring/include/openssl/opensslfeatures.h +68 -0
- data/vendor/ring/include/openssl/opensslv.h +18 -0
- data/vendor/ring/include/openssl/ossl_typ.h +18 -0
- data/vendor/ring/include/openssl/poly1305.h +51 -0
- data/vendor/ring/include/openssl/rand.h +70 -0
- data/vendor/ring/include/openssl/rsa.h +399 -0
- data/vendor/ring/include/openssl/thread.h +133 -0
- data/vendor/ring/include/openssl/type_check.h +71 -0
- data/vendor/ring/mk/Common.props +63 -0
- data/vendor/ring/mk/Windows.props +42 -0
- data/vendor/ring/mk/WindowsTest.props +18 -0
- data/vendor/ring/mk/appveyor.bat +62 -0
- data/vendor/ring/mk/bottom_of_makefile.mk +54 -0
- data/vendor/ring/mk/ring.mk +266 -0
- data/vendor/ring/mk/top_of_makefile.mk +214 -0
- data/vendor/ring/mk/travis.sh +40 -0
- data/vendor/ring/mk/update-travis-yml.py +229 -0
- data/vendor/ring/ring.sln +153 -0
- data/vendor/ring/src/aead.rs +682 -0
- data/vendor/ring/src/agreement.rs +248 -0
- data/vendor/ring/src/c.rs +129 -0
- data/vendor/ring/src/constant_time.rs +37 -0
- data/vendor/ring/src/der.rs +96 -0
- data/vendor/ring/src/digest.rs +690 -0
- data/vendor/ring/src/digest_tests.txt +57 -0
- data/vendor/ring/src/ecc.rs +28 -0
- data/vendor/ring/src/ecc_build.rs +279 -0
- data/vendor/ring/src/ecc_curves.rs +117 -0
- data/vendor/ring/src/ed25519_tests.txt +2579 -0
- data/vendor/ring/src/exe_tests.rs +46 -0
- data/vendor/ring/src/ffi.rs +29 -0
- data/vendor/ring/src/file_test.rs +187 -0
- data/vendor/ring/src/hkdf.rs +153 -0
- data/vendor/ring/src/hkdf_tests.txt +59 -0
- data/vendor/ring/src/hmac.rs +414 -0
- data/vendor/ring/src/hmac_tests.txt +97 -0
- data/vendor/ring/src/input.rs +312 -0
- data/vendor/ring/src/lib.rs +41 -0
- data/vendor/ring/src/pbkdf2.rs +265 -0
- data/vendor/ring/src/pbkdf2_tests.txt +113 -0
- data/vendor/ring/src/polyfill.rs +57 -0
- data/vendor/ring/src/rand.rs +28 -0
- data/vendor/ring/src/signature.rs +314 -0
- data/vendor/ring/third-party/NIST/README.md +9 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA1LongMsg.rsp +263 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA1Monte.rsp +309 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA1ShortMsg.rsp +267 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA224LongMsg.rsp +263 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA224Monte.rsp +309 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA224ShortMsg.rsp +267 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA256LongMsg.rsp +263 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA256Monte.rsp +309 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA256ShortMsg.rsp +267 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA384LongMsg.rsp +519 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA384Monte.rsp +309 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA384ShortMsg.rsp +523 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA512LongMsg.rsp +519 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA512Monte.rsp +309 -0
- data/vendor/ring/third-party/NIST/SHAVS/SHA512ShortMsg.rsp +523 -0
- data/vendor/ring/third-party/NIST/sha256sums.txt +1 -0
- metadata +333 -0
@@ -0,0 +1,690 @@
|
|
1
|
+
// Copyright 2015 Brian Smith.
|
2
|
+
//
|
3
|
+
// Permission to use, copy, modify, and/or distribute this software for any
|
4
|
+
// purpose with or without fee is hereby granted, provided that the above
|
5
|
+
// copyright notice and this permission notice appear in all copies.
|
6
|
+
//
|
7
|
+
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
|
8
|
+
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
9
|
+
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
10
|
+
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
11
|
+
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
12
|
+
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
13
|
+
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
14
|
+
|
15
|
+
//! SHA-2 and the legacy SHA-1 digest algorithm.
|
16
|
+
//!
|
17
|
+
//! If all the data is available in a single contiguous slice then the `digest`
|
18
|
+
//! function should be used. Otherwise, the digest can be calculated in
|
19
|
+
//! multiple steps using `Context`.
|
20
|
+
|
21
|
+
// Note on why are we doing things the hard way: It would be easy to implement
|
22
|
+
// this using the C `EVP_MD`/`EVP_MD_CTX` interface. However, if we were to do
|
23
|
+
// things that way, we'd have a hard dependency on `malloc` and other overhead.
|
24
|
+
// The goal for this implementation is to drive the overhead as close to zero
|
25
|
+
// as possible.
|
26
|
+
|
27
|
+
use super::{c, polyfill};
|
28
|
+
|
29
|
+
// XXX: endian-specific.
|
30
|
+
// XXX: Replace with `const fn` when `const fn` is stable:
|
31
|
+
// https://github.com/rust-lang/rust/issues/24111
|
32
|
+
macro_rules! u32x2 {
|
33
|
+
( $first:expr, $second:expr ) =>
|
34
|
+
((($second as u64) << 32) | ($first as u64))
|
35
|
+
}
|
36
|
+
|
37
|
+
/// A context for multi-step (Init-Update-Finish) digest calculations.
|
38
|
+
///
|
39
|
+
/// C analog: `EVP_MD_CTX`.
|
40
|
+
///
|
41
|
+
/// # Examples
|
42
|
+
///
|
43
|
+
/// ```
|
44
|
+
/// use ring::digest;
|
45
|
+
///
|
46
|
+
/// let one_shot = digest::digest(&digest::SHA384, "hello, world".as_bytes());
|
47
|
+
///
|
48
|
+
/// let mut ctx = digest::Context::new(&digest::SHA384);
|
49
|
+
/// ctx.update("hello".as_bytes());
|
50
|
+
/// ctx.update(", ".as_bytes());
|
51
|
+
/// ctx.update("world".as_bytes());
|
52
|
+
/// let multi_part = ctx.finish();
|
53
|
+
///
|
54
|
+
/// assert_eq!(&one_shot.as_ref(), &multi_part.as_ref());
|
55
|
+
/// ```
|
56
|
+
pub struct Context {
|
57
|
+
// We use u64 to try to ensure 64-bit alignment/padding.
|
58
|
+
state: [u64; MAX_CHAINING_LEN / 8],
|
59
|
+
|
60
|
+
// Note that SHA-512 has a 128-bit input bit counter, but this
|
61
|
+
// implementation only supports up to 2^64-1 input bits for all algorithms,
|
62
|
+
// so a 64-bit counter is more than sufficient.
|
63
|
+
completed_data_blocks: u64,
|
64
|
+
|
65
|
+
// TODO: More explicitly force 64-bit alignment for |pending|.
|
66
|
+
pending: [u8; MAX_BLOCK_LEN],
|
67
|
+
num_pending: usize,
|
68
|
+
|
69
|
+
pub algorithm: &'static Algorithm,
|
70
|
+
}
|
71
|
+
|
72
|
+
impl Context {
|
73
|
+
/// Constructs a new context.
|
74
|
+
///
|
75
|
+
/// C analogs: `EVP_DigestInit`, `EVP_DigestInit_ex`
|
76
|
+
pub fn new(algorithm: &'static Algorithm) -> Context {
|
77
|
+
Context {
|
78
|
+
algorithm: algorithm,
|
79
|
+
state: algorithm.initial_state,
|
80
|
+
completed_data_blocks: 0,
|
81
|
+
pending: [0u8; MAX_BLOCK_LEN],
|
82
|
+
num_pending: 0,
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
/// Updates the digest with all the data in `data`. `update` may be called
|
87
|
+
/// zero or more times until `finish` is called. It must not be called
|
88
|
+
/// after `finish` has been called.
|
89
|
+
///
|
90
|
+
/// C analog: `EVP_DigestUpdate`
|
91
|
+
pub fn update(&mut self, data: &[u8]) {
|
92
|
+
if data.len() < self.algorithm.block_len - self.num_pending {
|
93
|
+
polyfill::slice::fill_from_slice(
|
94
|
+
&mut self.pending[self.num_pending..
|
95
|
+
(self.num_pending + data.len())],
|
96
|
+
data);
|
97
|
+
self.num_pending += data.len();
|
98
|
+
return;
|
99
|
+
}
|
100
|
+
|
101
|
+
let mut remaining = data;
|
102
|
+
if self.num_pending > 0 {
|
103
|
+
let to_copy = self.algorithm.block_len - self.num_pending;
|
104
|
+
polyfill::slice::fill_from_slice(
|
105
|
+
&mut self.pending[self.num_pending..self.algorithm.block_len],
|
106
|
+
&data[..to_copy]);
|
107
|
+
|
108
|
+
unsafe {
|
109
|
+
(self.algorithm.block_data_order)(self.state.as_mut_ptr(),
|
110
|
+
self.pending.as_ptr(), 1);
|
111
|
+
}
|
112
|
+
self.completed_data_blocks =
|
113
|
+
self.completed_data_blocks.checked_add(1).unwrap();
|
114
|
+
|
115
|
+
remaining = &remaining[to_copy..];
|
116
|
+
self.num_pending = 0;
|
117
|
+
}
|
118
|
+
|
119
|
+
let num_blocks = remaining.len() / self.algorithm.block_len;
|
120
|
+
let num_to_save_for_later = remaining.len() % self.algorithm.block_len;
|
121
|
+
if num_blocks > 0 {
|
122
|
+
unsafe {
|
123
|
+
(self.algorithm.block_data_order)(self.state.as_mut_ptr(),
|
124
|
+
remaining.as_ptr(),
|
125
|
+
num_blocks);
|
126
|
+
}
|
127
|
+
self.completed_data_blocks =
|
128
|
+
self.completed_data_blocks.checked_add(widen_u64(num_blocks))
|
129
|
+
.unwrap();
|
130
|
+
}
|
131
|
+
if num_to_save_for_later > 0 {
|
132
|
+
polyfill::slice::fill_from_slice(
|
133
|
+
&mut self.pending[self.num_pending..
|
134
|
+
(self.num_pending + num_to_save_for_later)],
|
135
|
+
&remaining[(remaining.len() - num_to_save_for_later)..]);
|
136
|
+
self.num_pending = num_to_save_for_later;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
/// Finalizes the digest calculation and returns the digest value. `finish`
|
141
|
+
/// consumes the context so it cannot be (mis-)used after `finish` has been
|
142
|
+
/// called.
|
143
|
+
///
|
144
|
+
/// C analogs: `EVP_DigestFinal`, `EVP_DigestFinal_ex`
|
145
|
+
pub fn finish(mut self) -> Digest {
|
146
|
+
// We know |num_pending < self.algorithm.block_len|, because we would
|
147
|
+
// have processed the block otherwise.
|
148
|
+
|
149
|
+
let mut padding_pos = self.num_pending;
|
150
|
+
self.pending[padding_pos] = 0x80;
|
151
|
+
padding_pos += 1;
|
152
|
+
|
153
|
+
if padding_pos > self.algorithm.block_len - self.algorithm.len_len {
|
154
|
+
polyfill::slice::fill(
|
155
|
+
&mut self.pending[padding_pos..self.algorithm.block_len], 0);
|
156
|
+
unsafe {
|
157
|
+
(self.algorithm.block_data_order)(self.state.as_mut_ptr(),
|
158
|
+
self.pending.as_ptr(), 1);
|
159
|
+
}
|
160
|
+
// We don't increase |self.completed_data_blocks| because the
|
161
|
+
// padding isn't data, and so it isn't included in the data length.
|
162
|
+
padding_pos = 0;
|
163
|
+
}
|
164
|
+
|
165
|
+
polyfill::slice::fill(
|
166
|
+
&mut self.pending[padding_pos..(self.algorithm.block_len - 8)], 0);
|
167
|
+
|
168
|
+
// Output the length, in bits, in big endian order.
|
169
|
+
let mut completed_data_bits: u64 =
|
170
|
+
self.completed_data_blocks
|
171
|
+
.checked_mul(widen_u64(self.algorithm.block_len)).unwrap()
|
172
|
+
.checked_add(widen_u64(self.num_pending)).unwrap()
|
173
|
+
.checked_mul(8).unwrap();
|
174
|
+
|
175
|
+
for b in (&mut self.pending[(self.algorithm.block_len - 8)..
|
176
|
+
self.algorithm.block_len]).into_iter().rev() {
|
177
|
+
*b = completed_data_bits as u8;
|
178
|
+
completed_data_bits /= 0x100;
|
179
|
+
}
|
180
|
+
unsafe {
|
181
|
+
(self.algorithm.block_data_order)(self.state.as_mut_ptr(),
|
182
|
+
self.pending.as_ptr(), 1);
|
183
|
+
}
|
184
|
+
|
185
|
+
Digest {
|
186
|
+
algorithm: self.algorithm,
|
187
|
+
value: (self.algorithm.format_output)(&self.state),
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
/// The algorithm that this context is using.
|
192
|
+
#[inline(always)]
|
193
|
+
pub fn algorithm(&self) -> &'static Algorithm { self.algorithm }
|
194
|
+
}
|
195
|
+
|
196
|
+
// XXX: This should just be `#[derive(Clone)]` but that doesn't work because
|
197
|
+
// `[u8; 128]` doesn't implement `Clone`.
|
198
|
+
impl Clone for Context {
|
199
|
+
fn clone(&self) -> Context {
|
200
|
+
Context {
|
201
|
+
state: self.state,
|
202
|
+
pending: self.pending,
|
203
|
+
completed_data_blocks: self.completed_data_blocks,
|
204
|
+
num_pending: self.num_pending,
|
205
|
+
algorithm: self.algorithm
|
206
|
+
}
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
/// Returns the digest of `data` using the given digest algorithm.
|
211
|
+
///
|
212
|
+
/// C analog: `EVP_Digest`
|
213
|
+
///
|
214
|
+
/// # Examples:
|
215
|
+
///
|
216
|
+
/// ```
|
217
|
+
/// extern crate ring;
|
218
|
+
/// extern crate rustc_serialize;
|
219
|
+
///
|
220
|
+
/// # fn main() {
|
221
|
+
/// use ring::digest;
|
222
|
+
/// use rustc_serialize::hex::FromHex;
|
223
|
+
///
|
224
|
+
/// let expected_hex = "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b";
|
225
|
+
/// let expected: Vec<u8> = expected_hex.from_hex().unwrap();
|
226
|
+
/// let actual = digest::digest(&digest::SHA256, "hello, world".as_bytes());
|
227
|
+
///
|
228
|
+
/// assert_eq!(&expected, &actual.as_ref());
|
229
|
+
/// # }
|
230
|
+
/// ```
|
231
|
+
pub fn digest(algorithm: &'static Algorithm, data: &[u8]) -> Digest {
|
232
|
+
let mut ctx = Context::new(algorithm);
|
233
|
+
ctx.update(data);
|
234
|
+
ctx.finish()
|
235
|
+
}
|
236
|
+
|
237
|
+
/// A calculated digest value.
|
238
|
+
///
|
239
|
+
/// Use `as_ref` to get the value as a `&[u8]`.
|
240
|
+
pub struct Digest {
|
241
|
+
value: [u64; MAX_OUTPUT_LEN / 8],
|
242
|
+
algorithm: &'static Algorithm,
|
243
|
+
}
|
244
|
+
|
245
|
+
impl Digest {
|
246
|
+
/// The algorithm that was used to calculate the digest value.
|
247
|
+
#[inline(always)]
|
248
|
+
pub fn algorithm(&self) -> &'static Algorithm { self.algorithm }
|
249
|
+
}
|
250
|
+
|
251
|
+
impl AsRef<[u8]> for Digest {
|
252
|
+
#[inline(always)]
|
253
|
+
fn as_ref(&self) -> &[u8] {
|
254
|
+
&(polyfill::slice::u64_as_u8(&self.value))[..self.algorithm.output_len]
|
255
|
+
}
|
256
|
+
}
|
257
|
+
|
258
|
+
/// A digest algorithm.
|
259
|
+
///
|
260
|
+
/// C analog: `EVP_MD`
|
261
|
+
pub struct Algorithm {
|
262
|
+
/// C analog: `EVP_MD_size`
|
263
|
+
pub output_len: usize,
|
264
|
+
|
265
|
+
/// The size of the chaining value of the digest function, in bytes. For
|
266
|
+
/// non-truncated algorithms (SHA-1, SHA-256, SHA-512), this is equal to
|
267
|
+
/// `output_len`. For truncated algorithms (e.g. SHA-384, SHA-512/256),
|
268
|
+
/// this is equal to the length before truncation. This is mostly helpful
|
269
|
+
/// for determining the size of an HMAC key that is appropriate for the
|
270
|
+
/// digest algorithm.
|
271
|
+
pub chaining_len: usize,
|
272
|
+
|
273
|
+
/// C analog: `EVP_MD_block_size`
|
274
|
+
pub block_len: usize,
|
275
|
+
|
276
|
+
/// The length of the length in the padding.
|
277
|
+
len_len: usize,
|
278
|
+
|
279
|
+
block_data_order: unsafe extern fn(state: *mut u64, data: *const u8,
|
280
|
+
num: c::size_t),
|
281
|
+
format_output: fn (input: &[u64; MAX_CHAINING_LEN / 8]) ->
|
282
|
+
[u64; MAX_OUTPUT_LEN / 8],
|
283
|
+
|
284
|
+
initial_state: [u64; MAX_CHAINING_LEN / 8],
|
285
|
+
|
286
|
+
/// The OpenSSL/BoringSSL NID for the algorithm. For all the algorithms
|
287
|
+
/// defined in this module, `a.nid == b.nid` implies that `a` and `b` are
|
288
|
+
/// references to the same algorithm.
|
289
|
+
pub nid: c::int,
|
290
|
+
}
|
291
|
+
|
292
|
+
/// SHA-256 as specified in [FIPS 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
293
|
+
pub static SHA1: Algorithm = Algorithm {
|
294
|
+
output_len: 160 / 8,
|
295
|
+
chaining_len: 160 / 8,
|
296
|
+
block_len: 512 / 8,
|
297
|
+
len_len: 64 / 8,
|
298
|
+
block_data_order: sha1_block_data_order,
|
299
|
+
format_output: sha256_format_output,
|
300
|
+
initial_state: [
|
301
|
+
u32x2!(0x67452301, 0xefcdab89),
|
302
|
+
u32x2!(0x98badcfe, 0x10325476),
|
303
|
+
u32x2!(0xc3d2e1f0, 0),
|
304
|
+
0, 0, 0, 0, 0,
|
305
|
+
],
|
306
|
+
nid: 64, // NID_sha1
|
307
|
+
};
|
308
|
+
|
309
|
+
/// SHA-256 as specified in [FIPS 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
310
|
+
pub static SHA256: Algorithm = Algorithm {
|
311
|
+
output_len: 256 / 8,
|
312
|
+
chaining_len: 256 / 8,
|
313
|
+
block_len: 512 / 8,
|
314
|
+
len_len: 64 / 8,
|
315
|
+
block_data_order: sha256_block_data_order,
|
316
|
+
format_output: sha256_format_output,
|
317
|
+
initial_state: [
|
318
|
+
u32x2!(0x6a09e667, 0xbb67ae85),
|
319
|
+
u32x2!(0x3c6ef372, 0xa54ff53a),
|
320
|
+
u32x2!(0x510e527f, 0x9b05688c),
|
321
|
+
u32x2!(0x1f83d9ab, 0x5be0cd19),
|
322
|
+
0, 0, 0, 0,
|
323
|
+
],
|
324
|
+
nid: 672, // NID_sha256
|
325
|
+
|
326
|
+
};
|
327
|
+
|
328
|
+
/// SHA-384 as specified in [FIPS 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
329
|
+
pub static SHA384: Algorithm = Algorithm {
|
330
|
+
output_len: 384 / 8,
|
331
|
+
chaining_len: 512 / 8,
|
332
|
+
block_len: 1024 / 8,
|
333
|
+
len_len: 128 / 8,
|
334
|
+
block_data_order: sha512_block_data_order,
|
335
|
+
format_output: sha512_format_output,
|
336
|
+
initial_state: [
|
337
|
+
0xcbbb9d5dc1059ed8,
|
338
|
+
0x629a292a367cd507,
|
339
|
+
0x9159015a3070dd17,
|
340
|
+
0x152fecd8f70e5939,
|
341
|
+
0x67332667ffc00b31,
|
342
|
+
0x8eb44a8768581511,
|
343
|
+
0xdb0c2e0d64f98fa7,
|
344
|
+
0x47b5481dbefa4fa4,
|
345
|
+
],
|
346
|
+
nid: 673, // NID_sha384
|
347
|
+
};
|
348
|
+
|
349
|
+
/// SHA-512 as specified in [FIPS 180-4](http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
350
|
+
pub static SHA512: Algorithm = Algorithm {
|
351
|
+
output_len: 512 / 8,
|
352
|
+
chaining_len: 512 / 8,
|
353
|
+
block_len: 1024 / 8,
|
354
|
+
len_len: 128 / 8,
|
355
|
+
block_data_order: sha512_block_data_order,
|
356
|
+
format_output: sha512_format_output,
|
357
|
+
initial_state: [
|
358
|
+
0x6a09e667f3bcc908,
|
359
|
+
0xbb67ae8584caa73b,
|
360
|
+
0x3c6ef372fe94f82b,
|
361
|
+
0xa54ff53a5f1d36f1,
|
362
|
+
0x510e527fade682d1,
|
363
|
+
0x9b05688c2b3e6c1f,
|
364
|
+
0x1f83d9abfb41bd6b,
|
365
|
+
0x5be0cd19137e2179,
|
366
|
+
],
|
367
|
+
nid: 674, // NID_sha512
|
368
|
+
};
|
369
|
+
|
370
|
+
#[inline(always)]
|
371
|
+
fn widen_u64(x: usize) -> u64 { x as u64 }
|
372
|
+
|
373
|
+
/// The maximum block length (`Algorithm::block_len`) of all the algorithms in
|
374
|
+
/// this module.
|
375
|
+
pub const MAX_BLOCK_LEN: usize = 1024 / 8;
|
376
|
+
|
377
|
+
/// The maximum output length (`Algorithm::output_len`) of all the algorithms
|
378
|
+
/// in this module.
|
379
|
+
pub const MAX_OUTPUT_LEN: usize = 512 / 8;
|
380
|
+
|
381
|
+
/// The maximum chaining length ('Algorithm::chaining_len`) of all the
|
382
|
+
/// algorithms in this module.
|
383
|
+
pub const MAX_CHAINING_LEN: usize = MAX_OUTPUT_LEN;
|
384
|
+
|
385
|
+
fn sha256_format_output(input: &[u64; MAX_CHAINING_LEN / 8])
|
386
|
+
-> [u64; MAX_OUTPUT_LEN / 8] {
|
387
|
+
let in32 = &polyfill::slice::u64_as_u32(input)[0..8];
|
388
|
+
[
|
389
|
+
u32x2!(in32[0].to_be(), in32[1].to_be()),
|
390
|
+
u32x2!(in32[2].to_be(), in32[3].to_be()),
|
391
|
+
u32x2!(in32[4].to_be(), in32[5].to_be()),
|
392
|
+
u32x2!(in32[6].to_be(), in32[7].to_be()),
|
393
|
+
0,
|
394
|
+
0,
|
395
|
+
0,
|
396
|
+
0,
|
397
|
+
]
|
398
|
+
}
|
399
|
+
|
400
|
+
fn sha512_format_output(input: &[u64; MAX_CHAINING_LEN / 8])
|
401
|
+
-> [u64; MAX_OUTPUT_LEN / 8] {
|
402
|
+
[
|
403
|
+
input[0].to_be(),
|
404
|
+
input[1].to_be(),
|
405
|
+
input[2].to_be(),
|
406
|
+
input[3].to_be(),
|
407
|
+
input[4].to_be(),
|
408
|
+
input[5].to_be(),
|
409
|
+
input[6].to_be(),
|
410
|
+
input[7].to_be(),
|
411
|
+
]
|
412
|
+
}
|
413
|
+
|
414
|
+
extern {
|
415
|
+
fn sha1_block_data_order(state: *mut u64, data: *const u8, num: c::size_t);
|
416
|
+
fn sha256_block_data_order(state: *mut u64, data: *const u8, num: c::size_t);
|
417
|
+
fn sha512_block_data_order(state: *mut u64, data: *const u8, num: c::size_t);
|
418
|
+
}
|
419
|
+
|
420
|
+
#[cfg(test)]
|
421
|
+
pub mod test_util {
|
422
|
+
use super::super::digest;
|
423
|
+
|
424
|
+
pub static ALL_ALGORITHMS: [&'static digest::Algorithm; 4] = [
|
425
|
+
&digest::SHA1,
|
426
|
+
&digest::SHA256,
|
427
|
+
&digest::SHA384,
|
428
|
+
&digest::SHA512,
|
429
|
+
];
|
430
|
+
}
|
431
|
+
|
432
|
+
#[cfg(test)]
|
433
|
+
mod tests {
|
434
|
+
use super::super::{digest, file_test};
|
435
|
+
|
436
|
+
/// Test vectors from BoringSSL.
|
437
|
+
#[test]
|
438
|
+
fn test_bssl() {
|
439
|
+
file_test::run("src/digest_tests.txt", |section, test_case| {
|
440
|
+
assert_eq!(section, "");
|
441
|
+
let digest_alg = test_case.consume_digest_alg("Hash").unwrap();
|
442
|
+
let input = test_case.consume_bytes("Input");
|
443
|
+
let repeat = test_case.consume_usize("Repeat");
|
444
|
+
let expected = test_case.consume_bytes("Output");
|
445
|
+
|
446
|
+
let mut ctx = digest::Context::new(digest_alg);
|
447
|
+
let mut data = Vec::new();
|
448
|
+
for _ in 0..repeat {
|
449
|
+
ctx.update(&input);
|
450
|
+
data.extend(&input);
|
451
|
+
}
|
452
|
+
let actual_from_chunks = ctx.finish();
|
453
|
+
assert_eq!(&expected, &actual_from_chunks.as_ref());
|
454
|
+
|
455
|
+
let actual_from_one_shot = digest::digest(digest_alg, &data);
|
456
|
+
assert_eq!(&expected, &actual_from_one_shot.as_ref());
|
457
|
+
});
|
458
|
+
}
|
459
|
+
|
460
|
+
mod shavs {
|
461
|
+
use super::super::super::{digest, file_test};
|
462
|
+
use rustc_serialize::hex::ToHex;
|
463
|
+
|
464
|
+
macro_rules! shavs_tests {
|
465
|
+
( $algorithm_name:ident ) => {
|
466
|
+
#[allow(non_snake_case)]
|
467
|
+
mod $algorithm_name {
|
468
|
+
use super::{run_known_answer_test, run_monte_carlo_test};
|
469
|
+
use super::super::super::super::{digest};
|
470
|
+
|
471
|
+
#[test]
|
472
|
+
fn short_msg_known_answer_test() {
|
473
|
+
run_known_answer_test(
|
474
|
+
&digest::$algorithm_name,
|
475
|
+
&format!("third-party/NIST/SHAVS/{}ShortMsg.rsp",
|
476
|
+
stringify!($algorithm_name)));
|
477
|
+
}
|
478
|
+
|
479
|
+
#[test]
|
480
|
+
fn long_msg_known_answer_test() {
|
481
|
+
run_known_answer_test(
|
482
|
+
&digest::$algorithm_name,
|
483
|
+
&format!("third-party/NIST/SHAVS/{}LongMsg.rsp",
|
484
|
+
stringify!($algorithm_name)));
|
485
|
+
}
|
486
|
+
|
487
|
+
#[test]
|
488
|
+
fn monte_carlo_test() {
|
489
|
+
run_monte_carlo_test(
|
490
|
+
&digest::$algorithm_name,
|
491
|
+
&format!("third-party/NIST/SHAVS/{}Monte.rsp",
|
492
|
+
stringify!($algorithm_name)));
|
493
|
+
}
|
494
|
+
}
|
495
|
+
}
|
496
|
+
}
|
497
|
+
|
498
|
+
fn run_known_answer_test(digest_alg: &'static digest::Algorithm,
|
499
|
+
file_name: &str, ) {
|
500
|
+
let section_name = &format!("L = {}", digest_alg.output_len);
|
501
|
+
file_test::run(file_name, |section, test_case| {
|
502
|
+
assert_eq!(section_name, section);
|
503
|
+
let len_bits = test_case.consume_usize("Len");
|
504
|
+
|
505
|
+
let mut msg = test_case.consume_bytes("Msg");
|
506
|
+
// The "msg" field contains the dummy value "00" when the
|
507
|
+
// length is zero.
|
508
|
+
if len_bits == 0 {
|
509
|
+
assert_eq!(msg, &[0u8]);
|
510
|
+
msg.truncate(0);
|
511
|
+
}
|
512
|
+
|
513
|
+
assert_eq!(msg.len() * 8, len_bits);
|
514
|
+
let expected = test_case.consume_bytes("MD");
|
515
|
+
let actual = digest::digest(digest_alg, &msg);
|
516
|
+
assert_eq!(&expected, &actual.as_ref());
|
517
|
+
});
|
518
|
+
}
|
519
|
+
|
520
|
+
fn run_monte_carlo_test(digest_alg: &'static digest::Algorithm,
|
521
|
+
file_name: &str) {
|
522
|
+
let section_name = &format!("L = {}", digest_alg.output_len);
|
523
|
+
|
524
|
+
let mut expected_count: isize = -1;
|
525
|
+
let mut seed = Vec::with_capacity(digest_alg.output_len);
|
526
|
+
|
527
|
+
file_test::run_mut(file_name, &mut |section, test_case| {
|
528
|
+
assert_eq!(section_name, section);
|
529
|
+
|
530
|
+
if expected_count == -1 {
|
531
|
+
seed.extend(test_case.consume_bytes("Seed"));
|
532
|
+
expected_count = 0;
|
533
|
+
return;
|
534
|
+
}
|
535
|
+
|
536
|
+
assert!(expected_count >= 0);
|
537
|
+
let actual_count = test_case.consume_usize("COUNT");
|
538
|
+
assert_eq!(expected_count as usize, actual_count);
|
539
|
+
expected_count += 1;
|
540
|
+
|
541
|
+
let expected_md = test_case.consume_bytes("MD");
|
542
|
+
|
543
|
+
let mut mds = Vec::with_capacity(1000);
|
544
|
+
mds.push(seed.clone());
|
545
|
+
mds.push(seed.clone());
|
546
|
+
mds.push(seed.clone());
|
547
|
+
for i in 3..1003 {
|
548
|
+
let mut ctx = digest::Context::new(digest_alg);
|
549
|
+
ctx.update(&mds[i - 3]);
|
550
|
+
ctx.update(&mds[i - 2]);
|
551
|
+
ctx.update(&mds[i - 1]);
|
552
|
+
let md_i = ctx.finish();
|
553
|
+
mds.push(Vec::from(md_i.as_ref()));
|
554
|
+
}
|
555
|
+
assert_eq!(1003, mds.len());
|
556
|
+
let md_j = mds.last().unwrap();
|
557
|
+
println!("{}\n{}", expected_md.to_hex(), md_j.to_hex());
|
558
|
+
assert_eq!(&expected_md, md_j);
|
559
|
+
seed = md_j.clone();
|
560
|
+
});
|
561
|
+
|
562
|
+
assert_eq!(expected_count, 100);
|
563
|
+
}
|
564
|
+
|
565
|
+
shavs_tests!(SHA1);
|
566
|
+
shavs_tests!(SHA256);
|
567
|
+
shavs_tests!(SHA384);
|
568
|
+
shavs_tests!(SHA512);
|
569
|
+
}
|
570
|
+
|
571
|
+
/// Test some ways in which `Context::update` and/or `Context::finish`
|
572
|
+
/// could go wrong by testing every combination of updating three inputs
|
573
|
+
/// that vary from zero bytes to twice the size of the block length.
|
574
|
+
///
|
575
|
+
/// This is not run in dev (debug) builds because it is too slow.
|
576
|
+
macro_rules! test_i_u_f {
|
577
|
+
( $test_name:ident, $alg:expr) => {
|
578
|
+
#[cfg(not(debug_assertions))]
|
579
|
+
#[test]
|
580
|
+
fn $test_name() {
|
581
|
+
let mut input = vec![0u8; $alg.block_len * 2];
|
582
|
+
for i in 0..input.len() {
|
583
|
+
input[i] = i as u8;
|
584
|
+
}
|
585
|
+
|
586
|
+
for i in 0..input.len() {
|
587
|
+
for j in 0..input.len() {
|
588
|
+
for k in 0..input.len() {
|
589
|
+
let part1 = &input[0..i];
|
590
|
+
let part2 = &input[0..j];
|
591
|
+
let part3 = &input[0..k];
|
592
|
+
|
593
|
+
let mut ctx = digest::Context::new(&$alg);
|
594
|
+
ctx.update(part1);
|
595
|
+
ctx.update(part2);
|
596
|
+
ctx.update(part3);
|
597
|
+
let i_u_f = ctx.finish();
|
598
|
+
|
599
|
+
let mut combined = Vec::<u8>::new();
|
600
|
+
combined.extend(part1);
|
601
|
+
combined.extend(part2);
|
602
|
+
combined.extend(part3);
|
603
|
+
let one_shot = digest::digest(&$alg, &combined);
|
604
|
+
|
605
|
+
assert_eq!(i_u_f.as_ref(), one_shot.as_ref());
|
606
|
+
}
|
607
|
+
}
|
608
|
+
}
|
609
|
+
}
|
610
|
+
}
|
611
|
+
}
|
612
|
+
test_i_u_f!(test_i_u_f_sha1, digest::SHA1);
|
613
|
+
test_i_u_f!(test_i_u_f_sha256, digest::SHA256);
|
614
|
+
test_i_u_f!(test_i_u_f_sha384, digest::SHA384);
|
615
|
+
test_i_u_f!(test_i_u_f_sha512, digest::SHA512);
|
616
|
+
|
617
|
+
/// See https://bugzilla.mozilla.org/show_bug.cgi?id=610162. This tests the
|
618
|
+
/// calculation of 8GB of the byte 123.
|
619
|
+
///
|
620
|
+
/// You can verify the expected values in many ways. One way is
|
621
|
+
/// `python ~/p/write_big.py`, where write_big.py is:
|
622
|
+
///
|
623
|
+
/// ```python
|
624
|
+
/// chunk = bytearray([123] * (16 * 1024))
|
625
|
+
/// with open('tempfile', 'w') as f:
|
626
|
+
/// for i in xrange(0, 8 * 1024 * 1024 * 1024, len(chunk)):
|
627
|
+
/// f.write(chunk)
|
628
|
+
/// ```
|
629
|
+
/// Then:
|
630
|
+
///
|
631
|
+
/// ```sh
|
632
|
+
/// sha1sum -b tempfile
|
633
|
+
/// sha256sum -b tempfile
|
634
|
+
/// sha384sum -b tempfile
|
635
|
+
/// sha512sum -b tempfile
|
636
|
+
/// ```
|
637
|
+
///
|
638
|
+
/// This is not run in dev (debug) builds because it is too slow.
|
639
|
+
macro_rules! test_large_digest {
|
640
|
+
( $test_name:ident, $alg:expr, $len:expr, $expected:expr) => {
|
641
|
+
#[cfg(not(debug_assertions))]
|
642
|
+
#[test]
|
643
|
+
fn $test_name() {
|
644
|
+
let chunk = vec![123u8; 16 * 1024];
|
645
|
+
let chunk_len = chunk.len() as u64;
|
646
|
+
let mut ctx = digest::Context::new(&$alg);
|
647
|
+
let mut hashed = 0u64;
|
648
|
+
loop {
|
649
|
+
ctx.update(&chunk);
|
650
|
+
hashed += chunk_len;
|
651
|
+
if hashed >= 8u64 * 1024 * 1024 * 1024 {
|
652
|
+
break;
|
653
|
+
}
|
654
|
+
}
|
655
|
+
let calculated = ctx.finish();
|
656
|
+
let expected: [u8; $len] = $expected;
|
657
|
+
assert_eq!(&expected[..], calculated.as_ref());
|
658
|
+
}
|
659
|
+
}
|
660
|
+
}
|
661
|
+
test_large_digest!(test_large_digest_sha1, digest::SHA1, 160 / 8, [
|
662
|
+
0xCA, 0xC3, 0x4C, 0x31, 0x90, 0x5B, 0xDE, 0x3B,
|
663
|
+
0xE4, 0x0D, 0x46, 0x6D, 0x70, 0x76, 0xAD, 0x65,
|
664
|
+
0x3C, 0x20, 0xE4, 0xBD
|
665
|
+
]);
|
666
|
+
test_large_digest!(test_large_digest_sha256, digest::SHA256, 256 / 8, [
|
667
|
+
0x8D, 0xD1, 0x6D, 0xD8, 0xB2, 0x5A, 0x29, 0xCB,
|
668
|
+
0x7F, 0xB9, 0xAE, 0x86, 0x72, 0xE9, 0xCE, 0xD6,
|
669
|
+
0x65, 0x4C, 0xB6, 0xC3, 0x5C, 0x58, 0x21, 0xA7,
|
670
|
+
0x07, 0x97, 0xC5, 0xDD, 0xAE, 0x5C, 0x68, 0xBD
|
671
|
+
]);
|
672
|
+
test_large_digest!(test_large_digest_sha384, digest::SHA384, 384 / 8, [
|
673
|
+
0x3D, 0xFE, 0xC1, 0xA9, 0xD0, 0x9F, 0x08, 0xD5,
|
674
|
+
0xBB, 0xE8, 0x7C, 0x9E, 0xE0, 0x0A, 0x87, 0x0E,
|
675
|
+
0xB0, 0xEA, 0x8E, 0xEA, 0xDB, 0x82, 0x36, 0xAE,
|
676
|
+
0x74, 0xCF, 0x9F, 0xDC, 0x86, 0x1C, 0xE3, 0xE9,
|
677
|
+
0xB0, 0x68, 0xCD, 0x19, 0x3E, 0x39, 0x90, 0x02,
|
678
|
+
0xE1, 0x58, 0x5D, 0x66, 0xC4, 0x55, 0x11, 0x9B
|
679
|
+
]);
|
680
|
+
test_large_digest!(test_large_digest_sha512, digest::SHA512, 512 / 8, [
|
681
|
+
0xFC, 0x8A, 0x98, 0x20, 0xFC, 0x82, 0xD8, 0x55,
|
682
|
+
0xF8, 0xFF, 0x2F, 0x6E, 0xAE, 0x41, 0x60, 0x04,
|
683
|
+
0x08, 0xE9, 0x49, 0xD7, 0xCD, 0x1A, 0xED, 0x22,
|
684
|
+
0xEB, 0x55, 0xE1, 0xFD, 0x80, 0x50, 0x3B, 0x01,
|
685
|
+
0x2F, 0xC6, 0xF4, 0x33, 0x86, 0xFB, 0x60, 0x75,
|
686
|
+
0x2D, 0xA5, 0xA9, 0x93, 0xE7, 0x00, 0x45, 0xA8,
|
687
|
+
0x49, 0x1A, 0x6B, 0xEC, 0x9C, 0x98, 0xC8, 0x19,
|
688
|
+
0xA6, 0xA9, 0x88, 0x3E, 0x2F, 0x09, 0xB9, 0x9A
|
689
|
+
]);
|
690
|
+
}
|