519 lines · c
1/*===----------------- keylockerintrin.h - KL Intrinsics -------------------===2 *3 * Permission is hereby granted, free of charge, to any person obtaining a copy4 * of this software and associated documentation files (the "Software"), to deal5 * in the Software without restriction, including without limitation the rights6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell7 * copies of the Software, and to permit persons to whom the Software is8 * furnished to do so, subject to the following conditions:9 *10 * The above copyright notice and this permission notice shall be included in11 * all copies or substantial portions of the Software.12 *13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN19 * THE SOFTWARE.20 *21 *===-----------------------------------------------------------------------===22 */23 24#ifndef __IMMINTRIN_H25#error "Never use <keylockerintrin.h> directly; include <immintrin.h> instead."26#endif27 28#ifndef _KEYLOCKERINTRIN_H29#define _KEYLOCKERINTRIN_H30 31/* Define the default attributes for the functions in this file. */32#define __DEFAULT_FN_ATTRS \33 __attribute__((__always_inline__, __nodebug__, __target__("kl"),\34 __min_vector_width__(128)))35 36/// Load internal wrapping key from __intkey, __enkey_lo and __enkey_hi. __ctl37/// will assigned to EAX, whch specifies the KeySource and whether backing up38/// the key is permitted. The 256-bit encryption key is loaded from the two39/// explicit operands (__enkey_lo and __enkey_hi). The 128-bit integrity key is40/// loaded from the implicit operand XMM0 which assigned by __intkey.41///42/// \headerfile <x86intrin.h>43///44/// This intrinsic corresponds to the <c> LOADIWKEY </c> instructions.45///46/// \code{.operation}47/// IF CPL > 0 // LOADKWKEY only allowed at ring 0 (supervisor mode)48/// GP (0)49/// FI50/// IF “LOADIWKEY exiting” VM execution control set51/// VMexit52/// FI53/// IF __ctl[4:1] > 1 // Reserved KeySource encoding used54/// GP (0)55/// FI56/// IF __ctl[31:5] != 0 // Reserved bit in __ctl is set57/// GP (0)58/// FI59/// IF __ctl[0] AND (CPUID.19H.ECX[0] == 0) // NoBackup is not supported on this part60/// GP (0)61/// FI62/// IF (__ctl[4:1] == 1) AND (CPUID.19H.ECX[1] == 0) // KeySource of 1 is not supported on this part63/// GP (0)64/// FI65/// IF (__ctl[4:1] == 0) // KeySource of 0.66/// IWKey.Encryption Key[127:0] := __enkey_hi[127:0]:67/// IWKey.Encryption Key[255:128] := __enkey_lo[127:0]68/// IWKey.IntegrityKey[127:0] := __intkey[127:0]69/// IWKey.NoBackup := __ctl[0]70/// IWKey.KeySource := __ctl[4:1]71/// ZF := 072/// ELSE // KeySource of 1. See RDSEED definition for details of randomness73/// IF HW_NRND_GEN.ready == 1 // Full-entropy random data from RDSEED was received74/// IWKey.Encryption Key[127:0] := __enkey_hi[127:0] XOR HW_NRND_GEN.data[127:0]75/// IWKey.Encryption Key[255:128] := __enkey_lo[127:0] XOR HW_NRND_GEN.data[255:128]76/// IWKey.Encryption Key[255:0] := __enkey_hi[127:0]:__enkey_lo[127:0] XOR HW_NRND_GEN.data[255:0]77/// IWKey.IntegrityKey[127:0] := __intkey[127:0] XOR HW_NRND_GEN.data[383:256]78/// IWKey.NoBackup := __ctl[0]79/// IWKey.KeySource := __ctl[4:1]80/// ZF := 081/// ELSE // Random data was not returned from RDSEED. IWKey was not loaded82/// ZF := 183/// FI84/// FI85/// dst := ZF86/// OF := 087/// SF := 088/// AF := 089/// PF := 090/// CF := 091/// \endcode92static __inline__ void __DEFAULT_FN_ATTRS93_mm_loadiwkey (unsigned int __ctl, __m128i __intkey,94 __m128i __enkey_lo, __m128i __enkey_hi) {95 __builtin_ia32_loadiwkey (__intkey, __enkey_lo, __enkey_hi, __ctl);96}97 98/// Wrap a 128-bit AES key from __key into a key handle and output in99/// ((__m128i*)__h) to ((__m128i*)__h) + 2 and a 32-bit value as return.100/// The explicit source operand __htype specifies handle restrictions.101///102/// \headerfile <x86intrin.h>103///104/// This intrinsic corresponds to the <c> ENCODEKEY128 </c> instructions.105///106/// \code{.operation}107/// InputKey[127:0] := __key[127:0]108/// KeyMetadata[2:0] := __htype[2:0]109/// KeyMetadata[23:3] := 0 // Reserved for future usage110/// KeyMetadata[27:24] := 0 // KeyType is AES-128 (value of 0)111/// KeyMetadata[127:28] := 0 // Reserved for future usage112/// Handle[383:0] := WrapKey128(InputKey[127:0], KeyMetadata[127:0],113/// IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])114/// dst[0] := IWKey.NoBackup115/// dst[4:1] := IWKey.KeySource[3:0]116/// dst[31:5] := 0117/// MEM[__h+127:__h] := Handle[127:0] // AAD118/// MEM[__h+255:__h+128] := Handle[255:128] // Integrity Tag119/// MEM[__h+383:__h+256] := Handle[383:256] // CipherText120/// OF := 0121/// SF := 0122/// ZF := 0123/// AF := 0124/// PF := 0125/// CF := 0126/// \endcode127static __inline__ unsigned int __DEFAULT_FN_ATTRS128_mm_encodekey128_u32(unsigned int __htype, __m128i __key, void *__h) {129 return __builtin_ia32_encodekey128_u32(__htype, (__v2di)__key, __h);130}131 132/// Wrap a 256-bit AES key from __key_hi:__key_lo into a key handle, then133/// output handle in ((__m128i*)__h) to ((__m128i*)__h) + 3 and134/// a 32-bit value as return.135/// The explicit source operand __htype specifies handle restrictions.136///137/// \headerfile <x86intrin.h>138///139/// This intrinsic corresponds to the <c> ENCODEKEY256 </c> instructions.140///141/// \code{.operation}142/// InputKey[127:0] := __key_lo[127:0]143/// InputKey[255:128] := __key_hi[255:128]144/// KeyMetadata[2:0] := __htype[2:0]145/// KeyMetadata[23:3] := 0 // Reserved for future usage146/// KeyMetadata[27:24] := 1 // KeyType is AES-256 (value of 1)147/// KeyMetadata[127:28] := 0 // Reserved for future usage148/// Handle[511:0] := WrapKey256(InputKey[255:0], KeyMetadata[127:0],149/// IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0])150/// dst[0] := IWKey.NoBackup151/// dst[4:1] := IWKey.KeySource[3:0]152/// dst[31:5] := 0153/// MEM[__h+127:__h] := Handle[127:0] // AAD154/// MEM[__h+255:__h+128] := Handle[255:128] // Tag155/// MEM[__h+383:__h+256] := Handle[383:256] // CipherText[127:0]156/// MEM[__h+511:__h+384] := Handle[511:384] // CipherText[255:128]157/// OF := 0158/// SF := 0159/// ZF := 0160/// AF := 0161/// PF := 0162/// CF := 0163/// \endcode164static __inline__ unsigned int __DEFAULT_FN_ATTRS165_mm_encodekey256_u32(unsigned int __htype, __m128i __key_lo, __m128i __key_hi,166 void *__h) {167 return __builtin_ia32_encodekey256_u32(__htype, (__v2di)__key_lo,168 (__v2di)__key_hi, __h);169}170 171/// The AESENC128KL performs 10 rounds of AES to encrypt the __idata using172/// the 128-bit key in the handle from the __h. It stores the result in the173/// __odata. And return the affected ZF flag status.174///175/// \headerfile <x86intrin.h>176///177/// This intrinsic corresponds to the <c> AESENC128KL </c> instructions.178///179/// \code{.operation}180/// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.181/// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||182/// (Handle[127:0] AND (CPL > 0)) ||183/// Handle[383:256] ||184/// HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )185/// IF (IllegalHandle)186/// ZF := 1187/// ELSE188/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)189/// IF (Authentic == 0)190/// ZF := 1191/// ELSE192/// MEM[__odata+127:__odata] := AES128Encrypt (__idata[127:0], UnwrappedKey)193/// ZF := 0194/// FI195/// FI196/// dst := ZF197/// OF := 0198/// SF := 0199/// AF := 0200/// PF := 0201/// CF := 0202/// \endcode203static __inline__ unsigned char __DEFAULT_FN_ATTRS204_mm_aesenc128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {205 return __builtin_ia32_aesenc128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);206}207 208/// The AESENC256KL performs 14 rounds of AES to encrypt the __idata using209/// the 256-bit key in the handle from the __h. It stores the result in the210/// __odata. And return the affected ZF flag status.211///212/// \headerfile <x86intrin.h>213///214/// This intrinsic corresponds to the <c> AESENC256KL </c> instructions.215///216/// \code{.operation}217/// Handle[511:0] := MEM[__h+511:__h] // Load is not guaranteed to be atomic.218/// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||219/// (Handle[127:0] AND (CPL > 0)) ||220/// Handle[255:128] ||221/// HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256 )222/// IF (IllegalHandle)223/// ZF := 1224/// MEM[__odata+127:__odata] := 0225/// ELSE226/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)227/// IF (Authentic == 0)228/// ZF := 1229/// MEM[__odata+127:__odata] := 0230/// ELSE231/// MEM[__odata+127:__odata] := AES256Encrypt (__idata[127:0], UnwrappedKey)232/// ZF := 0233/// FI234/// FI235/// dst := ZF236/// OF := 0237/// SF := 0238/// AF := 0239/// PF := 0240/// CF := 0241/// \endcode242static __inline__ unsigned char __DEFAULT_FN_ATTRS243_mm_aesenc256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {244 return __builtin_ia32_aesenc256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);245}246 247/// The AESDEC128KL performs 10 rounds of AES to decrypt the __idata using248/// the 128-bit key in the handle from the __h. It stores the result in the249/// __odata. And return the affected ZF flag status.250///251/// \headerfile <x86intrin.h>252///253/// This intrinsic corresponds to the <c> AESDEC128KL </c> instructions.254///255/// \code{.operation}256/// Handle[383:0] := MEM[__h+383:__h] // Load is not guaranteed to be atomic.257/// IllegalHandle := (HandleReservedBitSet (Handle[383:0]) ||258/// (Handle[127:0] AND (CPL > 0)) ||259/// Handle[383:256] ||260/// HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128)261/// IF (IllegalHandle)262/// ZF := 1263/// MEM[__odata+127:__odata] := 0264/// ELSE265/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)266/// IF (Authentic == 0)267/// ZF := 1268/// MEM[__odata+127:__odata] := 0269/// ELSE270/// MEM[__odata+127:__odata] := AES128Decrypt (__idata[127:0], UnwrappedKey)271/// ZF := 0272/// FI273/// FI274/// dst := ZF275/// OF := 0276/// SF := 0277/// AF := 0278/// PF := 0279/// CF := 0280/// \endcode281static __inline__ unsigned char __DEFAULT_FN_ATTRS282_mm_aesdec128kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {283 return __builtin_ia32_aesdec128kl_u8((__v2di *)__odata, (__v2di)__idata, __h);284}285 286/// The AESDEC256KL performs 10 rounds of AES to decrypt the __idata using287/// the 256-bit key in the handle from the __h. It stores the result in the288/// __odata. And return the affected ZF flag status.289///290/// \headerfile <x86intrin.h>291///292/// This intrinsic corresponds to the <c> AESDEC256KL </c> instructions.293///294/// \code{.operation}295/// Handle[511:0] := MEM[__h+511:__h]296/// IllegalHandle := (HandleReservedBitSet (Handle[511:0]) ||297/// (Handle[127:0] AND (CPL > 0)) ||298/// Handle[383:256] ||299/// HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES256)300/// IF (IllegalHandle)301/// ZF := 1302/// MEM[__odata+127:__odata] := 0303/// ELSE304/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)305/// IF (Authentic == 0)306/// ZF := 1307/// MEM[__odata+127:__odata] := 0308/// ELSE309/// MEM[__odata+127:__odata] := AES256Decrypt (__idata[127:0], UnwrappedKey)310/// ZF := 0311/// FI312/// FI313/// dst := ZF314/// OF := 0315/// SF := 0316/// AF := 0317/// PF := 0318/// CF := 0319/// \endcode320static __inline__ unsigned char __DEFAULT_FN_ATTRS321_mm_aesdec256kl_u8(__m128i* __odata, __m128i __idata, const void *__h) {322 return __builtin_ia32_aesdec256kl_u8((__v2di *)__odata, (__v2di)__idata, __h);323}324 325#undef __DEFAULT_FN_ATTRS326 327/* Define the default attributes for the functions in this file. */328#define __DEFAULT_FN_ATTRS \329 __attribute__((__always_inline__, __nodebug__, __target__("kl,widekl"),\330 __min_vector_width__(128)))331 332/// Encrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle333/// at __h and store each resultant block back from __odata to __odata+7. And334/// return the affected ZF flag status.335///336/// \headerfile <x86intrin.h>337///338/// This intrinsic corresponds to the <c> AESENCWIDE128KL </c> instructions.339///340/// \code{.operation}341/// Handle := MEM[__h+383:__h]342/// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||343/// (Handle[127:0] AND (CPL > 0)) ||344/// Handle[255:128] ||345/// HandleKeyType (Handle[383:0]) != HANDLE_KEY_TYPE_AES128 )346/// IF (IllegalHandle)347/// ZF := 1348/// FOR i := 0 to 7349/// __odata[i] := 0350/// ENDFOR351/// ELSE352/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)353/// IF Authentic == 0354/// ZF := 1355/// FOR i := 0 to 7356/// __odata[i] := 0357/// ENDFOR358/// ELSE359/// FOR i := 0 to 7360/// __odata[i] := AES128Encrypt (__idata[i], UnwrappedKey)361/// ENDFOR362/// ZF := 0363/// FI364/// FI365/// dst := ZF366/// OF := 0367/// SF := 0368/// AF := 0369/// PF := 0370/// CF := 0371/// \endcode372static __inline__ unsigned char __DEFAULT_FN_ATTRS373_mm_aesencwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {374 return __builtin_ia32_aesencwide128kl_u8((__v2di *)__odata,375 (const __v2di *)__idata, __h);376}377 378/// Encrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle379/// at __h and store each resultant block back from __odata to __odata+7. And380/// return the affected ZF flag status.381///382/// \headerfile <x86intrin.h>383///384/// This intrinsic corresponds to the <c> AESENCWIDE256KL </c> instructions.385///386/// \code{.operation}387/// Handle[511:0] := MEM[__h+511:__h]388/// IllegalHandle := ( HandleReservedBitSet (Handle[511:0]) ||389/// (Handle[127:0] AND (CPL > 0)) ||390/// Handle[255:128] ||391/// HandleKeyType (Handle[511:0]) != HANDLE_KEY_TYPE_AES512 )392/// IF (IllegalHandle)393/// ZF := 1394/// FOR i := 0 to 7395/// __odata[i] := 0396/// ENDFOR397/// ELSE398/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)399/// IF Authentic == 0400/// ZF := 1401/// FOR i := 0 to 7402/// __odata[i] := 0403/// ENDFOR404/// ELSE405/// FOR i := 0 to 7406/// __odata[i] := AES256Encrypt (__idata[i], UnwrappedKey)407/// ENDFOR408/// ZF := 0409/// FI410/// FI411/// dst := ZF412/// OF := 0413/// SF := 0414/// AF := 0415/// PF := 0416/// CF := 0417/// \endcode418static __inline__ unsigned char __DEFAULT_FN_ATTRS419_mm_aesencwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {420 return __builtin_ia32_aesencwide256kl_u8((__v2di *)__odata,421 (const __v2di *)__idata, __h);422}423 424/// Decrypt __idata[0] to __idata[7] using 128-bit AES key indicated by handle425/// at __h and store each resultant block back from __odata to __odata+7. And426/// return the affected ZF flag status.427///428/// \headerfile <x86intrin.h>429///430/// This intrinsic corresponds to the <c> AESDECWIDE128KL </c> instructions.431///432/// \code{.operation}433/// Handle[383:0] := MEM[__h+383:__h]434/// IllegalHandle := ( HandleReservedBitSet (Handle[383:0]) ||435/// (Handle[127:0] AND (CPL > 0)) ||436/// Handle[255:128] ||437/// HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES128 )438/// IF (IllegalHandle)439/// ZF := 1440/// FOR i := 0 to 7441/// __odata[i] := 0442/// ENDFOR443/// ELSE444/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate384 (Handle[383:0], IWKey)445/// IF Authentic == 0446/// ZF := 1447/// FOR i := 0 to 7448/// __odata[i] := 0449/// ENDFOR450/// ELSE451/// FOR i := 0 to 7452/// __odata[i] := AES128Decrypt (__idata[i], UnwrappedKey)453/// ENDFOR454/// ZF := 0455/// FI456/// FI457/// dst := ZF458/// OF := 0459/// SF := 0460/// AF := 0461/// PF := 0462/// CF := 0463/// \endcode464static __inline__ unsigned char __DEFAULT_FN_ATTRS465_mm_aesdecwide128kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {466 return __builtin_ia32_aesdecwide128kl_u8((__v2di *)__odata,467 (const __v2di *)__idata, __h);468}469 470/// Decrypt __idata[0] to __idata[7] using 256-bit AES key indicated by handle471/// at __h and store each resultant block back from __odata to __odata+7. And472/// return the affected ZF flag status.473///474/// \headerfile <x86intrin.h>475///476/// This intrinsic corresponds to the <c> AESDECWIDE256KL </c> instructions.477///478/// \code{.operation}479/// Handle[511:0] := MEM[__h+511:__h]480/// IllegalHandle = ( HandleReservedBitSet (Handle[511:0]) ||481/// (Handle[127:0] AND (CPL > 0)) ||482/// Handle[255:128] ||483/// HandleKeyType (Handle) != HANDLE_KEY_TYPE_AES512 )484/// If (IllegalHandle)485/// ZF := 1486/// FOR i := 0 to 7487/// __odata[i] := 0488/// ENDFOR489/// ELSE490/// (UnwrappedKey, Authentic) := UnwrapKeyAndAuthenticate512 (Handle[511:0], IWKey)491/// IF Authentic == 0492/// ZF := 1493/// FOR i := 0 to 7494/// __odata[i] := 0495/// ENDFOR496/// ELSE497/// FOR i := 0 to 7498/// __odata[i] := AES256Decrypt (__idata[i], UnwrappedKey)499/// ENDFOR500/// ZF := 0501/// FI502/// FI503/// dst := ZF504/// OF := 0505/// SF := 0506/// AF := 0507/// PF := 0508/// CF := 0509/// \endcode510static __inline__ unsigned char __DEFAULT_FN_ATTRS511_mm_aesdecwide256kl_u8(__m128i __odata[8], const __m128i __idata[8], const void* __h) {512 return __builtin_ia32_aesdecwide256kl_u8((__v2di *)__odata,513 (const __v2di *)__idata, __h);514}515 516#undef __DEFAULT_FN_ATTRS517 518#endif /* _KEYLOCKERINTRIN_H */519