crypto\aes_256_gcm/
win.rs1use super::*;
5use crate::win::*;
6use std::sync::LazyLock;
7use windows::Win32::Security::Cryptography::BCRYPT_ALG_HANDLE;
8use windows::Win32::Security::Cryptography::BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO;
9use windows::Win32::Security::Cryptography::BCRYPT_KEY_HANDLE;
10use windows::Win32::Security::Cryptography::BCRYPT_OPEN_ALGORITHM_PROVIDER_FLAGS;
11use zerocopy::IntoBytes;
12
13static AES_256_GCM: LazyLock<Result<AlgHandle, Aes256GcmError>> = LazyLock::new(|| {
14 const CHAINING_MODE: &[u16] = wchar::wchz!("ChainingModeGCM");
15 let mut handle = BCRYPT_ALG_HANDLE::default();
16
17 unsafe {
19 let handle = windows::Win32::Security::Cryptography::BCryptOpenAlgorithmProvider(
20 &mut handle,
21 windows::Win32::Security::Cryptography::BCRYPT_AES_ALGORITHM,
22 None,
23 BCRYPT_OPEN_ALGORITHM_PROVIDER_FLAGS(0),
24 )
25 .ok()
26 .map(|()| AlgHandle(handle))
27 .map_err(|e| err(e, "open algorithm provider"))?;
28
29 windows::Win32::Security::Cryptography::BCryptSetProperty(
30 handle.0.into(),
31 windows::Win32::Security::Cryptography::BCRYPT_CHAINING_MODE,
32 CHAINING_MODE.as_bytes(),
33 0,
34 )
35 .ok()
36 .map_err(|e| err(e, "setting GCM Property"))?;
37
38 Ok(handle)
39 }
40});
41
42fn err(err: windows_result::Error, op: &'static str) -> Aes256GcmError {
43 Aes256GcmError(crate::BackendError(err, op))
44}
45
46pub struct Aes256GcmInner {
47 key: KeyHandle,
48}
49
50pub struct Aes256GcmEncCtxInner<'a> {
51 key: &'a KeyHandle,
52}
53
54pub struct Aes256GcmDecCtxInner<'a> {
55 key: &'a KeyHandle,
56}
57
58impl Aes256GcmInner {
59 pub fn new(key: &[u8; KEY_LEN]) -> Result<Self, Aes256GcmError> {
60 let mut handle = BCRYPT_KEY_HANDLE::default();
61 let key = unsafe {
63 windows::Win32::Security::Cryptography::BCryptImportKey(
64 AES_256_GCM.as_ref().map_err(|e| e.clone())?.0,
65 None,
66 windows::Win32::Security::Cryptography::BCRYPT_KEY_DATA_BLOB,
67 &mut handle,
68 None,
69 KeyBlob32::new(key).as_bytes(),
70 0,
71 )
72 }
73 .ok()
74 .map(|()| KeyHandle(handle))
75 .map_err(|e| err(e, "importing key"))?;
76
77 Ok(Aes256GcmInner { key })
78 }
79
80 pub fn enc_ctx(&self) -> Result<Aes256GcmEncCtxInner<'_>, Aes256GcmError> {
81 Ok(Aes256GcmEncCtxInner { key: &self.key })
82 }
83
84 pub fn dec_ctx(&self) -> Result<Aes256GcmDecCtxInner<'_>, Aes256GcmError> {
85 Ok(Aes256GcmDecCtxInner { key: &self.key })
86 }
87}
88
89impl Aes256GcmEncCtxInner<'_> {
90 pub fn cipher(
91 &mut self,
92 iv: &[u8],
93 data: &[u8],
94 tag: &mut [u8],
95 ) -> Result<Vec<u8>, Aes256GcmError> {
96 let mut crypted_len = 0;
97 let mut iv_buffer = iv.to_vec();
98 let mut nonce_buffer = iv.to_vec();
99 let mut crypted_data = vec![0; data.len()];
100
101 let mut auth_mode = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO {
102 cbSize: size_of::<BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO>() as u32,
103 dwInfoVersion: windows::Win32::Security::Cryptography::BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION,
104 pbNonce: nonce_buffer.as_mut_ptr(),
105 cbNonce: nonce_buffer.len() as u32,
106 pbTag: tag.as_mut_ptr(),
107 cbTag: tag.len() as u32,
108 ..Default::default()
109 };
110
111 unsafe {
113 windows::Win32::Security::Cryptography::BCryptEncrypt(
114 self.key.0,
115 Some(data),
116 Some(std::ptr::from_mut(&mut auth_mode).cast()),
117 Some(&mut iv_buffer),
118 Some(&mut crypted_data),
119 &mut crypted_len,
120 windows::Win32::Security::Cryptography::BCRYPT_FLAGS(0),
121 )
122 .ok()
123 .map_err(|e| err(e, "encrypt"))
124 }?;
125 assert_eq!(crypted_len as usize, data.len());
126 Ok(crypted_data)
127 }
128}
129
130impl Aes256GcmDecCtxInner<'_> {
131 pub fn cipher(
132 &mut self,
133 iv: &[u8],
134 data: &[u8],
135 tag: &[u8],
136 ) -> Result<Vec<u8>, Aes256GcmError> {
137 let mut crypted_len = 0;
138 let mut iv_buffer = iv.to_vec();
139 let mut nonce_buffer = iv.to_vec();
140 let mut crypted_data = vec![0; data.len()];
141 let mut tag_buffer = tag.to_vec();
142
143 let mut auth_mode = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO {
144 cbSize: size_of::<BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO>() as u32,
145 dwInfoVersion: windows::Win32::Security::Cryptography::BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION,
146 pbNonce: nonce_buffer.as_mut_ptr(),
147 cbNonce: nonce_buffer.len() as u32,
148 pbTag: tag_buffer.as_mut_ptr(),
149 cbTag: tag_buffer.len() as u32,
150 ..Default::default()
151 };
152
153 unsafe {
155 windows::Win32::Security::Cryptography::BCryptDecrypt(
156 self.key.0,
157 Some(data),
158 Some(std::ptr::from_mut(&mut auth_mode).cast()),
159 Some(&mut iv_buffer),
160 Some(&mut crypted_data),
161 &mut crypted_len,
162 windows::Win32::Security::Cryptography::BCRYPT_FLAGS(0),
163 )
164 .ok()
165 .map_err(|e| err(e, "decrypt"))
166 }?;
167 assert_eq!(crypted_len as usize, data.len());
168 Ok(crypted_data)
169 }
170}