1 // Copyright 2023 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 //! A parking ground for the semi-dormant metadata code.
16 //!
17 //! Eventually, when we have a clearer idea of how metadat encryption and identity providers
18 //! interact, this is likely to change aggressively.
19 
20 use alloc::vec::Vec;
21 use crypto_provider::{
22     aead::{Aead, AeadInit},
23     aes::{self},
24     CryptoProvider,
25 };
26 
27 use crate::credential::{MetadataDecryptionError, ProtocolVersion};
28 
29 #[cfg(test)]
30 mod tests;
31 
32 /// Encrypts the given plaintext metadata bytes to allow that metadata
33 /// to be shared with receiving devices.
encrypt_metadata<C: CryptoProvider, V: ProtocolVersion>( hkdf: &np_hkdf::NpKeySeedHkdf<C>, identity_token: V::IdentityToken, plaintext_metadata: &[u8], ) -> Vec<u8>34 pub fn encrypt_metadata<C: CryptoProvider, V: ProtocolVersion>(
35     hkdf: &np_hkdf::NpKeySeedHkdf<C>,
36     identity_token: V::IdentityToken,
37     plaintext_metadata: &[u8],
38 ) -> Vec<u8> {
39     let aead = <<C as CryptoProvider>::Aes128Gcm as AeadInit<aes::Aes128Key>>::new(
40         &V::extract_metadata_key::<C>(identity_token),
41     );
42     // No additional authenticated data for encrypted metadata.
43     aead.encrypt(plaintext_metadata, &[], &V::metadata_nonce_from_key_seed(hkdf))
44         .expect("Metadata encryption should be infallible")
45 }
46 
47 /// Decrypt the given metadata using the given hkdf and version-specific
48 /// identity token. Returns [`MetadataDecryptionError`] in the case that
49 /// the decryption operation failed.
50 ///
51 /// See also [decrypt_metadata_with_nonce].
decrypt_metadata<C: CryptoProvider, V: ProtocolVersion>( hkdf: &np_hkdf::NpKeySeedHkdf<C>, identity_token: V::IdentityToken, encrypted_metadata: &[u8], ) -> Result<Vec<u8>, MetadataDecryptionError>52 pub fn decrypt_metadata<C: CryptoProvider, V: ProtocolVersion>(
53     hkdf: &np_hkdf::NpKeySeedHkdf<C>,
54     identity_token: V::IdentityToken,
55     encrypted_metadata: &[u8],
56 ) -> Result<Vec<u8>, MetadataDecryptionError> {
57     decrypt_metadata_with_nonce::<C, V>(
58         V::metadata_nonce_from_key_seed(hkdf),
59         identity_token,
60         encrypted_metadata,
61     )
62 }
63 
64 /// Decrypt the given metadata using the given hkdf and version-specific
65 /// identity token. Returns [`MetadataDecryptionError`] in the case that
66 /// the decryption operation failed.
67 ///
68 /// See also [decrypt_metadata].
decrypt_metadata_with_nonce<C: CryptoProvider, V: ProtocolVersion>( nonce: <C::Aes128Gcm as Aead>::Nonce, identity_token: V::IdentityToken, encrypted_metadata: &[u8], ) -> Result<Vec<u8>, MetadataDecryptionError>69 pub fn decrypt_metadata_with_nonce<C: CryptoProvider, V: ProtocolVersion>(
70     nonce: <C::Aes128Gcm as Aead>::Nonce,
71     identity_token: V::IdentityToken,
72     encrypted_metadata: &[u8],
73 ) -> Result<Vec<u8>, MetadataDecryptionError> {
74     // No additional authenticated data for encrypted metadata.
75     let metadata_key = V::extract_metadata_key::<C>(identity_token);
76     <<C as CryptoProvider>::Aes128Gcm as AeadInit<aes::Aes128Key>>::new(&metadata_key)
77         .decrypt(encrypted_metadata, &[], &nonce)
78         .map_err(|_| MetadataDecryptionError)
79 }
80