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 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 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 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 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 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 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 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 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 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 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 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