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