2022年5月31日火曜日

ESP32EのAESハードウェアアクセラレータを使う

 前回のテストではSerial.print()の有り無しでAES_TEXT_n_REGからの読み出しが出来ていなかったりしていましたが、関数(クラス)に纏めることで正常に動作するようになりました。おそらくコンパイラの問題だとは思いますが、うまい記述が思いつかないし、とりあえず正常に動作しているのでOKとしました。

使い方

適当な場所に

ESP32E_AES_HA_Test.ino

を作成し、下記のコードをコピー&ペーストし、保存します。

inoファイルと同じ場所に、

ESP32E_AES_Hardware_Accelerator.h

ESP32E_AES_Hardware_Accelerator.cpp

を保存します。


/*
* FILE: ESP32E_AES_HA_Test.ino
* AUTHOR: PiT
* PURPOSE: Arduino library for ESP32E AES Hardware Accelerator
* VERSION: 1.0.0
*/
#include "ESP32E_AES_Hardware_Accelerator.h"
void setup() {
uint32_t encrypt_text[4];
uint32_t encrypt_text_second[4];
uint32_t decrypt_text[4];
Serial.begin(115200);
delay(1000);
AES_HardwareAccelerator AES;
uint32_t plane_text[] = {0x3243f6a8, 0x885a308d, 0x313198a2, 0xe0370734};
uint32_t cipher_key[] = {0x2b7e1516, 0x28aed2a6, 0xabf71588, 0x09cf4f3c};
uint32_t crypto_sample_text[] = {0x3925841d, 0x02dc09fb, 0xdc118597, 0x196a0b32};
Serial.print("plane_text: ");
showText(plane_text);
//Enable AES module
AES.enable();
Serial.println("encrypt");
//1. Initialize AES_MODE_REG, AES_KEY_n_REG, AES_TEXT_m_REG and AES_ENDIAN_REG.
AES.setMode_AES128Encrypt();
AES.setCipherKey(cipher_key);
AES.setTextReg(plane_text);
//2. Write 1 to AES_START_REG.
//3. Wait until AES_IDLE_REG reads 1.
AES.start();
//4. Read results from AES_TEXT_m_REG
AES.getTextReg(encrypt_text);
Serial.print("ENC : ");
showText(encrypt_text);
Serial.print("SAMPL: ");
showText(crypto_sample_text);
//DeCypher
Serial.println("decrypt");
AES.setMode_AES128Decrypt();
AES.setTextReg(crypto_sample_text);
AES.setCipherKey(cipher_key);
AES.start();
AES.getTextReg(decrypt_text);
Serial.print("DEC : ");
showText(decrypt_text);
Serial.print("SAMPL: ");
showText(plane_text);
//Disable AES module
AES.disable();
}
void loop() {
// put your main code here, to run repeatedly:
}
void showText(uint32_t * text) {
for (int i = 0; i < 4; i++)
{
char str[10];
sprintf(str, "%08x ", text[i]);
Serial.print(str);
}
Serial.println();
}

