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