xref: /freebsd/contrib/llvm-project/clang/lib/Headers/keylockerintrin.h (revision fe6060f10f634930ff71b7c50291ddc610da2475)
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
102e8d8bef9SDimitry Andric /// ((__m128i*)__h) to ((__m128i*)__h) + 5  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 /// MEM[__h+511:__h+384] := 0 // Reserved for future usage
124e8d8bef9SDimitry Andric /// MEM[__h+639:__h+512] := 0 // Reserved for future usage
125e8d8bef9SDimitry Andric /// MEM[__h+767:__h+640] := 0 // Reserved for future usage
126e8d8bef9SDimitry Andric /// OF := 0
127e8d8bef9SDimitry Andric /// SF := 0
128e8d8bef9SDimitry Andric /// ZF := 0
129e8d8bef9SDimitry Andric /// AF := 0
130e8d8bef9SDimitry Andric /// PF := 0
131e8d8bef9SDimitry Andric /// CF := 0
132e8d8bef9SDimitry Andric /// \endoperation
133e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
134e8d8bef9SDimitry Andric _mm_encodekey128_u32(unsigned int __htype, __m128i __key, void *__h) {
135e8d8bef9SDimitry Andric   return __builtin_ia32_encodekey128_u32(__htype, (__v2di)__key, __h);
136e8d8bef9SDimitry Andric }
137e8d8bef9SDimitry Andric 
138e8d8bef9SDimitry Andric /// Wrap a 256-bit AES key from __key_hi:__key_lo into a key handle, then
139e8d8bef9SDimitry Andric /// output handle in ((__m128i*)__h) to ((__m128i*)__h) + 6 and
140e8d8bef9SDimitry Andric /// a 32-bit value as return.
141e8d8bef9SDimitry Andric /// The explicit source operand __htype specifies handle restrictions.
142e8d8bef9SDimitry Andric ///
143e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
144e8d8bef9SDimitry Andric ///
145e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> ENCODEKEY256 </c> instructions.
146e8d8bef9SDimitry Andric ///
147e8d8bef9SDimitry Andric /// \operation
148e8d8bef9SDimitry Andric /// InputKey[127:0] := __key_lo[127:0]
149e8d8bef9SDimitry Andric /// InputKey[255:128] := __key_hi[255:128]
150e8d8bef9SDimitry Andric /// KeyMetadata[2:0] := __htype[2:0]
151e8d8bef9SDimitry Andric /// KeyMetadata[23:3] := 0 // Reserved for future usage
152e8d8bef9SDimitry Andric /// KeyMetadata[27:24] := 1 // KeyType is AES-256 (value of 1)
153e8d8bef9SDimitry Andric /// KeyMetadata[127:28] := 0 // Reserved for future usage
154e8d8bef9SDimitry Andric /// Handle[511:0] := WrapKey256(InputKey[255:0], KeyMetadata[127:0],
155e8d8bef9SDimitry Andric ///                  IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])
156e8d8bef9SDimitry Andric /// dst[0] := IWKey.NoBackup
157e8d8bef9SDimitry Andric /// dst[4:1] := IWKey.KeySource[3:0]
158e8d8bef9SDimitry Andric /// dst[31:5] := 0
159e8d8bef9SDimitry Andric /// MEM[__h+127:__h]   := Handle[127:0] // AAD
160e8d8bef9SDimitry Andric /// MEM[__h+255:__h+128] := Handle[255:128] // Tag
161e8d8bef9SDimitry Andric /// MEM[__h+383:__h+256] := Handle[383:256] // CipherText[127:0]
162e8d8bef9SDimitry Andric /// MEM[__h+511:__h+384] := Handle[511:384] // CipherText[255:128]
163e8d8bef9SDimitry Andric /// MEM[__h+639:__h+512] := 0 // Reserved for future usage
164e8d8bef9SDimitry Andric /// MEM[__h+767:__h+640] := 0 // Reserved for future usage
165e8d8bef9SDimitry Andric /// MEM[__h+895:__h+768] := 0 Integrity// Reserved for future usage
166e8d8bef9SDimitry Andric /// OF := 0
167e8d8bef9SDimitry Andric /// SF := 0
168e8d8bef9SDimitry Andric /// ZF := 0
169e8d8bef9SDimitry Andric /// AF := 0
170e8d8bef9SDimitry Andric /// PF := 0
171e8d8bef9SDimitry Andric /// CF := 0
172e8d8bef9SDimitry Andric /// \endoperation
173e8d8bef9SDimitry Andric static __inline__ unsigned int __DEFAULT_FN_ATTRS
174e8d8bef9SDimitry Andric _mm_encodekey256_u32(unsigned int __htype, __m128i __key_lo, __m128i __key_hi,
175e8d8bef9SDimitry Andric                      void *__h) {
176e8d8bef9SDimitry Andric   return __builtin_ia32_encodekey256_u32(__htype, (__v2di)__key_lo,
177e8d8bef9SDimitry Andric                                          (__v2di)__key_hi, __h);
178e8d8bef9SDimitry Andric }
179e8d8bef9SDimitry Andric 
180e8d8bef9SDimitry Andric /// The AESENC128KL performs 10 rounds of AES to encrypt the __idata using
181e8d8bef9SDimitry Andric /// the 128-bit key in the handle from the __h. It stores the result in the
182e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
183e8d8bef9SDimitry Andric ///
184e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
185e8d8bef9SDimitry Andric ///
186e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENC128KL </c> instructions.
187e8d8bef9SDimitry Andric ///
188e8d8bef9SDimitry Andric /// \operation
189e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.
190e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
191e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
192e8d8bef9SDimitry Andric ///                    Handle[383:256] ||
193e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )
194e8d8bef9SDimitry Andric /// IF (IllegalHandle)
195e8d8bef9SDimitry Andric ///   ZF := 1
196e8d8bef9SDimitry Andric /// ELSE
197e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
198e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
199e8d8bef9SDimitry Andric ///     ZF := 1
200e8d8bef9SDimitry Andric ///   ELSE
201e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES128Encrypt (__idata[127:0], UnwrappedKey)
202e8d8bef9SDimitry Andric ///     ZF := 0
203e8d8bef9SDimitry Andric ///   FI
204e8d8bef9SDimitry Andric /// FI
205e8d8bef9SDimitry Andric /// dst := ZF
206e8d8bef9SDimitry Andric /// OF := 0
207e8d8bef9SDimitry Andric /// SF := 0
208e8d8bef9SDimitry Andric /// AF := 0
209e8d8bef9SDimitry Andric /// PF := 0
210e8d8bef9SDimitry Andric /// CF := 0
211e8d8bef9SDimitry Andric /// \endoperation
212e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
213e8d8bef9SDimitry Andric _mm_aesenc128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
214e8d8bef9SDimitry Andric   return __builtin_ia32_aesenc128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
215e8d8bef9SDimitry Andric }
216e8d8bef9SDimitry Andric 
217e8d8bef9SDimitry Andric /// The AESENC256KL performs 14 rounds of AES to encrypt the __idata using
218e8d8bef9SDimitry Andric /// the 256-bit key in the handle from the __h. It stores the result in the
219e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
220e8d8bef9SDimitry Andric ///
221e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
222e8d8bef9SDimitry Andric ///
223e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENC256KL </c> instructions.
224e8d8bef9SDimitry Andric ///
225e8d8bef9SDimitry Andric /// \operation
226e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h] // Load is not guaranteed to be atomic.
227e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||
228e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
229e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
230e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256 )
231e8d8bef9SDimitry Andric /// IF (IllegalHandle)
232e8d8bef9SDimitry Andric ///   ZF := 1
233*fe6060f1SDimitry Andric ///   MEM[__odata+127:__odata] := 0
234e8d8bef9SDimitry Andric /// ELSE
235e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
236e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
237e8d8bef9SDimitry Andric ///     ZF := 1
238*fe6060f1SDimitry Andric ///     MEM[__odata+127:__odata] := 0
239e8d8bef9SDimitry Andric ///   ELSE
240e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES256Encrypt (__idata[127:0], UnwrappedKey)
241e8d8bef9SDimitry Andric ///     ZF := 0
242e8d8bef9SDimitry Andric ///   FI
243e8d8bef9SDimitry Andric /// FI
244e8d8bef9SDimitry Andric /// dst := ZF
245e8d8bef9SDimitry Andric /// OF := 0
246e8d8bef9SDimitry Andric /// SF := 0
247e8d8bef9SDimitry Andric /// AF := 0
248e8d8bef9SDimitry Andric /// PF := 0
249e8d8bef9SDimitry Andric /// CF := 0
250e8d8bef9SDimitry Andric /// \endoperation
251e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
252e8d8bef9SDimitry Andric _mm_aesenc256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
253e8d8bef9SDimitry Andric   return __builtin_ia32_aesenc256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
254e8d8bef9SDimitry Andric }
255e8d8bef9SDimitry Andric 
256e8d8bef9SDimitry Andric /// The AESDEC128KL performs 10 rounds of AES to decrypt the __idata using
257e8d8bef9SDimitry Andric /// the 128-bit key in the handle from the __h. It stores the result in the
258e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
259e8d8bef9SDimitry Andric ///
260e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
261e8d8bef9SDimitry Andric ///
262e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDEC128KL </c> instructions.
263e8d8bef9SDimitry Andric ///
264e8d8bef9SDimitry Andric /// \operation
265e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.
266e8d8bef9SDimitry Andric /// IllegalHandle := (HandleReservedBitSet (Handle[383:0]) ||
267e8d8bef9SDimitry Andric ///                  (Handle[127:0] AND (CPL > 0)) ||
268e8d8bef9SDimitry Andric ///                  Handle[383:256] ||
269e8d8bef9SDimitry Andric ///                  HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128)
270e8d8bef9SDimitry Andric /// IF (IllegalHandle)
271e8d8bef9SDimitry Andric ///   ZF := 1
272*fe6060f1SDimitry Andric ///   MEM[__odata+127:__odata] := 0
273e8d8bef9SDimitry Andric /// ELSE
274e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
275e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
276e8d8bef9SDimitry Andric ///     ZF := 1
277*fe6060f1SDimitry Andric ///     MEM[__odata+127:__odata] := 0
278e8d8bef9SDimitry Andric ///   ELSE
279e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES128Decrypt (__idata[127:0], UnwrappedKey)
280e8d8bef9SDimitry Andric ///     ZF := 0
281e8d8bef9SDimitry Andric ///   FI
282e8d8bef9SDimitry Andric /// FI
283e8d8bef9SDimitry Andric /// dst := ZF
284e8d8bef9SDimitry Andric /// OF := 0
285e8d8bef9SDimitry Andric /// SF := 0
286e8d8bef9SDimitry Andric /// AF := 0
287e8d8bef9SDimitry Andric /// PF := 0
288e8d8bef9SDimitry Andric /// CF := 0
289e8d8bef9SDimitry Andric /// \endoperation
290e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
291e8d8bef9SDimitry Andric _mm_aesdec128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
292e8d8bef9SDimitry Andric   return __builtin_ia32_aesdec128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
293e8d8bef9SDimitry Andric }
294e8d8bef9SDimitry Andric 
295e8d8bef9SDimitry Andric /// The AESDEC256KL performs 10 rounds of AES to decrypt the __idata using
296e8d8bef9SDimitry Andric /// the 256-bit key in the handle from the __h. It stores the result in the
297e8d8bef9SDimitry Andric /// __odata. And return the affected ZF flag status.
298e8d8bef9SDimitry Andric ///
299e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
300e8d8bef9SDimitry Andric ///
301e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDEC256KL </c> instructions.
302e8d8bef9SDimitry Andric ///
303e8d8bef9SDimitry Andric /// \operation
304e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
305e8d8bef9SDimitry Andric /// IllegalHandle := (HandleReservedBitSet (Handle[511:0]) ||
306e8d8bef9SDimitry Andric ///                   (Handle[127:0] AND (CPL > 0)) ||
307e8d8bef9SDimitry Andric ///                   Handle[383:256] ||
308e8d8bef9SDimitry Andric ///                   HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256)
309e8d8bef9SDimitry Andric /// IF (IllegalHandle)
310e8d8bef9SDimitry Andric ///   ZF := 1
311*fe6060f1SDimitry Andric ///   MEM[__odata+127:__odata] := 0
312e8d8bef9SDimitry Andric /// ELSE
313e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
314e8d8bef9SDimitry Andric ///   IF (Authentic == 0)
315e8d8bef9SDimitry Andric ///     ZF := 1
316*fe6060f1SDimitry Andric ///     MEM[__odata+127:__odata] := 0
317e8d8bef9SDimitry Andric ///   ELSE
318e8d8bef9SDimitry Andric ///     MEM[__odata+127:__odata] := AES256Decrypt (__idata[127:0], UnwrappedKey)
319e8d8bef9SDimitry Andric ///     ZF := 0
320e8d8bef9SDimitry Andric ///   FI
321e8d8bef9SDimitry Andric /// FI
322e8d8bef9SDimitry Andric /// dst := ZF
323e8d8bef9SDimitry Andric /// OF := 0
324e8d8bef9SDimitry Andric /// SF := 0
325e8d8bef9SDimitry Andric /// AF := 0
326e8d8bef9SDimitry Andric /// PF := 0
327e8d8bef9SDimitry Andric /// CF := 0
328e8d8bef9SDimitry Andric /// \endoperation
329e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
330e8d8bef9SDimitry Andric _mm_aesdec256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {
331e8d8bef9SDimitry Andric   return __builtin_ia32_aesdec256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);
332e8d8bef9SDimitry Andric }
333e8d8bef9SDimitry Andric 
334e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
335e8d8bef9SDimitry Andric 
336e8d8bef9SDimitry Andric #endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \
337e8d8bef9SDimitry Andric           || defined(__KL__) */
338e8d8bef9SDimitry Andric 
339e8d8bef9SDimitry Andric #if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) ||      \
340e8d8bef9SDimitry Andric     defined(__WIDEKL__)
341e8d8bef9SDimitry Andric 
342e8d8bef9SDimitry Andric /* Define the default attributes for the functions in this file. */
343e8d8bef9SDimitry Andric #define __DEFAULT_FN_ATTRS \
344e8d8bef9SDimitry Andric   __attribute__((__always_inline__, __nodebug__, __target__("kl,widekl"),\
345e8d8bef9SDimitry Andric                  __min_vector_width__(128)))
346e8d8bef9SDimitry Andric 
347e8d8bef9SDimitry Andric /// Encrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle
348e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
349e8d8bef9SDimitry Andric /// return the affected ZF flag status.
350e8d8bef9SDimitry Andric ///
351e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
352e8d8bef9SDimitry Andric ///
353e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENCWIDE128KL </c> instructions.
354e8d8bef9SDimitry Andric ///
355e8d8bef9SDimitry Andric /// \operation
356e8d8bef9SDimitry Andric /// Handle := MEM[__h+383:__h]
357e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
358e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
359e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
360e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )
361e8d8bef9SDimitry Andric /// IF (IllegalHandle)
362e8d8bef9SDimitry Andric ///   ZF := 1
363*fe6060f1SDimitry Andric ///   FOR i := 0 to 7
364*fe6060f1SDimitry Andric ///     __odata[i] := 0
365*fe6060f1SDimitry Andric ///   ENDFOR
366e8d8bef9SDimitry Andric /// ELSE
367e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
368e8d8bef9SDimitry Andric ///   IF Authentic == 0
369e8d8bef9SDimitry Andric ///     ZF := 1
370*fe6060f1SDimitry Andric ///     FOR i := 0 to 7
371*fe6060f1SDimitry Andric ///       __odata[i] := 0
372*fe6060f1SDimitry Andric ///     ENDFOR
373e8d8bef9SDimitry Andric ///   ELSE
374e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
375e8d8bef9SDimitry Andric ///       __odata[i] := AES128Encrypt (__idata[i], UnwrappedKey)
376e8d8bef9SDimitry Andric ///     ENDFOR
377e8d8bef9SDimitry Andric ///     ZF := 0
378e8d8bef9SDimitry Andric ///   FI
379e8d8bef9SDimitry Andric /// FI
380e8d8bef9SDimitry Andric /// dst := ZF
381e8d8bef9SDimitry Andric /// OF := 0
382e8d8bef9SDimitry Andric /// SF := 0
383e8d8bef9SDimitry Andric /// AF := 0
384e8d8bef9SDimitry Andric /// PF := 0
385e8d8bef9SDimitry Andric /// CF := 0
386e8d8bef9SDimitry Andric /// \endoperation
387e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
388e8d8bef9SDimitry Andric _mm_aesencwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
389e8d8bef9SDimitry Andric   return __builtin_ia32_aesencwide128kl_u8((__v2di *)__odata,
390e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
391e8d8bef9SDimitry Andric }
392e8d8bef9SDimitry Andric 
393e8d8bef9SDimitry Andric /// Encrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle
394e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
395e8d8bef9SDimitry Andric /// return the affected ZF flag status.
396e8d8bef9SDimitry Andric ///
397e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
398e8d8bef9SDimitry Andric ///
399e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESENCWIDE256KL </c> instructions.
400e8d8bef9SDimitry Andric ///
401e8d8bef9SDimitry Andric /// \operation
402e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
403e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||
404e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
405e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
406e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES512 )
407e8d8bef9SDimitry Andric /// IF (IllegalHandle)
408e8d8bef9SDimitry Andric ///   ZF := 1
409*fe6060f1SDimitry Andric ///   FOR i := 0 to 7
410*fe6060f1SDimitry Andric ///     __odata[i] := 0
411*fe6060f1SDimitry Andric ///   ENDFOR
412e8d8bef9SDimitry Andric /// ELSE
413e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
414e8d8bef9SDimitry Andric ///   IF Authentic == 0
415e8d8bef9SDimitry Andric ///     ZF := 1
416*fe6060f1SDimitry Andric ///     FOR i := 0 to 7
417*fe6060f1SDimitry Andric ///       __odata[i] := 0
418*fe6060f1SDimitry Andric ///     ENDFOR
419e8d8bef9SDimitry Andric ///   ELSE
420e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
421e8d8bef9SDimitry Andric ///       __odata[i] := AES256Encrypt (__idata[i], UnwrappedKey)
422e8d8bef9SDimitry Andric ///     ENDFOR
423e8d8bef9SDimitry Andric ///     ZF := 0
424e8d8bef9SDimitry Andric ///   FI
425e8d8bef9SDimitry Andric /// FI
426e8d8bef9SDimitry Andric /// dst := ZF
427e8d8bef9SDimitry Andric /// OF := 0
428e8d8bef9SDimitry Andric /// SF := 0
429e8d8bef9SDimitry Andric /// AF := 0
430e8d8bef9SDimitry Andric /// PF := 0
431e8d8bef9SDimitry Andric /// CF := 0
432e8d8bef9SDimitry Andric /// \endoperation
433e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
434e8d8bef9SDimitry Andric _mm_aesencwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
435e8d8bef9SDimitry Andric   return __builtin_ia32_aesencwide256kl_u8((__v2di *)__odata,
436e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
437e8d8bef9SDimitry Andric }
438e8d8bef9SDimitry Andric 
439e8d8bef9SDimitry Andric /// Decrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle
440e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
441e8d8bef9SDimitry Andric /// return the affected ZF flag status.
442e8d8bef9SDimitry Andric ///
443e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
444e8d8bef9SDimitry Andric ///
445e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDECWIDE128KL </c> instructions.
446e8d8bef9SDimitry Andric ///
447e8d8bef9SDimitry Andric /// \operation
448e8d8bef9SDimitry Andric /// Handle[383:0] := MEM[__h+383:__h]
449e8d8bef9SDimitry Andric /// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||
450e8d8bef9SDimitry Andric ///                    (Handle[127:0] AND (CPL > 0)) ||
451e8d8bef9SDimitry Andric ///                    Handle[255:128] ||
452e8d8bef9SDimitry Andric ///                    HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128 )
453e8d8bef9SDimitry Andric /// IF (IllegalHandle)
454e8d8bef9SDimitry Andric ///   ZF := 1
455*fe6060f1SDimitry Andric ///   FOR i := 0 to 7
456*fe6060f1SDimitry Andric ///     __odata[i] := 0
457*fe6060f1SDimitry Andric ///   ENDFOR
458e8d8bef9SDimitry Andric /// ELSE
459e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)
460e8d8bef9SDimitry Andric ///   IF Authentic == 0
461e8d8bef9SDimitry Andric ///     ZF := 1
462*fe6060f1SDimitry Andric ///     FOR i := 0 to 7
463*fe6060f1SDimitry Andric ///       __odata[i] := 0
464*fe6060f1SDimitry Andric ///     ENDFOR
465e8d8bef9SDimitry Andric ///   ELSE
466e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
467e8d8bef9SDimitry Andric ///       __odata[i] := AES128Decrypt (__idata[i], UnwrappedKey)
468e8d8bef9SDimitry Andric ///     ENDFOR
469e8d8bef9SDimitry Andric ///     ZF := 0
470e8d8bef9SDimitry Andric ///   FI
471e8d8bef9SDimitry Andric /// FI
472e8d8bef9SDimitry Andric /// dst := ZF
473e8d8bef9SDimitry Andric /// OF := 0
474e8d8bef9SDimitry Andric /// SF := 0
475e8d8bef9SDimitry Andric /// AF := 0
476e8d8bef9SDimitry Andric /// PF := 0
477e8d8bef9SDimitry Andric /// CF := 0
478e8d8bef9SDimitry Andric /// \endoperation
479e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
480e8d8bef9SDimitry Andric _mm_aesdecwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
481e8d8bef9SDimitry Andric   return __builtin_ia32_aesdecwide128kl_u8((__v2di *)__odata,
482e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
483e8d8bef9SDimitry Andric }
484e8d8bef9SDimitry Andric 
485e8d8bef9SDimitry Andric /// Decrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle
486e8d8bef9SDimitry Andric /// at __h and store each resultant block back from __odata to __odata+7. And
487e8d8bef9SDimitry Andric /// return the affected ZF flag status.
488e8d8bef9SDimitry Andric ///
489e8d8bef9SDimitry Andric /// \headerfile <x86intrin.h>
490e8d8bef9SDimitry Andric ///
491e8d8bef9SDimitry Andric /// This intrinsic corresponds to the <c> AESDECWIDE256KL </c> instructions.
492e8d8bef9SDimitry Andric ///
493e8d8bef9SDimitry Andric /// \operation
494e8d8bef9SDimitry Andric /// Handle[511:0] := MEM[__h+511:__h]
495e8d8bef9SDimitry Andric /// IllegalHandle = ( HandleReservedBitSet (Handle[511:0]) ||
496e8d8bef9SDimitry Andric ///                   (Handle[127:0] AND (CPL > 0)) ||
497e8d8bef9SDimitry Andric ///                   Handle[255:128] ||
498e8d8bef9SDimitry Andric ///                   HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES512 )
499e8d8bef9SDimitry Andric /// If (IllegalHandle)
500e8d8bef9SDimitry Andric ///   ZF := 1
501*fe6060f1SDimitry Andric ///   FOR i := 0 to 7
502*fe6060f1SDimitry Andric ///     __odata[i] := 0
503*fe6060f1SDimitry Andric ///   ENDFOR
504e8d8bef9SDimitry Andric /// ELSE
505e8d8bef9SDimitry Andric ///   (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)
506e8d8bef9SDimitry Andric ///   IF Authentic == 0
507e8d8bef9SDimitry Andric ///     ZF := 1
508*fe6060f1SDimitry Andric ///     FOR i := 0 to 7
509*fe6060f1SDimitry Andric ///       __odata[i] := 0
510*fe6060f1SDimitry Andric ///     ENDFOR
511e8d8bef9SDimitry Andric ///   ELSE
512e8d8bef9SDimitry Andric ///     FOR i := 0 to 7
513e8d8bef9SDimitry Andric ///       __odata[i] := AES256Decrypt (__idata[i], UnwrappedKey)
514e8d8bef9SDimitry Andric ///     ENDFOR
515e8d8bef9SDimitry Andric ///     ZF := 0
516e8d8bef9SDimitry Andric ///   FI
517e8d8bef9SDimitry Andric /// FI
518e8d8bef9SDimitry Andric /// dst := ZF
519e8d8bef9SDimitry Andric /// OF := 0
520e8d8bef9SDimitry Andric /// SF := 0
521e8d8bef9SDimitry Andric /// AF := 0
522e8d8bef9SDimitry Andric /// PF := 0
523e8d8bef9SDimitry Andric /// CF := 0
524e8d8bef9SDimitry Andric /// \endoperation
525e8d8bef9SDimitry Andric static __inline__ unsigned char __DEFAULT_FN_ATTRS
526e8d8bef9SDimitry Andric _mm_aesdecwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {
527e8d8bef9SDimitry Andric   return __builtin_ia32_aesdecwide256kl_u8((__v2di *)__odata,
528e8d8bef9SDimitry Andric                                            (const __v2di *)__idata, __h);
529e8d8bef9SDimitry Andric }
530e8d8bef9SDimitry Andric 
531e8d8bef9SDimitry Andric #undef __DEFAULT_FN_ATTRS
532e8d8bef9SDimitry Andric 
533e8d8bef9SDimitry Andric #endif /* !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) \
534e8d8bef9SDimitry Andric           || defined(__WIDEKL__) */
535e8d8bef9SDimitry Andric 
536e8d8bef9SDimitry Andric #endif /* _KEYLOCKERINTRIN_H */
537