1 // Copyright 2022 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 //! Traits for AES-CTR. 16 use super::{AesBlock, AesKey, BLOCK_SIZE}; 17 18 /// The number of bytes used for the nonce, with the remaining bytes in a block used as the counter. 19 /// 20 /// Other lengths may be used, but 12 is a good general purpose choice. 21 pub const AES_CTR_NONCE_LEN: usize = 12; 22 23 /// The nonce portion of the nonce+counter block used by CTR mode. 24 pub type AesCtrNonce = [u8; AES_CTR_NONCE_LEN]; 25 26 /// An implementation of AES-CTR. 27 /// 28 /// An AesCtr impl must only be used for encryption _or_ decryption, not both. Since CTR mode 29 /// is stateful, mixing encrypts and decrypts may advance the internal state in unexpected ways. 30 /// Create separate encrypt/decrypt instances if both operations are needed. 31 pub trait AesCtr { 32 /// The [AesKey] this cipher uses. See [super::Aes128Key] and [super::Aes256Key] for the common AES-128 and 33 /// AES-256 cases. 34 type Key: AesKey; 35 36 /// Build a `Self` from key material. new(key: &Self::Key, nonce_and_counter: NonceAndCounter) -> Self37 fn new(key: &Self::Key, nonce_and_counter: NonceAndCounter) -> Self; 38 39 /// Applies the key stream to the data in place, advancing the counter state appropriately. apply_keystream(&mut self, data: &mut [u8])40 fn apply_keystream(&mut self, data: &mut [u8]); 41 } 42 43 /// The combined nonce and counter that CTR increments and encrypts to form the keystream. 44 pub struct NonceAndCounter { 45 block: AesBlock, 46 } 47 48 impl NonceAndCounter { 49 /// Appends 4 zero bytes of counter to the nonce from_nonce(nonce: AesCtrNonce) -> Self50 pub fn from_nonce(nonce: AesCtrNonce) -> Self { 51 let mut block = [0; BLOCK_SIZE]; 52 block[..12].copy_from_slice(nonce.as_slice()); 53 NonceAndCounter { block } 54 } 55 56 /// Initialize from an already concatenated nonce and counter 57 // Not recommended for general use, so restricted so only test vectors can use it 58 #[cfg(feature = "test_vectors")] from_block(block: AesBlock) -> Self59 pub fn from_block(block: AesBlock) -> Self { 60 Self { block } 61 } 62 63 /// Nonce and counter as an AES block-sized byte array as_block_array(&self) -> AesBlock64 pub fn as_block_array(&self) -> AesBlock { 65 self.block 66 } 67 } 68