18
#include "qapi/error.h"
19
#include "migration/vmstate.h"
20
#include "crypto/hash.h"
21
+#include "crypto/cipher.h"
22
#include "hw/core/qdev-properties.h"
23
#include "hw/core/irq.h"
24
#include "trace.h"
25
25
-#define R_CRYPT_CMD (0x10 / 4)
26
+/* Crypto engine registers */
27
+#define R_CRYPT_SRC (0x00 / 4)
28
+#define R_CRYPT_DEST (0x04 / 4)
29
+#define R_CRYPT_CONTEXT (0x08 / 4)
30
+#define R_CRYPT_DATA_LEN (0x0c / 4)
31
+/* HACE0C[27:0] holds the crypto data length */
32
+#define CRYPT_DATA_LEN_MASK 0x0FFFFFFF
33
+#define R_CRYPT_CMD (0x10 / 4)
34
+/* Crypto engine command register (HACE10) bits */
35
+#define CRYPT_CMD_ENCRYPT BIT(7)
36
+#define CRYPT_CMD_ISR_EN BIT(12)
37
+#define CRYPT_CMD_DES_SELECT BIT(16)
38
+#define CRYPT_CMD_TRIPLE_DES BIT(17)
39
+#define CRYPT_CMD_SRC_SG_CTRL BIT(18)
40
+/* Operation mode HACE10[6:4] */
41
+#define CRYPT_CMD_OP_MODE_MASK (0x7 << 4)
42
+#define CRYPT_CMD_ECB (0x0 << 4)
43
+#define CRYPT_CMD_CBC (0x1 << 4)
44
+/* AES key length HACE10[3:2] */
45
+#define CRYPT_CMD_AES_KEY_LEN_MASK (0x3 << 2)
46
+#define CRYPT_CMD_AES256 (0x2 << 2)
47
+#define CRYPT_CMD_AES192 (0x1 << 2)
48
+#define CRYPT_CMD_AES128 (0x0 << 2)
49
+
50
+/*
51
+ * Crypto context buffer layout (HACE08). The IV is at the start of the buffer
52
+ * (DES places its 8 byte IV at offset 8) and the cipher key at offset 0x10.
53
+ */
54
+#define CRYPT_CTX_IV_OFFSET 0x00
55
+#define CRYPT_CTX_DES_IV_OFFSET 0x08
56
+#define CRYPT_CTX_KEY_OFFSET 0x10
57
+#define CRYPT_CTX_SIZE 0x30
58
59
#define R_STATUS (0x1c / 4)
60
#define HASH_IRQ BIT(9)
97
/* Other cmd bits */
98
#define HASH_IRQ_EN BIT(9)
99
#define HASH_SG_EN BIT(18)
68
-#define CRYPT_IRQ_EN BIT(12)
100
/* Scatter-gather data list */
101
#define SG_LIST_LEN_SIZE 4
102
#define SG_LIST_LEN_MASK 0x0FFFFFFF
532
}
533
}
534
535
+static bool crypt_aes_alg(uint32_t cmd, QCryptoCipherAlgo *alg, size_t *keylen)
536
+{
537
+ switch (cmd & CRYPT_CMD_AES_KEY_LEN_MASK) {
538
+ case CRYPT_CMD_AES128:
539
+ *alg = QCRYPTO_CIPHER_ALGO_AES_128;
540
+ *keylen = 16;
541
+ break;
542
+ case CRYPT_CMD_AES192:
543
+ *alg = QCRYPTO_CIPHER_ALGO_AES_192;
544
+ *keylen = 24;
545
+ break;
546
+ case CRYPT_CMD_AES256:
547
+ *alg = QCRYPTO_CIPHER_ALGO_AES_256;
548
+ *keylen = 32;
549
+ break;
550
+ default:
551
+ return false;
552
+ }
553
+
554
+ return true;
555
+}
556
+
557
+/*
558
+ * Decode the crypto command register into a libqcrypto algorithm/mode pair
559
+ * and the block/IV geometry. Returns false for unsupported selections.
560
+ */
561
+static bool crypt_decode_cmd(uint32_t cmd, QCryptoCipherAlgo *alg,
562
+ QCryptoCipherMode *mode, size_t *keylen,
563
+ size_t *blocklen, size_t *iv_offset)
564
+{
565
+ if (cmd & CRYPT_CMD_DES_SELECT) {
566
+ *blocklen = 8;
567
+ *iv_offset = CRYPT_CTX_DES_IV_OFFSET;
568
+ if (cmd & CRYPT_CMD_TRIPLE_DES) {
569
+ *alg = QCRYPTO_CIPHER_ALGO_3DES;
570
+ *keylen = 24;
571
+ } else {
572
+ *alg = QCRYPTO_CIPHER_ALGO_DES;
573
+ *keylen = 8;
574
+ }
575
+ } else {
576
+ *blocklen = 16;
577
+ *iv_offset = CRYPT_CTX_IV_OFFSET;
578
+ if (!crypt_aes_alg(cmd, alg, keylen)) {
579
+ return false;
580
+ }
581
+ }
582
+
583
+ switch (cmd & CRYPT_CMD_OP_MODE_MASK) {
584
+ case CRYPT_CMD_ECB:
585
+ *mode = QCRYPTO_CIPHER_MODE_ECB;
586
+ break;
587
+ case CRYPT_CMD_CBC:
588
+ *mode = QCRYPTO_CIPHER_MODE_CBC;
589
+ break;
590
+ default:
591
+ return false;
592
+ }
593
+
594
+ return true;
595
+}
596
+
597
+/*
598
+ * Direct access mode: the source/destination register (HACE00/HACE04) points
599
+ * at a single contiguous buffer in DRAM. Copy @len bytes between it and the
600
+ * bounce buffer @buf; when @to_dram is true @buf is written out, otherwise it
601
+ * is read in. Returns true on success.
602
+ */
603
+static bool crypt_prepare_direct(AspeedHACEState *s, uint64_t addr,
604
+ uint8_t *buf, uint32_t len, bool to_dram)
605
+{
606
+ return !address_space_rw(&s->dram_as, addr, MEMTXATTRS_UNSPECIFIED,
607
+ buf, len, to_dram);
608
+}
609
+
610
+/*
611
+ * Perform an AES/DES/3DES ECB/CBC operation in direct access mode: the source
612
+ * and destination are single contiguous buffers (HACE00/HACE04) and the IV/key
613
+ * come from the context buffer (HACE08). For CBC the resulting chaining IV is
614
+ * written back to the context buffer so the driver can continue the chain.
615
+ */
616
+static void do_crypt_operation(AspeedHACEState *s, uint32_t cmd)
617
+{
618
+ uint32_t len = s->regs[R_CRYPT_DATA_LEN];
619
+ bool encrypt = cmd & CRYPT_CMD_ENCRYPT;
620
+ g_autoptr(QCryptoCipher) cipher = NULL;
621
+ g_autofree uint8_t *src_buf = NULL;
622
+ g_autofree uint8_t *dst_buf = NULL;
623
+ uint8_t ctx[CRYPT_CTX_SIZE];
624
+ Error *local_err = NULL;
625
+ QCryptoCipherMode mode;
626
+ QCryptoCipherAlgo alg;
627
+ const uint8_t *next_iv;
628
+ uint64_t ctx_addr;
629
+ uint64_t src_addr;
630
+ uint64_t dst_addr;
631
+ size_t iv_offset;
632
+ size_t blocklen;
633
+ size_t keylen;
634
+
635
+ if (len == 0) {
636
+ return;
637
+ }
638
+
639
+ if (!crypt_decode_cmd(cmd, &alg, &mode, &keylen, &blocklen, &iv_offset)) {
640
+ qemu_log_mask(LOG_UNIMP,
641
+ "%s: Unsupported crypt command 0x%x\n", __func__, cmd);
642
+ return;
643
+ }
644
+
645
+ if (!qcrypto_cipher_supports(alg, mode)) {
646
+ qemu_log_mask(LOG_UNIMP,
647
+ "%s: cipher mode not supported by the crypto backend\n",
648
+ __func__);
649
+ return;
650
+ }
651
+
652
+ /* Fetch the IV and key from the context buffer in DRAM. */
653
+ ctx_addr = s->regs[R_CRYPT_CONTEXT];
654
+ if (address_space_read(&s->dram_as, ctx_addr, MEMTXATTRS_UNSPECIFIED,
655
+ ctx, sizeof(ctx))) {
656
+ qemu_log_mask(LOG_GUEST_ERROR,
657
+ "%s: Failed to read context, addr=0x%" HWADDR_PRIx "\n",
658
+ __func__, ctx_addr);
659
+ return;
660
+ }
661
+
662
+ if (trace_event_get_state_backends(TRACE_ASPEED_HACE_HEXDUMP)) {
663
+ hace_hexdump("context", (char *)ctx, sizeof(ctx));
664
+ }
665
+
666
+ cipher = qcrypto_cipher_new(alg, mode, ctx + CRYPT_CTX_KEY_OFFSET, keylen,
667
+ &local_err);
668
+ if (cipher == NULL) {
669
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto cipher new failed: %s\n",
670
+ __func__, error_get_pretty(local_err));
671
+ error_free(local_err);
672
+ return;
673
+ }
674
+
675
+ if (mode != QCRYPTO_CIPHER_MODE_ECB &&
676
+ qcrypto_cipher_setiv(cipher, ctx + iv_offset, blocklen,
677
+ &local_err) < 0) {
678
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto cipher setiv failed: %s\n",
679
+ __func__, error_get_pretty(local_err));
680
+ error_free(local_err);
681
+ return;
682
+ }
683
+
684
+ src_buf = g_malloc0(len);
685
+ dst_buf = g_malloc0(len);
686
+
687
+ src_addr = s->regs[R_CRYPT_SRC];
688
+ if (!crypt_prepare_direct(s, src_addr, src_buf, len, false)) {
689
+ qemu_log_mask(LOG_GUEST_ERROR,
690
+ "%s: Failed to read src, addr=0x%" HWADDR_PRIx "\n",
691
+ __func__, src_addr);
692
+ return;
693
+ }
694
+
695
+ if (trace_event_get_state_backends(TRACE_ASPEED_HACE_HEXDUMP)) {
696
+ hace_hexdump("src", (char *)src_buf, len);
697
+ }
698
+
699
+ if (encrypt) {
700
+ if (qcrypto_cipher_encrypt(cipher, src_buf, dst_buf, len,
701
+ &local_err) < 0) {
702
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: encrypt failed: %s\n",
703
+ __func__, error_get_pretty(local_err));
704
+ error_free(local_err);
705
+ return;
706
+ }
707
+ } else {
708
+ if (qcrypto_cipher_decrypt(cipher, src_buf, dst_buf, len,
709
+ &local_err) < 0) {
710
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: decrypt failed: %s\n",
711
+ __func__, error_get_pretty(local_err));
712
+ error_free(local_err);
713
+ return;
714
+ }
715
+ }
716
+
717
+ dst_addr = s->regs[R_CRYPT_DEST];
718
+ if (!crypt_prepare_direct(s, dst_addr, dst_buf, len, true)) {
719
+ qemu_log_mask(LOG_GUEST_ERROR,
720
+ "%s: Failed to write dst, addr=0x%" HWADDR_PRIx "\n",
721
+ __func__, dst_addr);
722
+ return;
723
+ }
724
+
725
+ if (trace_event_get_state_backends(TRACE_ASPEED_HACE_HEXDUMP)) {
726
+ hace_hexdump("dst", (char *)dst_buf, len);
727
+ }
728
+
729
+ if (mode == QCRYPTO_CIPHER_MODE_CBC) {
730
+ /*
731
+ * CBC chains on the last ciphertext block: the final block of the
732
+ * output when encrypting, or of the input when decrypting. Write it
733
+ * back as the IV for the next request.
734
+ */
735
+ next_iv = (encrypt ? dst_buf : src_buf) + len - blocklen;
736
+ if (address_space_write(&s->dram_as, ctx_addr + iv_offset,
737
+ MEMTXATTRS_UNSPECIFIED, next_iv, blocklen)) {
738
+ qemu_log_mask(LOG_GUEST_ERROR,
739
+ "%s: Failed to write IV, addr=0x%" HWADDR_PRIx "\n",
740
+ __func__, ctx_addr + iv_offset);
741
+ }
742
+ }
743
+}
744
+
745
static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size)
746
{
747
AspeedHACEState *s = ASPEED_HACE(opaque);
772
qemu_irq_lower(s->irq);
773
}
774
}
534
- if (ahc->raise_crypt_interrupt_workaround) {
535
- if (data & CRYPT_IRQ) {
536
- data &= ~CRYPT_IRQ;
775
+ if (data & CRYPT_IRQ) {
776
+ data &= ~CRYPT_IRQ;
777
538
- if (s->regs[addr] & CRYPT_IRQ) {
539
- qemu_irq_lower(s->irq);
540
- }
778
+ if (s->regs[addr] & CRYPT_IRQ) {
779
+ qemu_irq_lower(s->irq);
780
}
781
}
782
break;
783
+ case R_CRYPT_SRC:
784
+ case R_CRYPT_DEST:
785
+ case R_CRYPT_CONTEXT:
786
+ data &= ahc->src_mask;
787
+ break;
788
+ case R_CRYPT_DATA_LEN:
789
+ data &= CRYPT_DATA_LEN_MASK;
790
+ break;
791
case R_HASH_SRC:
792
data &= ahc->src_mask;
793
break;
836
break;
837
}
838
case R_CRYPT_CMD:
592
- qemu_log_mask(LOG_UNIMP, "%s: Crypt commands not implemented\n",
593
- __func__);
594
- if (ahc->raise_crypt_interrupt_workaround) {
595
- s->regs[R_STATUS] |= CRYPT_IRQ;
596
- if (data & CRYPT_IRQ_EN) {
597
- qemu_irq_raise(s->irq);
598
- }
839
+ /*
840
+ * The AST2700 crypto engine needs 64-bit DMA and AES-GCM, which are
841
+ * added later; until then it keeps the temporary workaround of only
842
+ * raising the completion interrupt without running the command.
843
+ */
844
+ if (!ahc->raise_crypt_interrupt_workaround) {
845
+ do_crypt_operation(s, data);
846
+ }
847
+
848
+ /* Hardware raises the crypt interrupt once the command finishes. */
849
+ s->regs[R_STATUS] |= CRYPT_IRQ;
850
+ if (data & CRYPT_CMD_ISR_EN) {
851
+ qemu_irq_raise(s->irq);
852
}
853
break;
854
case R_HASH_SRC_HI: