/rust/registry/src/index.crates.io-6f17d22bba15001f/aws-lc-rs-1.13.0/src/iv.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2018 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 | | #![allow(dead_code)] |
6 | | |
7 | | //! Initialization Vector (IV) cryptographic primitives |
8 | | |
9 | | use crate::error::Unspecified; |
10 | | use crate::rand; |
11 | | use zeroize::Zeroize; |
12 | | |
13 | | /// Length of a 128-bit IV in bytes. |
14 | | pub const IV_LEN_128_BIT: usize = 16; |
15 | | |
16 | | /// An initialization vector that must be unique for the lifetime of the associated key |
17 | | /// it is used with. |
18 | | pub struct FixedLength<const L: usize>([u8; L]); |
19 | | |
20 | | impl<const L: usize> FixedLength<L> { |
21 | | /// Returns the size of the iv in bytes. |
22 | | #[allow(clippy::must_use_candidate)] |
23 | 0 | pub fn size(&self) -> usize { |
24 | 0 | L |
25 | 0 | } |
26 | | |
27 | | /// Constructs a new [`FixedLength`] from pseudo-random bytes. |
28 | | /// |
29 | | /// # Errors |
30 | | /// |
31 | | /// * [`Unspecified`]: Returned if there is a failure generating `L` bytes. |
32 | 0 | pub fn new() -> Result<Self, Unspecified> { |
33 | 0 | let mut iv_bytes = [0u8; L]; |
34 | 0 | rand::fill(&mut iv_bytes)?; |
35 | 0 | Ok(Self(iv_bytes)) |
36 | 0 | } |
37 | | } |
38 | | |
39 | | impl<const L: usize> Drop for FixedLength<L> { |
40 | 0 | fn drop(&mut self) { |
41 | 0 | self.0.zeroize(); |
42 | 0 | } |
43 | | } |
44 | | |
45 | | impl<const L: usize> AsRef<[u8; L]> for FixedLength<L> { |
46 | | #[inline] |
47 | 0 | fn as_ref(&self) -> &[u8; L] { |
48 | 0 | &self.0 |
49 | 0 | } |
50 | | } |
51 | | |
52 | | impl<const L: usize> From<&[u8; L]> for FixedLength<L> { |
53 | | #[inline] |
54 | 0 | fn from(bytes: &[u8; L]) -> Self { |
55 | 0 | FixedLength(bytes.to_owned()) |
56 | 0 | } |
57 | | } |
58 | | |
59 | | impl<const L: usize> From<[u8; L]> for FixedLength<L> { |
60 | | #[inline] |
61 | 0 | fn from(bytes: [u8; L]) -> Self { |
62 | 0 | FixedLength(bytes) |
63 | 0 | } |
64 | | } |
65 | | |
66 | | impl<const L: usize> TryFrom<&[u8]> for FixedLength<L> { |
67 | | type Error = Unspecified; |
68 | | |
69 | 0 | fn try_from(value: &[u8]) -> Result<Self, Self::Error> { |
70 | 0 | let value: &[u8; L] = value.try_into()?; |
71 | 0 | Ok(Self::from(*value)) |
72 | 0 | } |
73 | | } |
74 | | |
75 | | impl<const L: usize> TryFrom<FixedLength<L>> for [u8; L] { |
76 | | type Error = Unspecified; |
77 | | |
78 | 0 | fn try_from(value: FixedLength<L>) -> Result<Self, Self::Error> { |
79 | 0 | Ok(value.0) |
80 | 0 | } |
81 | | } |
82 | | |
83 | | #[cfg(test)] |
84 | | mod tests { |
85 | | use crate::iv::FixedLength; |
86 | | |
87 | | #[test] |
88 | | fn test_size() { |
89 | | let fixed = FixedLength::from([0u8; 16]); |
90 | | assert_eq!(16, fixed.size()); |
91 | | |
92 | | let array = [0u8; 12]; |
93 | | let fixed = FixedLength::<12>::try_from(array.as_slice()).unwrap(); |
94 | | assert_eq!(12, fixed.size()); |
95 | | |
96 | | assert!(FixedLength::<16>::try_from(array.as_slice()).is_err()); |
97 | | |
98 | | assert!(TryInto::<[u8; 12]>::try_into(fixed).is_ok()); |
99 | | } |
100 | | } |