汇编 intel AES-NI AND PCLMULQDQ 指令

简介: 供了硬件加速,用于使用高级加密标准(AES)对数据进行加密和解密。AES-NI 指令可以提高执行使用 AES 算法进行加密和解密的应用程序的速度。这对于诸如磁盘加密、网络安全连接以及其他加密操作的应用程序特别有益。

使用XMM寄存器(128位)来执行加密和解密操作

AESDEC

AESDEC xmm1, xmm2/m128

        Perform one round of an AES decryption flow, using the Equivalent Inverse Cipher, using one 128-bit data (state) from xmm1 with one 128-bit round key from 
xmm2/m128

        执行AES(高级加密标准)算法的解密步骤。其中xmm1寄存器用作轮密钥的输入,xmm2/m128则是待解密的数据。
STATE := SRC1;
RoundKey := SRC2;
STATE := InvShiftRows( STATE );
STATE := InvSubBytes( STATE );
STATE := InvMixColumns( STATE );
DEST[127:0] := STATE XOR RoundKey;
DEST[MAXVL-1:128] (Unmodified)

AESDECLAST

AESDECLAST xmm1, xmm2/m128
         Perform the last round of an AES decryption flow, using the Equivalent Inverse Cipher, using one 128-bit data (state) from xmm1 with one 128-bit round key from xmm2/m128.

        指令用于执行AES算法的最后解密步骤,其中xmm1寄存器用作最后一轮密钥的输入,xmm2/m128则是待解密的数据。

STATE := SRC1;
RoundKey := SRC2;
STATE := InvShiftRows( STATE );
STATE := InvSubBytes( STATE );
DEST[127:0] := STATE XOR RoundKey;
DEST[MAXVL-1:128] (Unmodified)

AESENC

AESENC xmm1, xmm2/m128
        Perform one round of an AES encryption flow, using one 128-bit data (state) from xmm1 with one 128-bit round key from xmm2/m128.

。该指令用于执行AES算法的加密步骤,其中xmm1寄存器用作轮密钥的输入,xmm2/m128则是待加密的数据。

AESENC 
STATE := SRC1;
RoundKey := SRC2;
STATE := ShiftRows( STATE );
STATE := SubBytes( STATE );
STATE := MixColumns( STATE );
DEST[127:0] := STATE XOR RoundKey;
DEST[MAXVL-1:128] (Unmodified)

AESENCLAST

AESENCLAST xmm1, xmm2/m128
         Perform the last round of an AES encryption flow, using one 128-bit data (state) from xmm1 with one 128-bit round key from xmm2/m128.

        用于执行AES算法的最后加密步骤,其中xmm1寄存器用作最后一轮密钥的输入,xmm2/m128则是待加密的数据。

AESENCLAST 
STATE := SRC1;
RoundKey := SRC2;
STATE := ShiftRows( STATE );
STATE := SubBytes( STATE );
DEST[127:0] := STATE XOR RoundKey;
DEST[MAXVL-1:128] (Unmodified)

AESIMC

AESIMC xmm1, xmm2/m128

         Perform the InvMixColumn transformation on a 128-bit round key from xmm2/m128 and store the result in xmm1.

        对xmm2/m128操作数执行AES逆混合列变换,并将结果存储在xmm1中。这条指令用于AES解密过程中,在最后一轮解密后对数据进行转换。

AESIMC
DEST[127:0] := InvMixColumns( SRC );
DEST[MAXVL-1:128] (Unmodified)

AESKEYGENASSIST

AESKEYGENASSIST xmm1, xmm2/m128, imm8
         Assist in AES round key generation using an 8 bits Round Constant (RCON) specified in the immediate byte, operating on 128 bits of data specified in xmm2/m128 and stores the result in xmm1.

用于辅助生成用于AES加密和解密的轮密钥。指令以xmm2/m128作为输入,并执行密钥扩展操作,imm8即时值指定密钥扩展的类型

