• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Salt used in a V1 advertisement.
16 use crate::np_salt_hkdf;
17 use crypto_provider::{hkdf::Hkdf, CryptoProvider, CryptoRng, FromCryptoRng};
18 
19 /// Length of a V1 extended salt
20 pub const EXTENDED_SALT_LEN: usize = 16;
21 
22 /// Salt optionally included in V1 advertisement header.
23 ///
24 /// The salt is never used directly; rather, a derived salt should be extracted as needed for any
25 /// section or DE that requires it.
26 #[derive(Clone, Copy, PartialEq, Debug, Eq)]
27 pub struct ExtendedV1Salt {
28     data: [u8; EXTENDED_SALT_LEN],
29 }
30 
31 impl ExtendedV1Salt {
32     /// Derive a salt for a particular DE, if applicable.
33     ///
34     /// Returns none if the requested size is larger than HKDF allows or if offset arithmetic
35     /// overflows.
derive<const N: usize, C: CryptoProvider>( &self, de: Option<DataElementOffset>, ) -> Option<[u8; N]>36     pub fn derive<const N: usize, C: CryptoProvider>(
37         &self,
38         de: Option<DataElementOffset>,
39     ) -> Option<[u8; N]> {
40         let hkdf = np_salt_hkdf::<C>(&self.data);
41         let mut arr = [0_u8; N];
42         // 0-based offsets -> 1-based indices w/ 0 indicating not present
43         hkdf.expand_multi_info(
44             &[
45                 b"V1 derived salt",
46                 &de.and_then(|d| d.offset.checked_add(1))
47                     .map(|o| o.into())
48                     .unwrap_or(0_u32)
49                     .to_be_bytes(),
50             ],
51             &mut arr,
52         )
53         .map(|_| arr)
54         .ok()
55     }
56 
57     /// Returns the salt bytes as a slice
as_slice(&self) -> &[u8]58     pub fn as_slice(&self) -> &[u8] {
59         self.data.as_slice()
60     }
61 
62     /// Returns the salt bytes as an array
into_array(self) -> [u8; EXTENDED_SALT_LEN]63     pub fn into_array(self) -> [u8; EXTENDED_SALT_LEN] {
64         self.data
65     }
66 
67     /// Returns the salt bytes as a reference to an array
bytes(&self) -> &[u8; EXTENDED_SALT_LEN]68     pub fn bytes(&self) -> &[u8; EXTENDED_SALT_LEN] {
69         &self.data
70     }
71 }
72 
73 impl From<[u8; EXTENDED_SALT_LEN]> for ExtendedV1Salt {
from(arr: [u8; EXTENDED_SALT_LEN]) -> Self74     fn from(arr: [u8; EXTENDED_SALT_LEN]) -> Self {
75         Self { data: arr }
76     }
77 }
78 
79 impl FromCryptoRng for ExtendedV1Salt {
new_random<R: CryptoRng>(rng: &mut R) -> Self80     fn new_random<R: CryptoRng>(rng: &mut R) -> Self {
81         rng.gen::<[u8; EXTENDED_SALT_LEN]>().into()
82     }
83 }
84 
85 /// Offset of a data element in its containing section, used with [ExtendedV1Salt].
86 #[derive(PartialEq, Eq, Debug, Clone, Copy, PartialOrd, Ord)]
87 pub struct DataElementOffset {
88     /// 0-based offset of the DE in the advertisement
89     offset: u8,
90 }
91 
92 impl DataElementOffset {
93     /// The zero offset
94     pub const ZERO: DataElementOffset = Self { offset: 0 };
95 
96     /// Returns the offset as a usize
as_u8(&self) -> u897     pub fn as_u8(&self) -> u8 {
98         self.offset
99     }
100 
101     /// Returns the next offset.
102     ///
103     /// Does not handle overflow as there can't be more than 2^8 DEs in a section.
incremented(&self) -> Self104     pub const fn incremented(&self) -> Self {
105         Self { offset: self.offset + 1 }
106     }
107 }
108 
109 impl From<u8> for DataElementOffset {
from(num: u8) -> Self110     fn from(num: u8) -> Self {
111         Self { offset: num }
112     }
113 }
114