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