imm8:

  • 0x01:用于生成第一轮子密钥。
  • 0x02:用于生成第二轮子密钥。
  • 0x04:用于生成第三轮子密钥。
  • 0x08:用于生成第四轮子密钥。

AESKEYGENASSIST
X3[31:0] := SRC [127: 96];
X2[31:0] := SRC [95: 64];
X1[31:0] := SRC [63: 32];
X0[31:0] := SRC [31: 0];
RCON[31:0] := ZeroExtend(imm8[7:0]);
DEST[31:0] := SubWord(X1);
DEST[63:32 ] := RotWord( SubWord(X1) ) XOR RCON;
DEST[95:64] := SubWord(X3);
DEST[127:96] := RotWord( SubWord(X3) ) XOR RCON;
DEST[MAXVL-1:128] (Unmodified)

PCLMULQDQ

PCLMULQDQ xmm1, xmm2/m128, imm8
        Carry-less multiplication of one quadword of xmm1 by one quadword of xmm2/m128, stores the 128-bit result in xmm1. The immediate is used to determine which quadwords of xmm1 and xmm2/m128 should be used.

        执行两个64位操作数的无进位乘法,其中源操作数为xmm2/m128,目标操作数为xmm1,生成一个128位的结果。imm8即时值指定了源操作数中用于乘法的64位位置。这条指令在密码应用和纠错码等需要无进位乘法的场景中非常有用。

        IMM8:            

  • 0x00:选择源操作数的低64位进行乘法。
  • 0x01:选择源操作数的高64位进行乘法。
  • 0x10:选择目标操作数的低64位进行乘法。
  • 0x11:选择目标操作数的高64位进行乘法。

在AES 的CBC,CTR 中使用

在AES中的作用是执行乘法运算,特别是在AES加密过程中的MixColumns操作中使用到了PCLMULQDQ指令。

在AES加密中,MixColumns阶段涉及对列进行线性变换,这需要进行有限域GF(2^8)上的多项式乘法。PCLMULQDQ指令可以高效地执行无进位乘法,即“carry-less multiplication”,这种乘法操作在GF(2^128)上的多项式乘法中非常有用。

通过PCLMULQDQ指令,可以快速且有效地执行AES加密中MixColumns操作所需的乘法运算,从而提高加密速度和效率。因此,PCLMULQDQ指令在现代处理器中被广泛应用于加速AES加密算法的执行。

Carry-less multiplication(无进位乘法)是一种在计算机科学和密码学中常用的乘法技术。它执行两个多项式的乘法,但不考虑传统乘法中的进位操作。在有限域上进行无进位乘法可以提高计算效率,并且在一些加密算法中具有重要的应用。

在密码学中,无进位乘法通常用于实现AES(Advanced Encryption Standard)加密算法中的MixColumns操作。这个操作涉及对列向量进行线性变换,需要进行有限域GF(2^8)上的多项式乘法。PCLMULQDQ指令是一种硬件级别的指令,可以高效地执行无进位乘法,因此在现代处理器中被广泛应用于加速AES加密算法的执行

define PCLMUL128(X,Y): // helper function
	FOR i := 0 to 63:
		TMP [ i ] := X[ 0 ] and Y[ i ]
		FOR j := 1 to i:
			TMP [ i ] := TMP [ i ] xor (X[ j ] and Y[ i - j ])
		DEST[ i ] := TMP[ i ]
	FOR i := 64 to 126:
		TMP [ i ] := 0
		FOR j := i - 63 to 63:
			TMP [ i ] := TMP [ i ] xor (X[ j ] and Y[ i - j ])
		DEST[ i ] := TMP[ i ]
	DEST[127] := 0;
	RETURN DEST // 128b vector

PCLMULQDQ (SSE Version)
IF imm8[0] = 0:
	TEMP1 := SRC1.qword[0]
ELSE:
	TEMP1 := SRC1.qword[1]
IF imm8[4] = 0:
	TEMP2 := SRC2.qword[0]
