1mod ffi;
6
7#[derive(Debug)]
8pub enum Error {
9 SdkInitError,
10 SdkGenericError,
11 SdkKmsConfigError,
12 SdkKmsClientError,
13 SdkKmsDecryptError,
14 SdkKmsEncryptError,
15}
16
17pub fn kms_decrypt(
20 aws_region: &[u8],
21 aws_key_id: &[u8],
22 aws_secret_key: &[u8],
23 aws_session_token: &[u8],
24 ciphertext: &[u8],
25) -> Result<Vec<u8>, Error> {
26 unsafe {
28 ffi::aws_nitro_enclaves_library_init(std::ptr::null_mut());
29 };
30
31 let allocator = unsafe { ffi::aws_nitro_enclaves_get_allocator() };
33 if allocator.is_null() {
34 unsafe {
35 ffi::aws_nitro_enclaves_library_clean_up();
36 }
37 return Err(Error::SdkInitError);
38 }
39 let region = unsafe {
41 let reg = ffi::aws_string_new_from_array(allocator, aws_region.as_ptr(), aws_region.len());
42 if reg.is_null() {
43 ffi::aws_nitro_enclaves_library_clean_up();
44 return Err(Error::SdkGenericError);
45 }
46 reg
47 };
48 let mut endpoint = {
50 let mut ep = ffi::aws_socket_endpoint {
51 address: [0; ffi::AWS_ADDRESS_MAX_LEN],
52 port: ffi::AWS_NE_VSOCK_PROXY_PORT,
53 };
54 ep.address[..ffi::AWS_NE_VSOCK_PROXY_ADDR.len()]
55 .copy_from_slice(&ffi::AWS_NE_VSOCK_PROXY_ADDR);
56 ep
57 };
58 let key_id = unsafe {
60 let kid = ffi::aws_string_new_from_array(allocator, aws_key_id.as_ptr(), aws_key_id.len());
61 if kid.is_null() {
62 ffi::aws_string_destroy_secure(region);
63 ffi::aws_nitro_enclaves_library_clean_up();
64 return Err(Error::SdkGenericError);
65 }
66 kid
67 };
68 let secret_key = unsafe {
70 let skey = ffi::aws_string_new_from_array(
71 allocator,
72 aws_secret_key.as_ptr(),
73 aws_secret_key.len(),
74 );
75 if skey.is_null() {
76 ffi::aws_string_destroy_secure(key_id);
77 ffi::aws_string_destroy_secure(region);
78 ffi::aws_nitro_enclaves_library_clean_up();
79 return Err(Error::SdkGenericError);
80 }
81 skey
82 };
83 let session_token = unsafe {
85 let sess_token = ffi::aws_string_new_from_array(
86 allocator,
87 aws_session_token.as_ptr(),
88 aws_session_token.len(),
89 );
90 if sess_token.is_null() {
91 ffi::aws_string_destroy_secure(secret_key);
92 ffi::aws_string_destroy_secure(key_id);
93 ffi::aws_string_destroy_secure(region);
94 ffi::aws_nitro_enclaves_library_clean_up();
95 return Err(Error::SdkGenericError);
96 }
97 sess_token
98 };
99 let kms_client_cfg = unsafe {
101 let cfg = ffi::aws_nitro_enclaves_kms_client_config_default(
103 region,
104 &mut endpoint,
105 ffi::AWS_SOCKET_VSOCK_DOMAIN,
106 key_id,
107 secret_key,
108 session_token,
109 );
110
111 if cfg.is_null() {
112 ffi::aws_string_destroy_secure(key_id);
113 ffi::aws_string_destroy_secure(secret_key);
114 ffi::aws_string_destroy_secure(session_token);
115 ffi::aws_string_destroy_secure(region);
116 ffi::aws_nitro_enclaves_library_clean_up();
117 return Err(Error::SdkKmsConfigError);
118 }
119 cfg
120 };
121 let kms_client = unsafe { ffi::aws_nitro_enclaves_kms_client_new(kms_client_cfg) };
123 if kms_client.is_null() {
124 unsafe {
125 ffi::aws_string_destroy_secure(key_id);
126 ffi::aws_string_destroy_secure(secret_key);
127 ffi::aws_string_destroy_secure(session_token);
128 ffi::aws_string_destroy_secure(region);
129 ffi::aws_nitro_enclaves_kms_client_config_destroy(kms_client_cfg);
130 ffi::aws_nitro_enclaves_library_clean_up();
131 }
132 return Err(Error::SdkKmsClientError);
133 }
134 let ciphertext_buf = unsafe {
136 ffi::aws_byte_buf_from_array(ciphertext.as_ptr() as *mut ffi::c_void, ciphertext.len())
137 };
138
139 let mut plaintext_buf: ffi::aws_byte_buf = unsafe { std::mem::zeroed() };
141 let rc =
142 unsafe { ffi::aws_kms_decrypt_blocking(kms_client, &ciphertext_buf, &mut plaintext_buf) };
143 if rc != 0 {
144 unsafe {
145 ffi::aws_string_destroy_secure(key_id);
146 ffi::aws_string_destroy_secure(secret_key);
147 ffi::aws_string_destroy_secure(session_token);
148 ffi::aws_string_destroy_secure(region);
149 ffi::aws_nitro_enclaves_kms_client_config_destroy(kms_client_cfg);
150 ffi::aws_nitro_enclaves_kms_client_destroy(kms_client);
151 ffi::aws_nitro_enclaves_library_clean_up();
152 }
153 return Err(Error::SdkKmsDecryptError);
154 }
155
156 unsafe {
158 ffi::aws_string_destroy_secure(key_id);
159 ffi::aws_string_destroy_secure(secret_key);
160 ffi::aws_string_destroy_secure(session_token);
161 ffi::aws_string_destroy_secure(region);
162 ffi::aws_nitro_enclaves_kms_client_config_destroy(kms_client_cfg);
163 ffi::aws_nitro_enclaves_kms_client_destroy(kms_client);
164 ffi::aws_nitro_enclaves_library_clean_up();
165 }
166
167 let plaintext = unsafe {
169 std::slice::from_raw_parts(plaintext_buf.buffer, plaintext_buf.len as usize).to_vec()
170 };
171 unsafe { ffi::aws_byte_buf_clean_up_secure(&mut plaintext_buf) };
172
173 Ok(plaintext)
174}
175
176pub fn seed_entropy(bytes_to_seed: usize) -> Result<(), ()> {
178 let rc = unsafe { ffi::aws_nitro_enclaves_library_seed_entropy(bytes_to_seed) };
179 if rc == 0 {
180 Ok(())
181 } else {
182 Err(())
183 }
184}
185
186pub fn kms_encrypt(
189 aws_region: &[u8],
190 aws_key_id: &[u8],
191 aws_secret_key: &[u8],
192 aws_session_token: &[u8],
193 aws_kms_key_id: &[u8],
194 plaintext: &[u8],
195) -> Result<Vec<u8>, Error> {
196 unsafe {
198 ffi::aws_nitro_enclaves_library_init(std::ptr::null_mut());
199 };
200
201 let allocator = unsafe { ffi::aws_nitro_enclaves_get_allocator() };
203 if allocator.is_null() {
204 unsafe {
205 ffi::aws_nitro_enclaves_library_clean_up();
206 }
207 return Err(Error::SdkInitError);
208 }
209 let region = unsafe {
211 let reg = ffi::aws_string_new_from_array(allocator, aws_region.as_ptr(), aws_region.len());
212 if reg.is_null() {
213 ffi::aws_nitro_enclaves_library_clean_up();
214 return Err(Error::SdkGenericError);
215 }
216 reg
217 };
218 let mut endpoint = {
220 let mut ep = ffi::aws_socket_endpoint {
221 address: [0; ffi::AWS_ADDRESS_MAX_LEN],
222 port: ffi::AWS_NE_VSOCK_PROXY_PORT,
223 };
224 ep.address[..ffi::AWS_NE_VSOCK_PROXY_ADDR.len()]
225 .copy_from_slice(&ffi::AWS_NE_VSOCK_PROXY_ADDR);
226 ep
227 };
228 let key_id = unsafe {
230 let kid = ffi::aws_string_new_from_array(allocator, aws_key_id.as_ptr(), aws_key_id.len());
231 if kid.is_null() {
232 ffi::aws_string_destroy_secure(region);
233 ffi::aws_nitro_enclaves_library_clean_up();
234 return Err(Error::SdkGenericError);
235 }
236 kid
237 };
238 let secret_key = unsafe {
240 let skey = ffi::aws_string_new_from_array(
241 allocator,
242 aws_secret_key.as_ptr(),
243 aws_secret_key.len(),
244 );
245 if skey.is_null() {
246 ffi::aws_string_destroy_secure(key_id);
247 ffi::aws_string_destroy_secure(region);
248 ffi::aws_nitro_enclaves_library_clean_up();
249 return Err(Error::SdkGenericError);
250 }
251 skey
252 };
253 let session_token = unsafe {
255 let sess_token = ffi::aws_string_new_from_array(
256 allocator,
257 aws_session_token.as_ptr(),
258 aws_session_token.len(),
259 );
260 if sess_token.is_null() {
261 ffi::aws_string_destroy_secure(secret_key);
262 ffi::aws_string_destroy_secure(key_id);
263 ffi::aws_string_destroy_secure(region);
264 ffi::aws_nitro_enclaves_library_clean_up();
265 return Err(Error::SdkGenericError);
266 }
267 sess_token
268 };
269 let kms_key_id = unsafe {
271 let kms_kid = ffi::aws_string_new_from_array(
272 allocator,
273 aws_kms_key_id.as_ptr(),
274 aws_kms_key_id.len(),
275 );
276 if kms_kid.is_null() {
277 ffi::aws_string_destroy_secure(secret_key);
278 ffi::aws_string_destroy_secure(key_id);
279 ffi::aws_string_destroy_secure(region);
280 ffi::aws_string_destroy_secure(session_token);
281 ffi::aws_nitro_enclaves_library_clean_up();
282 return Err(Error::SdkGenericError);
283 }
284 kms_kid
285 };
286
287 let kms_client_cfg = unsafe {
289 let cfg = ffi::aws_nitro_enclaves_kms_client_config_default(
291 region,
292 &mut endpoint,
293 ffi::AWS_SOCKET_VSOCK_DOMAIN,
294 key_id,
295 secret_key,
296 session_token,
297 );
298
299 if cfg.is_null() {
300 ffi::aws_string_destroy_secure(key_id);
301 ffi::aws_string_destroy_secure(secret_key);
302 ffi::aws_string_destroy_secure(session_token);
303 ffi::aws_string_destroy_secure(region);
304 ffi::aws_string_destroy_secure(kms_key_id);
305 ffi::aws_nitro_enclaves_library_clean_up();
306 return Err(Error::SdkKmsConfigError);
307 }
308 cfg
309 };
310 let kms_client = unsafe { ffi::aws_nitro_enclaves_kms_client_new(kms_client_cfg) };
312 if kms_client.is_null() {
313 unsafe {
314 ffi::aws_string_destroy_secure(key_id);
315 ffi::aws_string_destroy_secure(secret_key);
316 ffi::aws_string_destroy_secure(session_token);
317 ffi::aws_string_destroy_secure(region);
318 ffi::aws_string_destroy_secure(kms_key_id);
319 ffi::aws_nitro_enclaves_kms_client_config_destroy(kms_client_cfg);
320 ffi::aws_nitro_enclaves_library_clean_up();
321 }
322 return Err(Error::SdkKmsClientError);
323 }
324 let plaintext_buf = unsafe {
326 ffi::aws_byte_buf_from_array(plaintext.as_ptr() as *mut ffi::c_void, plaintext.len())
327 };
328
329 let mut ciphertext_buf: ffi::aws_byte_buf = unsafe { std::mem::zeroed() };
331 let rc = unsafe {
332 ffi::aws_kms_encrypt_blocking(kms_client, kms_key_id, &plaintext_buf, &mut ciphertext_buf)
333 };
334 if rc != 0 {
335 unsafe {
336 ffi::aws_string_destroy_secure(key_id);
337 ffi::aws_string_destroy_secure(secret_key);
338 ffi::aws_string_destroy_secure(session_token);
339 ffi::aws_string_destroy_secure(region);
340 ffi::aws_string_destroy_secure(kms_key_id);
341 ffi::aws_nitro_enclaves_kms_client_config_destroy(kms_client_cfg);
342 ffi::aws_nitro_enclaves_kms_client_destroy(kms_client);
343 ffi::aws_nitro_enclaves_library_clean_up();
344 }
345 return Err(Error::SdkKmsEncryptError);
346 }
347
348 unsafe {
350 ffi::aws_string_destroy_secure(key_id);
351 ffi::aws_string_destroy_secure(secret_key);
352 ffi::aws_string_destroy_secure(session_token);
353 ffi::aws_string_destroy_secure(region);
354 ffi::aws_string_destroy_secure(kms_key_id);
355 ffi::aws_nitro_enclaves_kms_client_config_destroy(kms_client_cfg);
356 ffi::aws_nitro_enclaves_kms_client_destroy(kms_client);
357 ffi::aws_nitro_enclaves_library_clean_up();
358 }
359
360 let ciphertext = unsafe {
362 std::slice::from_raw_parts(ciphertext_buf.buffer, ciphertext_buf.len as usize).to_vec()
363 };
364 unsafe { ffi::aws_byte_buf_clean_up_secure(&mut ciphertext_buf) };
365
366 Ok(ciphertext)
367}