Intelは2008年にx86アーキテクチャの新しいチームを提案し、対称AES(Advanced Encryption Standard)暗号化アルゴリズムのハードウェアサポートを追加しました。 AESは現在、最も人気のあるブロック暗号アルゴリズムの1つです。 したがって、ハードウェア実装により、この暗号化アルゴリズム(OpenSSL、The Bat、TrueCrypt ... )を使用したプログラムの生産性が向上するはずです 。 チームの新しい拡張には、AES-NIという名前が付けられました。 次の指示が含まれています。
- AESENC-1ラウンドのAES暗号化を実行し、
- AESENCLAST- AES暗号化の最後のラウンドを実行し、
- AESDEC-AESの復号化を1ラウンド実行し、
- AESDECLAST-AES復号化の最後のラウンドを実行し、
- AESKEYGENASSIST-AESラウンドキーの生成に貢献し、
- AESIMC-逆混合カラム。
AES暗号化アルゴリズム自体についてはすでに多くのことが述べられているため、この投稿ではこれらの命令の使用方法について説明します。
まず、AESの仕組みを覚えておいてください。 これは、これらの命令で実装されるメカニズムを理解するために必要です。
AESアルゴリズムは4つの機能を使用します。
- AddRound-キーを持つXOR(排他的OR)メッセージ、
- SubBytes-置換関数、
- ShiftRows-指定されたルールに従ってブロック内のフィールドを循環的にシフトします。
- MixColumns-混合手順。
暗号化アルゴリズム自体は次のようになります。
はじめに
開始するには、プロセッサにAES-NI拡張が存在することを確認する必要があります。 これを行うには、値eax = 0x00000001の特別なCPUIDコマンドがあり、現在の拡張機能に関連するレジスタのビットを設定する必要があります。 AES拡張の場合、これはECXレジスタの25ビットです。
AES-NI検証コード:
mov eax,0x00000001; CPUID; test ecx,0x2000000; je L_no_AES;
ビットが1に設定されている場合、暗号化に進むことができます。
キー拡張/ ExpandKey
擬似コードのキー拡張アルゴリズムは次のようになります。
KeyExpansion(byte key[4*Nk], word w[Nb*(Nr+1)], Nk) begin word temp i = 0; while ( i < Nk) w[i] = word(key[4*i], key[4*i+1], key[4*i+2], key[4*i+3]) i = i+1 end while i = Nk while ( i < Nb * (Nr+1)) temp = w[i-1] if (i mod Nk = 0) temp = SubWord(RotWord(temp)) xor Rcon[i/Nk] else if (Nk > 6 and i mod Nk = 4) temp = SubWord(temp) end if w[i] = w[i-Nk] xor temp i = i + 1 end while end
ハードウェアをサポートするには、AESKEYGENASSIST命令を使用する必要があります。この命令は次を実行します。
AESKEYGENASSIST xmm1, xmm2/m128, imm8 Tmp := xmm2/LOAD(m128) X3[31-0] = Tmp[127-96]; X2[31-0] = Tmp[95-64]; X1[31-0] = Tmp[63-32]; X0[31-0] = Tmp[31-0]; RCON[7-0]:= imm8; RCON [31-8]:= 0; xmm1 :=[RotWord (SubWord (X3)) XOR RCON, SubWord (X3), RotWord (SubWord (X1)) XOR RCON, SubWord (X1)]
簡単にわかるように、命令は実行されません。
w[i] = w[i-Nk] xor temp
MMX命令を使用して、これらの操作を自分で実行する必要があります。
キー拡張128bの例
aeskeygenassist xmm2, xmm1, 0x1 ; 1 pshufd xmm2, xmm2, 0xff; movups xmm3, xmm4; pxor xmm2,xmm3; pshufd xmm2, xmm2, 0x00; pshufd xmm3, xmm3, 0x39; pslldq xmm3,0x4; pxor xmm2,xmm3; pshufd xmm2, xmm2, 0x14; pshufd xmm3, xmm3, 0x38; pslldq xmm3,0x4; pxor xmm2,xmm3; pshufd xmm2, xmm2, 0xA4; pshufd xmm3, xmm3, 0x34; pslldq xmm3,0x4; pxor xmm2,xmm3;
暗号化
暗号化の1ラウンドを実装するために、次のアクションを実行するAESENC命令が使用されます。
AESENC xmm1, xmm2/m128 Tmp = xmm1 Round Key := xmm2/m128 Tmp = ShiftRows (Tmp) Tmp = SubBytes (Tmp) Tmp = MixColumns (Tmp) xmm1 = Tmp xor Round Key
暗号化の最後のラウンドは、AESENCLASTステートメントを使用して実装されます。
AESENC xmm1, xmm2/m128 Tmp = xmm1 Round Key := xmm2/m128 Tmp = ShiftRows (Tmp) Tmp = SubBytes (Tmp) xmm1 = Tmp xor Round Key
この命令とAESENCの違いは、最後のステップのMixColums操作が実行されないことです。
暗号化の例
aesenc xmm1, xmm2 ; aesenclast xmm1, xmm3;
解読
復号化手順を実装するには、AESDEC命令を使用します。
AESDEC xmm1, xmm2/m128 Tmp = xmm1 Round Key = xmm2/m128 Tmp = InvShift Rows (Tmp) Tmp = InvSubBytes (Tmp) Tmp = InvMixColumns (Tmp) xmm1 = Tmp xor Round Key
InvKeyを取得するには、キーでInvMixClomuns操作を実行する必要があります。 これを行う命令はAESIMC xmm1.xmm2です
そして、復号化の最後のラウンドでは、AESDECLAST命令が使用されます:
AESDECLAST xmm1, xmm2/m128 State = xmm1 Round Key = xmm2/m128 Tmp = InvShift Rows (State) Tmp = InvSubBytes (Tmp) xmm1= Tmp xor RoundKey
復号化の例
aesmic xmm2,xmm2; aesdec xmm1, xmm2 ; aesdeclast xmm1, xmm3;
そのため、ハードウェアサポートにより、暗号化速度がかなり向上します。 投稿の完了として、暗号化および復号化操作をECBモードで実装するC ++クラスを提供します。 テストの実行後、1つのコアi5-3740(3.2GHz)で暗号化速度が達成され、 320MB /秒に相当しました