wasefire_board_api/crypto/
aead.rs1use crypto_common::generic_array::{ArrayLength, GenericArray};
18
19use crate::{Error, Support};
20
21#[derive(Copy, Clone)]
23pub struct AeadSupport {
24 pub no_copy: bool,
26
27 pub in_place_no_copy: bool,
29}
30
31impl From<AeadSupport> for bool {
32 fn from(value: AeadSupport) -> Self {
33 value.no_copy || value.in_place_no_copy
34 }
35}
36
37pub trait Api<Key, Iv>: Support<AeadSupport> + Send
39where
40 Key: ArrayLength<u8>,
41 Iv: ArrayLength<u8>,
42{
43 type Tag: ArrayLength<u8>;
45
46 fn encrypt(
51 key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], clear: Option<&[u8]>, cipher: &mut [u8],
52 tag: &mut Array<Self::Tag>,
53 ) -> Result<(), Error>;
54
55 fn decrypt(
60 key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], cipher: Option<&[u8]>,
61 tag: &Array<Self::Tag>, clear: &mut [u8],
62 ) -> Result<(), Error>;
63}
64
65pub type Array<N> = GenericArray<u8, N>;
67
68#[cfg(feature = "internal-software-crypto-aead")]
69mod software {
70 use aead::{AeadCore, AeadInPlace};
71 use crypto_common::{KeyInit, KeySizeUser};
72
73 use super::*;
74
75 impl<T: AeadInPlace> Support<AeadSupport> for T {
76 const SUPPORT: AeadSupport = AeadSupport { no_copy: false, in_place_no_copy: true };
77 }
78
79 impl<Key, Iv, T> Api<Key, Iv> for T
80 where
81 T: Send + KeyInit + AeadInPlace,
82 T: KeySizeUser<KeySize = Key>,
83 T: AeadCore<NonceSize = Iv>,
84 Key: ArrayLength<u8>,
85 Iv: ArrayLength<u8>,
86 {
87 type Tag = T::TagSize;
88
89 fn encrypt(
90 key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], clear: Option<&[u8]>, cipher: &mut [u8],
91 tag: &mut Array<Self::Tag>,
92 ) -> Result<(), Error> {
93 let aead = T::new(key);
94 if let Some(clear) = clear {
95 cipher.copy_from_slice(clear);
96 }
97 tag.copy_from_slice(
98 &aead.encrypt_in_place_detached(iv, aad, cipher).map_err(|_| Error::world(0))?,
99 );
100 Ok(())
101 }
102
103 fn decrypt(
104 key: &Array<Key>, iv: &Array<Iv>, aad: &[u8], cipher: Option<&[u8]>,
105 tag: &Array<Self::Tag>, clear: &mut [u8],
106 ) -> Result<(), Error> {
107 let aead = T::new(key);
108 if let Some(cipher) = cipher {
109 clear.copy_from_slice(cipher);
110 }
111 aead.decrypt_in_place_detached(iv, aad, clear, tag).map_err(|_| Error::world(0))
112 }
113 }
114}