// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 use crate::{ aead, aesgcm::{NONCE_LEN, TAG_LEN}, ring_aead::{Aad, LessSafeKey, Nonce}, }; impl aead::Aead for LessSafeKey { type Nonce = [u8; NONCE_LEN]; type Tag = [u8; TAG_LEN]; fn encrypt( &self, nonce: &[u8; NONCE_LEN], aad: &[u8], input: &mut [u8], tag_buf: &mut [u8; TAG_LEN], ) -> aead::Result { let nonce = Nonce::assume_unique_for_key(*nonce); let aad = Aad::from(aad); let tag = self .seal_in_place_separate_tag(nonce, aad, input) .map_err(|_| aead::Error::INTERNAL_ERROR)?; tag_buf.copy_from_slice(tag.as_ref()); Ok(()) } fn decrypt( &self, nonce: &[u8; NONCE_LEN], aad: &[u8], input: &mut [u8], tag: &[u8; TAG_LEN], ) -> aead::Result { let nonce = Nonce::assume_unique_for_key(*nonce); let aad = Aad::from(aad); let input = unsafe { // ring requires that the input and tag be passed as a single slice // so we extend the input slice here. // This is only safe if they are contiguous debug_assert_eq!( if input.is_empty() { (*input).as_ptr() } else { (&input[input.len() - 1] as *const u8).add(1) }, (*tag).as_ptr() ); let ptr = input.as_mut_ptr(); let len = input.len() + TAG_LEN; core::slice::from_raw_parts_mut(ptr, len) }; self.open_in_place(nonce, aad, input) .map_err(|_| aead::Error::DECRYPT_ERROR)?; Ok(()) } } macro_rules! impl_aesgcm { ($name:ident, $lower:ident) => { #[cfg(any(test, feature = "testing"))] pub mod $lower { use crate::{ aesgcm::testing::$lower::Implementation, ring_aead::{$name, LessSafeKey, UnboundKey}, }; pub fn implementations(impls: &mut Vec<Implementation>) { impls.push(Implementation { name: "ring", new: |key| { let key = UnboundKey::new(&$name, &key).unwrap(); let key = LessSafeKey::new(key); Box::new(key) }, }); } } }; } impl_aesgcm!(AES_128_GCM, aes128); impl_aesgcm!(AES_256_GCM, aes256);