1*c960b389SAlexander Graf /*
2*c960b389SAlexander Graf * QEMU Apple AES device emulation
3*c960b389SAlexander Graf *
4*c960b389SAlexander Graf * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
5*c960b389SAlexander Graf *
6*c960b389SAlexander Graf * This work is licensed under the terms of the GNU GPL, version 2 or later.
7*c960b389SAlexander Graf * See the COPYING file in the top-level directory.
8*c960b389SAlexander Graf *
9*c960b389SAlexander Graf * SPDX-License-Identifier: GPL-2.0-or-later
10*c960b389SAlexander Graf */
11*c960b389SAlexander Graf
12*c960b389SAlexander Graf #include "qemu/osdep.h"
13*c960b389SAlexander Graf #include "trace.h"
14*c960b389SAlexander Graf #include "crypto/hash.h"
15*c960b389SAlexander Graf #include "crypto/aes.h"
16*c960b389SAlexander Graf #include "crypto/cipher.h"
17*c960b389SAlexander Graf #include "hw/irq.h"
18*c960b389SAlexander Graf #include "hw/sysbus.h"
19*c960b389SAlexander Graf #include "hw/vmapple/vmapple.h"
20*c960b389SAlexander Graf #include "migration/vmstate.h"
21*c960b389SAlexander Graf #include "qemu/cutils.h"
22*c960b389SAlexander Graf #include "qemu/log.h"
23*c960b389SAlexander Graf #include "qemu/module.h"
24*c960b389SAlexander Graf #include "system/dma.h"
25*c960b389SAlexander Graf
26*c960b389SAlexander Graf OBJECT_DECLARE_SIMPLE_TYPE(AESState, APPLE_AES)
27*c960b389SAlexander Graf
28*c960b389SAlexander Graf #define MAX_FIFO_SIZE 9
29*c960b389SAlexander Graf
30*c960b389SAlexander Graf #define CMD_KEY 0x1
31*c960b389SAlexander Graf #define CMD_KEY_CONTEXT_SHIFT 27
32*c960b389SAlexander Graf #define CMD_KEY_CONTEXT_MASK (0x1 << CMD_KEY_CONTEXT_SHIFT)
33*c960b389SAlexander Graf #define CMD_KEY_SELECT_MAX_IDX 0x7
34*c960b389SAlexander Graf #define CMD_KEY_SELECT_SHIFT 24
35*c960b389SAlexander Graf #define CMD_KEY_SELECT_MASK (CMD_KEY_SELECT_MAX_IDX << CMD_KEY_SELECT_SHIFT)
36*c960b389SAlexander Graf #define CMD_KEY_KEY_LEN_NUM 4u
37*c960b389SAlexander Graf #define CMD_KEY_KEY_LEN_SHIFT 22
38*c960b389SAlexander Graf #define CMD_KEY_KEY_LEN_MASK ((CMD_KEY_KEY_LEN_NUM - 1u) << CMD_KEY_KEY_LEN_SHIFT)
39*c960b389SAlexander Graf #define CMD_KEY_ENCRYPT_SHIFT 20
40*c960b389SAlexander Graf #define CMD_KEY_ENCRYPT_MASK (0x1 << CMD_KEY_ENCRYPT_SHIFT)
41*c960b389SAlexander Graf #define CMD_KEY_BLOCK_MODE_SHIFT 16
42*c960b389SAlexander Graf #define CMD_KEY_BLOCK_MODE_MASK (0x3 << CMD_KEY_BLOCK_MODE_SHIFT)
43*c960b389SAlexander Graf #define CMD_IV 0x2
44*c960b389SAlexander Graf #define CMD_IV_CONTEXT_SHIFT 26
45*c960b389SAlexander Graf #define CMD_IV_CONTEXT_MASK (0x3 << CMD_KEY_CONTEXT_SHIFT)
46*c960b389SAlexander Graf #define CMD_DSB 0x3
47*c960b389SAlexander Graf #define CMD_SKG 0x4
48*c960b389SAlexander Graf #define CMD_DATA 0x5
49*c960b389SAlexander Graf #define CMD_DATA_KEY_CTX_SHIFT 27
50*c960b389SAlexander Graf #define CMD_DATA_KEY_CTX_MASK (0x1 << CMD_DATA_KEY_CTX_SHIFT)
51*c960b389SAlexander Graf #define CMD_DATA_IV_CTX_SHIFT 25
52*c960b389SAlexander Graf #define CMD_DATA_IV_CTX_MASK (0x3 << CMD_DATA_IV_CTX_SHIFT)
53*c960b389SAlexander Graf #define CMD_DATA_LEN_MASK 0xffffff
54*c960b389SAlexander Graf #define CMD_STORE_IV 0x6
55*c960b389SAlexander Graf #define CMD_STORE_IV_ADDR_MASK 0xffffff
56*c960b389SAlexander Graf #define CMD_WRITE_REG 0x7
57*c960b389SAlexander Graf #define CMD_FLAG 0x8
58*c960b389SAlexander Graf #define CMD_FLAG_STOP_MASK BIT(26)
59*c960b389SAlexander Graf #define CMD_FLAG_RAISE_IRQ_MASK BIT(27)
60*c960b389SAlexander Graf #define CMD_FLAG_INFO_MASK 0xff
61*c960b389SAlexander Graf #define CMD_MAX 0x10
62*c960b389SAlexander Graf
63*c960b389SAlexander Graf #define CMD_SHIFT 28
64*c960b389SAlexander Graf
65*c960b389SAlexander Graf #define REG_STATUS 0xc
66*c960b389SAlexander Graf #define REG_STATUS_DMA_READ_RUNNING BIT(0)
67*c960b389SAlexander Graf #define REG_STATUS_DMA_READ_PENDING BIT(1)
68*c960b389SAlexander Graf #define REG_STATUS_DMA_WRITE_RUNNING BIT(2)
69*c960b389SAlexander Graf #define REG_STATUS_DMA_WRITE_PENDING BIT(3)
70*c960b389SAlexander Graf #define REG_STATUS_BUSY BIT(4)
71*c960b389SAlexander Graf #define REG_STATUS_EXECUTING BIT(5)
72*c960b389SAlexander Graf #define REG_STATUS_READY BIT(6)
73*c960b389SAlexander Graf #define REG_STATUS_TEXT_DPA_SEEDED BIT(7)
74*c960b389SAlexander Graf #define REG_STATUS_UNWRAP_DPA_SEEDED BIT(8)
75*c960b389SAlexander Graf
76*c960b389SAlexander Graf #define REG_IRQ_STATUS 0x18
77*c960b389SAlexander Graf #define REG_IRQ_STATUS_INVALID_CMD BIT(2)
78*c960b389SAlexander Graf #define REG_IRQ_STATUS_FLAG BIT(5)
79*c960b389SAlexander Graf #define REG_IRQ_ENABLE 0x1c
80*c960b389SAlexander Graf #define REG_WATERMARK 0x20
81*c960b389SAlexander Graf #define REG_Q_STATUS 0x24
82*c960b389SAlexander Graf #define REG_FLAG_INFO 0x30
83*c960b389SAlexander Graf #define REG_FIFO 0x200
84*c960b389SAlexander Graf
85*c960b389SAlexander Graf static const uint32_t key_lens[CMD_KEY_KEY_LEN_NUM] = {
86*c960b389SAlexander Graf [0] = 16,
87*c960b389SAlexander Graf [1] = 24,
88*c960b389SAlexander Graf [2] = 32,
89*c960b389SAlexander Graf [3] = 64,
90*c960b389SAlexander Graf };
91*c960b389SAlexander Graf
92*c960b389SAlexander Graf typedef struct Key {
93*c960b389SAlexander Graf uint32_t key_len;
94*c960b389SAlexander Graf uint8_t key[32];
95*c960b389SAlexander Graf } Key;
96*c960b389SAlexander Graf
97*c960b389SAlexander Graf typedef struct IV {
98*c960b389SAlexander Graf uint32_t iv[4];
99*c960b389SAlexander Graf } IV;
100*c960b389SAlexander Graf
101*c960b389SAlexander Graf static Key builtin_keys[CMD_KEY_SELECT_MAX_IDX + 1] = {
102*c960b389SAlexander Graf [1] = {
103*c960b389SAlexander Graf .key_len = 32,
104*c960b389SAlexander Graf .key = { 0x1 },
105*c960b389SAlexander Graf },
106*c960b389SAlexander Graf [2] = {
107*c960b389SAlexander Graf .key_len = 32,
108*c960b389SAlexander Graf .key = { 0x2 },
109*c960b389SAlexander Graf },
110*c960b389SAlexander Graf [3] = {
111*c960b389SAlexander Graf .key_len = 32,
112*c960b389SAlexander Graf .key = { 0x3 },
113*c960b389SAlexander Graf }
114*c960b389SAlexander Graf };
115*c960b389SAlexander Graf
116*c960b389SAlexander Graf struct AESState {
117*c960b389SAlexander Graf SysBusDevice parent_obj;
118*c960b389SAlexander Graf
119*c960b389SAlexander Graf qemu_irq irq;
120*c960b389SAlexander Graf MemoryRegion iomem1;
121*c960b389SAlexander Graf MemoryRegion iomem2;
122*c960b389SAlexander Graf AddressSpace *as;
123*c960b389SAlexander Graf
124*c960b389SAlexander Graf uint32_t status;
125*c960b389SAlexander Graf uint32_t q_status;
126*c960b389SAlexander Graf uint32_t irq_status;
127*c960b389SAlexander Graf uint32_t irq_enable;
128*c960b389SAlexander Graf uint32_t watermark;
129*c960b389SAlexander Graf uint32_t flag_info;
130*c960b389SAlexander Graf uint32_t fifo[MAX_FIFO_SIZE];
131*c960b389SAlexander Graf uint32_t fifo_idx;
132*c960b389SAlexander Graf Key key[2];
133*c960b389SAlexander Graf IV iv[4];
134*c960b389SAlexander Graf bool is_encrypt;
135*c960b389SAlexander Graf QCryptoCipherMode block_mode;
136*c960b389SAlexander Graf };
137*c960b389SAlexander Graf
aes_update_irq(AESState * s)138*c960b389SAlexander Graf static void aes_update_irq(AESState *s)
139*c960b389SAlexander Graf {
140*c960b389SAlexander Graf qemu_set_irq(s->irq, !!(s->irq_status & s->irq_enable));
141*c960b389SAlexander Graf }
142*c960b389SAlexander Graf
aes1_read(void * opaque,hwaddr offset,unsigned size)143*c960b389SAlexander Graf static uint64_t aes1_read(void *opaque, hwaddr offset, unsigned size)
144*c960b389SAlexander Graf {
145*c960b389SAlexander Graf AESState *s = opaque;
146*c960b389SAlexander Graf uint64_t res = 0;
147*c960b389SAlexander Graf
148*c960b389SAlexander Graf switch (offset) {
149*c960b389SAlexander Graf case REG_STATUS:
150*c960b389SAlexander Graf res = s->status;
151*c960b389SAlexander Graf break;
152*c960b389SAlexander Graf case REG_IRQ_STATUS:
153*c960b389SAlexander Graf res = s->irq_status;
154*c960b389SAlexander Graf break;
155*c960b389SAlexander Graf case REG_IRQ_ENABLE:
156*c960b389SAlexander Graf res = s->irq_enable;
157*c960b389SAlexander Graf break;
158*c960b389SAlexander Graf case REG_WATERMARK:
159*c960b389SAlexander Graf res = s->watermark;
160*c960b389SAlexander Graf break;
161*c960b389SAlexander Graf case REG_Q_STATUS:
162*c960b389SAlexander Graf res = s->q_status;
163*c960b389SAlexander Graf break;
164*c960b389SAlexander Graf case REG_FLAG_INFO:
165*c960b389SAlexander Graf res = s->flag_info;
166*c960b389SAlexander Graf break;
167*c960b389SAlexander Graf
168*c960b389SAlexander Graf default:
169*c960b389SAlexander Graf qemu_log_mask(LOG_UNIMP, "%s: Unknown AES MMIO offset %" PRIx64 "\n",
170*c960b389SAlexander Graf __func__, offset);
171*c960b389SAlexander Graf break;
172*c960b389SAlexander Graf }
173*c960b389SAlexander Graf
174*c960b389SAlexander Graf trace_aes_read(offset, res);
175*c960b389SAlexander Graf
176*c960b389SAlexander Graf return res;
177*c960b389SAlexander Graf }
178*c960b389SAlexander Graf
fifo_append(AESState * s,uint64_t val)179*c960b389SAlexander Graf static void fifo_append(AESState *s, uint64_t val)
180*c960b389SAlexander Graf {
181*c960b389SAlexander Graf if (s->fifo_idx == MAX_FIFO_SIZE) {
182*c960b389SAlexander Graf /* Exceeded the FIFO. Bail out */
183*c960b389SAlexander Graf return;
184*c960b389SAlexander Graf }
185*c960b389SAlexander Graf
186*c960b389SAlexander Graf s->fifo[s->fifo_idx++] = val;
187*c960b389SAlexander Graf }
188*c960b389SAlexander Graf
has_payload(AESState * s,uint32_t elems)189*c960b389SAlexander Graf static bool has_payload(AESState *s, uint32_t elems)
190*c960b389SAlexander Graf {
191*c960b389SAlexander Graf return s->fifo_idx >= elems + 1;
192*c960b389SAlexander Graf }
193*c960b389SAlexander Graf
cmd_key(AESState * s)194*c960b389SAlexander Graf static bool cmd_key(AESState *s)
195*c960b389SAlexander Graf {
196*c960b389SAlexander Graf uint32_t cmd = s->fifo[0];
197*c960b389SAlexander Graf uint32_t key_select = (cmd & CMD_KEY_SELECT_MASK) >> CMD_KEY_SELECT_SHIFT;
198*c960b389SAlexander Graf uint32_t ctxt = (cmd & CMD_KEY_CONTEXT_MASK) >> CMD_KEY_CONTEXT_SHIFT;
199*c960b389SAlexander Graf uint32_t key_len;
200*c960b389SAlexander Graf
201*c960b389SAlexander Graf switch ((cmd & CMD_KEY_BLOCK_MODE_MASK) >> CMD_KEY_BLOCK_MODE_SHIFT) {
202*c960b389SAlexander Graf case 0:
203*c960b389SAlexander Graf s->block_mode = QCRYPTO_CIPHER_MODE_ECB;
204*c960b389SAlexander Graf break;
205*c960b389SAlexander Graf case 1:
206*c960b389SAlexander Graf s->block_mode = QCRYPTO_CIPHER_MODE_CBC;
207*c960b389SAlexander Graf break;
208*c960b389SAlexander Graf default:
209*c960b389SAlexander Graf return false;
210*c960b389SAlexander Graf }
211*c960b389SAlexander Graf
212*c960b389SAlexander Graf s->is_encrypt = cmd & CMD_KEY_ENCRYPT_MASK;
213*c960b389SAlexander Graf key_len = key_lens[(cmd & CMD_KEY_KEY_LEN_MASK) >> CMD_KEY_KEY_LEN_SHIFT];
214*c960b389SAlexander Graf
215*c960b389SAlexander Graf if (key_select) {
216*c960b389SAlexander Graf trace_aes_cmd_key_select_builtin(ctxt, key_select,
217*c960b389SAlexander Graf s->is_encrypt ? "en" : "de",
218*c960b389SAlexander Graf QCryptoCipherMode_str(s->block_mode));
219*c960b389SAlexander Graf s->key[ctxt] = builtin_keys[key_select];
220*c960b389SAlexander Graf } else {
221*c960b389SAlexander Graf trace_aes_cmd_key_select_new(ctxt, key_len,
222*c960b389SAlexander Graf s->is_encrypt ? "en" : "de",
223*c960b389SAlexander Graf QCryptoCipherMode_str(s->block_mode));
224*c960b389SAlexander Graf if (key_len > sizeof(s->key[ctxt].key)) {
225*c960b389SAlexander Graf return false;
226*c960b389SAlexander Graf }
227*c960b389SAlexander Graf if (!has_payload(s, key_len / sizeof(uint32_t))) {
228*c960b389SAlexander Graf /* wait for payload */
229*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
230*c960b389SAlexander Graf return false;
231*c960b389SAlexander Graf }
232*c960b389SAlexander Graf memcpy(&s->key[ctxt].key, &s->fifo[1], key_len);
233*c960b389SAlexander Graf s->key[ctxt].key_len = key_len;
234*c960b389SAlexander Graf }
235*c960b389SAlexander Graf
236*c960b389SAlexander Graf return true;
237*c960b389SAlexander Graf }
238*c960b389SAlexander Graf
cmd_iv(AESState * s)239*c960b389SAlexander Graf static bool cmd_iv(AESState *s)
240*c960b389SAlexander Graf {
241*c960b389SAlexander Graf uint32_t cmd = s->fifo[0];
242*c960b389SAlexander Graf uint32_t ctxt = (cmd & CMD_IV_CONTEXT_MASK) >> CMD_IV_CONTEXT_SHIFT;
243*c960b389SAlexander Graf
244*c960b389SAlexander Graf if (!has_payload(s, 4)) {
245*c960b389SAlexander Graf /* wait for payload */
246*c960b389SAlexander Graf return false;
247*c960b389SAlexander Graf }
248*c960b389SAlexander Graf memcpy(&s->iv[ctxt].iv, &s->fifo[1], sizeof(s->iv[ctxt].iv));
249*c960b389SAlexander Graf trace_aes_cmd_iv(ctxt, s->fifo[1], s->fifo[2], s->fifo[3], s->fifo[4]);
250*c960b389SAlexander Graf
251*c960b389SAlexander Graf return true;
252*c960b389SAlexander Graf }
253*c960b389SAlexander Graf
dump_data(const char * desc,const void * p,size_t len)254*c960b389SAlexander Graf static void dump_data(const char *desc, const void *p, size_t len)
255*c960b389SAlexander Graf {
256*c960b389SAlexander Graf static const size_t MAX_LEN = 0x1000;
257*c960b389SAlexander Graf char hex[MAX_LEN * 2 + 1] = "";
258*c960b389SAlexander Graf
259*c960b389SAlexander Graf if (len > MAX_LEN) {
260*c960b389SAlexander Graf return;
261*c960b389SAlexander Graf }
262*c960b389SAlexander Graf
263*c960b389SAlexander Graf qemu_hexdump_to_buffer(hex, sizeof(hex), p, len);
264*c960b389SAlexander Graf trace_aes_dump_data(desc, hex);
265*c960b389SAlexander Graf }
266*c960b389SAlexander Graf
cmd_data(AESState * s)267*c960b389SAlexander Graf static bool cmd_data(AESState *s)
268*c960b389SAlexander Graf {
269*c960b389SAlexander Graf uint32_t cmd = s->fifo[0];
270*c960b389SAlexander Graf uint32_t ctxt_iv = 0;
271*c960b389SAlexander Graf uint32_t ctxt_key = (cmd & CMD_DATA_KEY_CTX_MASK) >> CMD_DATA_KEY_CTX_SHIFT;
272*c960b389SAlexander Graf uint32_t len = cmd & CMD_DATA_LEN_MASK;
273*c960b389SAlexander Graf uint64_t src_addr = s->fifo[2];
274*c960b389SAlexander Graf uint64_t dst_addr = s->fifo[3];
275*c960b389SAlexander Graf QCryptoCipherAlgo alg;
276*c960b389SAlexander Graf g_autoptr(QCryptoCipher) cipher = NULL;
277*c960b389SAlexander Graf g_autoptr(GByteArray) src = NULL;
278*c960b389SAlexander Graf g_autoptr(GByteArray) dst = NULL;
279*c960b389SAlexander Graf MemTxResult r;
280*c960b389SAlexander Graf
281*c960b389SAlexander Graf src_addr |= ((uint64_t)s->fifo[1] << 16) & 0xffff00000000ULL;
282*c960b389SAlexander Graf dst_addr |= ((uint64_t)s->fifo[1] << 32) & 0xffff00000000ULL;
283*c960b389SAlexander Graf
284*c960b389SAlexander Graf trace_aes_cmd_data(ctxt_key, ctxt_iv, src_addr, dst_addr, len);
285*c960b389SAlexander Graf
286*c960b389SAlexander Graf if (!has_payload(s, 3)) {
287*c960b389SAlexander Graf /* wait for payload */
288*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
289*c960b389SAlexander Graf return false;
290*c960b389SAlexander Graf }
291*c960b389SAlexander Graf
292*c960b389SAlexander Graf if (ctxt_key >= ARRAY_SIZE(s->key) ||
293*c960b389SAlexander Graf ctxt_iv >= ARRAY_SIZE(s->iv)) {
294*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid key or iv\n", __func__);
295*c960b389SAlexander Graf return false;
296*c960b389SAlexander Graf }
297*c960b389SAlexander Graf
298*c960b389SAlexander Graf src = g_byte_array_sized_new(len);
299*c960b389SAlexander Graf g_byte_array_set_size(src, len);
300*c960b389SAlexander Graf dst = g_byte_array_sized_new(len);
301*c960b389SAlexander Graf g_byte_array_set_size(dst, len);
302*c960b389SAlexander Graf
303*c960b389SAlexander Graf r = dma_memory_read(s->as, src_addr, src->data, len, MEMTXATTRS_UNSPECIFIED);
304*c960b389SAlexander Graf if (r != MEMTX_OK) {
305*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA read of %"PRIu32" bytes "
306*c960b389SAlexander Graf "from 0x%"PRIx64" failed. (r=%d)\n",
307*c960b389SAlexander Graf __func__, len, src_addr, r);
308*c960b389SAlexander Graf return false;
309*c960b389SAlexander Graf }
310*c960b389SAlexander Graf
311*c960b389SAlexander Graf dump_data("cmd_data(): src_data=", src->data, len);
312*c960b389SAlexander Graf
313*c960b389SAlexander Graf switch (s->key[ctxt_key].key_len) {
314*c960b389SAlexander Graf case 128 / 8:
315*c960b389SAlexander Graf alg = QCRYPTO_CIPHER_ALGO_AES_128;
316*c960b389SAlexander Graf break;
317*c960b389SAlexander Graf case 192 / 8:
318*c960b389SAlexander Graf alg = QCRYPTO_CIPHER_ALGO_AES_192;
319*c960b389SAlexander Graf break;
320*c960b389SAlexander Graf case 256 / 8:
321*c960b389SAlexander Graf alg = QCRYPTO_CIPHER_ALGO_AES_256;
322*c960b389SAlexander Graf break;
323*c960b389SAlexander Graf default:
324*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid key length\n", __func__);
325*c960b389SAlexander Graf return false;
326*c960b389SAlexander Graf }
327*c960b389SAlexander Graf cipher = qcrypto_cipher_new(alg, s->block_mode,
328*c960b389SAlexander Graf s->key[ctxt_key].key,
329*c960b389SAlexander Graf s->key[ctxt_key].key_len, NULL);
330*c960b389SAlexander Graf if (!cipher) {
331*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to create cipher object\n",
332*c960b389SAlexander Graf __func__);
333*c960b389SAlexander Graf return false;
334*c960b389SAlexander Graf }
335*c960b389SAlexander Graf if (s->block_mode != QCRYPTO_CIPHER_MODE_ECB) {
336*c960b389SAlexander Graf if (qcrypto_cipher_setiv(cipher, (void *)s->iv[ctxt_iv].iv,
337*c960b389SAlexander Graf sizeof(s->iv[ctxt_iv].iv), NULL) != 0) {
338*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to set IV\n", __func__);
339*c960b389SAlexander Graf return false;
340*c960b389SAlexander Graf }
341*c960b389SAlexander Graf }
342*c960b389SAlexander Graf if (s->is_encrypt) {
343*c960b389SAlexander Graf if (qcrypto_cipher_encrypt(cipher, src->data, dst->data, len, NULL) != 0) {
344*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: Encryption failed\n", __func__);
345*c960b389SAlexander Graf return false;
346*c960b389SAlexander Graf }
347*c960b389SAlexander Graf } else {
348*c960b389SAlexander Graf if (qcrypto_cipher_decrypt(cipher, src->data, dst->data, len, NULL) != 0) {
349*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: Decryption failed\n", __func__);
350*c960b389SAlexander Graf return false;
351*c960b389SAlexander Graf }
352*c960b389SAlexander Graf }
353*c960b389SAlexander Graf
354*c960b389SAlexander Graf dump_data("cmd_data(): dst_data=", dst->data, len);
355*c960b389SAlexander Graf r = dma_memory_write(s->as, dst_addr, dst->data, len, MEMTXATTRS_UNSPECIFIED);
356*c960b389SAlexander Graf if (r != MEMTX_OK) {
357*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA write of %"PRIu32" bytes "
358*c960b389SAlexander Graf "to 0x%"PRIx64" failed. (r=%d)\n",
359*c960b389SAlexander Graf __func__, len, src_addr, r);
360*c960b389SAlexander Graf return false;
361*c960b389SAlexander Graf }
362*c960b389SAlexander Graf
363*c960b389SAlexander Graf return true;
364*c960b389SAlexander Graf }
365*c960b389SAlexander Graf
cmd_store_iv(AESState * s)366*c960b389SAlexander Graf static bool cmd_store_iv(AESState *s)
367*c960b389SAlexander Graf {
368*c960b389SAlexander Graf uint32_t cmd = s->fifo[0];
369*c960b389SAlexander Graf uint32_t ctxt = (cmd & CMD_IV_CONTEXT_MASK) >> CMD_IV_CONTEXT_SHIFT;
370*c960b389SAlexander Graf uint64_t addr = s->fifo[1];
371*c960b389SAlexander Graf MemTxResult dma_result;
372*c960b389SAlexander Graf
373*c960b389SAlexander Graf if (!has_payload(s, 1)) {
374*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR, "%s: No payload\n", __func__);
375*c960b389SAlexander Graf return false;
376*c960b389SAlexander Graf }
377*c960b389SAlexander Graf
378*c960b389SAlexander Graf if (ctxt >= ARRAY_SIZE(s->iv)) {
379*c960b389SAlexander Graf qemu_log_mask(LOG_GUEST_ERROR,
380*c960b389SAlexander Graf "%s: Invalid context. ctxt = %u, allowed: 0..%zu\n",
381*c960b389SAlexander Graf __func__, ctxt, ARRAY_SIZE(s->iv) - 1);
382*c960b389SAlexander Graf return false;
383*c960b389SAlexander Graf }
384*c960b389SAlexander Graf
385*c960b389SAlexander Graf addr |= ((uint64_t)cmd << 32) & 0xff00000000ULL;
386*c960b389SAlexander Graf dma_result = dma_memory_write(&address_space_memory, addr,
387*c960b389SAlexander Graf &s->iv[ctxt].iv, sizeof(s->iv[ctxt].iv),
388*c960b389SAlexander Graf MEMTXATTRS_UNSPECIFIED);
389*c960b389SAlexander Graf
390*c960b389SAlexander Graf trace_aes_cmd_store_iv(ctxt, addr, s->iv[ctxt].iv[0], s->iv[ctxt].iv[1],
391*c960b389SAlexander Graf s->iv[ctxt].iv[2], s->iv[ctxt].iv[3]);
392*c960b389SAlexander Graf
393*c960b389SAlexander Graf return dma_result == MEMTX_OK;
394*c960b389SAlexander Graf }
395*c960b389SAlexander Graf
cmd_flag(AESState * s)396*c960b389SAlexander Graf static bool cmd_flag(AESState *s)
397*c960b389SAlexander Graf {
398*c960b389SAlexander Graf uint32_t cmd = s->fifo[0];
399*c960b389SAlexander Graf uint32_t raise_irq = cmd & CMD_FLAG_RAISE_IRQ_MASK;
400*c960b389SAlexander Graf
401*c960b389SAlexander Graf /* We always process data when it's coming in, so fire an IRQ immediately */
402*c960b389SAlexander Graf if (raise_irq) {
403*c960b389SAlexander Graf s->irq_status |= REG_IRQ_STATUS_FLAG;
404*c960b389SAlexander Graf }
405*c960b389SAlexander Graf
406*c960b389SAlexander Graf s->flag_info = cmd & CMD_FLAG_INFO_MASK;
407*c960b389SAlexander Graf
408*c960b389SAlexander Graf trace_aes_cmd_flag(!!raise_irq, s->flag_info);
409*c960b389SAlexander Graf
410*c960b389SAlexander Graf return true;
411*c960b389SAlexander Graf }
412*c960b389SAlexander Graf
fifo_process(AESState * s)413*c960b389SAlexander Graf static void fifo_process(AESState *s)
414*c960b389SAlexander Graf {
415*c960b389SAlexander Graf uint32_t cmd = s->fifo[0] >> CMD_SHIFT;
416*c960b389SAlexander Graf bool success = false;
417*c960b389SAlexander Graf
418*c960b389SAlexander Graf if (!s->fifo_idx) {
419*c960b389SAlexander Graf return;
420*c960b389SAlexander Graf }
421*c960b389SAlexander Graf
422*c960b389SAlexander Graf switch (cmd) {
423*c960b389SAlexander Graf case CMD_KEY:
424*c960b389SAlexander Graf success = cmd_key(s);
425*c960b389SAlexander Graf break;
426*c960b389SAlexander Graf case CMD_IV:
427*c960b389SAlexander Graf success = cmd_iv(s);
428*c960b389SAlexander Graf break;
429*c960b389SAlexander Graf case CMD_DATA:
430*c960b389SAlexander Graf success = cmd_data(s);
431*c960b389SAlexander Graf break;
432*c960b389SAlexander Graf case CMD_STORE_IV:
433*c960b389SAlexander Graf success = cmd_store_iv(s);
434*c960b389SAlexander Graf break;
435*c960b389SAlexander Graf case CMD_FLAG:
436*c960b389SAlexander Graf success = cmd_flag(s);
437*c960b389SAlexander Graf break;
438*c960b389SAlexander Graf default:
439*c960b389SAlexander Graf s->irq_status |= REG_IRQ_STATUS_INVALID_CMD;
440*c960b389SAlexander Graf break;
441*c960b389SAlexander Graf }
442*c960b389SAlexander Graf
443*c960b389SAlexander Graf if (success) {
444*c960b389SAlexander Graf s->fifo_idx = 0;
445*c960b389SAlexander Graf }
446*c960b389SAlexander Graf
447*c960b389SAlexander Graf trace_aes_fifo_process(cmd, success);
448*c960b389SAlexander Graf }
449*c960b389SAlexander Graf
aes1_write(void * opaque,hwaddr offset,uint64_t val,unsigned size)450*c960b389SAlexander Graf static void aes1_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
451*c960b389SAlexander Graf {
452*c960b389SAlexander Graf AESState *s = opaque;
453*c960b389SAlexander Graf
454*c960b389SAlexander Graf trace_aes_write(offset, val);
455*c960b389SAlexander Graf
456*c960b389SAlexander Graf switch (offset) {
457*c960b389SAlexander Graf case REG_IRQ_STATUS:
458*c960b389SAlexander Graf s->irq_status &= ~val;
459*c960b389SAlexander Graf break;
460*c960b389SAlexander Graf case REG_IRQ_ENABLE:
461*c960b389SAlexander Graf s->irq_enable = val;
462*c960b389SAlexander Graf break;
463*c960b389SAlexander Graf case REG_FIFO:
464*c960b389SAlexander Graf fifo_append(s, val);
465*c960b389SAlexander Graf fifo_process(s);
466*c960b389SAlexander Graf break;
467*c960b389SAlexander Graf default:
468*c960b389SAlexander Graf qemu_log_mask(LOG_UNIMP,
469*c960b389SAlexander Graf "%s: Unknown AES MMIO offset %"PRIx64", data %"PRIx64"\n",
470*c960b389SAlexander Graf __func__, offset, val);
471*c960b389SAlexander Graf return;
472*c960b389SAlexander Graf }
473*c960b389SAlexander Graf
474*c960b389SAlexander Graf aes_update_irq(s);
475*c960b389SAlexander Graf }
476*c960b389SAlexander Graf
477*c960b389SAlexander Graf static const MemoryRegionOps aes1_ops = {
478*c960b389SAlexander Graf .read = aes1_read,
479*c960b389SAlexander Graf .write = aes1_write,
480*c960b389SAlexander Graf .endianness = DEVICE_NATIVE_ENDIAN,
481*c960b389SAlexander Graf .valid = {
482*c960b389SAlexander Graf .min_access_size = 4,
483*c960b389SAlexander Graf .max_access_size = 8,
484*c960b389SAlexander Graf },
485*c960b389SAlexander Graf .impl = {
486*c960b389SAlexander Graf .min_access_size = 4,
487*c960b389SAlexander Graf .max_access_size = 4,
488*c960b389SAlexander Graf },
489*c960b389SAlexander Graf };
490*c960b389SAlexander Graf
aes2_read(void * opaque,hwaddr offset,unsigned size)491*c960b389SAlexander Graf static uint64_t aes2_read(void *opaque, hwaddr offset, unsigned size)
492*c960b389SAlexander Graf {
493*c960b389SAlexander Graf uint64_t res = 0;
494*c960b389SAlexander Graf
495*c960b389SAlexander Graf switch (offset) {
496*c960b389SAlexander Graf case 0:
497*c960b389SAlexander Graf res = 0;
498*c960b389SAlexander Graf break;
499*c960b389SAlexander Graf default:
500*c960b389SAlexander Graf qemu_log_mask(LOG_UNIMP,
501*c960b389SAlexander Graf "%s: Unknown AES MMIO 2 offset %"PRIx64"\n",
502*c960b389SAlexander Graf __func__, offset);
503*c960b389SAlexander Graf break;
504*c960b389SAlexander Graf }
505*c960b389SAlexander Graf
506*c960b389SAlexander Graf trace_aes_2_read(offset, res);
507*c960b389SAlexander Graf
508*c960b389SAlexander Graf return res;
509*c960b389SAlexander Graf }
510*c960b389SAlexander Graf
aes2_write(void * opaque,hwaddr offset,uint64_t val,unsigned size)511*c960b389SAlexander Graf static void aes2_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
512*c960b389SAlexander Graf {
513*c960b389SAlexander Graf trace_aes_2_write(offset, val);
514*c960b389SAlexander Graf
515*c960b389SAlexander Graf switch (offset) {
516*c960b389SAlexander Graf default:
517*c960b389SAlexander Graf qemu_log_mask(LOG_UNIMP,
518*c960b389SAlexander Graf "%s: Unknown AES MMIO 2 offset %"PRIx64", data %"PRIx64"\n",
519*c960b389SAlexander Graf __func__, offset, val);
520*c960b389SAlexander Graf return;
521*c960b389SAlexander Graf }
522*c960b389SAlexander Graf }
523*c960b389SAlexander Graf
524*c960b389SAlexander Graf static const MemoryRegionOps aes2_ops = {
525*c960b389SAlexander Graf .read = aes2_read,
526*c960b389SAlexander Graf .write = aes2_write,
527*c960b389SAlexander Graf .endianness = DEVICE_NATIVE_ENDIAN,
528*c960b389SAlexander Graf .valid = {
529*c960b389SAlexander Graf .min_access_size = 4,
530*c960b389SAlexander Graf .max_access_size = 8,
531*c960b389SAlexander Graf },
532*c960b389SAlexander Graf .impl = {
533*c960b389SAlexander Graf .min_access_size = 4,
534*c960b389SAlexander Graf .max_access_size = 4,
535*c960b389SAlexander Graf },
536*c960b389SAlexander Graf };
537*c960b389SAlexander Graf
aes_reset(Object * obj,ResetType type)538*c960b389SAlexander Graf static void aes_reset(Object *obj, ResetType type)
539*c960b389SAlexander Graf {
540*c960b389SAlexander Graf AESState *s = APPLE_AES(obj);
541*c960b389SAlexander Graf
542*c960b389SAlexander Graf s->status = 0x3f80;
543*c960b389SAlexander Graf s->q_status = 2;
544*c960b389SAlexander Graf s->irq_status = 0;
545*c960b389SAlexander Graf s->irq_enable = 0;
546*c960b389SAlexander Graf s->watermark = 0;
547*c960b389SAlexander Graf }
548*c960b389SAlexander Graf
aes_init(Object * obj)549*c960b389SAlexander Graf static void aes_init(Object *obj)
550*c960b389SAlexander Graf {
551*c960b389SAlexander Graf AESState *s = APPLE_AES(obj);
552*c960b389SAlexander Graf
553*c960b389SAlexander Graf memory_region_init_io(&s->iomem1, obj, &aes1_ops, s, TYPE_APPLE_AES, 0x4000);
554*c960b389SAlexander Graf memory_region_init_io(&s->iomem2, obj, &aes2_ops, s, TYPE_APPLE_AES, 0x4000);
555*c960b389SAlexander Graf sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem1);
556*c960b389SAlexander Graf sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem2);
557*c960b389SAlexander Graf sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
558*c960b389SAlexander Graf s->as = &address_space_memory;
559*c960b389SAlexander Graf }
560*c960b389SAlexander Graf
aes_class_init(ObjectClass * klass,void * data)561*c960b389SAlexander Graf static void aes_class_init(ObjectClass *klass, void *data)
562*c960b389SAlexander Graf {
563*c960b389SAlexander Graf ResettableClass *rc = RESETTABLE_CLASS(klass);
564*c960b389SAlexander Graf
565*c960b389SAlexander Graf rc->phases.hold = aes_reset;
566*c960b389SAlexander Graf }
567*c960b389SAlexander Graf
568*c960b389SAlexander Graf static const TypeInfo aes_info = {
569*c960b389SAlexander Graf .name = TYPE_APPLE_AES,
570*c960b389SAlexander Graf .parent = TYPE_SYS_BUS_DEVICE,
571*c960b389SAlexander Graf .instance_size = sizeof(AESState),
572*c960b389SAlexander Graf .class_init = aes_class_init,
573*c960b389SAlexander Graf .instance_init = aes_init,
574*c960b389SAlexander Graf };
575*c960b389SAlexander Graf
aes_register_types(void)576*c960b389SAlexander Graf static void aes_register_types(void)
577*c960b389SAlexander Graf {
578*c960b389SAlexander Graf type_register_static(&aes_info);
579*c960b389SAlexander Graf }
580*c960b389SAlexander Graf
581*c960b389SAlexander Graf type_init(aes_register_types)
582