ELSE:
	TEMP2 := SRC2.qword[1]
	DEST[127:0] := PCLMUL128(TEMP1, TEMP2)
	DEST[MAXVL-1:128] (Unmodified)
section .data
    state db 0x04, 0xe0, 0x48, 0x28
          db 0x66, 0xcb, 0xf8, 0x06
          db 0x81, 0x19, 0xd3, 0x26
          db 0xe5, 0x9a, 0x7a, 0x4c

    mix_columns_matrix db 0x02, 0x03, 0x01, 0x01
                      db 0x01, 0x02, 0x03, 0x01
                      db 0x01, 0x01, 0x02, 0x03
                      db 0x03, 0x01, 0x01, 0x02

section .text
global _start

_start:
    movdqu xmm0, [state]  ; 加载状态矩阵到XMM寄存器xmm0
    movdqu xmm1, [mix_columns_matrix]  ; 加载MixColumns矩阵到XMM寄存器xmm1

    ; 执行MixColumns操作
    pclmulqdq xmm0, xmm1, 0x00  ; 使用PCLMULQDQ指令执行MixColumns操作

    ; 输出结果
    movdqu [result], xmm0

section .bss
    result resb 16  ; 存储MixColumns操作后的状态矩阵

AES-NI 加密模式
ECB

将明文分成块,每个块独立加密。相同的明文块会得到相同的密文块,可能导致安全性问题

加密:

        1: 加载128位密钥到XMM 寄存器

        2: 将待加密的明文数据加载到XMM 寄存器

        3: 使用AESENC 指令执行加密操作,将密钥和明文数据作为输入,得到密文数据

        4: 存储加密后的数据或继续处理其他数据块

于解密
    1:加载128位密钥到XMM寄存器。
    2:将待解密的密文数据加载到XMM寄存器。
    3:使用AESDEC指令执行解密操作,将密钥和密文数据作为输入,得到明文数据。
    4:存储解密后的数据或继续处理其他数据块

        

每个数据块都是独立加密的,因此对于大于128位的数据,需要按照数据块大小分割数据并分别进行加密和解密

section .data
    key db 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
    plaintext db "This is a secret message", 0
    ciphertext rb 16

section .text
    global _start

    ; 加密函数
    aes_ecb_encrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm0, [plaintext]  ; Load plaintext
        AESENC xmm0, xmm1       ; Encrypt using AES-NI instruction
        movdqu [ciphertext], xmm0  ; Store ciphertext
        ret

    ; 解密函数
    aes_ecb_decrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm0, [ciphertext]  ; Load ciphertext
        AESDEC xmm0, xmm1       ; Decrypt using AES-NI instruction
        movdqu [plaintext], xmm0  ; Store plaintext
        ret

_start:
    ; 调用加密函数
    call aes_ecb_encrypt

    ; 调用解密函数
    call aes_ecb_decrypt

    ; 退出程序
    mov eax, 60         ; syscall number for exit
    xor edi, edi        ; exit code 0
    syscall

CBC

使用前一个密文块作为下一个明文块的输入,增加了安全性

每个明文块会先与前一个密文块进行异或运算,然后再进行加密。解密时需要先解密密文块,然后与前一个密文块进行异或运算得到明文块

加密:
    1:将初始向量(IV)与第一个明文块进行异或运算。
    2:对结果进行加密得到第一个密文块。
    3:将第一个密文块与第二个明文块进行异或运算。
    4:对结果进行加密得到第二个密文块。
    5:依此类推,直到所有明文块都被处理。
解密:
    1:解密第一个密文块得到第一个明文块。
    2:将解密得到的第一个明文块与初始向量(IV)进行异或运算得到第一个明文块的原始内容。
    3:解密第二个密文块得到第二个明文块。
    4:将解密得到的第二个明文块与第一个密文块进行异或运算得到第二个明文块的原始内容。
    5:依此类推,直到所有密文块都被处理

section .data
    key db 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
    iv  db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    plaintext db "This is a secret message", 0
    ciphertext rb 16

