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