wasefire_board_api/crypto/
cbc.rs1use crypto_common::generic_array::{ArrayLength, GenericArray};
18#[cfg(feature = "internal-software-crypto-cbc")]
19pub use software::*;
20
21use crate::{Error, Support};
22
23pub trait Api<Key, Block>: Support<bool> + Send
25where
26 Key: ArrayLength<u8>,
27 Block: ArrayLength<u8>,
28{
29 fn encrypt(key: &Array<Key>, iv: &Array<Block>, blocks: &mut [u8]) -> Result<(), Error>;
31
32 fn decrypt(key: &Array<Key>, iv: &Array<Block>, blocks: &mut [u8]) -> Result<(), Error>;
34}
35
36pub type Array<N> = GenericArray<u8, N>;
38
39#[cfg(feature = "internal-software-crypto-cbc")]
40mod software {
41 use core::marker::PhantomData;
42
43 use aes::cipher::{BlockCipher, BlockDecryptMut, BlockEncryptMut};
44 use cbc::{Decryptor, Encryptor};
45 use crypto_common::{KeyInit, KeyIvInit, KeySizeUser};
46 use wasefire_error::Code;
47
48 use super::*;
49
50 pub struct Software<C> {
52 cipher: PhantomData<C>,
53 }
54
55 impl<C> Support<bool> for Software<C> {
56 const SUPPORT: bool = true;
57 }
58
59 impl<Key, Block, C> Api<Key, Block> for Software<C>
60 where
61 C: Send + KeyInit + KeySizeUser<KeySize = Key>,
62 C: BlockCipher<BlockSize = Block> + BlockDecryptMut + BlockEncryptMut,
63 Key: ArrayLength<u8>,
64 Block: ArrayLength<u8>,
65 {
66 fn encrypt(key: &Array<Key>, iv: &Array<Block>, blocks: &mut [u8]) -> Result<(), Error> {
67 Ok(Encryptor::<C>::new(key, iv).encrypt_blocks_mut(convert_blocks(blocks)?))
68 }
69
70 fn decrypt(key: &Array<Key>, iv: &Array<Block>, blocks: &mut [u8]) -> Result<(), Error> {
71 Ok(Decryptor::<C>::new(key, iv).decrypt_blocks_mut(convert_blocks(blocks)?))
72 }
73 }
74
75 fn convert_blocks<N: ArrayLength<u8>>(blocks: &mut [u8]) -> Result<&mut [Array<N>], Error> {
76 if !blocks.len().is_multiple_of(N::USIZE) {
77 return Err(Error::user(Code::InvalidLength));
78 }
79 let ptr = blocks.as_mut_ptr() as *mut Array<N>;
80 let len = blocks.len() / N::USIZE;
81 let blocks = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
83 Ok(blocks)
84 }
85}