1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Utilities for encryption and decryption.
18 
19 use crate::aidl_err;
20 use alloc::vec::Vec;
21 use authgraph_core::key::{AesKey, Nonce12};
22 use authgraph_core::traits::{AesGcm, Rng};
23 use coset::{iana, CborSerializable, CoseEncrypt0, CoseEncrypt0Builder, HeaderBuilder};
24 use secretkeeper_comm::wire::{AidlErrorCode, ApiError};
25 
26 /// Decrypt a message.
decrypt_message( aes_gcm: &dyn AesGcm, key: &AesKey, encrypt0: &CoseEncrypt0, external_aad: &[u8], ) -> Result<Vec<u8>, ApiError>27 pub fn decrypt_message(
28     aes_gcm: &dyn AesGcm,
29     key: &AesKey,
30     encrypt0: &CoseEncrypt0,
31     external_aad: &[u8],
32 ) -> Result<Vec<u8>, ApiError> {
33     let nonce12 = Nonce12::try_from(&encrypt0.unprotected.iv[..])
34         .map_err(|e| aidl_err!(InternalError, "nonce of unexpected size: {e:?}"))?;
35     encrypt0
36         .decrypt(external_aad, |ct, aad| aes_gcm.decrypt(key, ct, aad, &nonce12))
37         .map_err(|e| aidl_err!(InternalError, "failed to decrypt message: {e:?}"))
38 }
39 
40 /// Encrypt a message.
encrypt_message( aes_gcm: &dyn AesGcm, rng: &dyn Rng, key: &AesKey, session_id: &[u8], msg: &[u8], external_aad: &[u8], ) -> Result<Vec<u8>, ApiError>41 pub fn encrypt_message(
42     aes_gcm: &dyn AesGcm,
43     rng: &dyn Rng,
44     key: &AesKey,
45     session_id: &[u8],
46     msg: &[u8],
47     external_aad: &[u8],
48 ) -> Result<Vec<u8>, ApiError> {
49     let nonce12 = Nonce12::new(rng);
50     let encrypt0 = CoseEncrypt0Builder::new()
51         .protected(
52             HeaderBuilder::new()
53                 .algorithm(iana::Algorithm::A256GCM)
54                 .key_id(session_id.to_vec())
55                 .build(),
56         )
57         .unprotected(HeaderBuilder::new().iv(nonce12.0.to_vec()).build())
58         .try_create_ciphertext(msg, external_aad, |plaintext, aad| {
59             aes_gcm.encrypt(key, plaintext, aad, &nonce12)
60         })
61         .map_err(|e| aidl_err!(InternalError, "failed to encrypt message: {e:?}"))?
62         .build();
63     encrypt0
64         .to_vec()
65         .map_err(|e| aidl_err!(InternalError, "failed to serialize CoseEncrypt0: {e:?}"))
66 }
67