Skip to content

Commit

Permalink
[X86] Support Intel Key Locker
Browse files Browse the repository at this point in the history
Key Locker provides a mechanism to encrypt and decrypt data with an AES key without having access
to the raw key value by converting AES keys into “handles”. These handles can be used to perform the
same encryption and decryption operations as the original AES keys, but they only work on the current
system and only until they are revoked. If software revokes Key Locker handles (e.g., on a reboot),
then any previous handles can no longer be used.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D88398
  • Loading branch information
xiangzh1 committed Sep 30, 2020
1 parent 8c05c7c commit 413577a
Show file tree
Hide file tree
Showing 34 changed files with 3,317 additions and 4 deletions.
19 changes: 19 additions & 0 deletions clang/include/clang/Basic/BuiltinsX86.def
Expand Up @@ -1900,6 +1900,25 @@ TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid")
TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd")
TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd")

// KEY LOCKER
TARGET_BUILTIN(__builtin_ia32_loadiwkey, "vUiV2OiV2OiV2Oi", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_encodekey128,
"UiUiV2OiV2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_encodekey256,
"UiUiV2OiV2OiV2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesenc128kl, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesenc256kl, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesdec128kl, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesdec256kl, "UcV2Oi*V2OivC*", "nV:128:", "kl")
TARGET_BUILTIN(__builtin_ia32_aesencwide128kl,
"UcvC*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2OiV2OiV2OiV2OiV2OiV2OiV2OiV2Oi", "nV:128:", "kl,widekl")
TARGET_BUILTIN(__builtin_ia32_aesencwide256kl,
"UcvC*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2OiV2OiV2OiV2OiV2OiV2OiV2OiV2Oi", "nV:128:", "kl,widekl")
TARGET_BUILTIN(__builtin_ia32_aesdecwide128kl,
"UcvC*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2OiV2OiV2OiV2OiV2OiV2OiV2OiV2Oi", "nV:128:", "kl,widekl")
TARGET_BUILTIN(__builtin_ia32_aesdecwide256kl,
"UcvC*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2Oi*V2OiV2OiV2OiV2OiV2OiV2OiV2OiV2Oi", "nV:128:", "kl,widekl")

// SERIALIZE
TARGET_BUILTIN(__builtin_ia32_serialize, "v", "n", "serialize")

Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Expand Up @@ -3253,6 +3253,10 @@ def minvpcid : Flag<["-"], "minvpcid">, Group<m_x86_Features_Group>;
def mno_invpcid : Flag<["-"], "mno-invpcid">, Group<m_x86_Features_Group>;
def mgfni : Flag<["-"], "mgfni">, Group<m_x86_Features_Group>;
def mno_gfni : Flag<["-"], "mno-gfni">, Group<m_x86_Features_Group>;
def mkl : Flag<["-"], "mkl">, Group<m_x86_Features_Group>;
def mno_kl : Flag<["-"], "mno-kl">, Group<m_x86_Features_Group>;
def mwidekl : Flag<["-"], "mwidekl">, Group<m_x86_Features_Group>;
def mno_widekl : Flag<["-"], "mno-widekl">, Group<m_x86_Features_Group>;
def mlwp : Flag<["-"], "mlwp">, Group<m_x86_Features_Group>;
def mno_lwp : Flag<["-"], "mno-lwp">, Group<m_x86_Features_Group>;
def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>;
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Basic/Targets/X86.cpp
Expand Up @@ -276,6 +276,10 @@ bool X86TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasCLDEMOTE = true;
} else if (Feature == "+rdpid") {
HasRDPID = true;
} else if (Feature == "+kl") {
HasKL = true;
} else if (Feature == "+widekl") {
HasWIDEKL = true;
} else if (Feature == "+retpoline-external-thunk") {
HasRetpolineExternalThunk = true;
} else if (Feature == "+sahf") {
Expand Down Expand Up @@ -678,6 +682,10 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__PREFETCHWT1__");
if (HasCLZERO)
Builder.defineMacro("__CLZERO__");
if (HasKL)
Builder.defineMacro("__KL__");
if (HasWIDEKL)
Builder.defineMacro("__WIDEKL__");
if (HasRDPID)
Builder.defineMacro("__RDPID__");
if (HasCLDEMOTE)
Expand Down Expand Up @@ -833,6 +841,8 @@ bool X86TargetInfo::isValidFeatureName(StringRef Name) const {
.Case("fxsr", true)
.Case("gfni", true)
.Case("invpcid", true)
.Case("kl", true)
.Case("widekl", true)
.Case("lwp", true)
.Case("lzcnt", true)
.Case("mmx", true)
Expand Down Expand Up @@ -919,6 +929,8 @@ bool X86TargetInfo::hasFeature(StringRef Feature) const {
.Case("fxsr", HasFXSR)
.Case("gfni", HasGFNI)
.Case("invpcid", HasINVPCID)
.Case("kl", HasKL)
.Case("widekl", HasWIDEKL)
.Case("lwp", HasLWP)
.Case("lzcnt", HasLZCNT)
.Case("mm3dnow", MMX3DNowLevel >= AMD3DNow)
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/X86.h
Expand Up @@ -127,6 +127,8 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
bool HasPTWRITE = false;
bool HasINVPCID = false;
bool HasENQCMD = false;
bool HasKL = false; // For key locker
bool HasWIDEKL = false; // For wide key locker
bool HasAMXTILE = false;
bool HasAMXINT8 = false;
bool HasAMXBF16 = false;
Expand Down
87 changes: 87 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Expand Up @@ -14037,6 +14037,93 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
case X86::BI__builtin_ia32_psubusb128:
case X86::BI__builtin_ia32_psubusw128:
return EmitX86BinaryIntrinsic(*this, Ops, Intrinsic::usub_sat);
case X86::BI__builtin_ia32_encodekey128:
case X86::BI__builtin_ia32_encodekey256:
case X86::BI__builtin_ia32_aesenc128kl:
case X86::BI__builtin_ia32_aesdec128kl:
case X86::BI__builtin_ia32_aesenc256kl:
case X86::BI__builtin_ia32_aesdec256kl:
case X86::BI__builtin_ia32_aesencwide128kl:
case X86::BI__builtin_ia32_aesdecwide128kl:
case X86::BI__builtin_ia32_aesencwide256kl:
case X86::BI__builtin_ia32_aesdecwide256kl: {
int FirstReturnOp;
int ResultCount;
SmallVector<Value*, 9> InOps;
unsigned ID;

switch (BuiltinID) {
default: llvm_unreachable("Unsupported intrinsic!");
case X86::BI__builtin_ia32_encodekey128:
ID = Intrinsic::x86_encodekey128;
InOps = {Ops[0], Ops[1]};
FirstReturnOp = 2;
ResultCount = 6;
break;
case X86::BI__builtin_ia32_encodekey256:
ID = Intrinsic::x86_encodekey256;
InOps = {Ops[0], Ops[1], Ops[2]};
FirstReturnOp = 3;
ResultCount = 7;
break;
case X86::BI__builtin_ia32_aesenc128kl:
case X86::BI__builtin_ia32_aesdec128kl:
case X86::BI__builtin_ia32_aesenc256kl:
case X86::BI__builtin_ia32_aesdec256kl: {
InOps = {Ops[1], Ops[2]};
FirstReturnOp = 0;
ResultCount = 1;
switch (BuiltinID) {
case X86::BI__builtin_ia32_aesenc128kl:
ID = Intrinsic::x86_aesenc128kl;
break;
case X86::BI__builtin_ia32_aesdec128kl:
ID = Intrinsic::x86_aesdec128kl;
break;
case X86::BI__builtin_ia32_aesenc256kl:
ID = Intrinsic::x86_aesenc256kl;
break;
case X86::BI__builtin_ia32_aesdec256kl:
ID = Intrinsic::x86_aesdec256kl;
break;
}
break;
}
case X86::BI__builtin_ia32_aesencwide128kl:
case X86::BI__builtin_ia32_aesdecwide128kl:
case X86::BI__builtin_ia32_aesencwide256kl:
case X86::BI__builtin_ia32_aesdecwide256kl: {
InOps = {Ops[0], Ops[9], Ops[10], Ops[11], Ops[12], Ops[13],
Ops[14], Ops[15], Ops[16]};
FirstReturnOp = 1;
ResultCount = 8;
switch (BuiltinID) {
case X86::BI__builtin_ia32_aesencwide128kl:
ID = Intrinsic::x86_aesencwide128kl;
break;
case X86::BI__builtin_ia32_aesdecwide128kl:
ID = Intrinsic::x86_aesdecwide128kl;
break;
case X86::BI__builtin_ia32_aesencwide256kl:
ID = Intrinsic::x86_aesencwide256kl;
break;
case X86::BI__builtin_ia32_aesdecwide256kl:
ID = Intrinsic::x86_aesdecwide256kl;
break;
}
break;
}
}

Value *Call = Builder.CreateCall(CGM.getIntrinsic(ID), InOps);

for (int i = 0; i < ResultCount; ++i) {
Builder.CreateDefaultAlignedStore(Builder.CreateExtractValue(Call, i + 1),
Ops[FirstReturnOp + i]);
}

return Builder.CreateExtractValue(Call, 0);
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Headers/CMakeLists.txt
Expand Up @@ -72,6 +72,8 @@ set(files
inttypes.h
invpcidintrin.h
iso646.h
keylockerintrin.h
keylocker_wide_intrin.h
limits.h
lwpintrin.h
lzcntintrin.h
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/Headers/immintrin.h
Expand Up @@ -471,6 +471,16 @@ _storebe_i64(void * __P, long long __D) {
#include <invpcidintrin.h>
#endif

#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
defined(__KL__)
#include <keylockerintrin.h>
#endif

#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
defined(__WIDEKL__)
#include <keylocker_wide_intrin.h>
#endif

#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
defined(__AMXTILE__) || defined(__AMXINT8__) || defined(__AMXBF16__)
#include <amxintrin.h>
Expand Down

0 comments on commit 413577a

Please sign in to comment.