aws_lc_rs/digest/
sha.rs

1// Copyright 2015-2022 Brian Smith.
2// SPDX-License-Identifier: ISC
3// Modifications copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4// SPDX-License-Identifier: Apache-2.0 OR ISC
5
6use crate::digest::{Algorithm, AlgorithmID, Context};
7
8/// The length of a block for SHA-1, in bytes.
9const SHA1_BLOCK_LEN: usize = 512 / 8;
10
11/// The length of the output of SHA-1, in bytes.
12pub const SHA1_OUTPUT_LEN: usize = 160 / 8;
13
14/// The length of the output of SHA-224, in bytes.
15pub const SHA224_OUTPUT_LEN: usize = 224 / 8;
16
17/// The length of the output of SHA-256, in bytes.
18pub const SHA256_OUTPUT_LEN: usize = 256 / 8;
19
20/// The length of a block for SHA-256-based algorithms, in bytes.
21const SHA256_BLOCK_LEN: usize = 512 / 8;
22
23/// The length of the output of SHA-384, in bytes.
24pub const SHA384_OUTPUT_LEN: usize = 384 / 8;
25
26/// The length of the output of SHA-512, in bytes.
27pub const SHA512_OUTPUT_LEN: usize = 512 / 8;
28
29/// The length of the output of SHA-512/256, in bytes.
30pub const SHA512_256_OUTPUT_LEN: usize = 256 / 8;
31
32/// The length of a block for SHA-512-based algorithms, in bytes.
33const SHA512_BLOCK_LEN: usize = 1024 / 8;
34
35/// The length of a block for SHA3-256-based algorithms, in bytes.
36const SHA3_256_BLOCK_LEN: usize = 136;
37
38/// The length of a block for SHA3-384-based algorithms, in bytes.
39const SHA3_384_BLOCK_LEN: usize = 104;
40
41/// The length of a block for SHA3-512-based algorithms, in bytes.
42const SHA3_512_BLOCK_LEN: usize = 72;
43
44/// The length of the output of SHA3-256 in bytes.
45pub const SHA3_256_OUTPUT_LEN: usize = 256 / 8;
46
47/// The length of the output of SHA3-384, in bytes.
48pub const SHA3_384_OUTPUT_LEN: usize = 384 / 8;
49
50/// The length of the output of SHA3-512, in bytes.
51pub const SHA3_512_OUTPUT_LEN: usize = 512 / 8;
52
53/// SHA-1, SHA-224, and SHA-256 are limited to an input size of 2^64-1 bits.
54/// SHA-384, SHA-512, and SHA-512/256 are limited to an input size of 2^128-1 bits according to the spec.
55/// u64 is more than sufficient enough for practical usecases, so we limit the input length to 2^64-1 bits.
56#[allow(clippy::cast_possible_truncation)]
57const DIGEST_MAX_INPUT_LEN: u64 = u64::MAX;
58
59/// SHA-1 as specified in [FIPS 180-4]. Deprecated.
60///
61/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
62#[allow(deprecated)]
63pub static SHA1_FOR_LEGACY_USE_ONLY: Algorithm = Algorithm {
64    output_len: SHA1_OUTPUT_LEN,
65    chaining_len: SHA1_OUTPUT_LEN,
66    block_len: SHA1_BLOCK_LEN,
67    max_input_len: DIGEST_MAX_INPUT_LEN,
68
69    one_shot_hash: sha1_digest,
70
71    id: AlgorithmID::SHA1,
72};
73
74/// SHA-224 as specified in [FIPS 180-4].
75///
76/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
77#[allow(deprecated)]
78pub static SHA224: Algorithm = Algorithm {
79    output_len: SHA224_OUTPUT_LEN,
80
81    // The chaining length is equivalent to the length before truncation.
82    // SHA-224 is truncated from 256 bits so the chaining length is 256 bits, or 32 bytes.
83    chaining_len: SHA256_OUTPUT_LEN,
84    block_len: SHA256_BLOCK_LEN,
85    max_input_len: DIGEST_MAX_INPUT_LEN,
86
87    one_shot_hash: sha224_digest,
88
89    id: AlgorithmID::SHA224,
90};
91
92/// SHA-256 as specified in [FIPS 180-4].
93///
94/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
95#[allow(deprecated)]
96pub static SHA256: Algorithm = Algorithm {
97    output_len: SHA256_OUTPUT_LEN,
98    chaining_len: SHA256_OUTPUT_LEN,
99    block_len: SHA256_BLOCK_LEN,
100    max_input_len: DIGEST_MAX_INPUT_LEN,
101
102    one_shot_hash: sha256_digest,
103
104    id: AlgorithmID::SHA256,
105};
106
107/// SHA-384 as specified in [FIPS 180-4].
108///
109/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
110#[allow(deprecated)]
111pub static SHA384: Algorithm = Algorithm {
112    output_len: SHA384_OUTPUT_LEN,
113
114    // The chaining length is equivalent to the length before truncation.
115    // SHA-384 is truncated from 512 bits so the chaining length is 512 bits, or 64 bytes.
116    chaining_len: SHA512_OUTPUT_LEN,
117    block_len: SHA512_BLOCK_LEN,
118    max_input_len: DIGEST_MAX_INPUT_LEN,
119
120    one_shot_hash: sha384_digest,
121
122    id: AlgorithmID::SHA384,
123};
124
125/// SHA-512 as specified in [FIPS 180-4].
126///
127/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
128#[allow(deprecated)]
129pub static SHA512: Algorithm = Algorithm {
130    output_len: SHA512_OUTPUT_LEN,
131    chaining_len: SHA512_OUTPUT_LEN,
132    block_len: SHA512_BLOCK_LEN,
133    max_input_len: DIGEST_MAX_INPUT_LEN,
134
135    one_shot_hash: sha512_digest,
136
137    id: AlgorithmID::SHA512,
138};
139
140/// SHA-512/256 as specified in [FIPS 180-4].
141///
142/// [FIPS 180-4]: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
143#[allow(deprecated)]
144pub static SHA512_256: Algorithm = Algorithm {
145    output_len: SHA512_256_OUTPUT_LEN,
146    chaining_len: SHA512_OUTPUT_LEN,
147    block_len: SHA512_BLOCK_LEN,
148    max_input_len: DIGEST_MAX_INPUT_LEN,
149
150    one_shot_hash: sha512_256_digest,
151
152    id: AlgorithmID::SHA512_256,
153};
154
155/// SHA3-256 as specified in [FIPS 202].
156///
157/// [FIPS 202]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
158#[allow(deprecated)]
159pub static SHA3_256: Algorithm = Algorithm {
160    output_len: SHA3_256_OUTPUT_LEN,
161    chaining_len: SHA3_256_OUTPUT_LEN,
162    block_len: SHA3_256_BLOCK_LEN,
163    max_input_len: DIGEST_MAX_INPUT_LEN,
164
165    one_shot_hash: sha3_256_digest,
166
167    id: AlgorithmID::SHA3_256,
168};
169
170/// SHA3-384 as specified in [FIPS 202].
171///
172/// [FIPS 202]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
173#[allow(deprecated)]
174pub static SHA3_384: Algorithm = Algorithm {
175    output_len: SHA3_384_OUTPUT_LEN,
176    chaining_len: SHA3_384_OUTPUT_LEN,
177    block_len: SHA3_384_BLOCK_LEN,
178    max_input_len: DIGEST_MAX_INPUT_LEN,
179
180    one_shot_hash: sha3_384_digest,
181
182    id: AlgorithmID::SHA3_384,
183};
184
185/// SHA3-512 as specified in [FIPS 202].
186///
187/// [FIPS 202]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
188#[allow(deprecated)]
189pub static SHA3_512: Algorithm = Algorithm {
190    output_len: SHA3_512_OUTPUT_LEN,
191    chaining_len: SHA3_512_OUTPUT_LEN,
192    block_len: SHA3_512_BLOCK_LEN,
193    max_input_len: DIGEST_MAX_INPUT_LEN,
194
195    one_shot_hash: sha3_512_digest,
196
197    id: AlgorithmID::SHA3_512,
198};
199
200fn sha1_digest(msg: &[u8], output: &mut [u8]) {
201    unsafe {
202        aws_lc::SHA1(msg.as_ptr(), msg.len(), output.as_mut_ptr());
203    }
204}
205
206fn sha224_digest(msg: &[u8], output: &mut [u8]) {
207    unsafe {
208        aws_lc::SHA224(msg.as_ptr(), msg.len(), output.as_mut_ptr());
209    }
210}
211
212fn sha256_digest(msg: &[u8], output: &mut [u8]) {
213    unsafe {
214        aws_lc::SHA256(msg.as_ptr(), msg.len(), output.as_mut_ptr());
215    }
216}
217
218fn sha384_digest(msg: &[u8], output: &mut [u8]) {
219    unsafe {
220        aws_lc::SHA384(msg.as_ptr(), msg.len(), output.as_mut_ptr());
221    }
222}
223
224fn sha512_digest(msg: &[u8], output: &mut [u8]) {
225    unsafe {
226        aws_lc::SHA512(msg.as_ptr(), msg.len(), output.as_mut_ptr());
227    }
228}
229
230fn sha512_256_digest(msg: &[u8], output: &mut [u8]) {
231    unsafe {
232        aws_lc::SHA512_256(msg.as_ptr(), msg.len(), output.as_mut_ptr());
233    }
234}
235
236fn sha3_256_digest(msg: &[u8], output: &mut [u8]) {
237    let mut ctx = Context::new(&SHA3_256);
238    ctx.update(msg);
239    let digest = ctx.finish();
240    output[0..SHA3_256_OUTPUT_LEN].copy_from_slice(digest.as_ref());
241}
242
243fn sha3_384_digest(msg: &[u8], output: &mut [u8]) {
244    let mut ctx = Context::new(&SHA3_384);
245    ctx.update(msg);
246    let digest = ctx.finish();
247    output[0..SHA3_384_OUTPUT_LEN].copy_from_slice(digest.as_ref());
248}
249
250fn sha3_512_digest(msg: &[u8], output: &mut [u8]) {
251    let mut ctx = Context::new(&SHA3_512);
252    ctx.update(msg);
253    let digest = ctx.finish();
254    output[0..SHA3_512_OUTPUT_LEN].copy_from_slice(digest.as_ref());
255}