qemu/hw/misc/csu_aes.c
<<
>>
Prefs
   1/*
   2 * QEMU model of ZynqMP CSU AES-GCM block
   3 *
   4 * Copyright (c) 2013 Xilinx Inc
   5 * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
   6 *
   7 * This code is licensed under the GNU GPL.
   8 */
   9
  10#include "qemu/osdep.h"
  11#include "hw/sysbus.h"
  12#include "qemu/log.h"
  13#include "qapi/error.h"
  14
  15#include "hw/stream.h"
  16#include "qemu/bitops.h"
  17#include "sysemu/dma.h"
  18#include "hw/register-dep.h"
  19#include "hw/zynqmp_aes_key.h"
  20#include "hw/fdt_generic_util.h"
  21
  22#include "hw/misc/xlnx-aes.h"
  23
  24#ifndef ZYNQMP_CSU_AES_ERR_DEBUG
  25#define ZYNQMP_CSU_AES_ERR_DEBUG 0
  26#endif
  27
  28#define TYPE_ZYNQMP_CSU_AES "zynqmp.csu-aes"
  29#define TYPE_ZYNQMP_CSU_DEVKEY_SINK "zynqmp.csu-aes.devkey-sink"
  30
  31#define ZYNQMP_CSU_AES(obj) \
  32     OBJECT_CHECK(ZynqMPCSUAES, (obj), TYPE_ZYNQMP_CSU_AES)
  33
  34#define ZYNQMP_CSU_KEY_SINK(obj) \
  35     OBJECT_CHECK(CSUKeySink, (obj), TYPE_ZYNQMP_CSU_DEVKEY_SINK)
  36
  37DEP_REG32(AES_STATUS, 0x00)
  38    DEP_FIELD(AES_STATUS, OKR_ZEROED, 1, 11)
  39    DEP_FIELD(AES_STATUS, BOOT_ZEROED, 1, 10)
  40    DEP_FIELD(AES_STATUS, KUP_ZEROED, 1, 9)
  41    DEP_FIELD(AES_STATUS, AES_KEY_ZEROED, 1, 8)
  42    DEP_FIELD(AES_STATUS, KEY_INIT_DONE, 1, 4)
  43    DEP_FIELD(AES_STATUS, GCM_TAG_PASS, 1, 3)
  44    DEP_FIELD(AES_STATUS, DONE, 1, 2)
  45    DEP_FIELD(AES_STATUS, READY, 1, 1)
  46    DEP_FIELD(AES_STATUS, BUSY, 1, 0)
  47DEP_REG32(AES_KEY_SRC, 0x04)
  48    DEP_FIELD(AES_KEY_SRC, KEY_SRC, 4, 0)
  49
  50#define AES_KEYSRC_KUP        0
  51#define AES_KEYSRC_DEV        1
  52
  53DEP_REG32(AES_KEY_LOAD, 0x08)
  54    DEP_FIELD(AES_KEY_LOAD, KEY_LOAD, 1, 0)
  55DEP_REG32(AES_START_MSG, 0x0c)
  56    DEP_FIELD(AES_START_MSG, START_MSG, 1, 0)
  57DEP_REG32(AES_RESET, 0x10)
  58    DEP_FIELD(AES_RESET, RESET, 1, 0)
  59DEP_REG32(AES_KEY_CLEAR, 0x14)
  60    DEP_FIELD(AES_KEY_CLEAR, AES_KUP_ZERO, 1, 1)
  61    DEP_FIELD(AES_KEY_CLEAR, AES_KEY_ZERO, 1, 0)
  62DEP_REG32(AES_CFG, 0x18)
  63    DEP_FIELD(AES_CFG, ENCRYPT_DECRYPT_N, 1, 0)
  64DEP_REG32(AES_KUP_WR, 0x1c)
  65    DEP_FIELD(AES_KUP_WR, IV_WRITE, 1, 1)
  66    DEP_FIELD(AES_KUP_WR, KUP_WRITE, 1, 0)
  67DEP_REG32(AES_KUP_0, 0x20)
  68DEP_REG32(AES_KUP_1, 0x24)
  69DEP_REG32(AES_KUP_2, 0x28)
  70DEP_REG32(AES_KUP_3, 0x2c)
  71DEP_REG32(AES_KUP_4, 0x30)
  72DEP_REG32(AES_KUP_5, 0x34)
  73DEP_REG32(AES_KUP_6, 0x38)
  74DEP_REG32(AES_KUP_7, 0x3c)
  75DEP_REG32(AES_IV_0, 0x40)
  76DEP_REG32(AES_IV_1, 0x44)
  77DEP_REG32(AES_IV_2, 0x48)
  78DEP_REG32(AES_IV_3, 0x4c)
  79
  80#define R_MAX                      (R_AES_IV_3 + 1)
  81
  82static const DepRegisterAccessInfo aes_regs_info[] = {
  83    { .name = "AES_STATUS",  .decode.addr = A_AES_STATUS,
  84        .reset = 0xf00,
  85        .rsvd = 0xe0,
  86        .ro = 0xfff,
  87    },{ .name = "AES_KEY_SRC",  .decode.addr = A_AES_KEY_SRC,
  88    },{ .name = "AES_KEY_LOAD",  .decode.addr = A_AES_KEY_LOAD,
  89    },{ .name = "AES_START_MSG",  .decode.addr = A_AES_START_MSG,
  90    },{ .name = "AES_KUP_WR",  .decode.addr = A_AES_KUP_WR,
  91    },{ .name = "AES_RESET",  .decode.addr = A_AES_RESET,
  92    },{ .name = "AES_KEY_CLEAR",  .decode.addr = A_AES_KEY_CLEAR,
  93    },{ .name = "AES_CFG",  .decode.addr = A_AES_CFG,
  94    },{ .name = "AES_KUP_0",  .decode.addr = A_AES_KUP_0,
  95    },{ .name = "AES_KUP_1",  .decode.addr = A_AES_KUP_1,
  96    },{ .name = "AES_KUP_2",  .decode.addr = A_AES_KUP_2,
  97    },{ .name = "AES_KUP_3",  .decode.addr = A_AES_KUP_3,
  98    },{ .name = "AES_KUP_4",  .decode.addr = A_AES_KUP_4,
  99    },{ .name = "AES_KUP_5",  .decode.addr = A_AES_KUP_5,
 100    },{ .name = "AES_KUP_6",  .decode.addr = A_AES_KUP_6,
 101    },{ .name = "AES_KUP_7",  .decode.addr = A_AES_KUP_7,
 102    },{ .name = "AES_IV_0",  .decode.addr = A_AES_IV_0,
 103        .ro = 0xffffffffL,
 104    },{ .name = "AES_IV_1",  .decode.addr = A_AES_IV_1,
 105        .ro = 0xffffffffL,
 106    },{ .name = "AES_IV_2",  .decode.addr = A_AES_IV_2,
 107        .ro = 0xffffffffL,
 108    },{ .name = "AES_IV_3",  .decode.addr = A_AES_IV_3,
 109        .ro = 0xffffffffL,
 110    }
 111};
 112
 113typedef struct ZynqMPCSUAES ZynqMPCSUAES;
 114
 115typedef struct CSUKeySink {
 116    Object parent;
 117    ZynqMPCSUAES *tmr;
 118
 119    union {
 120        uint8_t key[256 / 8];
 121        uint32_t k32[256 / 32];
 122    };
 123} CSUKeySink;
 124
 125/* This implements a model of the wrapper logic around the Helion unit.  */
 126struct ZynqMPCSUAES {
 127    SysBusDevice busdev;
 128    MemoryRegion iomem;
 129    StreamSlave *tx_dev;
 130
 131    XlnxAES *aes;
 132    qemu_irq aes_rst;
 133    bool aes_done;
 134    bool aes_busy;
 135
 136    bool key_loaded;
 137    uint32_t data_count;
 138    uint32_t regs[R_MAX];
 139    DepRegisterInfo regs_info[R_MAX];
 140
 141    union {
 142        struct {
 143            bool kup_write;
 144            bool boot_write;
 145            bool okr_write;
 146            bool iv_write;
 147            bool key_decrypt;
 148        };
 149        bool bl[5];
 150    } inputs;
 151
 152    CSUKeySink bbram_key;
 153    CSUKeySink boot_key;
 154    CSUKeySink efuse_key;
 155    CSUKeySink family_key;
 156    CSUKeySink okr_key;
 157    CSUKeySink puf_key;
 158    CSUKeySink *dev_key;
 159
 160    struct {
 161        uint32_t key[256 / 32];
 162        uint32_t iv[128 / 32];
 163    } feedback;
 164
 165    StreamCanPushNotifyFn notify;
 166    void *notify_opaque;
 167    /* Debug only */
 168    const char *prefix;
 169    /* AES needs blocks of 16 bytes.  */
 170    uint8_t buf[16];
 171    uint8_t bufpos;
 172};
 173
 174/* Xilinx wrapper logic.
 175 *
 176 * Disable AAD.
 177 * Cap encryption lengths to 256bit.
 178 */
 179static int xlx_aes_push_data(ZynqMPCSUAES *s,
 180                             uint8_t *data8x, int len,
 181                             bool last_word , int lw_len,
 182                             uint8_t *outbuf, int *outlen)
 183{
 184    uint8_t *wbuf = data8x;
 185    int wlen = len;
 186    int rlen = len;
 187
 188//    printf("%s len=%d eop=%d\n", __func__, len, last_word);
 189    /* 16 bytes write buffer.  */
 190    if (s->aes->state != PAYLOAD && (s->bufpos || wlen < 16)) {
 191        unsigned int tocopy = MIN(16 - s->bufpos, wlen);
 192
 193        memcpy(s->buf + s->bufpos, wbuf, tocopy);
 194        s->bufpos += tocopy;
 195        rlen = tocopy;
 196        assert(s->bufpos <= 16);
 197
 198        /* Full block?  */
 199        if (s->bufpos == 16 || last_word) {
 200            last_word = (tocopy == wlen) && last_word;
 201            wbuf = s->buf;
 202            wlen = s->bufpos;
 203            s->bufpos = 0;
 204        } else {
 205            return tocopy;
 206        }
 207    }
 208
 209    /* End the AAD phase after the 16 bytes of IV.  */
 210    if (s->data_count < 16) {
 211        int plen = MIN(16 - s->data_count, wlen);
 212        s->data_count += plen;
 213        last_word = s->data_count == 16;
 214
 215        xlnx_aes_push_data(s->aes, wbuf, plen,
 216                             last_word, 4, NULL, NULL);
 217        return plen;
 218    }
 219
 220    s->data_count += wlen;
 221    /* FIXME: Encryption of more than 256 might be HW limited??  */
 222    if (s->aes->encrypt && s->data_count > 32) {
 223        qemu_log_mask(LOG_GUEST_ERROR,
 224                      "%s: encryption of more than 256 bits!\n", s->prefix);
 225    }
 226    xlnx_aes_push_data(s->aes, wbuf, wlen, last_word, lw_len,
 227                         outbuf, outlen);
 228    return rlen;
 229}
 230
 231static uint32_t shift_in_u32(uint32_t *a, unsigned int size, uint32_t data)
 232{
 233    unsigned int i;
 234    uint32_t r = a[0];
 235
 236    for (i = 1; i < size; i++) {
 237        a[i - 1] = a[i];
 238    }
 239    a[i - 1] = data;
 240
 241    return r;
 242}
 243
 244static void update_devkey_sink(CSUKeySink *ks, void *key)
 245{
 246    memcpy(ks->key, key, sizeof(ks->key));
 247}
 248
 249static void xlx_aes_feedback(ZynqMPCSUAES *s, unsigned char *buf, int len)
 250{
 251    bool key_feedback;
 252    bool kup_key_feedback;
 253    bool iv_feedback;
 254    int i;
 255
 256    iv_feedback = s->inputs.iv_write;
 257    iv_feedback |= s->regs[R_AES_KUP_WR] & R_AES_KUP_WR_IV_WRITE_MASK;
 258
 259    kup_key_feedback = s->inputs.kup_write;
 260    kup_key_feedback |= s->regs[R_AES_KUP_WR] & R_AES_KUP_WR_KUP_WRITE_MASK;
 261
 262    key_feedback = kup_key_feedback;
 263    key_feedback |= s->inputs.okr_write | s->inputs.boot_write;
 264
 265    assert((len & 3) == 0);
 266
 267    for (i = 0; i < len; i += 4) {
 268        uint32_t data;
 269        memcpy(&data, buf + i, 4);
 270
 271        if (iv_feedback) {
 272            data = shift_in_u32(s->feedback.iv, ARRAY_SIZE(s->feedback.iv),
 273                               data);
 274        }
 275        if (key_feedback) {
 276            shift_in_u32(s->feedback.key, ARRAY_SIZE(s->feedback.key), data);
 277        }
 278    }
 279
 280    /* feedback the AES output into Key and IV storage.  */
 281    if (iv_feedback) {
 282        for (i = 0; i < ARRAY_SIZE(s->feedback.iv); i++) {
 283            s->regs[R_AES_IV_0 + i] = s->feedback.iv[i];
 284        }
 285    }
 286    if (s->inputs.kup_write | kup_key_feedback) {
 287        for (i = 0; i < ARRAY_SIZE(s->feedback.key); i++) {
 288            s->regs[R_AES_KUP_0 + i] = s->feedback.key[i];
 289        }
 290    }
 291
 292    if (s->inputs.boot_write) {
 293        update_devkey_sink(&s->boot_key, s->feedback.key);
 294    }
 295    if (s->inputs.okr_write) {
 296        update_devkey_sink(&s->okr_key, s->feedback.key);
 297    }
 298}
 299
 300static void bswap32_buf8(uint8_t *buf, int len)
 301{
 302    int i;
 303
 304    assert((len & 3) == 0);
 305    for (i = 0; i < len; i += 4) {
 306        uint8_t v[4];
 307
 308        v[0] = buf[i];
 309        v[1] = buf[i + 1];
 310        v[2] = buf[i + 2];
 311        v[3] = buf[i + 3];
 312        buf[i] = v[3];
 313        buf[i + 1] = v[2];
 314        buf[i + 2] = v[1];
 315        buf[i + 3] = v[0];
 316    }
 317}
 318
 319static size_t xlx_aes_stream_push(StreamSlave *obj, uint8_t *buf, size_t len,
 320                                  uint32_t attr)
 321{
 322    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
 323    unsigned char outbuf[8 * 1024 + 16];
 324    int outlen = 0;
 325    bool feedback;
 326    size_t ret;
 327
 328    /* When encrypting, we need to be prepared to receive the 16 byte tag.  */
 329    if (len > (sizeof(outbuf) - 16)) {
 330        len = sizeof(outbuf) - 16;
 331        attr &= ~STREAM_ATTR_EOP;
 332    }
 333
 334    /* TODO: Add explicit eop to the stream interface.  */
 335    bswap32_buf8(buf, len);
 336    ret = xlx_aes_push_data(s, buf, len, stream_attr_has_eop(attr), 4,
 337                            outbuf, &outlen);
 338    bswap32_buf8(outbuf, outlen);
 339
 340    /* No flow-control on the output.  */
 341    feedback = s->inputs.iv_write | s->inputs.kup_write;
 342    feedback |= s->inputs.boot_write | s->inputs.okr_write;
 343    feedback |= s->regs[R_AES_KUP_WR]
 344                & (R_AES_KUP_WR_IV_WRITE_MASK | R_AES_KUP_WR_KUP_WRITE_MASK);
 345    if (feedback) {
 346        xlx_aes_feedback(s, outbuf, outlen);
 347        memset(outbuf, 0, outlen);
 348    }
 349    stream_push(s->tx_dev, outbuf, outlen, attr);
 350/*
 351      printf("%s len=%zd ret=%zd outlen=%d eop=%d\n",
 352             __func__, len, ret, outlen, attr);
 353*/
 354    return ret;
 355}
 356
 357static bool xlx_aes_stream_can_push(StreamSlave *obj,
 358                                    StreamCanPushNotifyFn notify,
 359                                    void *notify_opaque)
 360{
 361    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
 362/*    printf("%s: %d\n", __func__, s->aes->inp_ready); */
 363    return s->aes->inp_ready;
 364}
 365
 366static void xlx_aes_write_key(ZynqMPCSUAES *s, unsigned int pos, uint32_t val)
 367{
 368    if (s->inputs.key_decrypt) {
 369        xlx_aes_stream_push(STREAM_SLAVE(s), (void *) &val, sizeof val, 0);
 370    } else {
 371        xlnx_aes_write_key(s->aes, pos, val);
 372    }
 373}
 374
 375static void xlx_aes_load_key(ZynqMPCSUAES *s, int len)
 376{
 377    static uint32_t const zero_key[256 / 32] = { 0};
 378    const uint32_t *k32;
 379
 380    unsigned int src, i;
 381    src = (s->regs[R_AES_KEY_SRC] & R_AES_KEY_SRC_KEY_SRC_MASK)
 382           >> R_AES_KEY_SRC_KEY_SRC_SHIFT;
 383
 384    switch (src) {
 385    case AES_KEYSRC_KUP:
 386        k32 = &s->regs[R_AES_KUP_0];
 387        break;
 388    case AES_KEYSRC_DEV:
 389        k32 = s->dev_key ? s->dev_key->k32 : zero_key;
 390        break;
 391    default:
 392        hw_error("%s: Unsupported AES Key source %d\n", s->prefix, src);
 393        k32 = zero_key;
 394    }
 395
 396    for (i = 0; i < 8; i++) {
 397        xlx_aes_write_key(s, i, k32[i]);
 398    }
 399
 400    if (!s->inputs.key_decrypt) {
 401        xlnx_aes_load_key(s->aes, len);
 402    }
 403    s->key_loaded = true;
 404}
 405
 406static uint64_t xlx_aes_read(void *opaque, hwaddr addr, unsigned size)
 407{
 408    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
 409    uint32_t v;
 410
 411    addr >>= 2;
 412    assert(addr < R_MAX);
 413    v = dep_register_read(&s->regs_info[addr]);
 414    switch (addr) {
 415    case R_AES_KUP_0...R_AES_KUP_7:
 416        v = 0;
 417        break;
 418    case R_AES_STATUS:
 419        v = 0;
 420        v |= R_AES_STATUS_BOOT_ZEROED_MASK;
 421        v |= R_AES_STATUS_OKR_ZEROED_MASK;
 422        v |= R_AES_STATUS_KUP_ZEROED_MASK;
 423        v |= s->key_loaded ? R_AES_STATUS_KEY_INIT_DONE_MASK : 0;
 424        v |= s->aes->key_zeroed ? R_AES_STATUS_AES_KEY_ZEROED_MASK : 0;
 425        v |= s->aes->tag_ok ? R_AES_STATUS_GCM_TAG_PASS_MASK : 0;
 426        v |= s->aes->inp_ready ? R_AES_STATUS_READY_MASK : 0;
 427        v |= s->aes_busy ? R_AES_STATUS_BUSY_MASK : 0;
 428        v |= s->aes_done ? R_AES_STATUS_DONE_MASK : 0;
 429        break;
 430    default:
 431        break;
 432    }
 433    return v;
 434}
 435
 436static void xlx_aes_reset(DeviceState *dev)
 437{
 438    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(dev);
 439    int i;
 440
 441    for (i = 0; i < R_MAX; ++i) {
 442        dep_register_reset(&s->regs_info[i]);
 443    }
 444    qemu_irq_pulse(s->aes_rst);
 445    s->key_loaded = false;
 446    s->data_count = 0;
 447}
 448
 449static void xlx_aes_write(void *opaque, hwaddr addr, uint64_t value,
 450                      unsigned size)
 451{
 452    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
 453
 454    addr >>= 2;
 455    dep_register_write(&s->regs_info[addr], value, ~0);
 456
 457    switch (addr) {
 458    case R_AES_KEY_LOAD:
 459        if (value) {
 460            xlx_aes_load_key(s, 256);
 461        }
 462        break;
 463    case R_AES_START_MSG:
 464        if (value) {
 465            s->data_count = 0;
 466            xlnx_aes_start_message(s->aes,
 467                         s->regs[R_AES_CFG] & R_AES_CFG_ENCRYPT_DECRYPT_N_MASK);
 468        }
 469        break;
 470    case R_AES_RESET:
 471        if (value) {
 472            xlx_aes_reset(opaque);
 473        }
 474        break;
 475    case R_AES_KEY_CLEAR:
 476        if (value & R_AES_KEY_CLEAR_AES_KEY_ZERO_MASK) {
 477            xlnx_aes_key_zero(s->aes);
 478            s->regs[R_AES_KEY_CLEAR] &= ~R_AES_KEY_CLEAR_AES_KEY_ZERO_MASK;
 479            s->key_loaded = false;
 480        }
 481        if (value & R_AES_KEY_CLEAR_AES_KUP_ZERO_MASK) {
 482            s->regs[R_AES_KEY_CLEAR] &= ~R_AES_KEY_CLEAR_AES_KUP_ZERO_MASK;
 483            memset(&s->regs[R_AES_KUP_0], 0, 8 * 4);
 484        }
 485        break;
 486    default:
 487        break;
 488    }
 489}
 490
 491static const MemoryRegionOps aes_ops = {
 492    .read = xlx_aes_read,
 493    .write = xlx_aes_write,
 494    .endianness = DEVICE_LITTLE_ENDIAN,
 495};
 496
 497static void gpio_key_write_ctrl(void *opaque, int n, int level)
 498{
 499    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
 500    assert(n < ARRAY_SIZE(s->inputs.bl));
 501
 502    s->inputs.bl[n] = level;
 503}
 504
 505static void aes_busy_update(void *opaque, int n, int level)
 506{
 507    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
 508
 509    s->aes_busy = level;
 510}
 511
 512static void aes_done_update(void *opaque, int n, int level)
 513{
 514    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(opaque);
 515
 516    s->aes_done = level;
 517}
 518
 519static void aes_realize(DeviceState *dev, Error **errp)
 520{
 521    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(dev);
 522    const char *prefix = object_get_canonical_path(OBJECT(dev));
 523    int i;
 524
 525    for (i = 0; i < R_MAX; ++i) {
 526        DepRegisterInfo *r = &s->regs_info[i];
 527
 528        *r = (DepRegisterInfo) {
 529            .data = (uint8_t *)&s->regs[i],
 530            .data_size = sizeof(uint32_t),
 531            .access = &aes_regs_info[i],
 532            .debug = ZYNQMP_CSU_AES_ERR_DEBUG,
 533            .prefix = prefix,
 534            .opaque = s,
 535        };
 536        dep_register_init(r);
 537        qdev_pass_all_gpios(DEVICE(r), dev);
 538    }
 539    s->prefix = g_strdup_printf("%s:", object_get_canonical_path(OBJECT(s)));
 540    s->aes->prefix = s->prefix;
 541    qdev_init_gpio_in_named(dev, aes_busy_update, "busy", 1);
 542    qdev_init_gpio_in_named(dev, aes_done_update, "done", 1);
 543    qdev_init_gpio_out_named(dev, &s->aes_rst, "reset", 1);
 544    qdev_init_gpio_in_named(dev, gpio_key_write_ctrl, "key-wr", 5);
 545}
 546
 547static void csu_devkey_sink_init(ZynqMPCSUAES *s,
 548                                 const char *name, CSUKeySink *ks)
 549{
 550    char *ch_name;
 551
 552    ch_name = g_strdup_printf("zynqmp-aes-key-sink-%s-target", name);
 553    object_initialize(ks, sizeof(*ks), TYPE_ZYNQMP_CSU_DEVKEY_SINK);
 554    object_property_add_child(OBJECT(s), ch_name, (Object *)ks, &error_abort);
 555    free(ch_name);
 556
 557    /* Back link, non-qom for the moment.  */
 558    ks->tmr = s;
 559}
 560
 561static void aes_init(Object *obj)
 562{
 563    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
 564    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
 565
 566    /* Sources of device key, as shown in Xilinx UG1085, v1.9, Fig.12-2 */
 567    csu_devkey_sink_init(s, "bbram", &s->bbram_key);
 568    csu_devkey_sink_init(s, "boot", &s->boot_key);
 569    csu_devkey_sink_init(s, "efuses", &s->efuse_key);
 570    csu_devkey_sink_init(s, "family", &s->family_key);
 571    csu_devkey_sink_init(s, "operational", &s->okr_key);
 572    csu_devkey_sink_init(s, "puf", &s->puf_key);
 573
 574    /* A reference to one of above, to emulate the mux shown in Fig.12-2 */
 575    s->dev_key = NULL;
 576
 577    memory_region_init_io(&s->iomem, obj, &aes_ops, s,
 578                          "zynqmp.csu-aes", R_MAX * 4);
 579    sysbus_init_mmio(sbd, &s->iomem);
 580}
 581
 582static const VMStateDescription vmstate_aes = {
 583    .name = "zynqmp_csu_aes",
 584    .version_id = 1,
 585    .minimum_version_id = 1,
 586    .minimum_version_id_old = 1,
 587    .fields = (VMStateField[]) {
 588        VMSTATE_UINT8_ARRAY(buf, ZynqMPCSUAES, 16),
 589        VMSTATE_UINT8(bufpos, ZynqMPCSUAES),
 590        VMSTATE_UINT32_ARRAY(regs, ZynqMPCSUAES, R_MAX),
 591        VMSTATE_END_OF_LIST(),
 592    }
 593};
 594
 595static Property aes_properties[] = {
 596    DEFINE_PROP_LINK("stream-connected-aes",
 597                     ZynqMPCSUAES, tx_dev,
 598                     TYPE_STREAM_SLAVE, StreamSlave *),
 599    DEFINE_PROP_LINK("aes-core",
 600                     ZynqMPCSUAES, aes,
 601                     TYPE_XLNX_AES, XlnxAES *),
 602
 603    DEFINE_PROP_XLNX_AES_KEY256("zynqmp-aes-family-key",
 604                                ZynqMPCSUAES, family_key.key),
 605    DEFINE_PROP_XLNX_AES_KEY256("zynqmp-aes-puf-key",
 606                                ZynqMPCSUAES, puf_key.key),
 607
 608    DEFINE_PROP_END_OF_LIST(),
 609};
 610
 611static const FDTGenericGPIOSet aes_gpios[] = {
 612    {
 613      .names = &fdt_generic_gpio_name_set_gpio,
 614      .gpios = (FDTGenericGPIOConnection[]) {
 615        { .name = "key-wr", .fdt_index = 0, .range = 5 },
 616        { .name = "reset", .fdt_index = 5, .range = 1},
 617        { },
 618      },
 619    },
 620    { },
 621};
 622
 623static void aes_select_device_key(ZynqMPAESKeySink *obj, uint8_t *key, size_t len)
 624{
 625    ZynqMPCSUAES *s = ZYNQMP_CSU_AES(obj);
 626
 627    /*
 628     * Class-specific:
 629     * The key-material is 1-character key-sink label, not key values
 630     */
 631    assert(key);
 632    assert(len == 1);
 633
 634    switch (key[0]) {
 635    case 'M':
 636    case 'm':
 637        s->dev_key = &s->bbram_key;
 638        break;
 639    case 'E':
 640    case 'e':
 641        s->dev_key = &s->efuse_key;
 642        break;
 643    case 'B':
 644    case 'b':
 645        s->dev_key = &s->boot_key;
 646        break;
 647    case 'O':
 648    case 'o':
 649        s->dev_key = &s->okr_key;
 650        break;
 651    case 'F':
 652    case 'f':
 653        s->dev_key = &s->family_key;
 654        break;
 655    case 'P':
 656    case 'p':
 657        s->dev_key = &s->puf_key;
 658        break;
 659    default:
 660        s->dev_key = NULL;
 661    }
 662
 663    return;
 664}
 665
 666static void aes_class_init(ObjectClass *klass, void *data)
 667{
 668    DeviceClass *dc = DEVICE_CLASS(klass);
 669    StreamSlaveClass *ssc = STREAM_SLAVE_CLASS(klass);
 670    ZynqMPAESKeySinkClass *ksc = ZYNQMP_AES_KEY_SINK_CLASS(klass);
 671    FDTGenericGPIOClass *fggc = FDT_GENERIC_GPIO_CLASS(klass);
 672
 673
 674    dc->reset = xlx_aes_reset;
 675    dc->realize = aes_realize;
 676    dc->vmsd = &vmstate_aes;
 677    dc->props = aes_properties;
 678
 679    ssc->push = xlx_aes_stream_push;
 680    ssc->can_push = xlx_aes_stream_can_push;
 681
 682    ksc->update = aes_select_device_key;
 683    fggc->controller_gpios = aes_gpios;
 684}
 685
 686static void csu_devkey_sink_update(ZynqMPAESKeySink *obj,
 687                                   uint8_t *key, size_t len)
 688{
 689    CSUKeySink *ks = ZYNQMP_CSU_KEY_SINK(obj);
 690
 691    assert(len == sizeof(ks->key)); /* Support only 1 size */
 692    update_devkey_sink(ks, key);
 693}
 694
 695static void csu_devkey_sink_class_init(ObjectClass *klass, void *data)
 696{
 697    ZynqMPAESKeySinkClass *c = ZYNQMP_AES_KEY_SINK_CLASS(klass);
 698    c->update = csu_devkey_sink_update;
 699}
 700
 701static const TypeInfo aes_info = {
 702    .name          = TYPE_ZYNQMP_CSU_AES,
 703    .parent        = TYPE_SYS_BUS_DEVICE,
 704    .instance_size = sizeof(ZynqMPCSUAES),
 705    .class_init    = aes_class_init,
 706    .instance_init = aes_init,
 707    .interfaces = (InterfaceInfo[]) {
 708        { TYPE_STREAM_SLAVE },
 709        { TYPE_ZYNQMP_AES_KEY_SINK },
 710        { TYPE_FDT_GENERIC_GPIO },
 711        { }
 712    }
 713};
 714
 715static const TypeInfo csu_devkey_sink_info = {
 716    .name          = TYPE_ZYNQMP_CSU_DEVKEY_SINK,
 717    .parent        = TYPE_OBJECT,
 718    .instance_size = sizeof(CSUKeySink),
 719    .class_init    = csu_devkey_sink_class_init,
 720    .interfaces    = (InterfaceInfo[]) {
 721        { TYPE_ZYNQMP_AES_KEY_SINK },
 722        { }
 723    }
 724};
 725
 726static void aes_register_types(void)
 727{
 728    type_register_static(&aes_info);
 729    type_register_static(&csu_devkey_sink_info);
 730}
 731
 732type_init(aes_register_types)
 733