Introduction
These instructions do the inner steps of standard ciphers and hashes in hardware: an AES round, a few SHA rounds, a carry-less multiply for GCM and CRC. Each does one step; software still runs the loop, schedules the keys and handles the modes. Apart from VIA’s PadLock, they work in the XMM registers (YMM and ZMM for the wider forms), like SSE.
A program checks for each extension with CPUID:
| Extension | Brought by | CPUID |
|---|---|---|
| AES-NI | Intel Westmere, 2010 | leaf 1: ECX bit 25 |
| PCLMULQDQ | Intel Westmere, 2010 | leaf 1: ECX bit 1 |
| SHA | Intel Goldmont, 2016; AMD Zen, 2017 | leaf 7, subleaf 0: EBX bit 29 |
| GFNI | Intel Ice Lake, 2019 | leaf 7, subleaf 0: ECX bit 8 |
| VAES | Intel Ice Lake, 2019 | leaf 7, subleaf 0: ECX bit 9 |
| VPCLMULQDQ | Intel Ice Lake, 2019 | leaf 7, subleaf 0: ECX bit 10 |
| Key Locker | Intel Tiger Lake, 2020 | leaf 7, subleaf 0: ECX bit 23; then leaf 19h: EBX bit 0 (AESKLE) and bit 2 (WIDE_KL) |
| SHA512, SM3, SM4 | Intel Arrow Lake and Lunar Lake, 2024 | leaf 7, subleaf 1: EAX bits 0, 1 and 2 |
| VIA PadLock | VIA C3 (Nehemiah), 2003; SHA and MONTMUL with the VIA C7, 2005 | leaf C0000001h: EDX, a pair of bits per unit, one saying it is present and one that it is enabled |
The VEX forms also need AVX, and the EVEX forms AVX-512 (AVX512F, with AVX512VL for the 128-bit and 256-bit forms). VAES and VPCLMULQDQ are the 256-bit VEX and the EVEX forms of AES and PCLMULQDQ; their 128-bit VEX forms came with AVX.
The instructions
In the forms, xmm1 is the ModRM.reg operand and
xmm2/m128 the ModRM.r/m operand. NP means that no 66, F2 or
F3 prefix may be present. <XMM0> is an operand that is not
encoded: the instruction always uses XMM0.
AES
The state is a 128-bit AES block in xmm1; the round key is the second source. A
full AES-128 encryption is an XOR with the first round key, nine
aesenc and one aesenclast. The wider VEX and EVEX forms
do the same in each 128-bit lane, with a separate destination.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
aesenc | xmm1, xmm2/m128 | 66 0F 38 DC /r | One encryption round: ShiftRows, SubBytes, MixColumns, then XOR with the round key. VEX form: vaesenc. | AES-NI (Intel Westmere, 2010) |
aesenclast | xmm1, xmm2/m128 | 66 0F 38 DD /r | The last encryption round, without MixColumns. VEX form: vaesenclast. | AES-NI (Intel Westmere, 2010) |
aesdec | xmm1, xmm2/m128 | 66 0F 38 DE /r | One decryption round of the equivalent inverse cipher: InvShiftRows, InvSubBytes, InvMixColumns, then XOR with the round key. VEX form: vaesdec. | AES-NI (Intel Westmere, 2010) |
aesdeclast | xmm1, xmm2/m128 | 66 0F 38 DF /r | The last decryption round, without InvMixColumns. VEX form: vaesdeclast. | AES-NI (Intel Westmere, 2010) |
aesimc | xmm1, xmm2/m128 | 66 0F 38 DB /r | InvMixColumns of a round key, which turns the encryption key schedule into the one aesdec needs. VEX form: vaesimc. | AES-NI (Intel Westmere, 2010) |
aeskeygenassist | xmm1, xmm2/m128, imm8 | 66 0F 3A DF /r ib | For key expansion: from doublewords 1 and 3 of the source (X1, X3) it writes SubWord(X1), RotWord(SubWord(X1)) XOR imm8, SubWord(X3) and RotWord(SubWord(X3)) XOR imm8, from low to high. imm8 is the round constant. VEX form: vaeskeygenassist. | AES-NI (Intel Westmere, 2010) |
vaesenc | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256zmm1, zmm2, zmm3/m512 | VEX.128.66.0F38.WIG DC /rVEX.256.66.0F38.WIG DC /rEVEX.128/256/512.66.0F38.WIG DC /r | One encryption round in each 128-bit lane, as aesenc. The EVEX forms (128, 256 and 512 bits) take no mask. | AES-NI with AVX for VEX.128; VAES (Intel Ice Lake, 2019) for the others |
vaesenclast | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256zmm1, zmm2, zmm3/m512 | VEX.128.66.0F38.WIG DD /rVEX.256.66.0F38.WIG DD /rEVEX.128/256/512.66.0F38.WIG DD /r | The last encryption round in each lane, as aesenclast. | AES-NI with AVX for VEX.128; VAES (Intel Ice Lake, 2019) for the others |
vaesdec | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256zmm1, zmm2, zmm3/m512 | VEX.128.66.0F38.WIG DE /rVEX.256.66.0F38.WIG DE /rEVEX.128/256/512.66.0F38.WIG DE /r | One decryption round in each lane, as aesdec. | AES-NI with AVX for VEX.128; VAES (Intel Ice Lake, 2019) for the others |
vaesdeclast | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256zmm1, zmm2, zmm3/m512 | VEX.128.66.0F38.WIG DF /rVEX.256.66.0F38.WIG DF /rEVEX.128/256/512.66.0F38.WIG DF /r | The last decryption round in each lane, as aesdeclast. | AES-NI with AVX for VEX.128; VAES (Intel Ice Lake, 2019) for the others |
vaesimc | xmm1, xmm2/m128 | VEX.128.66.0F38.WIG DB /r | As aesimc. There is no wider form. | AES-NI (Intel Westmere, 2010), with AVX |
vaeskeygenassist | xmm1, xmm2/m128, imm8 | VEX.128.66.0F3A.WIG DF /r ib | As aeskeygenassist. There is no wider form. | AES-NI (Intel Westmere, 2010), with AVX |
Carry-less multiplication
A carry-less multiply is multiplication of polynomials over GF(2): partial products
are combined with XOR instead of addition. AES-GCM’s GHASH and fast CRC routines
are built on it. Assemblers also accept Intel’s names for the four immediates,
pclmullqlqdq (00h), pclmulhqlqdq (01h),
pclmullqhqdq (10h) and pclmulhqhqdq (11h); the
disassembler shows the immediate.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
pclmulqdq | xmm1, xmm2/m128, imm8 | 66 0F 3A 44 /r ib | Multiplies one quadword of xmm1 (the high one if imm8 bit 0 is set) by one of xmm2/m128 (the high one if imm8 bit 4 is set), carry-less, and writes the 128-bit product to xmm1. VEX form: vpclmulqdq. | PCLMULQDQ (Intel Westmere, 2010) |
vpclmulqdq | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8zmm1, zmm2, zmm3/m512, imm8 | VEX.128.66.0F3A.WIG 44 /r ibVEX.256.66.0F3A.WIG 44 /r ibEVEX.128/256/512.66.0F3A.WIG 44 /r ib | As pclmulqdq, with a separate destination; the wider forms do it in each 128-bit lane with the same imm8. | PCLMULQDQ with AVX for VEX.128; VPCLMULQDQ (Intel Ice Lake, 2019) for the others |
SHA-1 and SHA-256
The state and the message words are packed four 32-bit words to a register. Rounds and message scheduling are separate instructions, so that they can run interleaved.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
sha1rnds4 | xmm1, xmm2/m128, imm8 | NP 0F 3A CC /r ib | Four SHA-1 rounds on the state A, B, C, D in xmm1, with the four message words (E already added by sha1nexte) in xmm2/m128. imm8[1:0] picks the round function and constant: rounds 0–19, 20–39, 40–59 or 60–79. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
sha1nexte | xmm1, xmm2/m128 | NP 0F 38 C8 /r | Computes the next E, the A of four rounds before rotated left by 30, from xmm1, and adds it to the highest message word of xmm2/m128. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
sha1msg1 | xmm1, xmm2/m128 | NP 0F 38 C9 /r | The first step of the SHA-1 message schedule for the next four words: XORs of earlier words. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
sha1msg2 | xmm1, xmm2/m128 | NP 0F 38 CA /r | The last step of the SHA-1 message schedule: the remaining XOR and the rotate by one, giving the next four words. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
sha256rnds2 | xmm1, xmm2/m128, <XMM0> | NP 0F 38 CB /r | Two SHA-256 rounds. xmm1 holds the state words C, D, G and H, xmm2/m128 holds A, B, E and F, and the low two doublewords of XMM0 hold the two message words with their round constants added. The new A, B, E and F go to xmm1. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
sha256msg1 | xmm1, xmm2/m128 | NP 0F 38 CC /r | The first step of the SHA-256 message schedule for the next four words: adds σ0 of the following words. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
sha256msg2 | xmm1, xmm2/m128 | NP 0F 38 CD /r | The last step of the SHA-256 message schedule: adds σ1 of the words two places back, giving the next four words. | SHA (Intel Goldmont, 2016; AMD Zen, 2017) |
SHA-512
The SHA-512 instructions have VEX encodings only, take 256-bit YMM registers (four 64-bit words each), and take register operands only (ModRM.mod 11).
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vsha512rnds2 | ymm1, ymm2, xmm3 | VEX.256.F2.0F38.W0 CB 11:rrr:bbb | Two SHA-512 rounds on the state in ymm1 and ymm2, with two message words (round constants added) in xmm3. | SHA512 (Intel Arrow Lake and Lunar Lake, 2024) |
vsha512msg1 | ymm1, xmm2 | VEX.256.F2.0F38.W0 CC 11:rrr:bbb | The first step of the SHA-512 message schedule for the next four words. | SHA512 (Intel Arrow Lake and Lunar Lake, 2024) |
vsha512msg2 | ymm1, ymm2 | VEX.256.F2.0F38.W0 CD 11:rrr:bbb | The last step of the SHA-512 message schedule. | SHA512 (Intel Arrow Lake and Lunar Lake, 2024) |
SM3 and SM4
SM3 is the Chinese national hash function and SM4 the Chinese national block cipher (128-bit block and key). Both sets have VEX encodings only.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
vsm3msg1 | xmm1, xmm2, xmm3/m128 | VEX.128.NP.0F38.W0 DA /r | The first step of the SM3 message expansion for the next four words. | SM3 (Intel Arrow Lake and Lunar Lake, 2024) |
vsm3msg2 | xmm1, xmm2, xmm3/m128 | VEX.128.66.0F38.W0 DA /r | The last step of the SM3 message expansion. | SM3 (Intel Arrow Lake and Lunar Lake, 2024) |
vsm3rnds2 | xmm1, xmm2, xmm3/m128, imm8 | VEX.128.66.0F3A.W0 DE /r ib | Two SM3 rounds; imm8 gives the round number. | SM3 (Intel Arrow Lake and Lunar Lake, 2024) |
vsm4key4 | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.F3.0F38.W0 DA /rVEX.256.F3.0F38.W0 DA /r | Four rounds of the SM4 key expansion in each 128-bit lane. The disassembler also reads the EVEX forms (EVEX.F3.0F38.W0 DA /r, up to 512 bits), which Intel added later. | SM4 (Intel Arrow Lake and Lunar Lake, 2024) |
vsm4rnds4 | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256 | VEX.128.F2.0F38.W0 DA /rVEX.256.F2.0F38.W0 DA /r | Four SM4 encryption rounds in each 128-bit lane. EVEX forms as for vsm4key4, with F2. | SM4 (Intel Arrow Lake and Lunar Lake, 2024) |
Galois field (GFNI)
These work on bytes as elements of GF(28), with the reduction polynomial
x8 + x4 + x3 + x + 1, which AES uses. The affine
forms treat each quadword of the second source as an 8×8 bit matrix. Uses include
AES and SM4 S-boxes, bit permutations and erasure codes. The EVEX forms take a mask
({k1}{z}); the affine ones can also broadcast a quadword (m64bcst).
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
gf2p8affineqb | xmm1, xmm2/m128, imm8 | 66 0F 3A CE /r ib | Each byte x of xmm1 becomes A·x XOR imm8, where A is the matrix in the matching quadword of xmm2/m128. VEX form: vgf2p8affineqb. | GFNI (Intel Ice Lake, 2019) |
gf2p8affineinvqb | xmm1, xmm2/m128, imm8 | 66 0F 3A CF /r ib | The same applied to the inverse of each byte in GF(28) (0 stays 0). With AES’s matrix and 63h it gives the AES S-box. VEX form: vgf2p8affineinvqb. | GFNI (Intel Ice Lake, 2019) |
gf2p8mulb | xmm1, xmm2/m128 | 66 0F 38 CF /r | Multiplies bytes in GF(28). VEX form: vgf2p8mulb. | GFNI (Intel Ice Lake, 2019) |
vgf2p8affineqb | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 | VEX.128.66.0F3A.W1 CE /r ibVEX.256.66.0F3A.W1 CE /r ibEVEX.128/256/512.66.0F3A.W1 CE /r ib | As gf2p8affineqb, with a separate destination. | GFNI (Intel Ice Lake, 2019), with AVX or AVX-512 |
vgf2p8affineinvqb | xmm1, xmm2, xmm3/m128, imm8ymm1, ymm2, ymm3/m256, imm8zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst, imm8 | VEX.128.66.0F3A.W1 CF /r ibVEX.256.66.0F3A.W1 CF /r ibEVEX.128/256/512.66.0F3A.W1 CF /r ib | As gf2p8affineinvqb, with a separate destination. | GFNI (Intel Ice Lake, 2019), with AVX or AVX-512 |
vgf2p8mulb | xmm1, xmm2, xmm3/m128ymm1, ymm2, ymm3/m256zmm1 {k1}{z}, zmm2, zmm3/m512 | VEX.128.66.0F38.W0 CF /rVEX.256.66.0F38.W0 CF /rEVEX.128/256/512.66.0F38.W0 CF /r | As gf2p8mulb, with a separate destination. | GFNI (Intel Ice Lake, 2019), with AVX or AVX-512 |
Key Locker
Key Locker lets software use an AES key without holding it. The operating system
loads a secret wrapping key into the processor with loadiwkey. A
program turns its AES key into a handle with encodekey128 or
encodekey256 and can then discard the key: the encryption and
decryption instructions take the handle from memory, unwrap it inside the processor
and check it. A handle that fails the check, or whose restrictions forbid the
operation, sets ZF and leaves the data unchanged. All of them clear OF, SF, AF, PF
and CF. They need CR4.KL (bit 19) set.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
loadiwkey | xmm1, xmm2, <EAX>, <XMM0> | F3 0F 38 DC 11:rrr:bbb | Loads the internal wrapping key: the 256-bit encryption key from xmm1 and xmm2, the 128-bit integrity key from XMM0. EAX bit 0 forbids backing it up; bits 4:1 pick the key source (1 mixes in hardware random data). Ring 0 only. ZF reports a failure to get random data. | Key Locker (Intel Tiger Lake, 2020) |
encodekey128 | r32, r32, <XMM0–2>, <XMM4–6> | F3 0F 38 FA 11:rrr:bbb | Wraps the AES-128 key in XMM0 into a 384-bit handle in XMM0 to XMM2. The source register gives the handle’s restrictions (no encryption, no decryption, ring 0 only); the destination receives the wrapping key’s attributes. XMM4 to XMM6 are zeroed. | Key Locker (Intel Tiger Lake, 2020) |
encodekey256 | r32, r32, <XMM0–6> | F3 0F 38 FB 11:rrr:bbb | Wraps the AES-256 key in XMM0 (low half) and XMM1 (high half) into a 512-bit handle in XMM0 to XMM3; otherwise as encodekey128. | Key Locker (Intel Tiger Lake, 2020) |
aesenc128kl | xmm, m384 | F3 0F 38 DC !(11):rrr:bbb | Encrypts the block in xmm with the AES-128 key whose handle is at m384 (ten rounds). | Key Locker (Intel Tiger Lake, 2020) |
aesdec128kl | xmm, m384 | F3 0F 38 DD !(11):rrr:bbb | Decrypts the block in xmm with an AES-128 handle. | Key Locker (Intel Tiger Lake, 2020) |
aesenc256kl | xmm, m512 | F3 0F 38 DE !(11):rrr:bbb | Encrypts the block in xmm with an AES-256 handle (fourteen rounds). | Key Locker (Intel Tiger Lake, 2020) |
aesdec256kl | xmm, m512 | F3 0F 38 DF !(11):rrr:bbb | Decrypts the block in xmm with an AES-256 handle. | Key Locker (Intel Tiger Lake, 2020) |
aesencwide128kl | m384, <XMM0–7> | F3 0F 38 D8 !(11):000:bbb | Encrypts the eight blocks in XMM0 to XMM7 with an AES-128 handle. Needs WIDE_KL. | Key Locker (Intel Tiger Lake, 2020) |
aesdecwide128kl | m384, <XMM0–7> | F3 0F 38 D8 !(11):001:bbb | Decrypts eight blocks with an AES-128 handle. | Key Locker (Intel Tiger Lake, 2020) |
aesencwide256kl | m512, <XMM0–7> | F3 0F 38 D8 !(11):010:bbb | Encrypts eight blocks with an AES-256 handle. | Key Locker (Intel Tiger Lake, 2020) |
aesdecwide256kl | m512, <XMM0–7> | F3 0F 38 D8 !(11):011:bbb | Decrypts eight blocks with an AES-256 handle. | Key Locker (Intel Tiger Lake, 2020) |
VIA PadLock
VIA’s C3, C7 and Nano processors, and Zhaoxin’s, which descend from them, have PadLock units: a random number generator (RNG), AES (ACE, later ACE2), SHA (PHE) and a Montgomery multiplier (PMM). The instructions take no ModRM operands: each is a fixed ModRM byte after 0F A6 or 0F A7, and works on fixed general registers and memory. VIA writes XCRYPT, XSHA and MONTMUL with a REP prefix (F3), as below, and XSTORE with or without it. The disassembler names each from the opcode and ModRM byte, whether F3 is there or not.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
xstorerng | (none) | 0F A7 C0F3 0F A7 C0 | XSTORE: stores random bytes from the hardware random number generator at ES:[EDI] (RDI in 64-bit mode) and advances EDI. | VIA PadLock (VIA C3 (Nehemiah), 2003) |
xcryptecb | (none) | F3 0F A7 C8 | AES in ECB mode on ECX 16-byte blocks, from [ESI] to [EDI], with the control word at [EDX] and the key at [EBX]. | VIA PadLock (VIA C3 (Nehemiah), 2003) |
xcryptcbc | (none) | F3 0F A7 D0 | The same in CBC mode, with the initialisation vector at [EAX]. | VIA PadLock (VIA C3 (Nehemiah), 2003) |
xcryptctr | (none) | F3 0F A7 D8 | The same in counter (CTR) mode. | VIA PadLock (VIA C3 (Nehemiah), 2003; SHA and MONTMUL with the VIA C7, 2005) |
xcryptcfb | (none) | F3 0F A7 E0 | The same in CFB mode. | VIA PadLock (VIA C3 (Nehemiah), 2003) |
xcryptofb | (none) | F3 0F A7 E8 | The same in OFB mode. | VIA PadLock (VIA C3 (Nehemiah), 2003) |
xsha1 | (none) | F3 0F A6 C8 | SHA-1 over ECX bytes at [ESI], with the hash state at [EDI]. | VIA PadLock (VIA C7, 2005) |
xsha256 | (none) | F3 0F A6 D0 | SHA-256 over ECX bytes at [ESI], with the hash state at [EDI]. | VIA PadLock (VIA C7, 2005) |
montmul | (none) | F3 0F A6 C0 | Montgomery multiplication, the core of RSA, on operands in memory. | VIA PadLock (VIA C7, 2005) |
Notes
- Alignment. The legacy AES, PCLMULQDQ, SHA and GFNI forms follow SSE’s rule: a 128-bit memory operand must be 16-byte aligned. The VEX and EVEX forms have no such rule.
- Exceptions and flags. None of these raise SIMD floating-point exceptions. Of the XMM instructions, only Key Locker’s change the flags.
- Register-only forms.
loadiwkey,encodekey128,encodekey256and the SHA-512 instructions take two registers (ModRM.mod 11); the other Key Locker instructions take memory only. 0F 38 DC with F3 isloadiwkeywith a register andaesenc128klwith memory. - Names. VIA’s name for
xstorerngis XSTORE.
Links
Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manuals – Intel’s manuals; volume 2 describes each instruction
- Intel Architecture Instruction Set Extensions Programming Reference – Intel’s reference to instructions before they reach the main manual, among them SHA512, SM3 and SM4
- Intel Key Locker Specification – Intel’s specification of Key Locker
- AMD64 Architecture Programmer’s Manual, Volume 4 – AMD’s reference to the media instructions, with AES, PCLMULQDQ and SHA
- x86 and amd64 instruction reference – Félix Cloutier’s web copy of the instruction pages of Intel’s manual