1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# SPDX-License-Identifier: MIT
from ..utils import *
from enum import IntEnum
from .dart import DART, DARTRegs
import struct
from enum import IntEnum
class AES_OPCODE(IntEnum):
# 0 triggers an invalid command interrupt
SET_KEY = 1
SET_IV = 2
# 0x03 seems to take three additional argument, function unknown
# 0x04 seems to take one additional argument, function unknown
CRYPT = 5
GET_IV = 6
# 0x07 takes one additional argument, function unknown
BARRIER = 8 # can be used to trigger an IRQ but possibly also does more
# > 8 trigger an invalid command interrupt
class AES_SET_KEY_LEN(IntEnum):
AES128 = 0
AES192 = 1
AES256 = 2
class AES_SET_KEY_BLOCK_MODE(IntEnum):
ECB = 0
CBC = 1
CTR = 2
class AESCommandBase(Register32):
OPCODE = 31, 28, AES_OPCODE
class AESHwKey(IntEnum):
SOFTWARE = 0
UID = 1 # unique key for each chip
GID0 = 2 # (probably) globally unique key within a chip family
GID1 = 3 # globally unique key within a chip family
# 4-7 are probably empty / reserved for future use
class AESSetKeyCommand(AESCommandBase):
OPCODE = 31, 28, Constant(AES_OPCODE.SET_KEY)
SLOT = 27, 27
KEY_SELECT = 26, 24
KEYLEN = 23, 22, AES_SET_KEY_LEN
# setting bit 21 breaks the engine and sets two bits in the IRQ status
ENCRYPT = 20, 20
KEYGEN = 19, 18
BLOCK_MODE = 17, 16, AES_SET_KEY_BLOCK_MODE
# 15, 0 doesn't seem to have any effect
class AESCryptCommand(AESCommandBase):
OPCODE = 31, 28, Constant(AES_OPCODE.CRYPT)
KEY_SLOT = 27, 27
IV_SLOT = 26, 25
LEN = 24, 0
class AESBarrierCommand(AESCommandBase):
OPCODE = 31, 28, Constant(AES_OPCODE.BARRIER)
IRQ = 27, 27
class AESGetIVCommand(AESCommandBase):
OPCODE = 31, 28, Constant(AES_OPCODE.GET_IV)
class AESSetIVCommand(AESCommandBase):
OPCODE = 31, 28, Constant(AES_OPCODE.SET_IV)
SLOT = 27, 26
class AESIrqReg(Register32):
KEY1_EMPTY = 17, 17
KEY1_INVALID = 13, 13
KEY0_EMPTY = 11, 11
KEY0_INVALID = 7, 7
FLAG = 5, 5
UNKNOWN_COMMAND = 2, 2
FIFO_OVERFLOW = 1, 1
class AESControlReg(Register32):
START = 0, 0
STOP = 1, 1
CLEAR_FIFO = 2, 2
# TOOD: not convinced about RESET anymore, I remember this un-broke the engine once but I can't reproduce that anymore
RESET = 3, 3
class AESFifoStatusReg(Register32):
FIFO_WRITE_PTR = 31, 24
FIFO_READ_PTR = 23, 16
FIFO_LEVEL = 15, 8
FIFO_FULL = 2, 2
FIFO_EMPTY = 1, 1
class AESRegs(RegMap):
R_CONTROL = 0x08, AESControlReg
R_IRQ_STATUS = 0x18, AESIrqReg
R_IRQ_ENABLE = 0x1C, AESIrqReg
R_FIFO_STATUS = 0x24, AESFifoStatusReg
R_CMD_FIFO = 0x200, Register32
|