/*
* FILE: ESP32E_AES_Hardware_Accelerator.h
* AUTHOR: PiT
* PURPOSE: Arduino library for ESP32E AES Hardware Accelerator
* VERSION: 1.0.0
*/
#define DPORT_PERI_CLK_EN_REG *((volatile uint32_t *)0x3FF0001C)
#define DPORT_PERI_RST_EN_REG *((volatile uint32_t *)0x3FF00020)
#define AES_MODE_REG *((volatile uint32_t *)0x3FF01008)
#define AES_ENDIAN_REG *((volatile uint32_t *)0x3FF01040)
#define AES_KEY_0_REG *((volatile uint32_t *)0x3FF01010)
#define AES_KEY_1_REG *((volatile uint32_t *)0x3FF01014)
#define AES_KEY_2_REG *((volatile uint32_t *)0x3FF01018)
#define AES_KEY_3_REG *((volatile uint32_t *)0x3FF0101C)
#define AES_KEY_4_REG *((volatile uint32_t *)0x3FF01020)
#define AES_KEY_5_REG *((volatile uint32_t *)0x3FF01024)
#define AES_KEY_6_REG *((volatile uint32_t *)0x3FF01028)
#define AES_KEY_7_REG *((volatile uint32_t *)0x3FF0102C)
#define AES_TEXT_0_REG *((volatile uint32_t *)0x3FF01030)
#define AES_TEXT_1_REG *((volatile uint32_t *)0x3FF01034)
#define AES_TEXT_2_REG *((volatile uint32_t *)0x3FF01038)
#define AES_TEXT_3_REG *((volatile uint32_t *)0x3FF0103C)
#define AES_START_REG *((volatile uint32_t *)0x3FF01000)
#define AES_IDLE_REG *((volatile uint32_t *)0x3FF01004)
#define AES_MODE_AES128ENCRYPTION 0x00000000
#define AES_MODE_AES192ENCRYPTION 0x00000001
#define AES_MODE_AES256ENCRYPTION 0x00000002
#define AES_MODE_AES128DECRYPTION 0x00000004
#define AES_MODE_AES192DECRYPTION 0x00000005
#define AES_MODE_AES256DECRYPTION 0x00000006
#define AES_KEY_ENDIAN0 0x00000000
#define AES_KEY_ENDIAN1 0x00000001
#define AES_KEY_ENDIAN2 0x00000002
#define AES_KEY_ENDIAN3 0x00000003
#define AES_TEXT_ENDIAN0 0x00000000
#define AES_TEXT_ENDIAN1 0x00000014
#define AES_TEXT_ENDIAN2 0x00000028
#define AES_TEXT_ENDIAN3 0x0000003C
class AES_HardwareAccelerator {
public:
void enable();
void setMode_AES128Encrypt();
void setMode_AES128Decrypt();
void start();
void setCipherKey(uint32_t * cipher_key);
void setTextReg(uint32_t * text);
void getTextReg(uint32_t * text);
void disable();
};

/*
* FILE: ESP32E_AES_Hardware_Accelerator.cpp
* AUTHOR: PiT
* PURPOSE: Arduino library for ESP32E AES Hardware Accelerator
* VERSION: 1.0.0
*/
#include <Arduino.h>
#include "ESP32E_AES_Hardware_Accelerator.h"
void AES_HardwareAccelerator::enable() {
DPORT_PERI_CLK_EN_REG = DPORT_PERI_CLK_EN_REG | 0x00000001; // peripheral clock enable
DPORT_PERI_RST_EN_REG = DPORT_PERI_RST_EN_REG & (~(0x00000001 | 0x00000008 | 0x00000010)); // peripheral reset
}
void AES_HardwareAccelerator::setMode_AES128Encrypt() {
AES_MODE_REG = AES_MODE_AES128ENCRYPTION;
AES_ENDIAN_REG = AES_KEY_ENDIAN2 | AES_TEXT_ENDIAN2;
}
void AES_HardwareAccelerator::setMode_AES128Decrypt() {
AES_MODE_REG = AES_MODE_AES128DECRYPTION;
AES_ENDIAN_REG = AES_KEY_ENDIAN2 | AES_TEXT_ENDIAN2;
}
void AES_HardwareAccelerator::start() {
AES_START_REG = 0x00000001;
while (AES_IDLE_REG) {}
}
void AES_HardwareAccelerator::setCipherKey(uint32_t * cipher_key) {
AES_KEY_0_REG = cipher_key[0];
AES_KEY_1_REG = cipher_key[1];
AES_KEY_2_REG = cipher_key[2];
AES_KEY_3_REG = cipher_key[3];
}
void AES_HardwareAccelerator::setTextReg(uint32_t * text) {
AES_TEXT_0_REG = text[0];
AES_TEXT_1_REG = text[1];
AES_TEXT_2_REG = text[2];
AES_TEXT_3_REG = text[3];
}
void AES_HardwareAccelerator::getTextReg(uint32_t * text) {
text[0] = AES_TEXT_0_REG;
text[1] = AES_TEXT_1_REG;
text[2] = AES_TEXT_2_REG;
text[3] = AES_TEXT_3_REG;
}
void AES_HardwareAccelerator::disable() {
DPORT_PERI_CLK_EN_REG = 0x00000000; // peripheral clock enable
DPORT_PERI_RST_EN_REG = 0x0000000F; // peripheral reset
}

応用など

AES192やAES256などのモードは記述していませんが、ESP32E_AES_Hardware_Accelerator.hにDefineだけ記述しているので、それを参考にモード設定関数を作成すれば、他のモードでも動作すると思います。

手元にESP32Eしか持っていないので他のバージョンで動作するか確認できていませんが、たぶん動きます。

0 件のコメント:

コメントを投稿