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