zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

keylockerintrin.h (18282B) - Raw


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