2
0

aes.c 15 KB

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