section .text
    global _start

    ; 加密函数
    aes_cbc_encrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [plaintext]  ; Load plaintext
        AESENC xmm0, xmm2       ; XOR with IV
        AESENC xmm0, xmm1       ; Encrypt using AES-NI instruction
        movdqu [ciphertext], xmm0  ; Store ciphertext
        ret

    ; 解密函数
    aes_cbc_decrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [ciphertext]  ; Load ciphertext
        AESENCLAST xmm0, xmm1   ; Decrypt using AES-NI instruction
        AESENCLAST xmm0, xmm2   ; XOR with IV
        movdqu [plaintext], xmm0  ; Store plaintext
        ret

_start:
    ; 调用加密函数
    call aes_cbc_encrypt

    ; 调用解密函数
    call aes_cbc_decrypt

    ; 退出程序
    mov eax, 60         ; syscall number for exit
    xor edi, edi        ; exit code 0
    syscall

CTR

使用初始化向量和计数器生成密钥流,然后与明文进行异或操作来实现加密。

        CTR模式将初始向量(IV)视为计数器,对每个明文块使用不同的计数器值进行加密,然后将加密结果与明文块进行异或运算得到密文块

        有并行加密和解密的优势,并且不需要填充数据。但需要确保每个计数器值只用于加密一个明文块,以避免安全性问题。

加密:
   1: 选择一个随机的初始向量(IV)作为计数器的起始值。
    2:对每个明文块使用不同的计数器值进行加密,通常是通过对IV进行递增操作得到新的计数器值。
    3:将加密结果与对应的明文块进行异或运算得到密文块。
    4:依此类推,直到所有明文块都被处理。
解密:
    1:选择与加密时相同的初始向量(IV)作为计数器的起始值。
    2:对每个密文块使用不同的计数器值进行加密,通常是通过对IV进行递增操作得到新的计数器值。
    3:将解密结果与对应的密文块进行异或运算得到明文块。
    4:依此类推,直到所有密文块都被处理。
 

section .data
    key db 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
    iv  db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    plaintext db "This is a secret message", 0
    ciphertext rb 16

section .text
    global _start

    ; 加密函数
    aes_ctr_encrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [plaintext]  ; Load plaintext
        AESENC xmm2, xmm1       ; Encrypt IV using AES-NI instruction
        AESENC xmm0, xmm2       ; Encrypt plaintext using AES-NI instruction
        movdqu [ciphertext], xmm0  ; Store ciphertext
        ret

    ; 解密函数
    aes_ctr_decrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [ciphertext]  ; Load ciphertext
        AESENC xmm2, xmm1       ; Encrypt IV using AES-NI instruction
        AESENC xmm0, xmm2       ; Decrypt ciphertext using AES-NI instruction
        movdqu [plaintext], xmm0  ; Store plaintext
        ret

_start:
    ; 调用加密函数
    call aes_ctr_encrypt

    ; 调用解密函数
    call aes_ctr_decrypt

    ; 退出程序
    mov eax, 60         ; syscall number for exit
    xor edi, edi        ; exit code 0
    syscall

CFB

将前一个密文块的输出与密钥流进行异或操作,然后再与当前明文块进行异或操作

对称加密模式,它允许将块密码转换为流密码。在CFB模式下,前一个密文块会被输入到加密函数中,然后与明文进行异或运算以产生密文。

CFB模式可以实现部分加密和解密,因为每个密文块的生成只依赖于前一个密文块,而不需要整个消息。这使得CFB模式适用于流数据,并且能够隐藏明文中的重复模式

加密:
    将初始向量(IV)输入到加密函数中得到第一个密文块。
    将第一个密文块与第一个明文块进行异或运算得到加密结果。
    将第一个密文块输入到加密函数中得到第二个密文块。
    将第二个密文块与第二个明文块进行异或运算得到加密结果。
    依此类推,直到所有明文块都被处理。
