1use crate::core_arch::x86::__m128i;
6use crate::ptr;
7
8#[cfg(test)]
9use stdarch_test::assert_instr;
10
11#[repr(C, packed)]
12struct EncodeKey128Output(u32, __m128i, __m128i, __m128i, __m128i, __m128i, __m128i);
13
14#[repr(C, packed)]
15struct EncodeKey256Output(
16 u32,
17 __m128i,
18 __m128i,
19 __m128i,
20 __m128i,
21 __m128i,
22 __m128i,
23 __m128i,
24);
25
26#[repr(C, packed)]
27struct AesOutput(u8, __m128i);
28
29#[repr(C, packed)]
30struct WideAesOutput(
31 u8,
32 __m128i,
33 __m128i,
34 __m128i,
35 __m128i,
36 __m128i,
37 __m128i,
38 __m128i,
39 __m128i,
40);
41
42#[allow(improper_ctypes)]
43unsafe extern "unadjusted" {
44 #[link_name = "llvm.x86.loadiwkey"]
45 fn loadiwkey(integrity_key: __m128i, key_lo: __m128i, key_hi: __m128i, control: u32);
46
47 #[link_name = "llvm.x86.encodekey128"]
48 fn encodekey128(key_metadata: u32, key: __m128i) -> EncodeKey128Output;
49 #[link_name = "llvm.x86.encodekey256"]
50 fn encodekey256(key_metadata: u32, key_lo: __m128i, key_hi: __m128i) -> EncodeKey256Output;
51
52 #[link_name = "llvm.x86.aesenc128kl"]
53 fn aesenc128kl(data: __m128i, handle: *const u8) -> AesOutput;
54 #[link_name = "llvm.x86.aesdec128kl"]
55 fn aesdec128kl(data: __m128i, handle: *const u8) -> AesOutput;
56 #[link_name = "llvm.x86.aesenc256kl"]
57 fn aesenc256kl(data: __m128i, handle: *const u8) -> AesOutput;
58 #[link_name = "llvm.x86.aesdec256kl"]
59 fn aesdec256kl(data: __m128i, handle: *const u8) -> AesOutput;
60
61 #[link_name = "llvm.x86.aesencwide128kl"]
62 fn aesencwide128kl(
63 handle: *const u8,
64 i0: __m128i,
65 i1: __m128i,
66 i2: __m128i,
67 i3: __m128i,
68 i4: __m128i,
69 i5: __m128i,
70 i6: __m128i,
71 i7: __m128i,
72 ) -> WideAesOutput;
73 #[link_name = "llvm.x86.aesdecwide128kl"]
74 fn aesdecwide128kl(
75 handle: *const u8,
76 i0: __m128i,
77 i1: __m128i,
78 i2: __m128i,
79 i3: __m128i,
80 i4: __m128i,
81 i5: __m128i,
82 i6: __m128i,
83 i7: __m128i,
84 ) -> WideAesOutput;
85 #[link_name = "llvm.x86.aesencwide256kl"]
86 fn aesencwide256kl(
87 handle: *const u8,
88 i0: __m128i,
89 i1: __m128i,
90 i2: __m128i,
91 i3: __m128i,
92 i4: __m128i,
93 i5: __m128i,
94 i6: __m128i,
95 i7: __m128i,
96 ) -> WideAesOutput;
97 #[link_name = "llvm.x86.aesdecwide256kl"]
98 fn aesdecwide256kl(
99 handle: *const u8,
100 i0: __m128i,
101 i1: __m128i,
102 i2: __m128i,
103 i3: __m128i,
104 i4: __m128i,
105 i5: __m128i,
106 i6: __m128i,
107 i7: __m128i,
108 ) -> WideAesOutput;
109}
110
111#[inline]
129#[target_feature(enable = "kl")]
130#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
131#[cfg_attr(test, assert_instr(loadiwkey))]
132pub unsafe fn _mm_loadiwkey(
133 control: u32,
134 integrity_key: __m128i,
135 key_lo: __m128i,
136 key_hi: __m128i,
137) {
138 loadiwkey(integrity_key, key_lo, key_hi, control);
139}
140
141#[inline]
155#[target_feature(enable = "kl")]
156#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
157#[cfg_attr(test, assert_instr(encodekey128))]
158pub unsafe fn _mm_encodekey128_u32(key_params: u32, key: __m128i, handle: *mut u8) -> u32 {
159 let EncodeKey128Output(control, key0, key1, key2, _, _, _) = encodekey128(key_params, key);
160 ptr::write_unaligned(handle.cast(), [key0, key1, key2]);
161 control
162}
163
164#[inline]
178#[target_feature(enable = "kl")]
179#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
180#[cfg_attr(test, assert_instr(encodekey256))]
181pub unsafe fn _mm_encodekey256_u32(
182 key_params: u32,
183 key_lo: __m128i,
184 key_hi: __m128i,
185 handle: *mut u8,
186) -> u32 {
187 let EncodeKey256Output(control, key0, key1, key2, key3, _, _, _) =
188 encodekey256(key_params, key_lo, key_hi);
189 ptr::write_unaligned(handle.cast(), [key0, key1, key2, key3]);
190 control
191}
192
193#[inline]
200#[target_feature(enable = "kl")]
201#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
202#[cfg_attr(test, assert_instr(aesenc128kl))]
203pub unsafe fn _mm_aesenc128kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 {
204 let AesOutput(status, result) = aesenc128kl(input, handle);
205 *output = result;
206 status
207}
208
209#[inline]
216#[target_feature(enable = "kl")]
217#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
218#[cfg_attr(test, assert_instr(aesdec128kl))]
219pub unsafe fn _mm_aesdec128kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 {
220 let AesOutput(status, result) = aesdec128kl(input, handle);
221 *output = result;
222 status
223}
224
225#[inline]
232#[target_feature(enable = "kl")]
233#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
234#[cfg_attr(test, assert_instr(aesenc256kl))]
235pub unsafe fn _mm_aesenc256kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 {
236 let AesOutput(status, result) = aesenc256kl(input, handle);
237 *output = result;
238 status
239}
240
241#[inline]
248#[target_feature(enable = "kl")]
249#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
250#[cfg_attr(test, assert_instr(aesdec256kl))]
251pub unsafe fn _mm_aesdec256kl_u8(output: *mut __m128i, input: __m128i, handle: *const u8) -> u8 {
252 let AesOutput(status, result) = aesdec256kl(input, handle);
253 *output = result;
254 status
255}
256
257#[inline]
264#[target_feature(enable = "widekl")]
265#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
266#[cfg_attr(test, assert_instr(aesencwide128kl))]
267pub unsafe fn _mm_aesencwide128kl_u8(
268 output: *mut __m128i,
269 input: *const __m128i,
270 handle: *const u8,
271) -> u8 {
272 let input = &*ptr::slice_from_raw_parts(input, 8);
273 let WideAesOutput(status, out0, out1, out2, out3, out4, out5, out6, out7) = aesencwide128kl(
274 handle, input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
275 );
276 *output.cast() = [out0, out1, out2, out3, out4, out5, out6, out7];
277 status
278}
279
280#[inline]
287#[target_feature(enable = "widekl")]
288#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
289#[cfg_attr(test, assert_instr(aesdecwide128kl))]
290pub unsafe fn _mm_aesdecwide128kl_u8(
291 output: *mut __m128i,
292 input: *const __m128i,
293 handle: *const u8,
294) -> u8 {
295 let input = &*ptr::slice_from_raw_parts(input, 8);
296 let WideAesOutput(status, out0, out1, out2, out3, out4, out5, out6, out7) = aesdecwide128kl(
297 handle, input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
298 );
299 *output.cast() = [out0, out1, out2, out3, out4, out5, out6, out7];
300 status
301}
302
303#[inline]
310#[target_feature(enable = "widekl")]
311#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
312#[cfg_attr(test, assert_instr(aesencwide256kl))]
313pub unsafe fn _mm_aesencwide256kl_u8(
314 output: *mut __m128i,
315 input: *const __m128i,
316 handle: *const u8,
317) -> u8 {
318 let input = &*ptr::slice_from_raw_parts(input, 8);
319 let WideAesOutput(status, out0, out1, out2, out3, out4, out5, out6, out7) = aesencwide256kl(
320 handle, input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
321 );
322 *output.cast() = [out0, out1, out2, out3, out4, out5, out6, out7];
323 status
324}
325
326#[inline]
333#[target_feature(enable = "widekl")]
334#[stable(feature = "keylocker_x86", since = "CURRENT_RUSTC_VERSION")]
335#[cfg_attr(test, assert_instr(aesdecwide256kl))]
336pub unsafe fn _mm_aesdecwide256kl_u8(
337 output: *mut __m128i,
338 input: *const __m128i,
339 handle: *const u8,
340) -> u8 {
341 let input = &*ptr::slice_from_raw_parts(input, 8);
342 let WideAesOutput(status, out0, out1, out2, out3, out4, out5, out6, out7) = aesdecwide256kl(
343 handle, input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
344 );
345 *output.cast() = [out0, out1, out2, out3, out4, out5, out6, out7];
346 status
347}
348
349#[cfg(test)]
350mod tests {
351 use crate::core_arch::x86::*;
352 use stdarch_test::simd_test;
353
354 #[target_feature(enable = "kl")]
355 unsafe fn encodekey128() -> [u8; 48] {
356 let mut handle = [0; 48];
357 let _ = _mm_encodekey128_u32(0, _mm_setzero_si128(), handle.as_mut_ptr());
358 handle
359 }
360
361 #[target_feature(enable = "kl")]
362 unsafe fn encodekey256() -> [u8; 64] {
363 let mut handle = [0; 64];
364 let _ = _mm_encodekey256_u32(
365 0,
366 _mm_setzero_si128(),
367 _mm_setzero_si128(),
368 handle.as_mut_ptr(),
369 );
370 handle
371 }
372
373 #[simd_test(enable = "kl")]
374 unsafe fn test_mm_encodekey128_u32() {
375 encodekey128();
376 }
377
378 #[simd_test(enable = "kl")]
379 unsafe fn test_mm_encodekey256_u32() {
380 encodekey256();
381 }
382
383 #[simd_test(enable = "kl")]
384 unsafe fn test_mm_aesenc128kl_u8() {
385 let mut buffer = _mm_setzero_si128();
386 let key = encodekey128();
387
388 for _ in 0..100 {
389 let status = _mm_aesenc128kl_u8(&mut buffer, buffer, key.as_ptr());
390 assert_eq!(status, 0);
391 }
392 for _ in 0..100 {
393 let status = _mm_aesdec128kl_u8(&mut buffer, buffer, key.as_ptr());
394 assert_eq!(status, 0);
395 }
396
397 assert_eq_m128i(buffer, _mm_setzero_si128());
398 }
399
400 #[simd_test(enable = "kl")]
401 unsafe fn test_mm_aesdec128kl_u8() {
402 let mut buffer = _mm_setzero_si128();
403 let key = encodekey128();
404
405 for _ in 0..100 {
406 let status = _mm_aesdec128kl_u8(&mut buffer, buffer, key.as_ptr());
407 assert_eq!(status, 0);
408 }
409 for _ in 0..100 {
410 let status = _mm_aesenc128kl_u8(&mut buffer, buffer, key.as_ptr());
411 assert_eq!(status, 0);
412 }
413
414 assert_eq_m128i(buffer, _mm_setzero_si128());
415 }
416
417 #[simd_test(enable = "kl")]
418 unsafe fn test_mm_aesenc256kl_u8() {
419 let mut buffer = _mm_setzero_si128();
420 let key = encodekey256();
421
422 for _ in 0..100 {
423 let status = _mm_aesenc256kl_u8(&mut buffer, buffer, key.as_ptr());
424 assert_eq!(status, 0);
425 }
426 for _ in 0..100 {
427 let status = _mm_aesdec256kl_u8(&mut buffer, buffer, key.as_ptr());
428 assert_eq!(status, 0);
429 }
430
431 assert_eq_m128i(buffer, _mm_setzero_si128());
432 }
433
434 #[simd_test(enable = "kl")]
435 unsafe fn test_mm_aesdec256kl_u8() {
436 let mut buffer = _mm_setzero_si128();
437 let key = encodekey256();
438
439 for _ in 0..100 {
440 let status = _mm_aesdec256kl_u8(&mut buffer, buffer, key.as_ptr());
441 assert_eq!(status, 0);
442 }
443 for _ in 0..100 {
444 let status = _mm_aesenc256kl_u8(&mut buffer, buffer, key.as_ptr());
445 assert_eq!(status, 0);
446 }
447
448 assert_eq_m128i(buffer, _mm_setzero_si128());
449 }
450
451 #[simd_test(enable = "widekl")]
452 unsafe fn test_mm_aesencwide128kl_u8() {
453 let mut buffer = [_mm_setzero_si128(); 8];
454 let key = encodekey128();
455
456 for _ in 0..100 {
457 let status = _mm_aesencwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
458 assert_eq!(status, 0);
459 }
460 for _ in 0..100 {
461 let status = _mm_aesdecwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
462 assert_eq!(status, 0);
463 }
464
465 for elem in buffer {
466 assert_eq_m128i(elem, _mm_setzero_si128());
467 }
468 }
469
470 #[simd_test(enable = "widekl")]
471 unsafe fn test_mm_aesdecwide128kl_u8() {
472 let mut buffer = [_mm_setzero_si128(); 8];
473 let key = encodekey128();
474
475 for _ in 0..100 {
476 let status = _mm_aesdecwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
477 assert_eq!(status, 0);
478 }
479 for _ in 0..100 {
480 let status = _mm_aesencwide128kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
481 assert_eq!(status, 0);
482 }
483
484 for elem in buffer {
485 assert_eq_m128i(elem, _mm_setzero_si128());
486 }
487 }
488
489 #[simd_test(enable = "widekl")]
490 unsafe fn test_mm_aesencwide256kl_u8() {
491 let mut buffer = [_mm_setzero_si128(); 8];
492 let key = encodekey256();
493
494 for _ in 0..100 {
495 let status = _mm_aesencwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
496 assert_eq!(status, 0);
497 }
498 for _ in 0..100 {
499 let status = _mm_aesdecwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
500 assert_eq!(status, 0);
501 }
502
503 for elem in buffer {
504 assert_eq_m128i(elem, _mm_setzero_si128());
505 }
506 }
507
508 #[simd_test(enable = "widekl")]
509 unsafe fn test_mm_aesdecwide256kl_u8() {
510 let mut buffer = [_mm_setzero_si128(); 8];
511 let key = encodekey256();
512
513 for _ in 0..100 {
514 let status = _mm_aesdecwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
515 assert_eq!(status, 0);
516 }
517 for _ in 0..100 {
518 let status = _mm_aesencwide256kl_u8(buffer.as_mut_ptr(), buffer.as_ptr(), key.as_ptr());
519 assert_eq!(status, 0);
520 }
521
522 for elem in buffer {
523 assert_eq_m128i(elem, _mm_setzero_si128());
524 }
525 }
526}