m1n1/proxyclient/experiments/aes.py
Janne Grunau 68bba35263 experiments/aes.py: Simplify by using unified DART
Signed-off-by: Janne Grunau <j@jannau.net>
2023-01-28 10:48:46 +09:00

144 lines
3.6 KiB
Python

# SPDX-License-Identifier: MIT
import sys, pathlib
sys.path.append(str(pathlib.Path(__file__).resolve().parents[1]))
from m1n1.setup import *
from m1n1.shell import run_shell
from m1n1.hw.dart import DART
from m1n1.hw.aes import *
def aes_set_custom_key(
aes,
key,
encrypt=True,
mode=AES_SET_KEY_BLOCK_MODE.CTR,
keyslot=0,
keygen=0,
):
keylen = {
16: AES_SET_KEY_LEN.AES128,
24: AES_SET_KEY_LEN.AES192,
32: AES_SET_KEY_LEN.AES256,
}[len(key)]
aes.R_CMD_FIFO = AESSetKeyCommand(
KEY_SELECT=0,
KEYLEN=keylen,
ENCRYPT=1 if encrypt else 0,
BLOCK_MODE=mode,
SLOT=keyslot,
KEYGEN=keygen,
).value
for i in range(0, len(key), 4):
aes.R_CMD_FIFO = struct.unpack(">I", key[i : i + 4])[0]
def aes_set_hw_key(
aes,
key,
keylen=AES_SET_KEY_LEN.AES128,
encrypt=True,
mode=AES_SET_KEY_BLOCK_MODE.CTR,
slot=0,
keygen=0,
):
aes.R_CMD_FIFO = AESSetKeyCommand(
KEY_SELECT=key,
KEYLEN=keylen,
ENCRYPT=1 if encrypt else 0,
BLOCK_MODE=mode,
SLOT=slot,
KEYGEN=keygen,
).value
def aes_set_iv(aes, iv, slot=0):
assert len(iv) == 16
aes.R_CMD_FIFO = AESSetIVCommand(SLOT=slot)
for i in range(0, len(iv), 4):
aes.R_CMD_FIFO = struct.unpack(">I", iv[i : i + 4])[0]
def aes_crypt(aes, dart, data, key_slot=0, iv_slot=0):
assert len(data) % 16 == 0
bfr = p.memalign(0x4000, len(data))
iova = dart.iomap(1, bfr, len(data))
dart.iowrite(1, iova, data)
aes.R_CMD_FIFO = AESCryptCommand(LEN=len(data), KEY_SLOT=key_slot, IV_SLOT=iv_slot)
aes.R_CMD_FIFO = 0 # actually upper bits of addr
aes.R_CMD_FIFO = iova # src
aes.R_CMD_FIFO = iova # dst
aes.R_CMD_FIFO = AESBarrierCommand(IRQ=1).value
time.sleep(0.1)
# while aes.R_IRQ_STATUS.reg.FLAG != 1:
# pass
# aes.dump_regs()
aes.R_IRQ_STATUS = aes.R_IRQ_STATUS.val
res = dart.ioread(1, iova, len(data))
return res
def test_hw_key(key, keylen, keygen=0):
aes.R_IRQ_STATUS = aes.R_IRQ_STATUS.val
aes.R_CONTROL.set(CLEAR_FIFO=1)
aes.R_CONTROL.set(RESET=1)
aes.R_CONTROL.set(START=1)
# aes.dump_regs()
aes_set_hw_key(aes, key, keylen, slot=0, keygen=keygen)
# print(aes.R_IRQ_STATUS)
aes_set_iv(aes, b"\x00" * 16, slot=0)
chexdump(aes_crypt(aes, dart, b"\x00" * 16, key_slot=0, iv_slot=1))
# aes.dump_regs()
aes.R_CONTROL.set(STOP=1)
def test_custom_key(key, keygen=0):
aes.R_IRQ_STATUS = aes.R_IRQ_STATUS.val
aes.R_CONTROL.set(CLEAR_FIFO=1)
aes.R_CONTROL.set(RESET=1)
aes.R_CONTROL.set(START=1)
# aes.dump_regs()
aes_set_custom_key(aes, key, keyslot=0, keygen=keygen)
aes_set_iv(aes, b"\x00" * 16)
aes_set_iv(aes, b"\x11" * 16, slot=1)
chexdump(aes_crypt(aes, dart, b"\x00" * 16, key_slot=0, iv_slot=0))
# aes.dump_regs()
aes.R_CONTROL.set(STOP=1)
p.pmgr_adt_clocks_enable("/arm-io/aes")
dart = DART.from_adt(u, "/arm-io/dart-sio")
dart.initialize()
aes_base, _ = u.adt["/arm-io/aes"].get_reg(0)
aes = AESRegs(u, aes_base)
aes.dump_regs()
dart.dump_all()
for keygen in range(4):
print(f"zero key, keygen={keygen}", end="")
test_custom_key(b"\x00" * 16, keygen=keygen)
for keygen in range(4):
print("#" * 10)
for keylen in [
AES_SET_KEY_LEN.AES128,
AES_SET_KEY_LEN.AES192,
AES_SET_KEY_LEN.AES256,
]:
for i in (1, 3):
print(f"key = {i}, keylen={keylen}, keygen={keygen}", end="")
test_hw_key(i, keylen, keygen=keygen)
dart.dump_all()
run_shell(globals(), msg="Have fun!")