xref: /aosp_15_r20/system/authgraph/boringssl/src/aes.rs (revision 4185b0660fbe514985fdcf75410317caad8afad1)
1*4185b066SAndroid Build Coastguard Worker // Copyright 2023 Google LLC
2*4185b066SAndroid Build Coastguard Worker //
3*4185b066SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*4185b066SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*4185b066SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*4185b066SAndroid Build Coastguard Worker //
7*4185b066SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
8*4185b066SAndroid Build Coastguard Worker //
9*4185b066SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*4185b066SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*4185b066SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*4185b066SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*4185b066SAndroid Build Coastguard Worker // limitations under the License.
14*4185b066SAndroid Build Coastguard Worker //
15*4185b066SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
16*4185b066SAndroid Build Coastguard Worker 
17*4185b066SAndroid Build Coastguard Worker //! BoringSSL-based implementation for the AuthGraph AES traits.
18*4185b066SAndroid Build Coastguard Worker use crate::ossl;
19*4185b066SAndroid Build Coastguard Worker use authgraph_core::{
20*4185b066SAndroid Build Coastguard Worker     ag_err,
21*4185b066SAndroid Build Coastguard Worker     error::Error,
22*4185b066SAndroid Build Coastguard Worker     key::{AesKey, Nonce12},
23*4185b066SAndroid Build Coastguard Worker     traits::AesGcm,
24*4185b066SAndroid Build Coastguard Worker     vec_try, FallibleAllocExt,
25*4185b066SAndroid Build Coastguard Worker };
26*4185b066SAndroid Build Coastguard Worker use authgraph_wire::ErrorCode;
27*4185b066SAndroid Build Coastguard Worker use openssl::symm::{Cipher, Crypter, Mode};
28*4185b066SAndroid Build Coastguard Worker 
29*4185b066SAndroid Build Coastguard Worker /// Tag size for AES-GCM-256.
30*4185b066SAndroid Build Coastguard Worker const TAG_LEN: usize = 16;
31*4185b066SAndroid Build Coastguard Worker 
32*4185b066SAndroid Build Coastguard Worker /// BoringSSL-based implementation of the [`AesGcm`] trait.
33*4185b066SAndroid Build Coastguard Worker #[derive(Clone)]
34*4185b066SAndroid Build Coastguard Worker pub struct BoringAes;
35*4185b066SAndroid Build Coastguard Worker 
36*4185b066SAndroid Build Coastguard Worker impl AesGcm for BoringAes {
encrypt( &self, key: &AesKey, payload: &[u8], aad: &[u8], nonce: &Nonce12, ) -> Result<Vec<u8>, Error>37*4185b066SAndroid Build Coastguard Worker     fn encrypt(
38*4185b066SAndroid Build Coastguard Worker         &self,
39*4185b066SAndroid Build Coastguard Worker         key: &AesKey,
40*4185b066SAndroid Build Coastguard Worker         payload: &[u8],
41*4185b066SAndroid Build Coastguard Worker         aad: &[u8],
42*4185b066SAndroid Build Coastguard Worker         nonce: &Nonce12,
43*4185b066SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error> {
44*4185b066SAndroid Build Coastguard Worker         let cipher = Cipher::aes_256_gcm();
45*4185b066SAndroid Build Coastguard Worker         let mut crypter = ossl!(Crypter::new(cipher, Mode::Encrypt, &key.0, Some(&nonce.0)))?;
46*4185b066SAndroid Build Coastguard Worker 
47*4185b066SAndroid Build Coastguard Worker         ossl!(crypter.aad_update(aad))?;
48*4185b066SAndroid Build Coastguard Worker         let mut ct = vec_try![0; payload.len() + cipher.block_size()]?;
49*4185b066SAndroid Build Coastguard Worker         let mut count = ossl!(crypter.update(payload, &mut ct))?;
50*4185b066SAndroid Build Coastguard Worker         count += ossl!(crypter.finalize(&mut ct))?;
51*4185b066SAndroid Build Coastguard Worker         ct.truncate(count);
52*4185b066SAndroid Build Coastguard Worker 
53*4185b066SAndroid Build Coastguard Worker         let mut tag = [0; TAG_LEN];
54*4185b066SAndroid Build Coastguard Worker         ossl!(crypter.get_tag(&mut tag))?;
55*4185b066SAndroid Build Coastguard Worker         ct.try_extend_from_slice(&tag)?;
56*4185b066SAndroid Build Coastguard Worker 
57*4185b066SAndroid Build Coastguard Worker         Ok(ct)
58*4185b066SAndroid Build Coastguard Worker     }
59*4185b066SAndroid Build Coastguard Worker 
decrypt( &self, key: &AesKey, ct: &[u8], aad: &[u8], nonce: &Nonce12, ) -> Result<Vec<u8>, Error>60*4185b066SAndroid Build Coastguard Worker     fn decrypt(
61*4185b066SAndroid Build Coastguard Worker         &self,
62*4185b066SAndroid Build Coastguard Worker         key: &AesKey,
63*4185b066SAndroid Build Coastguard Worker         ct: &[u8],
64*4185b066SAndroid Build Coastguard Worker         aad: &[u8],
65*4185b066SAndroid Build Coastguard Worker         nonce: &Nonce12,
66*4185b066SAndroid Build Coastguard Worker     ) -> Result<Vec<u8>, Error> {
67*4185b066SAndroid Build Coastguard Worker         let cipher = Cipher::aes_256_gcm();
68*4185b066SAndroid Build Coastguard Worker         let mut crypter = ossl!(Crypter::new(cipher, Mode::Decrypt, &key.0, Some(&nonce.0)))?;
69*4185b066SAndroid Build Coastguard Worker 
70*4185b066SAndroid Build Coastguard Worker         let split_idx =
71*4185b066SAndroid Build Coastguard Worker             ct.len().checked_sub(TAG_LEN).ok_or_else(|| ag_err!(InternalError, "too short"))?;
72*4185b066SAndroid Build Coastguard Worker         let (ct, tag) = ct.split_at(split_idx);
73*4185b066SAndroid Build Coastguard Worker 
74*4185b066SAndroid Build Coastguard Worker         ossl!(crypter.aad_update(aad))?;
75*4185b066SAndroid Build Coastguard Worker         let mut pt = vec_try![0; ct.len() + cipher.block_size()]?;
76*4185b066SAndroid Build Coastguard Worker         let mut count = ossl!(crypter.update(ct, &mut pt))?;
77*4185b066SAndroid Build Coastguard Worker 
78*4185b066SAndroid Build Coastguard Worker         ossl!(crypter.set_tag(tag))?;
79*4185b066SAndroid Build Coastguard Worker         count += ossl!(crypter.finalize(&mut pt))?;
80*4185b066SAndroid Build Coastguard Worker         pt.truncate(count);
81*4185b066SAndroid Build Coastguard Worker 
82*4185b066SAndroid Build Coastguard Worker         Ok(pt)
83*4185b066SAndroid Build Coastguard Worker     }
box_clone(&self) -> Box<dyn AesGcm>84*4185b066SAndroid Build Coastguard Worker     fn box_clone(&self) -> Box<dyn AesGcm> {
85*4185b066SAndroid Build Coastguard Worker         Box::new(self.clone())
86*4185b066SAndroid Build Coastguard Worker     }
87*4185b066SAndroid Build Coastguard Worker }
88