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