if (*keybufsize < MINEP11AESKEYBLOBSIZE)
                        return -EINVAL;
                break;
+       case PKEY_TYPE_EP11_AES:
+               if (*keybufsize < (sizeof(struct ep11kblob_header) +
+                                  MINEP11AESKEYBLOBSIZE))
+                       return -EINVAL;
+               break;
        default:
                return -EINVAL;
        }
        for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
                card = apqns[i].card;
                dom = apqns[i].domain;
-               if (ktype == PKEY_TYPE_EP11) {
+               if (ktype == PKEY_TYPE_EP11 ||
+                   ktype == PKEY_TYPE_EP11_AES) {
                        rc = ep11_genaeskey(card, dom, ksize, kflags,
-                                           keybuf, keybufsize);
+                                           keybuf, keybufsize, ktype);
                } else if (ktype == PKEY_TYPE_CCA_DATA) {
                        rc = cca_genseckey(card, dom, ksize, keybuf);
                        *keybufsize = (rc ? 0 : SECKEYBLOBSIZE);
                apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries);
                if (IS_ERR(apqns))
                        return PTR_ERR(apqns);
-               kkey = kmalloc(klen, GFP_KERNEL);
+               kkey = kzalloc(klen, GFP_KERNEL);
                if (!kkey) {
                        kfree(apqns);
                        return -ENOMEM;
        for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
                card = apqns[i] >> 16;
                dom = apqns[i] & 0xFFFF;
-               rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
+               rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
+                                   PKEY_TYPE_EP11);
                if (rc == 0)
                        break;
        }
        if (is_xts) {
                keysize = MAXEP11AESKEYBLOBSIZE;
                buf += MAXEP11AESKEYBLOBSIZE;
-               rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
+               rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize,
+                                   PKEY_TYPE_EP11);
                if (rc == 0)
                        return 2 * MAXEP11AESKEYBLOBSIZE;
        }
 
        spin_unlock_bh(&card_list_lock);
 }
 
+static int ep11_kb_split(const u8 *kb, size_t kblen, u32 kbver,
+                        struct ep11kblob_header **kbhdr, size_t *kbhdrsize,
+                        u8 **kbpl, size_t *kbplsize)
+{
+       struct ep11kblob_header *hdr = NULL;
+       size_t hdrsize, plsize = 0;
+       int rc = -EINVAL;
+       u8 *pl = NULL;
+
+       if (kblen < sizeof(struct ep11kblob_header))
+               goto out;
+       hdr = (struct ep11kblob_header *)kb;
+
+       switch (kbver) {
+       case TOKVER_EP11_AES:
+               /* header overlays the payload */
+               hdrsize = 0;
+               break;
+       case TOKVER_EP11_ECC_WITH_HEADER:
+       case TOKVER_EP11_AES_WITH_HEADER:
+               /* payload starts after the header */
+               hdrsize = sizeof(struct ep11kblob_header);
+               break;
+       default:
+               goto out;
+       }
+
+       plsize = kblen - hdrsize;
+       pl = (u8 *)kb + hdrsize;
+
+       if (kbhdr)
+               *kbhdr = hdr;
+       if (kbhdrsize)
+               *kbhdrsize = hdrsize;
+       if (kbpl)
+               *kbpl = pl;
+       if (kbplsize)
+               *kbplsize = plsize;
+
+       rc = 0;
+out:
+       return rc;
+}
+
 /*
  * Simple check if the key blob is a valid EP11 AES key blob with header.
  */
  */
 #define KEY_ATTR_DEFAULTS 0x00200c00
 
-int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
-                  u8 *keybuf, size_t *keybufsize)
+static int _ep11_genaeskey(u16 card, u16 domain,
+                          u32 keybitsize, u32 keygenflags,
+                          u8 *keybuf, size_t *keybufsize)
 {
        struct keygen_req_pl {
                struct pl_head head;
        struct ep11_cprb *req = NULL, *rep = NULL;
        struct ep11_target_dev target;
        struct ep11_urb *urb = NULL;
-       struct ep11keyblob *kb;
        int api, rc = -ENOMEM;
 
        switch (keybitsize) {
                goto out;
        }
 
-       /* copy key blob and set header values */
+       /* copy key blob */
        memcpy(keybuf, rep_pl->data, rep_pl->data_len);
        *keybufsize = rep_pl->data_len;
-       kb = (struct ep11keyblob *)keybuf;
-       kb->head.type = TOKTYPE_NON_CCA;
-       kb->head.len = rep_pl->data_len;
-       kb->head.version = TOKVER_EP11_AES;
-       kb->head.bitlen = keybitsize;
 
 out:
        kfree(req);
        kfree(urb);
        return rc;
 }
+
+int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+                  u8 *keybuf, size_t *keybufsize, u32 keybufver)
+{
+       struct ep11kblob_header *hdr;
+       size_t hdr_size, pl_size;
+       u8 *pl;
+       int rc;
+
+       switch (keybufver) {
+       case TOKVER_EP11_AES:
+       case TOKVER_EP11_AES_WITH_HEADER:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       rc = ep11_kb_split(keybuf, *keybufsize, keybufver,
+                          &hdr, &hdr_size, &pl, &pl_size);
+       if (rc)
+               return rc;
+
+       rc = _ep11_genaeskey(card, domain, keybitsize, keygenflags,
+                            pl, &pl_size);
+       if (rc)
+               return rc;
+
+       *keybufsize = hdr_size + pl_size;
+
+       /* update header information */
+       hdr->type = TOKTYPE_NON_CCA;
+       hdr->len = *keybufsize;
+       hdr->version = keybufver;
+       hdr->bitlen = keybitsize;
+
+       return 0;
+}
 EXPORT_SYMBOL(ep11_genaeskey);
 
 static int ep11_cryptsingle(u16 card, u16 domain,
                     const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
 {
        int rc;
-       struct ep11keyblob *kb;
        u8 encbuf[64], *kek = NULL;
        size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
 
        }
 
        /* Step 1: generate AES 256 bit random kek key */
-       rc = ep11_genaeskey(card, domain, 256,
-                           0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
-                           kek, &keklen);
+       rc = _ep11_genaeskey(card, domain, 256,
+                            0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
+                            kek, &keklen);
        if (rc) {
                DEBUG_ERR(
                        "%s generate kek key failed, rc=%d\n",
                        __func__, rc);
                goto out;
        }
-       kb = (struct ep11keyblob *)kek;
-       memset(&kb->head, 0, sizeof(kb->head));
 
        /* Step 2: encrypt clear key value with the kek key */
        rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,