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
31*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__KL__)
32e8d8bef9SDimitry Andric
33e8d8bef9SDimitry Andric /* Define the default attributes for the functions in this file. */
34e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS \
35e8d8bef9SDimitry Andric __attribute__((__always_inline__, __nodebug__, __target__("kl"),\
36e8d8bef9SDimitry Andric __min_vector_width__(128)))
37e8d8bef9SDimitry Andric
38e8d8bef9SDimitry Andric /// Load internal wrapping key from __intkey, __enkey_lo and __enkey_hi. __ctl
39e8d8bef9SDimitry Andric /// will assigned to EAX, whch specifies the KeySource and whether backing up
40e8d8bef9SDimitry Andric /// the key is permitted. The 256-bit encryption key is loaded from the two
41e8d8bef9SDimitry Andric /// explicit operands (__enkey_lo and __enkey_hi). The 128-bit integrity key is
42e8d8bef9SDimitry Andric /// loaded from the implicit operand XMM0 which assigned by __intkey.
43e8d8bef9SDimitry Andric ///
44e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
45e8d8bef9SDimitry Andric ///
46e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> LOADIWKEY </c> instructions.
47e8d8bef9SDimitry Andric ///
4881ad6265SDimitry Andric /// \code{.operation}
49e8d8bef9SDimitry Andric /// IF CPL > 0 // LOADKWKEY only allowed at ring 0 (supervisor mode)
50e8d8bef9SDimitry Andric /// GP (0)
51e8d8bef9SDimitry Andric /// FI
52e8d8bef9SDimitry Andric /// IF “LOADIWKEY exiting” VM execution control set
53e8d8bef9SDimitry Andric /// VMexit
54e8d8bef9SDimitry Andric /// FI
55e8d8bef9SDimitry Andric /// IF __ctl[4:1] > 1 // Reserved KeySource encoding used
56e8d8bef9SDimitry Andric /// GP (0)
57e8d8bef9SDimitry Andric /// FI
58e8d8bef9SDimitry Andric /// IF __ctl[31:5] != 0 // Reserved bit in __ctl is set
59e8d8bef9SDimitry Andric /// GP (0)
60e8d8bef9SDimitry Andric /// FI
61e8d8bef9SDimitry Andric /// IF __ctl[0] AND (CPUID.19H.ECX[0] == 0) // NoBackup is not supported on this part
62e8d8bef9SDimitry Andric /// GP (0)
63e8d8bef9SDimitry Andric /// FI
64e8d8bef9SDimitry Andric /// IF (__ctl[4:1] == 1) AND (CPUID.19H.ECX[1] == 0) // KeySource of 1 is not supported on this part
65e8d8bef9SDimitry Andric /// GP (0)
66e8d8bef9SDimitry Andric /// FI
67e8d8bef9SDimitry Andric /// IF (__ctl[4:1] == 0) // KeySource of 0.
68e8d8bef9SDimitry Andric /// IWKey.Encryption Key[127:0] := __enkey_hi[127:0]:
69e8d8bef9SDimitry Andric /// IWKey.Encryption Key[255:128] := __enkey_lo[127:0]
70e8d8bef9SDimitry Andric /// IWKey.IntegrityKey[127:0] := __intkey[127:0]
71e8d8bef9SDimitry Andric /// IWKey.NoBackup := __ctl[0]
72e8d8bef9SDimitry Andric /// IWKey.KeySource := __ctl[4:1]
73e8d8bef9SDimitry Andric /// ZF := 0
74e8d8bef9SDimitry Andric /// ELSE // KeySource of 1. See RDSEED definition for details of randomness
75e8d8bef9SDimitry Andric /// IF HW_NRND_GEN.ready == 1 // Full-entropy random data from RDSEED was received
76e8d8bef9SDimitry Andric /// IWKey.Encryption Key[127:0] := __enkey_hi[127:0] XOR HW_NRND_GEN.data[127:0]
77e8d8bef9SDimitry Andric /// IWKey.Encryption Key[255:128] := __enkey_lo[127:0] XOR HW_NRND_GEN.data[255:128]
78e8d8bef9SDimitry Andric /// IWKey.Encryption Key[255:0] := __enkey_hi[127:0]:__enkey_lo[127:0] XOR HW_NRND_GEN.data[255:0]
79e8d8bef9SDimitry Andric /// IWKey.IntegrityKey[127:0] := __intkey[127:0] XOR HW_NRND_GEN.data[383:256]
80e8d8bef9SDimitry Andric /// IWKey.NoBackup := __ctl[0]
81e8d8bef9SDimitry Andric /// IWKey.KeySource := __ctl[4:1]
82e8d8bef9SDimitry Andric /// ZF := 0
83e8d8bef9SDimitry Andric /// ELSE // Random data was not returned from RDSEED. IWKey was not loaded
84e8d8bef9SDimitry Andric /// ZF := 1
85e8d8bef9SDimitry Andric /// FI
86e8d8bef9SDimitry Andric /// FI
87e8d8bef9SDimitry Andric /// dst := ZF
88e8d8bef9SDimitry Andric /// OF := 0
89e8d8bef9SDimitry Andric /// SF := 0
90e8d8bef9SDimitry Andric /// AF := 0
91e8d8bef9SDimitry Andric /// PF := 0
92e8d8bef9SDimitry Andric /// CF := 0
9381ad6265SDimitry Andric /// \endcode
94e8d8bef9SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
_mm_loadiwkey(unsigned int __ctl,__m128i __intkey,__m128i __enkey_lo,__m128i __enkey_hi)95e8d8bef9SDimitry Andric _mm_loadiwkey (unsigned int __ctl, __m128i __intkey,
96e8d8bef9SDimitry Andric __m128i __enkey_lo, __m128i __enkey_hi) {
97e8d8bef9SDimitry Andric __builtin_ia32_loadiwkey (__intkey, __enkey_lo, __enkey_hi, __ctl);
98e8d8bef9SDimitry Andric }
99e8d8bef9SDimitry Andric
100e8d8bef9SDimitry Andric /// Wrap a 128-bit AES key from __key into a key handle and output in
101349cc55cSDimitry Andric /// ((__m128i*)__h) to ((__m128i*)__h) + 2 and a 32-bit value as return.
102e8d8bef9SDimitry Andric /// The explicit source operand __htype specifies handle restrictions.
103e8d8bef9SDimitry Andric ///
104e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
105e8d8bef9SDimitry Andric ///
106e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> ENCODEKEY128 </c> instructions.
107e8d8bef9SDimitry Andric ///
10881ad6265SDimitry Andric /// \code{.operation}
109e8d8bef9SDimitry Andric /// InputKey[127:0] := __key[127:0]
110e8d8bef9SDimitry Andric /// KeyMetadata[2:0] := __htype[2:0]
111e8d8bef9SDimitry Andric /// KeyMetadata[23:3] := 0 // Reserved for future usage
112e8d8bef9SDimitry Andric /// KeyMetadata[27:24] := 0 // KeyType is AES-128 (value of 0)
113e8d8bef9SDimitry Andric /// KeyMetadata[127:28] := 0 // Reserved for future usage
114e8d8bef9SDimitry Andric /// Handle[383:0] := WrapKey128(InputKey[127:0], KeyMetadata[127:0],
115e8d8bef9SDimitry Andric /// IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])
116e8d8bef9SDimitry Andric /// dst[0] := IWKey.NoBackup
117e8d8bef9SDimitry Andric /// dst[4:1] := IWKey.KeySource[3:0]
118e8d8bef9SDimitry Andric /// dst[31:5] := 0
119e8d8bef9SDimitry Andric /// MEM[__h+127:__h] := Handle[127:0] // AAD
120e8d8bef9SDimitry Andric /// MEM[__h+255:__h+128] := Handle[255:128] // Integrity Tag
121e8d8bef9SDimitry Andric /// MEM[__h+383:__h+256] := Handle[383:256] // CipherText
122e8d8bef9SDimitry Andric /// OF := 0
123e8d8bef9SDimitry Andric /// SF := 0
124e8d8bef9SDimitry Andric /// ZF := 0
125e8d8bef9SDimitry Andric /// AF := 0
126e8d8bef9SDimitry Andric /// PF := 0
127e8d8bef9SDimitry Andric /// CF := 0
12881ad6265SDimitry Andric /// \endcode
129e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
_mm_encodekey128_u32(unsigned int __htype,__m128i __key,void * __h)130e8d8bef9SDimitry Andric _mm_encodekey128_u32(unsigned int __htype, __m128i __key, void *__h) {
131e8d8bef9SDimitry Andric return __builtin_ia32_encodekey128_u32(__htype, (__v2di)__key, __h);
132e8d8bef9SDimitry Andric }
133e8d8bef9SDimitry Andric
134e8d8bef9SDimitry Andric /// Wrap a 256-bit AES key from __key_hi:__key_lo into a key handle, then
135349cc55cSDimitry Andric /// output handle in ((__m128i*)__h) to ((__m128i*)__h) + 3 and
136e8d8bef9SDimitry Andric /// a 32-bit value as return.
137e8d8bef9SDimitry Andric /// The explicit source operand __htype specifies handle restrictions.
138e8d8bef9SDimitry Andric ///
139e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
140e8d8bef9SDimitry Andric ///
141e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> ENCODEKEY256 </c> instructions.
142e8d8bef9SDimitry Andric ///
14381ad6265SDimitry Andric /// \code{.operation}
144e8d8bef9SDimitry Andric /// InputKey[127:0] := __key_lo[127:0]
145e8d8bef9SDimitry Andric /// InputKey[255:128] := __key_hi[255:128]
146e8d8bef9SDimitry Andric /// KeyMetadata[2:0] := __htype[2:0]
147e8d8bef9SDimitry Andric /// KeyMetadata[23:3] := 0 // Reserved for future usage
148e8d8bef9SDimitry Andric /// KeyMetadata[27:24] := 1 // KeyType is AES-256 (value of 1)
149e8d8bef9SDimitry Andric /// KeyMetadata[127:28] := 0 // Reserved for future usage
150e8d8bef9SDimitry Andric /// Handle[511:0] := WrapKey256(InputKey[255:0], KeyMetadata[127:0],
151e8d8bef9SDimitry Andric /// IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])
152e8d8bef9SDimitry Andric /// dst[0] := IWKey.NoBackup
153e8d8bef9SDimitry Andric /// dst[4:1] := IWKey.KeySource[3:0]
154e8d8bef9SDimitry Andric /// dst[31:5] := 0
155e8d8bef9SDimitry Andric /// MEM[__h+127:__h] := Handle[127:0] // AAD
156e8d8bef9SDimitry Andric /// MEM[__h+255:__h+128] := Handle[255:128] // Tag
157e8d8bef9SDimitry Andric /// MEM[__h+383:__h+256] := Handle[383:256] // CipherText[127:0]
158e8d8bef9SDimitry Andric /// MEM[__h+511:__h+384] := Handle[511:384] // CipherText[255:128]
159e8d8bef9SDimitry Andric /// OF := 0
160e8d8bef9SDimitry Andric /// SF := 0
161e8d8bef9SDimitry Andric /// ZF := 0
162e8d8bef9SDimitry Andric /// AF := 0
163e8d8bef9SDimitry Andric /// PF := 0
164e8d8bef9SDimitry Andric /// CF := 0
16581ad6265SDimitry Andric /// \endcode
166e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
_mm_encodekey256_u32(unsigned int __htype,__m128i __key_lo,__m128i __key_hi,void * __h)167e8d8bef9SDimitry Andric _mm_encodekey256_u32(unsigned int __htype, __m128i __key_lo, __m128i __key_hi,
168e8d8bef9SDimitry Andric void *__h) {
169e8d8bef9SDimitry Andric return __builtin_ia32_encodekey256_u32(__htype, (__v2di)__key_lo,
170e8d8bef9SDimitry Andric (__v2di)__key_hi, __h);
171e8d8bef9SDimitry Andric }
172e8d8bef9SDimitry Andric
173e8d8bef9SDimitry Andric /// The AESENC128KL performs 10 rounds of AES to encrypt the __idata using
174e8d8bef9SDimitry Andric /// the 128-bit key in the handle from the __h. It stores the result in the
175e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
176e8d8bef9SDimitry Andric ///
177e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
178e8d8bef9SDimitry Andric ///
179e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENC128KL </c> instructions.
180e8d8bef9SDimitry Andric ///
18181ad6265SDimitry Andric /// \code{.operation}
182e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.
183e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
184e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
185e8d8bef9SDimitry Andric /// Handle[383:256] ||
186e8d8bef9SDimitry Andric /// HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )
187e8d8bef9SDimitry Andric /// IF (IllegalHandle)
188e8d8bef9SDimitry Andric /// ZF := 1
189e8d8bef9SDimitry Andric /// ELSE
190e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
191e8d8bef9SDimitry Andric /// IF (Authentic == 0)
192e8d8bef9SDimitry Andric /// ZF := 1
193e8d8bef9SDimitry Andric /// ELSE
194e8d8bef9SDimitry Andric /// MEM[__odata+127:__odata] := AES128Encrypt (__idata[127:0], UnwrappedKey)
195e8d8bef9SDimitry Andric /// ZF := 0
196e8d8bef9SDimitry Andric /// FI
197e8d8bef9SDimitry Andric /// FI
198e8d8bef9SDimitry Andric /// dst := ZF
199e8d8bef9SDimitry Andric /// OF := 0
200e8d8bef9SDimitry Andric /// SF := 0
201e8d8bef9SDimitry Andric /// AF := 0
202e8d8bef9SDimitry Andric /// PF := 0
203e8d8bef9SDimitry Andric /// CF := 0
20481ad6265SDimitry Andric /// \endcode
205e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesenc128kl_u8(__m128i * __odata,__m128i __idata,const void * __h)206e8d8bef9SDimitry Andric _mm_aesenc128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
207e8d8bef9SDimitry Andric return __builtin_ia32_aesenc128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
208e8d8bef9SDimitry Andric }
209e8d8bef9SDimitry Andric
210e8d8bef9SDimitry Andric /// The AESENC256KL performs 14 rounds of AES to encrypt the __idata using
211e8d8bef9SDimitry Andric /// the 256-bit key in the handle from the __h. It stores the result in the
212e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
213e8d8bef9SDimitry Andric ///
214e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
215e8d8bef9SDimitry Andric ///
216e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENC256KL </c> instructions.
217e8d8bef9SDimitry Andric ///
21881ad6265SDimitry Andric /// \code{.operation}
219e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h] // Load is not guaranteed to be atomic.
220e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||
221e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
222e8d8bef9SDimitry Andric /// Handle[255:128] ||
223e8d8bef9SDimitry Andric /// HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256 )
224e8d8bef9SDimitry Andric /// IF (IllegalHandle)
225e8d8bef9SDimitry Andric /// ZF := 1
226fe6060f1SDimitry Andric /// MEM[__odata+127:__odata] := 0
227e8d8bef9SDimitry Andric /// ELSE
228e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
229e8d8bef9SDimitry Andric /// IF (Authentic == 0)
230e8d8bef9SDimitry Andric /// ZF := 1
231fe6060f1SDimitry Andric /// MEM[__odata+127:__odata] := 0
232e8d8bef9SDimitry Andric /// ELSE
233e8d8bef9SDimitry Andric /// MEM[__odata+127:__odata] := AES256Encrypt (__idata[127:0], UnwrappedKey)
234e8d8bef9SDimitry Andric /// ZF := 0
235e8d8bef9SDimitry Andric /// FI
236e8d8bef9SDimitry Andric /// FI
237e8d8bef9SDimitry Andric /// dst := ZF
238e8d8bef9SDimitry Andric /// OF := 0
239e8d8bef9SDimitry Andric /// SF := 0
240e8d8bef9SDimitry Andric /// AF := 0
241e8d8bef9SDimitry Andric /// PF := 0
242e8d8bef9SDimitry Andric /// CF := 0
24381ad6265SDimitry Andric /// \endcode
244e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesenc256kl_u8(__m128i * __odata,__m128i __idata,const void * __h)245e8d8bef9SDimitry Andric _mm_aesenc256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
246e8d8bef9SDimitry Andric return __builtin_ia32_aesenc256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
247e8d8bef9SDimitry Andric }
248e8d8bef9SDimitry Andric
249e8d8bef9SDimitry Andric /// The AESDEC128KL performs 10 rounds of AES to decrypt the __idata using
250e8d8bef9SDimitry Andric /// the 128-bit key in the handle from the __h. It stores the result in the
251e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
252e8d8bef9SDimitry Andric ///
253e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
254e8d8bef9SDimitry Andric ///
255e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDEC128KL </c> instructions.
256e8d8bef9SDimitry Andric ///
25781ad6265SDimitry Andric /// \code{.operation}
258e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.
259e8d8bef9SDimitry Andric /// IllegalHandle := (HandleReservedBitSet (Handle[383:0]) ||
260e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
261e8d8bef9SDimitry Andric /// Handle[383:256] ||
262e8d8bef9SDimitry Andric /// HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128)
263e8d8bef9SDimitry Andric /// IF (IllegalHandle)
264e8d8bef9SDimitry Andric /// ZF := 1
265fe6060f1SDimitry Andric /// MEM[__odata+127:__odata] := 0
266e8d8bef9SDimitry Andric /// ELSE
267e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
268e8d8bef9SDimitry Andric /// IF (Authentic == 0)
269e8d8bef9SDimitry Andric /// ZF := 1
270fe6060f1SDimitry Andric /// MEM[__odata+127:__odata] := 0
271e8d8bef9SDimitry Andric /// ELSE
272e8d8bef9SDimitry Andric /// MEM[__odata+127:__odata] := AES128Decrypt (__idata[127:0], UnwrappedKey)
273e8d8bef9SDimitry Andric /// ZF := 0
274e8d8bef9SDimitry Andric /// FI
275e8d8bef9SDimitry Andric /// FI
276e8d8bef9SDimitry Andric /// dst := ZF
277e8d8bef9SDimitry Andric /// OF := 0
278e8d8bef9SDimitry Andric /// SF := 0
279e8d8bef9SDimitry Andric /// AF := 0
280e8d8bef9SDimitry Andric /// PF := 0
281e8d8bef9SDimitry Andric /// CF := 0
28281ad6265SDimitry Andric /// \endcode
283e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesdec128kl_u8(__m128i * __odata,__m128i __idata,const void * __h)284e8d8bef9SDimitry Andric _mm_aesdec128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
285e8d8bef9SDimitry Andric return __builtin_ia32_aesdec128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
286e8d8bef9SDimitry Andric }
287e8d8bef9SDimitry Andric
288e8d8bef9SDimitry Andric /// The AESDEC256KL performs 10 rounds of AES to decrypt the __idata using
289e8d8bef9SDimitry Andric /// the 256-bit key in the handle from the __h. It stores the result in the
290e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
291e8d8bef9SDimitry Andric ///
292e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
293e8d8bef9SDimitry Andric ///
294e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDEC256KL </c> instructions.
295e8d8bef9SDimitry Andric ///
29681ad6265SDimitry Andric /// \code{.operation}
297e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
298e8d8bef9SDimitry Andric /// IllegalHandle := (HandleReservedBitSet (Handle[511:0]) ||
299e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
300e8d8bef9SDimitry Andric /// Handle[383:256] ||
301e8d8bef9SDimitry Andric /// HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256)
302e8d8bef9SDimitry Andric /// IF (IllegalHandle)
303e8d8bef9SDimitry Andric /// ZF := 1
304fe6060f1SDimitry Andric /// MEM[__odata+127:__odata] := 0
305e8d8bef9SDimitry Andric /// ELSE
306e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
307e8d8bef9SDimitry Andric /// IF (Authentic == 0)
308e8d8bef9SDimitry Andric /// ZF := 1
309fe6060f1SDimitry Andric /// MEM[__odata+127:__odata] := 0
310e8d8bef9SDimitry Andric /// ELSE
311e8d8bef9SDimitry Andric /// MEM[__odata+127:__odata] := AES256Decrypt (__idata[127:0], UnwrappedKey)
312e8d8bef9SDimitry Andric /// ZF := 0
313e8d8bef9SDimitry Andric /// FI
314e8d8bef9SDimitry Andric /// FI
315e8d8bef9SDimitry Andric /// dst := ZF
316e8d8bef9SDimitry Andric /// OF := 0
317e8d8bef9SDimitry Andric /// SF := 0
318e8d8bef9SDimitry Andric /// AF := 0
319e8d8bef9SDimitry Andric /// PF := 0
320e8d8bef9SDimitry Andric /// CF := 0
32181ad6265SDimitry Andric /// \endcode
322e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesdec256kl_u8(__m128i * __odata,__m128i __idata,const void * __h)323e8d8bef9SDimitry Andric _mm_aesdec256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
324e8d8bef9SDimitry Andric return __builtin_ia32_aesdec256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
325e8d8bef9SDimitry Andric }
326e8d8bef9SDimitry Andric
327e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
328e8d8bef9SDimitry Andric
329*0fca6ea1SDimitry Andric #endif /* !defined(__SCE__ || __has_feature(modules) || defined(__KL__) */
330e8d8bef9SDimitry Andric
331*0fca6ea1SDimitry Andric #if !defined(__SCE__) || __has_feature(modules) || defined(__WIDEKL__)
332e8d8bef9SDimitry Andric
333e8d8bef9SDimitry Andric /* Define the default attributes for the functions in this file. */
334e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS \
335e8d8bef9SDimitry Andric __attribute__((__always_inline__, __nodebug__, __target__("kl,widekl"),\
336e8d8bef9SDimitry Andric __min_vector_width__(128)))
337e8d8bef9SDimitry Andric
338e8d8bef9SDimitry Andric /// Encrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle
339e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
340e8d8bef9SDimitry Andric /// return the affected ZF flag status.
341e8d8bef9SDimitry Andric ///
342e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
343e8d8bef9SDimitry Andric ///
344e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENCWIDE128KL </c> instructions.
345e8d8bef9SDimitry Andric ///
34681ad6265SDimitry Andric /// \code{.operation}
347e8d8bef9SDimitry Andric /// Handle := MEM[__h+383:__h]
348e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
349e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
350e8d8bef9SDimitry Andric /// Handle[255:128] ||
351e8d8bef9SDimitry Andric /// HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )
352e8d8bef9SDimitry Andric /// IF (IllegalHandle)
353e8d8bef9SDimitry Andric /// ZF := 1
354fe6060f1SDimitry Andric /// FOR i := 0 to 7
355fe6060f1SDimitry Andric /// __odata[i] := 0
356fe6060f1SDimitry Andric /// ENDFOR
357e8d8bef9SDimitry Andric /// ELSE
358e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
359e8d8bef9SDimitry Andric /// IF Authentic == 0
360e8d8bef9SDimitry Andric /// ZF := 1
361fe6060f1SDimitry Andric /// FOR i := 0 to 7
362fe6060f1SDimitry Andric /// __odata[i] := 0
363fe6060f1SDimitry Andric /// ENDFOR
364e8d8bef9SDimitry Andric /// ELSE
365e8d8bef9SDimitry Andric /// FOR i := 0 to 7
366e8d8bef9SDimitry Andric /// __odata[i] := AES128Encrypt (__idata[i], UnwrappedKey)
367e8d8bef9SDimitry Andric /// ENDFOR
368e8d8bef9SDimitry Andric /// ZF := 0
369e8d8bef9SDimitry Andric /// FI
370e8d8bef9SDimitry Andric /// FI
371e8d8bef9SDimitry Andric /// dst := ZF
372e8d8bef9SDimitry Andric /// OF := 0
373e8d8bef9SDimitry Andric /// SF := 0
374e8d8bef9SDimitry Andric /// AF := 0
375e8d8bef9SDimitry Andric /// PF := 0
376e8d8bef9SDimitry Andric /// CF := 0
37781ad6265SDimitry Andric /// \endcode
378e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesencwide128kl_u8(__m128i __odata[8],const __m128i __idata[8],const void * __h)379e8d8bef9SDimitry Andric _mm_aesencwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
380e8d8bef9SDimitry Andric return __builtin_ia32_aesencwide128kl_u8((__v2di *)__odata,
381e8d8bef9SDimitry Andric (const __v2di *)__idata, __h);
382e8d8bef9SDimitry Andric }
383e8d8bef9SDimitry Andric
384e8d8bef9SDimitry Andric /// Encrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle
385e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
386e8d8bef9SDimitry Andric /// return the affected ZF flag status.
387e8d8bef9SDimitry Andric ///
388e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
389e8d8bef9SDimitry Andric ///
390e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENCWIDE256KL </c> instructions.
391e8d8bef9SDimitry Andric ///
39281ad6265SDimitry Andric /// \code{.operation}
393e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
394e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||
395e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
396e8d8bef9SDimitry Andric /// Handle[255:128] ||
397e8d8bef9SDimitry Andric /// HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES512 )
398e8d8bef9SDimitry Andric /// IF (IllegalHandle)
399e8d8bef9SDimitry Andric /// ZF := 1
400fe6060f1SDimitry Andric /// FOR i := 0 to 7
401fe6060f1SDimitry Andric /// __odata[i] := 0
402fe6060f1SDimitry Andric /// ENDFOR
403e8d8bef9SDimitry Andric /// ELSE
404e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
405e8d8bef9SDimitry Andric /// IF Authentic == 0
406e8d8bef9SDimitry Andric /// ZF := 1
407fe6060f1SDimitry Andric /// FOR i := 0 to 7
408fe6060f1SDimitry Andric /// __odata[i] := 0
409fe6060f1SDimitry Andric /// ENDFOR
410e8d8bef9SDimitry Andric /// ELSE
411e8d8bef9SDimitry Andric /// FOR i := 0 to 7
412e8d8bef9SDimitry Andric /// __odata[i] := AES256Encrypt (__idata[i], UnwrappedKey)
413e8d8bef9SDimitry Andric /// ENDFOR
414e8d8bef9SDimitry Andric /// ZF := 0
415e8d8bef9SDimitry Andric /// FI
416e8d8bef9SDimitry Andric /// FI
417e8d8bef9SDimitry Andric /// dst := ZF
418e8d8bef9SDimitry Andric /// OF := 0
419e8d8bef9SDimitry Andric /// SF := 0
420e8d8bef9SDimitry Andric /// AF := 0
421e8d8bef9SDimitry Andric /// PF := 0
422e8d8bef9SDimitry Andric /// CF := 0
42381ad6265SDimitry Andric /// \endcode
424e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesencwide256kl_u8(__m128i __odata[8],const __m128i __idata[8],const void * __h)425e8d8bef9SDimitry Andric _mm_aesencwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
426e8d8bef9SDimitry Andric return __builtin_ia32_aesencwide256kl_u8((__v2di *)__odata,
427e8d8bef9SDimitry Andric (const __v2di *)__idata, __h);
428e8d8bef9SDimitry Andric }
429e8d8bef9SDimitry Andric
430e8d8bef9SDimitry Andric /// Decrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle
431e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
432e8d8bef9SDimitry Andric /// return the affected ZF flag status.
433e8d8bef9SDimitry Andric ///
434e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
435e8d8bef9SDimitry Andric ///
436e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDECWIDE128KL </c> instructions.
437e8d8bef9SDimitry Andric ///
43881ad6265SDimitry Andric /// \code{.operation}
439e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h]
440e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
441e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
442e8d8bef9SDimitry Andric /// Handle[255:128] ||
443e8d8bef9SDimitry Andric /// HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128 )
444e8d8bef9SDimitry Andric /// IF (IllegalHandle)
445e8d8bef9SDimitry Andric /// ZF := 1
446fe6060f1SDimitry Andric /// FOR i := 0 to 7
447fe6060f1SDimitry Andric /// __odata[i] := 0
448fe6060f1SDimitry Andric /// ENDFOR
449e8d8bef9SDimitry Andric /// ELSE
450e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
451e8d8bef9SDimitry Andric /// IF Authentic == 0
452e8d8bef9SDimitry Andric /// ZF := 1
453fe6060f1SDimitry Andric /// FOR i := 0 to 7
454fe6060f1SDimitry Andric /// __odata[i] := 0
455fe6060f1SDimitry Andric /// ENDFOR
456e8d8bef9SDimitry Andric /// ELSE
457e8d8bef9SDimitry Andric /// FOR i := 0 to 7
458e8d8bef9SDimitry Andric /// __odata[i] := AES128Decrypt (__idata[i], UnwrappedKey)
459e8d8bef9SDimitry Andric /// ENDFOR
460e8d8bef9SDimitry Andric /// ZF := 0
461e8d8bef9SDimitry Andric /// FI
462e8d8bef9SDimitry Andric /// FI
463e8d8bef9SDimitry Andric /// dst := ZF
464e8d8bef9SDimitry Andric /// OF := 0
465e8d8bef9SDimitry Andric /// SF := 0
466e8d8bef9SDimitry Andric /// AF := 0
467e8d8bef9SDimitry Andric /// PF := 0
468e8d8bef9SDimitry Andric /// CF := 0
46981ad6265SDimitry Andric /// \endcode
470e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesdecwide128kl_u8(__m128i __odata[8],const __m128i __idata[8],const void * __h)471e8d8bef9SDimitry Andric _mm_aesdecwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
472e8d8bef9SDimitry Andric return __builtin_ia32_aesdecwide128kl_u8((__v2di *)__odata,
473e8d8bef9SDimitry Andric (const __v2di *)__idata, __h);
474e8d8bef9SDimitry Andric }
475e8d8bef9SDimitry Andric
476e8d8bef9SDimitry Andric /// Decrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle
477e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
478e8d8bef9SDimitry Andric /// return the affected ZF flag status.
479e8d8bef9SDimitry Andric ///
480e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
481e8d8bef9SDimitry Andric ///
482e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDECWIDE256KL </c> instructions.
483e8d8bef9SDimitry Andric ///
48481ad6265SDimitry Andric /// \code{.operation}
485e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
486e8d8bef9SDimitry Andric /// IllegalHandle = ( HandleReservedBitSet (Handle[511:0]) ||
487e8d8bef9SDimitry Andric /// (Handle[127:0] AND (CPL > 0)) ||
488e8d8bef9SDimitry Andric /// Handle[255:128] ||
489e8d8bef9SDimitry Andric /// HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES512 )
490e8d8bef9SDimitry Andric /// If (IllegalHandle)
491e8d8bef9SDimitry Andric /// ZF := 1
492fe6060f1SDimitry Andric /// FOR i := 0 to 7
493fe6060f1SDimitry Andric /// __odata[i] := 0
494fe6060f1SDimitry Andric /// ENDFOR
495e8d8bef9SDimitry Andric /// ELSE
496e8d8bef9SDimitry Andric /// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
497e8d8bef9SDimitry Andric /// IF Authentic == 0
498e8d8bef9SDimitry Andric /// ZF := 1
499fe6060f1SDimitry Andric /// FOR i := 0 to 7
500fe6060f1SDimitry Andric /// __odata[i] := 0
501fe6060f1SDimitry Andric /// ENDFOR
502e8d8bef9SDimitry Andric /// ELSE
503e8d8bef9SDimitry Andric /// FOR i := 0 to 7
504e8d8bef9SDimitry Andric /// __odata[i] := AES256Decrypt (__idata[i], UnwrappedKey)
505e8d8bef9SDimitry Andric /// ENDFOR
506e8d8bef9SDimitry Andric /// ZF := 0
507e8d8bef9SDimitry Andric /// FI
508e8d8bef9SDimitry Andric /// FI
509e8d8bef9SDimitry Andric /// dst := ZF
510e8d8bef9SDimitry Andric /// OF := 0
511e8d8bef9SDimitry Andric /// SF := 0
512e8d8bef9SDimitry Andric /// AF := 0
513e8d8bef9SDimitry Andric /// PF := 0
514e8d8bef9SDimitry Andric /// CF := 0
51581ad6265SDimitry Andric /// \endcode
516e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
_mm_aesdecwide256kl_u8(__m128i __odata[8],const __m128i __idata[8],const void * __h)517e8d8bef9SDimitry Andric _mm_aesdecwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
518e8d8bef9SDimitry Andric return __builtin_ia32_aesdecwide256kl_u8((__v2di *)__odata,
519e8d8bef9SDimitry Andric (const __v2di *)__idata, __h);
520e8d8bef9SDimitry Andric }
521e8d8bef9SDimitry Andric
522e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
523e8d8bef9SDimitry Andric
524*0fca6ea1SDimitry Andric #endif /* !defined(__SCE__) || __has_feature(modules) || defined(__WIDEKL__) \
525*0fca6ea1SDimitry Andric */
526e8d8bef9SDimitry Andric
527e8d8bef9SDimitry Andric #endif /* _KEYLOCKERINTRIN_H */
528