解密:
    将初始向量(IV)输入到加密函数中得到第一个密文块。
    将第一个密文块与第一个密文块进行异或运算得到解密结果,即第一个明文块。
    将第一个密文块输入到加密函数中得到第二个密文块。
    将第二个密文块与第二个密文块进行异或运算得到解密结果,即第二个明文块。
    依此类推,直到所有密文块都被处理。
 

section .data
    key db 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
    iv  db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    plaintext db "This is a secret message", 0
    ciphertext rb 16

section .text
    global _start

    ; 加密函数
    aes_cfb_encrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [plaintext]  ; Load plaintext
        AESENC xmm2, xmm1       ; Encrypt IV using AES-NI instruction
        PXOR xmm0, xmm2         ; XOR plaintext with encrypted IV
        movdqu [ciphertext], xmm0  ; Store ciphertext
        ret

    ; 解密函数
    aes_cfb_decrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [ciphertext]  ; Load ciphertext
        AESENC xmm2, xmm1       ; Encrypt IV using AES-NI instruction
        PXOR xmm0, xmm2         ; XOR ciphertext with encrypted IV to get plaintext
        movdqu [plaintext], xmm0  ; Store plaintext
        ret

_start:
    ; 调用加密函数
    call aes_cfb_encrypt

    ; 调用解密函数
    call aes_cfb_decrypt

    ; 退出程序
    mov eax, 60         ; syscall number for exit
    xor edi, edi        ; exit code 0
    syscall

OFB

类似于CFB,但是使用前一个输出块而不是前一个密文块

一种对称加密模式,它将块密码转换为流密码。在OFB模式下,前一个密文块会被输入到加密函数中生成伪随机数流,然后与明文进行异或运算以产生密文

加密:
    将初始向量(IV)输入到加密函数中得到第一个伪随机数流。
    将第一个伪随机数流与第一个明文块进行异或运算得到第一个密文块。
    将第一个伪随机数流输入到加密函数中得到第二个伪随机数流。
    将第二个伪随机数流与第二个明文块进行异或运算得到第二个密文块。
    依此类推,直到所有明文块都被处理。
解密:
    与加密过程相同,将初始向量(IV)输入到加密函数中得到第一个伪随机数流。
    将第一个伪随机数流与第一个密文块进行异或运算得到第一个明文块。
    将第一个伪随机数流输入到加密函数中得到第二个伪随机数流。
    将第二个伪随机数流与第二个密文块进行异或运算得到第二个明文块。
    依此类推,直到所有密文块都被处理。

特点:
    加密和解密使用相同的算法,因此操作是可逆的。
    可以实现部分加密和解密,因为每个密文块的生成只依赖于前一个伪随机数流,而不需要整个消息。
    OFB模式可以并行处理数据,适用于流数据加密。

通过将块密码转换为流密码,提供了一种安全且高效的加密方式,同时保持了加密和解密操作的一致性。

section .data
    key db 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
    iv  db 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
    plaintext db "This is a secret message", 0
    ciphertext rb 16

section .text
    global _start

    ; 加密函数
    aes_ofb_encrypt:
        movdqu xmm1, [key]     ; Load key
        movdqu xmm2, [iv]      ; Load IV
        movdqu xmm0, [plaintext]  ; Load plaintext
        AESENC xmm2, xmm1       ; Encrypt IV using AES-NI instruction
        movdqu xmm3, xmm2       ; Save the encrypted IV
        PXOR xmm0, xmm2         ; XOR plaintext with encrypted IV
        movdqu [ciphertext], xmm0  ; Store ciphertext
        ret

    ; 解密函数(OFB模式下解密与加密相同)
    aes_ofb_decrypt:
        call aes_ofb_encrypt   ; OFB decryption is the same as encryption
        ret

_start:
    ; 调用加密函数
    call aes_ofb_encrypt

    ; 调用解密函数
    call aes_ofb_decrypt

    ; 退出程序
    mov eax, 60         ; syscall number for exit
    xor edi, edi        ; exit code 0
    syscall

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值