CPUが自分自身で暗合用命令を持つのは、x86だとVIAのC7くらいが最初だったと思うけど、ARMもARMv8はCPU自体に持つことになった (TIのOMAPとかはDSPにアクセラレータが入ってた記憶があるけど)。aarh64でもコンパイル時にオプションが必要なので標準命令に入ってないっぽいからIP的にはオプションなのかも。
IntelでもNehalemで同様にAES用の命令が追加されていて、既にOpenSSLとかNSSとかLinuxカーネルとかで既に使われてる。
ARMv8ではAES用、SHA1用、SHA2用の命令が追加されているのだけど、今日はAESの話。
まず最初にAESの暗号化のアルゴリズムを簡単に説明すると、
AddRoundKey
for i = 1 to 10
ShiftRows
SubBytes
MixColumns
AddRoundKey
ShiftRows
SubBytes
AddRoundKey
と表せる。ARMv8の場合は、このアルゴリズムをいくつかの専用命令で実装できるようになった。
aeseは、AESのアルゴリズムの内以下の命令を実行する。
AddRoundKey
ShiftRows
SubBytes
aesmcは、AESのアルゴリズムの内以下の命令を実行する。
MixColumns
同様に復元化はaesdとaesimcで可能。
このようにこの2つの命令を使うことで、AESの暗号化の実装が可能になってる。すなわち暗号化の際にはaeseとaesmcでRound処理をして最後のラウンドだけaeseとveor使って実装することができる。AES 128bitの暗号化をARMv8で実装すると (AddRoundKeyはXORなので)
for i = 1 to 10
aese
aesmc
aese
veor
ということになる。なおこれらは最近のチップ(Apple A7やNVIDIA Denver、Cortex-A57/53ベースのもの)であれば32ビットモード(aarch32)であっても利用可能。
サポートされているかどうかについてはLinuxであれば、/proc/cpuinfoを見れば、Featuresにaesがあるかどうかで確認できる。
Processor : NVIDIA Denver 1.0 rev 0 (aarch64)
processor : 0
processor : 1
Features : fp asimd aes pmull sha1 sha2 crc32
CPU implementer : 0x4e
CPU architecture: AArch64
CPU variant : 0x0
CPU part : 0x000
CPU revision : 0
Hardware : Flounder
Revision : 0000
Serial : 0000000000000000
MTS version : 33410787
また参考としてx86のAES専用命令の場合は、aesencとaesenclastを使って暗号化、aesdecとaesdeclastを使って復元化する。すなわち、x86でのAES 128bitの暗号化は、
AddRoundKey
for i = 1 to 10
aesenc
aesenclast
ということ。ARMとIntelで実装アイデアが違うのは興味深い。