xref: /freebsd/contrib/llvm-project/clang/lib/Headers/keylockerintrin.h (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
1e8d8bef9SDimitry Andric /*===----------------- keylockerintrin.h - KL Intrinsics -------------------===
2e8d8bef9SDimitry Andric  *
3e8d8bef9SDimitry Andric  * Permission is hereby granted, free of charge, to any person obtaining a copy
4e8d8bef9SDimitry Andric  * of this software and associated documentation files (the "Software"), to deal
5e8d8bef9SDimitry Andric  * in the Software without restriction, including without limitation the rights
6e8d8bef9SDimitry Andric  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7e8d8bef9SDimitry Andric  * copies of the Software, and to permit persons to whom the Software is
8e8d8bef9SDimitry Andric  * furnished to do so, subject to the following conditions:
9e8d8bef9SDimitry Andric  *
10e8d8bef9SDimitry Andric  * The above copyright notice and this permission notice shall be included in
11e8d8bef9SDimitry Andric  * all copies or substantial portions of the Software.
12e8d8bef9SDimitry Andric  *
13e8d8bef9SDimitry Andric  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14e8d8bef9SDimitry Andric  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15e8d8bef9SDimitry Andric  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16e8d8bef9SDimitry Andric  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17e8d8bef9SDimitry Andric  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18e8d8bef9SDimitry Andric  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19e8d8bef9SDimitry Andric  * THE SOFTWARE.
20e8d8bef9SDimitry Andric  *
21e8d8bef9SDimitry Andric  *===-----------------------------------------------------------------------===
22e8d8bef9SDimitry Andric  */
23e8d8bef9SDimitry Andric 
24e8d8bef9SDimitry Andric #ifndef __IMMINTRIN_H
25e8d8bef9SDimitry Andric #error "Never use <keylockerintrin.h> directly; include <immintrin.h> instead."
26e8d8bef9SDimitry Andric #endif
27e8d8bef9SDimitry Andric 
28e8d8bef9SDimitry Andric #ifndef _KEYLOCKERINTRIN_H
29e8d8bef9SDimitry Andric #define _KEYLOCKERINTRIN_H
30e8d8bef9SDimitry Andric 
31e8d8bef9SDimitry Andric #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
32e8d8bef9SDimitry Andric     defined(__KL__)
33e8d8bef9SDimitry Andric 
34e8d8bef9SDimitry Andric /* Define the default attributes for the functions in this file. */
35e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS \
36e8d8bef9SDimitry Andric   __attribute__((__always_inline__, __nodebug__, __target__("kl"),\
37e8d8bef9SDimitry Andric                  __min_vector_width__(128)))
38e8d8bef9SDimitry Andric 
39e8d8bef9SDimitry Andric /// Load internal wrapping key from __intkey, __enkey_lo and __enkey_hi. __ctl
40e8d8bef9SDimitry Andric /// will assigned to EAX, whch specifies the KeySource and whether backing up
41e8d8bef9SDimitry Andric /// the key is permitted. The 256-bit encryption key is loaded from the two
42e8d8bef9SDimitry Andric /// explicit operands (__enkey_lo and __enkey_hi). The 128-bit integrity key is
43e8d8bef9SDimitry Andric /// loaded from the implicit operand XMM0 which assigned by __intkey.
44e8d8bef9SDimitry Andric ///
45e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
46e8d8bef9SDimitry Andric ///
47e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> LOADIWKEY </c> instructions.
48e8d8bef9SDimitry Andric ///
49e8d8bef9SDimitry Andric /// \operation
50e8d8bef9SDimitry Andric /// IF CPL > 0 // LOADKWKEY only allowed at ring 0 (supervisor mode)
51e8d8bef9SDimitry Andric ///   GP (0)
52e8d8bef9SDimitry Andric /// FI
53e8d8bef9SDimitry Andric /// IF “LOADIWKEY exiting” VM execution control set
54e8d8bef9SDimitry Andric ///   VMexit
55e8d8bef9SDimitry Andric /// FI
56e8d8bef9SDimitry Andric /// IF __ctl[4:1] > 1 // Reserved KeySource encoding used
57e8d8bef9SDimitry Andric ///   GP (0)
58e8d8bef9SDimitry Andric /// FI
59e8d8bef9SDimitry Andric /// IF __ctl[31:5] != 0 // Reserved bit in __ctl is set
60e8d8bef9SDimitry Andric ///   GP (0)
61e8d8bef9SDimitry Andric /// FI
62e8d8bef9SDimitry Andric /// IF __ctl[0] AND (CPUID.19H.ECX[0] == 0) // NoBackup is not supported on this part
63e8d8bef9SDimitry Andric ///   GP (0)
64e8d8bef9SDimitry Andric /// FI
65e8d8bef9SDimitry Andric /// IF (__ctl[4:1] == 1) AND (CPUID.19H.ECX[1] == 0) // KeySource of 1 is not supported on this part
66e8d8bef9SDimitry Andric ///   GP (0)
67e8d8bef9SDimitry Andric /// FI
68e8d8bef9SDimitry Andric /// IF (__ctl[4:1] == 0) // KeySource of 0.
69e8d8bef9SDimitry Andric ///   IWKey.Encryption Key[127:0] := __enkey_hi[127:0]:
70e8d8bef9SDimitry Andric ///   IWKey.Encryption Key[255:128] := __enkey_lo[127:0]
71e8d8bef9SDimitry Andric ///   IWKey.IntegrityKey[127:0] := __intkey[127:0]
72e8d8bef9SDimitry Andric ///   IWKey.NoBackup := __ctl[0]
73e8d8bef9SDimitry Andric ///   IWKey.KeySource := __ctl[4:1]
74e8d8bef9SDimitry Andric ///   ZF := 0
75e8d8bef9SDimitry Andric /// ELSE // KeySource of 1. See RDSEED definition for details of randomness
76e8d8bef9SDimitry Andric ///   IF HW_NRND_GEN.ready == 1 // Full-entropy random data from RDSEED was received
77e8d8bef9SDimitry Andric ///     IWKey.Encryption Key[127:0] := __enkey_hi[127:0] XOR HW_NRND_GEN.data[127:0]
78e8d8bef9SDimitry Andric ///     IWKey.Encryption Key[255:128] := __enkey_lo[127:0] XOR HW_NRND_GEN.data[255:128]
79e8d8bef9SDimitry Andric ///     IWKey.Encryption Key[255:0] := __enkey_hi[127:0]:__enkey_lo[127:0] XOR HW_NRND_GEN.data[255:0]
80e8d8bef9SDimitry Andric ///     IWKey.IntegrityKey[127:0] := __intkey[127:0] XOR HW_NRND_GEN.data[383:256]
81e8d8bef9SDimitry Andric ///     IWKey.NoBackup := __ctl[0]
82e8d8bef9SDimitry Andric ///     IWKey.KeySource := __ctl[4:1]
83e8d8bef9SDimitry Andric ///     ZF := 0
84e8d8bef9SDimitry Andric ///   ELSE // Random data was not returned from RDSEED. IWKey was not loaded
85e8d8bef9SDimitry Andric ///     ZF := 1
86e8d8bef9SDimitry Andric ///   FI
87e8d8bef9SDimitry Andric /// FI
88e8d8bef9SDimitry Andric /// dst := ZF
89e8d8bef9SDimitry Andric /// OF := 0
90e8d8bef9SDimitry Andric /// SF := 0
91e8d8bef9SDimitry Andric /// AF := 0
92e8d8bef9SDimitry Andric /// PF := 0
93e8d8bef9SDimitry Andric /// CF := 0
94e8d8bef9SDimitry Andric /// \endoperation
95e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
96e8d8bef9SDimitry Andric _mm_loadiwkey (unsigned int __ctl, __m128i __intkey,
97e8d8bef9SDimitry Andric                __m128i __enkey_lo, __m128i __enkey_hi) {
98e8d8bef9SDimitry Andric   __builtin_ia32_loadiwkey (__intkey, __enkey_lo, __enkey_hi, __ctl);
99e8d8bef9SDimitry Andric }
100e8d8bef9SDimitry Andric 
101e8d8bef9SDimitry Andric /// Wrap a 128-bit AES key from __key into a key handle and output in
102*349cc55cSDimitry Andric /// ((__m128i*)__h) to ((__m128i*)__h) + 2  and a 32-bit value as return.
103e8d8bef9SDimitry Andric /// The explicit source operand __htype specifies handle restrictions.
104e8d8bef9SDimitry Andric ///
105e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
106e8d8bef9SDimitry Andric ///
107e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> ENCODEKEY128 </c> instructions.
108e8d8bef9SDimitry Andric ///
109e8d8bef9SDimitry Andric /// \operation
110e8d8bef9SDimitry Andric /// InputKey[127:0] := __key[127:0]
111e8d8bef9SDimitry Andric /// KeyMetadata[2:0] := __htype[2:0]
112e8d8bef9SDimitry Andric /// KeyMetadata[23:3] := 0 // Reserved for future usage
113e8d8bef9SDimitry Andric /// KeyMetadata[27:24] := 0 // KeyType is AES-128 (value of 0)
114e8d8bef9SDimitry Andric /// KeyMetadata[127:28] := 0 // Reserved for future usage
115e8d8bef9SDimitry Andric /// Handle[383:0] := WrapKey128(InputKey[127:0], KeyMetadata[127:0],
116e8d8bef9SDimitry Andric ///                  IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])
117e8d8bef9SDimitry Andric /// dst[0] := IWKey.NoBackup
118e8d8bef9SDimitry Andric /// dst[4:1] := IWKey.KeySource[3:0]
119e8d8bef9SDimitry Andric /// dst[31:5] := 0
120e8d8bef9SDimitry Andric /// MEM[__h+127:__h] := Handle[127:0]   // AAD
121e8d8bef9SDimitry Andric /// MEM[__h+255:__h+128] := Handle[255:128] // Integrity Tag
122e8d8bef9SDimitry Andric /// MEM[__h+383:__h+256] := Handle[383:256] // CipherText
123e8d8bef9SDimitry Andric /// OF := 0
124e8d8bef9SDimitry Andric /// SF := 0
125e8d8bef9SDimitry Andric /// ZF := 0
126e8d8bef9SDimitry Andric /// AF := 0
127e8d8bef9SDimitry Andric /// PF := 0
128e8d8bef9SDimitry Andric /// CF := 0
129e8d8bef9SDimitry Andric /// \endoperation
130e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
131e8d8bef9SDimitry Andric _mm_encodekey128_u32(unsigned int __htype, __m128i __key, void *__h) {
132e8d8bef9SDimitry Andric   return __builtin_ia32_encodekey128_u32(__htype, (__v2di)__key, __h);
133e8d8bef9SDimitry Andric }
134e8d8bef9SDimitry Andric 
135e8d8bef9SDimitry Andric /// Wrap a 256-bit AES key from __key_hi:__key_lo into a key handle, then
136*349cc55cSDimitry Andric /// output handle in ((__m128i*)__h) to ((__m128i*)__h) + 3 and
137e8d8bef9SDimitry Andric /// a 32-bit value as return.
138e8d8bef9SDimitry Andric /// The explicit source operand __htype specifies handle restrictions.
139e8d8bef9SDimitry Andric ///
140e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
141e8d8bef9SDimitry Andric ///
142e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> ENCODEKEY256 </c> instructions.
143e8d8bef9SDimitry Andric ///
144e8d8bef9SDimitry Andric /// \operation
145e8d8bef9SDimitry Andric /// InputKey[127:0] := __key_lo[127:0]
146e8d8bef9SDimitry Andric /// InputKey[255:128] := __key_hi[255:128]
147e8d8bef9SDimitry Andric /// KeyMetadata[2:0] := __htype[2:0]
148e8d8bef9SDimitry Andric /// KeyMetadata[23:3] := 0 // Reserved for future usage
149e8d8bef9SDimitry Andric /// KeyMetadata[27:24] := 1 // KeyType is AES-256 (value of 1)
150e8d8bef9SDimitry Andric /// KeyMetadata[127:28] := 0 // Reserved for future usage
151e8d8bef9SDimitry Andric /// Handle[511:0] := WrapKey256(InputKey[255:0], KeyMetadata[127:0],
152e8d8bef9SDimitry Andric ///                  IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])
153e8d8bef9SDimitry Andric /// dst[0] := IWKey.NoBackup
154e8d8bef9SDimitry Andric /// dst[4:1] := IWKey.KeySource[3:0]
155e8d8bef9SDimitry Andric /// dst[31:5] := 0
156e8d8bef9SDimitry Andric /// MEM[__h+127:__h]   := Handle[127:0] // AAD
157e8d8bef9SDimitry Andric /// MEM[__h+255:__h+128] := Handle[255:128] // Tag
158e8d8bef9SDimitry Andric /// MEM[__h+383:__h+256] := Handle[383:256] // CipherText[127:0]
159e8d8bef9SDimitry Andric /// MEM[__h+511:__h+384] := Handle[511:384] // CipherText[255:128]
160e8d8bef9SDimitry Andric /// OF := 0
161e8d8bef9SDimitry Andric /// SF := 0
162e8d8bef9SDimitry Andric /// ZF := 0
163e8d8bef9SDimitry Andric /// AF := 0
164e8d8bef9SDimitry Andric /// PF := 0
165e8d8bef9SDimitry Andric /// CF := 0
166e8d8bef9SDimitry Andric /// \endoperation
167e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
168e8d8bef9SDimitry Andric _mm_encodekey256_u32(unsigned int __htype, __m128i __key_lo, __m128i __key_hi,
169e8d8bef9SDimitry Andric                      void *__h) {
170e8d8bef9SDimitry Andric   return __builtin_ia32_encodekey256_u32(__htype, (__v2di)__key_lo,
171e8d8bef9SDimitry Andric                                          (__v2di)__key_hi, __h);
172e8d8bef9SDimitry Andric }
173e8d8bef9SDimitry Andric 
174e8d8bef9SDimitry Andric /// The AESENC128KL performs 10 rounds of AES to encrypt the __idata using
175e8d8bef9SDimitry Andric /// the 128-bit key in the handle from the __h. It stores the result in the
176e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
177e8d8bef9SDimitry Andric ///
178e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
179e8d8bef9SDimitry Andric ///
180e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENC128KL </c> instructions.
181e8d8bef9SDimitry Andric ///
182e8d8bef9SDimitry Andric /// \operation
183e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.
184e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
185e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
186e8d8bef9SDimitry Andric ///                    Handle[383:256] ||
187e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )
188e8d8bef9SDimitry Andric /// IF (IllegalHandle)
189e8d8bef9SDimitry Andric ///   ZF := 1
190e8d8bef9SDimitry Andric /// ELSE
191e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
192e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
193e8d8bef9SDimitry Andric ///     ZF := 1
194e8d8bef9SDimitry Andric ///   ELSE
195e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES128Encrypt (__idata[127:0], UnwrappedKey)
196e8d8bef9SDimitry Andric ///     ZF := 0
197e8d8bef9SDimitry Andric ///   FI
198e8d8bef9SDimitry Andric /// FI
199e8d8bef9SDimitry Andric /// dst := ZF
200e8d8bef9SDimitry Andric /// OF := 0
201e8d8bef9SDimitry Andric /// SF := 0
202e8d8bef9SDimitry Andric /// AF := 0
203e8d8bef9SDimitry Andric /// PF := 0
204e8d8bef9SDimitry Andric /// CF := 0
205e8d8bef9SDimitry Andric /// \endoperation
206e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
207e8d8bef9SDimitry Andric _mm_aesenc128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
208e8d8bef9SDimitry Andric   return __builtin_ia32_aesenc128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
209e8d8bef9SDimitry Andric }
210e8d8bef9SDimitry Andric 
211e8d8bef9SDimitry Andric /// The AESENC256KL performs 14 rounds of AES to encrypt the __idata using
212e8d8bef9SDimitry Andric /// the 256-bit key in the handle from the __h. It stores the result in the
213e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
214e8d8bef9SDimitry Andric ///
215e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
216e8d8bef9SDimitry Andric ///
217e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENC256KL </c> instructions.
218e8d8bef9SDimitry Andric ///
219e8d8bef9SDimitry Andric /// \operation
220e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h] // Load is not guaranteed to be atomic.
221e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||
222e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
223e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
224e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256 )
225e8d8bef9SDimitry Andric /// IF (IllegalHandle)
226e8d8bef9SDimitry Andric ///   ZF := 1
227fe6060f1SDimitry Andric ///   MEM[__odata+127:__odata] := 0
228e8d8bef9SDimitry Andric /// ELSE
229e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
230e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
231e8d8bef9SDimitry Andric ///     ZF := 1
232fe6060f1SDimitry Andric ///     MEM[__odata+127:__odata] := 0
233e8d8bef9SDimitry Andric ///   ELSE
234e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES256Encrypt (__idata[127:0], UnwrappedKey)
235e8d8bef9SDimitry Andric ///     ZF := 0
236e8d8bef9SDimitry Andric ///   FI
237e8d8bef9SDimitry Andric /// FI
238e8d8bef9SDimitry Andric /// dst := ZF
239e8d8bef9SDimitry Andric /// OF := 0
240e8d8bef9SDimitry Andric /// SF := 0
241e8d8bef9SDimitry Andric /// AF := 0
242e8d8bef9SDimitry Andric /// PF := 0
243e8d8bef9SDimitry Andric /// CF := 0
244e8d8bef9SDimitry Andric /// \endoperation
245e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
246e8d8bef9SDimitry Andric _mm_aesenc256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
247e8d8bef9SDimitry Andric   return __builtin_ia32_aesenc256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
248e8d8bef9SDimitry Andric }
249e8d8bef9SDimitry Andric 
250e8d8bef9SDimitry Andric /// The AESDEC128KL performs 10 rounds of AES to decrypt the __idata using
251e8d8bef9SDimitry Andric /// the 128-bit key in the handle from the __h. It stores the result in the
252e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
253e8d8bef9SDimitry Andric ///
254e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
255e8d8bef9SDimitry Andric ///
256e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDEC128KL </c> instructions.
257e8d8bef9SDimitry Andric ///
258e8d8bef9SDimitry Andric /// \operation
259e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.
260e8d8bef9SDimitry Andric /// IllegalHandle := (HandleReservedBitSet (Handle[383:0]) ||
261e8d8bef9SDimitry Andric ///                  (Handle[127:0] AND (CPL > 0)) ||
262e8d8bef9SDimitry Andric ///                  Handle[383:256] ||
263e8d8bef9SDimitry Andric ///                  HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128)
264e8d8bef9SDimitry Andric /// IF (IllegalHandle)
265e8d8bef9SDimitry Andric ///   ZF := 1
266fe6060f1SDimitry Andric ///   MEM[__odata+127:__odata] := 0
267e8d8bef9SDimitry Andric /// ELSE
268e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
269e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
270e8d8bef9SDimitry Andric ///     ZF := 1
271fe6060f1SDimitry Andric ///     MEM[__odata+127:__odata] := 0
272e8d8bef9SDimitry Andric ///   ELSE
273e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES128Decrypt (__idata[127:0], UnwrappedKey)
274e8d8bef9SDimitry Andric ///     ZF := 0
275e8d8bef9SDimitry Andric ///   FI
276e8d8bef9SDimitry Andric /// FI
277e8d8bef9SDimitry Andric /// dst := ZF
278e8d8bef9SDimitry Andric /// OF := 0
279e8d8bef9SDimitry Andric /// SF := 0
280e8d8bef9SDimitry Andric /// AF := 0
281e8d8bef9SDimitry Andric /// PF := 0
282e8d8bef9SDimitry Andric /// CF := 0
283e8d8bef9SDimitry Andric /// \endoperation
284e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
285e8d8bef9SDimitry Andric _mm_aesdec128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
286e8d8bef9SDimitry Andric   return __builtin_ia32_aesdec128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
287e8d8bef9SDimitry Andric }
288e8d8bef9SDimitry Andric 
289e8d8bef9SDimitry Andric /// The AESDEC256KL performs 10 rounds of AES to decrypt the __idata using
290e8d8bef9SDimitry Andric /// the 256-bit key in the handle from the __h. It stores the result in the
291e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
292e8d8bef9SDimitry Andric ///
293e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
294e8d8bef9SDimitry Andric ///
295e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDEC256KL </c> instructions.
296e8d8bef9SDimitry Andric ///
297e8d8bef9SDimitry Andric /// \operation
298e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
299e8d8bef9SDimitry Andric /// IllegalHandle := (HandleReservedBitSet (Handle[511:0]) ||
300e8d8bef9SDimitry Andric ///                   (Handle[127:0] AND (CPL > 0)) ||
301e8d8bef9SDimitry Andric ///                   Handle[383:256] ||
302e8d8bef9SDimitry Andric ///                   HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256)
303e8d8bef9SDimitry Andric /// IF (IllegalHandle)
304e8d8bef9SDimitry Andric ///   ZF := 1
305fe6060f1SDimitry Andric ///   MEM[__odata+127:__odata] := 0
306e8d8bef9SDimitry Andric /// ELSE
307e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
308e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
309e8d8bef9SDimitry Andric ///     ZF := 1
310fe6060f1SDimitry Andric ///     MEM[__odata+127:__odata] := 0
311e8d8bef9SDimitry Andric ///   ELSE
312e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES256Decrypt (__idata[127:0], UnwrappedKey)
313e8d8bef9SDimitry Andric ///     ZF := 0
314e8d8bef9SDimitry Andric ///   FI
315e8d8bef9SDimitry Andric /// FI
316e8d8bef9SDimitry Andric /// dst := ZF
317e8d8bef9SDimitry Andric /// OF := 0
318e8d8bef9SDimitry Andric /// SF := 0
319e8d8bef9SDimitry Andric /// AF := 0
320e8d8bef9SDimitry Andric /// PF := 0
321e8d8bef9SDimitry Andric /// CF := 0
322e8d8bef9SDimitry Andric /// \endoperation
323e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
324e8d8bef9SDimitry Andric _mm_aesdec256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
325e8d8bef9SDimitry Andric   return __builtin_ia32_aesdec256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
326e8d8bef9SDimitry Andric }
327e8d8bef9SDimitry Andric 
328e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
329e8d8bef9SDimitry Andric 
330e8d8bef9SDimitry Andric #endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \
331e8d8bef9SDimitry Andric           || defined(__KL__) */
332e8d8bef9SDimitry Andric 
333e8d8bef9SDimitry Andric #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
334e8d8bef9SDimitry Andric     defined(__WIDEKL__)
335e8d8bef9SDimitry Andric 
336e8d8bef9SDimitry Andric /* Define the default attributes for the functions in this file. */
337e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS \
338e8d8bef9SDimitry Andric   __attribute__((__always_inline__, __nodebug__, __target__("kl,widekl"),\
339e8d8bef9SDimitry Andric                  __min_vector_width__(128)))
340e8d8bef9SDimitry Andric 
341e8d8bef9SDimitry Andric /// Encrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle
342e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
343e8d8bef9SDimitry Andric /// return the affected ZF flag status.
344e8d8bef9SDimitry Andric ///
345e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
346e8d8bef9SDimitry Andric ///
347e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENCWIDE128KL </c> instructions.
348e8d8bef9SDimitry Andric ///
349e8d8bef9SDimitry Andric /// \operation
350e8d8bef9SDimitry Andric /// Handle := MEM[__h+383:__h]
351e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
352e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
353e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
354e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )
355e8d8bef9SDimitry Andric /// IF (IllegalHandle)
356e8d8bef9SDimitry Andric ///   ZF := 1
357fe6060f1SDimitry Andric ///   FOR i := 0 to 7
358fe6060f1SDimitry Andric ///     __odata[i] := 0
359fe6060f1SDimitry Andric ///   ENDFOR
360e8d8bef9SDimitry Andric /// ELSE
361e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
362e8d8bef9SDimitry Andric ///   IF Authentic == 0
363e8d8bef9SDimitry Andric ///     ZF := 1
364fe6060f1SDimitry Andric ///     FOR i := 0 to 7
365fe6060f1SDimitry Andric ///       __odata[i] := 0
366fe6060f1SDimitry Andric ///     ENDFOR
367e8d8bef9SDimitry Andric ///   ELSE
368e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
369e8d8bef9SDimitry Andric ///       __odata[i] := AES128Encrypt (__idata[i], UnwrappedKey)
370e8d8bef9SDimitry Andric ///     ENDFOR
371e8d8bef9SDimitry Andric ///     ZF := 0
372e8d8bef9SDimitry Andric ///   FI
373e8d8bef9SDimitry Andric /// FI
374e8d8bef9SDimitry Andric /// dst := ZF
375e8d8bef9SDimitry Andric /// OF := 0
376e8d8bef9SDimitry Andric /// SF := 0
377e8d8bef9SDimitry Andric /// AF := 0
378e8d8bef9SDimitry Andric /// PF := 0
379e8d8bef9SDimitry Andric /// CF := 0
380e8d8bef9SDimitry Andric /// \endoperation
381e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
382e8d8bef9SDimitry Andric _mm_aesencwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
383e8d8bef9SDimitry Andric   return __builtin_ia32_aesencwide128kl_u8((__v2di *)__odata,
384e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
385e8d8bef9SDimitry Andric }
386e8d8bef9SDimitry Andric 
387e8d8bef9SDimitry Andric /// Encrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle
388e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
389e8d8bef9SDimitry Andric /// return the affected ZF flag status.
390e8d8bef9SDimitry Andric ///
391e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
392e8d8bef9SDimitry Andric ///
393e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENCWIDE256KL </c> instructions.
394e8d8bef9SDimitry Andric ///
395e8d8bef9SDimitry Andric /// \operation
396e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
397e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||
398e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
399e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
400e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES512 )
401e8d8bef9SDimitry Andric /// IF (IllegalHandle)
402e8d8bef9SDimitry Andric ///   ZF := 1
403fe6060f1SDimitry Andric ///   FOR i := 0 to 7
404fe6060f1SDimitry Andric ///     __odata[i] := 0
405fe6060f1SDimitry Andric ///   ENDFOR
406e8d8bef9SDimitry Andric /// ELSE
407e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
408e8d8bef9SDimitry Andric ///   IF Authentic == 0
409e8d8bef9SDimitry Andric ///     ZF := 1
410fe6060f1SDimitry Andric ///     FOR i := 0 to 7
411fe6060f1SDimitry Andric ///       __odata[i] := 0
412fe6060f1SDimitry Andric ///     ENDFOR
413e8d8bef9SDimitry Andric ///   ELSE
414e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
415e8d8bef9SDimitry Andric ///       __odata[i] := AES256Encrypt (__idata[i], UnwrappedKey)
416e8d8bef9SDimitry Andric ///     ENDFOR
417e8d8bef9SDimitry Andric ///     ZF := 0
418e8d8bef9SDimitry Andric ///   FI
419e8d8bef9SDimitry Andric /// FI
420e8d8bef9SDimitry Andric /// dst := ZF
421e8d8bef9SDimitry Andric /// OF := 0
422e8d8bef9SDimitry Andric /// SF := 0
423e8d8bef9SDimitry Andric /// AF := 0
424e8d8bef9SDimitry Andric /// PF := 0
425e8d8bef9SDimitry Andric /// CF := 0
426e8d8bef9SDimitry Andric /// \endoperation
427e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
428e8d8bef9SDimitry Andric _mm_aesencwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
429e8d8bef9SDimitry Andric   return __builtin_ia32_aesencwide256kl_u8((__v2di *)__odata,
430e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
431e8d8bef9SDimitry Andric }
432e8d8bef9SDimitry Andric 
433e8d8bef9SDimitry Andric /// Decrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle
434e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
435e8d8bef9SDimitry Andric /// return the affected ZF flag status.
436e8d8bef9SDimitry Andric ///
437e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
438e8d8bef9SDimitry Andric ///
439e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDECWIDE128KL </c> instructions.
440e8d8bef9SDimitry Andric ///
441e8d8bef9SDimitry Andric /// \operation
442e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h]
443e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
444e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
445e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
446e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128 )
447e8d8bef9SDimitry Andric /// IF (IllegalHandle)
448e8d8bef9SDimitry Andric ///   ZF := 1
449fe6060f1SDimitry Andric ///   FOR i := 0 to 7
450fe6060f1SDimitry Andric ///     __odata[i] := 0
451fe6060f1SDimitry Andric ///   ENDFOR
452e8d8bef9SDimitry Andric /// ELSE
453e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
454e8d8bef9SDimitry Andric ///   IF Authentic == 0
455e8d8bef9SDimitry Andric ///     ZF := 1
456fe6060f1SDimitry Andric ///     FOR i := 0 to 7
457fe6060f1SDimitry Andric ///       __odata[i] := 0
458fe6060f1SDimitry Andric ///     ENDFOR
459e8d8bef9SDimitry Andric ///   ELSE
460e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
461e8d8bef9SDimitry Andric ///       __odata[i] := AES128Decrypt (__idata[i], UnwrappedKey)
462e8d8bef9SDimitry Andric ///     ENDFOR
463e8d8bef9SDimitry Andric ///     ZF := 0
464e8d8bef9SDimitry Andric ///   FI
465e8d8bef9SDimitry Andric /// FI
466e8d8bef9SDimitry Andric /// dst := ZF
467e8d8bef9SDimitry Andric /// OF := 0
468e8d8bef9SDimitry Andric /// SF := 0
469e8d8bef9SDimitry Andric /// AF := 0
470e8d8bef9SDimitry Andric /// PF := 0
471e8d8bef9SDimitry Andric /// CF := 0
472e8d8bef9SDimitry Andric /// \endoperation
473e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
474e8d8bef9SDimitry Andric _mm_aesdecwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
475e8d8bef9SDimitry Andric   return __builtin_ia32_aesdecwide128kl_u8((__v2di *)__odata,
476e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
477e8d8bef9SDimitry Andric }
478e8d8bef9SDimitry Andric 
479e8d8bef9SDimitry Andric /// Decrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle
480e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
481e8d8bef9SDimitry Andric /// return the affected ZF flag status.
482e8d8bef9SDimitry Andric ///
483e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
484e8d8bef9SDimitry Andric ///
485e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDECWIDE256KL </c> instructions.
486e8d8bef9SDimitry Andric ///
487e8d8bef9SDimitry Andric /// \operation
488e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
489e8d8bef9SDimitry Andric /// IllegalHandle = ( HandleReservedBitSet (Handle[511:0]) ||
490e8d8bef9SDimitry Andric ///                   (Handle[127:0] AND (CPL > 0)) ||
491e8d8bef9SDimitry Andric ///                   Handle[255:128] ||
492e8d8bef9SDimitry Andric ///                   HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES512 )
493e8d8bef9SDimitry Andric /// If (IllegalHandle)
494e8d8bef9SDimitry Andric ///   ZF := 1
495fe6060f1SDimitry Andric ///   FOR i := 0 to 7
496fe6060f1SDimitry Andric ///     __odata[i] := 0
497fe6060f1SDimitry Andric ///   ENDFOR
498e8d8bef9SDimitry Andric /// ELSE
499e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
500e8d8bef9SDimitry Andric ///   IF Authentic == 0
501e8d8bef9SDimitry Andric ///     ZF := 1
502fe6060f1SDimitry Andric ///     FOR i := 0 to 7
503fe6060f1SDimitry Andric ///       __odata[i] := 0
504fe6060f1SDimitry Andric ///     ENDFOR
505e8d8bef9SDimitry Andric ///   ELSE
506e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
507e8d8bef9SDimitry Andric ///       __odata[i] := AES256Decrypt (__idata[i], UnwrappedKey)
508e8d8bef9SDimitry Andric ///     ENDFOR
509e8d8bef9SDimitry Andric ///     ZF := 0
510e8d8bef9SDimitry Andric ///   FI
511e8d8bef9SDimitry Andric /// FI
512e8d8bef9SDimitry Andric /// dst := ZF
513e8d8bef9SDimitry Andric /// OF := 0
514e8d8bef9SDimitry Andric /// SF := 0
515e8d8bef9SDimitry Andric /// AF := 0
516e8d8bef9SDimitry Andric /// PF := 0
517e8d8bef9SDimitry Andric /// CF := 0
518e8d8bef9SDimitry Andric /// \endoperation
519e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
520e8d8bef9SDimitry Andric _mm_aesdecwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
521e8d8bef9SDimitry Andric   return __builtin_ia32_aesdecwide256kl_u8((__v2di *)__odata,
522e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
523e8d8bef9SDimitry Andric }
524e8d8bef9SDimitry Andric 
525e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
526e8d8bef9SDimitry Andric 
527e8d8bef9SDimitry Andric #endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \
528e8d8bef9SDimitry Andric           || defined(__WIDEKL__) */
529e8d8bef9SDimitry Andric 
530e8d8bef9SDimitry Andric #endif /* _KEYLOCKERINTRIN_H */
531