^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright IBM Corp. 2019
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author(s): Harald Freudenberger <freude@linux.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Collection of EP11 misc functions used by zcrypt and pkey
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #define KMSG_COMPONENT "zcrypt"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/zcrypt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/pkey.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <crypto/aes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "ap_bus.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "zcrypt_api.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "zcrypt_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "zcrypt_msgtype6.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "zcrypt_ep11misc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "zcrypt_ccamisc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DEBUG_DBG(...) ZCRYPT_DBF(DBF_DEBUG, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DEBUG_INFO(...) ZCRYPT_DBF(DBF_INFO, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* default iv used here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* ep11 card info cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct card_list_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u16 cardnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct ep11_card_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static LIST_HEAD(card_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static DEFINE_SPINLOCK(card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct card_list_entry *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) spin_lock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) list_for_each_entry(ptr, &card_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (ptr->cardnr == cardnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) memcpy(ci, &ptr->info, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) spin_unlock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct card_list_entry *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) spin_lock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) list_for_each_entry(ptr, &card_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (ptr->cardnr == cardnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) memcpy(&ptr->info, ci, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (!ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) spin_unlock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ptr->cardnr = cardnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) memcpy(&ptr->info, ci, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) list_add(&ptr->list, &card_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) spin_unlock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void card_cache_scrub(u16 cardnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct card_list_entry *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) spin_lock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) list_for_each_entry(ptr, &card_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ptr->cardnr == cardnr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) list_del(&ptr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) kfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) spin_unlock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static void __exit card_cache_free(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct card_list_entry *ptr, *pnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) spin_lock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) list_for_each_entry_safe(ptr, pnext, &card_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) list_del(&ptr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) kfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) spin_unlock_bh(&card_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * Simple check if the key blob is a valid EP11 AES key blob with header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) int ep11_check_aes_key_with_hdr(debug_info_t *dbg, int dbflvl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) const u8 *key, size_t keylen, int checkcpacfexp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct ep11kblob_header *hdr = (struct ep11kblob_header *) key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) struct ep11keyblob *kb = (struct ep11keyblob *) (key + sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (keylen < sizeof(*hdr) + sizeof(*kb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) DBF("%s key check failed, keylen %zu < %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) __func__, keylen, sizeof(*hdr) + sizeof(*kb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (hdr->type != TOKTYPE_NON_CCA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) DBF("%s key check failed, type 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) __func__, (int) hdr->type, TOKTYPE_NON_CCA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (hdr->hver != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) DBF("%s key check failed, header version 0x%02x != 0x00\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) __func__, (int) hdr->hver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (hdr->version != TOKVER_EP11_AES_WITH_HEADER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) DBF("%s key check failed, version 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) __func__, (int) hdr->version, TOKVER_EP11_AES_WITH_HEADER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (hdr->len > keylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) DBF("%s key check failed, header len %d keylen %zu mismatch\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) __func__, (int) hdr->len, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) if (hdr->len < sizeof(*hdr) + sizeof(*kb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) DBF("%s key check failed, header len %d < %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) __func__, (int) hdr->len, sizeof(*hdr) + sizeof(*kb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (kb->version != EP11_STRUCT_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) __func__, (int) kb->version, EP11_STRUCT_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) DBF("%s key check failed, PKEY_EXTRACTABLE is off\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #undef DBF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) EXPORT_SYMBOL(ep11_check_aes_key_with_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * Simple check if the key blob is a valid EP11 ECC key blob with header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int ep11_check_ecc_key_with_hdr(debug_info_t *dbg, int dbflvl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) const u8 *key, size_t keylen, int checkcpacfexp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct ep11kblob_header *hdr = (struct ep11kblob_header *) key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct ep11keyblob *kb = (struct ep11keyblob *) (key + sizeof(*hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (keylen < sizeof(*hdr) + sizeof(*kb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) DBF("%s key check failed, keylen %zu < %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) __func__, keylen, sizeof(*hdr) + sizeof(*kb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (hdr->type != TOKTYPE_NON_CCA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) DBF("%s key check failed, type 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) __func__, (int) hdr->type, TOKTYPE_NON_CCA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (hdr->hver != 0x00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) DBF("%s key check failed, header version 0x%02x != 0x00\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) __func__, (int) hdr->hver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (hdr->version != TOKVER_EP11_ECC_WITH_HEADER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) DBF("%s key check failed, version 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) __func__, (int) hdr->version, TOKVER_EP11_ECC_WITH_HEADER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (hdr->len > keylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) DBF("%s key check failed, header len %d keylen %zu mismatch\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) __func__, (int) hdr->len, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (hdr->len < sizeof(*hdr) + sizeof(*kb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) DBF("%s key check failed, header len %d < %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) __func__, (int) hdr->len, sizeof(*hdr) + sizeof(*kb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (kb->version != EP11_STRUCT_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) __func__, (int) kb->version, EP11_STRUCT_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) DBF("%s key check failed, PKEY_EXTRACTABLE is off\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) #undef DBF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) EXPORT_SYMBOL(ep11_check_ecc_key_with_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * Simple check if the key blob is a valid EP11 AES key blob with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * the header in the session field (old style EP11 AES key).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) int ep11_check_aes_key(debug_info_t *dbg, int dbflvl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const u8 *key, size_t keylen, int checkcpacfexp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct ep11keyblob *kb = (struct ep11keyblob *) key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (keylen < sizeof(*kb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) DBF("%s key check failed, keylen %zu < %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) __func__, keylen, sizeof(*kb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (kb->head.type != TOKTYPE_NON_CCA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) DBF("%s key check failed, type 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) __func__, (int) kb->head.type, TOKTYPE_NON_CCA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (kb->head.version != TOKVER_EP11_AES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) DBF("%s key check failed, version 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) __func__, (int) kb->head.version, TOKVER_EP11_AES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (kb->head.len > keylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) DBF("%s key check failed, header len %d keylen %zu mismatch\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) __func__, (int) kb->head.len, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (kb->head.len < sizeof(*kb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) DBF("%s key check failed, header len %d < %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) __func__, (int) kb->head.len, sizeof(*kb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (kb->version != EP11_STRUCT_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) DBF("%s key check failed, blob magic 0x%04x != 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) __func__, (int) kb->version, EP11_STRUCT_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (checkcpacfexp && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) DBF("%s key check failed, PKEY_EXTRACTABLE is off\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) #undef DBF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) EXPORT_SYMBOL(ep11_check_aes_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * Allocate and prepare ep11 cprb plus additional payload.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) static inline struct ep11_cprb *alloc_cprb(size_t payload_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) size_t len = sizeof(struct ep11_cprb) + payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct ep11_cprb *cprb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) cprb = kzalloc(len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!cprb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cprb->cprb_len = sizeof(struct ep11_cprb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) cprb->cprb_ver_id = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) memcpy(cprb->func_id, "T4", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cprb->ret_code = 0xFFFFFFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) cprb->payload_len = payload_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return cprb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Some helper functions related to ASN1 encoding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * Limited to length info <= 2 byte.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) #define ASN1TAGLEN(x) (2 + (x) + ((x) > 127 ? 1 : 0) + ((x) > 255 ? 1 : 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) static int asn1tag_write(u8 *ptr, u8 tag, const u8 *pvalue, u16 valuelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) ptr[0] = tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) if (valuelen > 255) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ptr[1] = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) *((u16 *)(ptr + 2)) = valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) memcpy(ptr + 4, pvalue, valuelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 4 + valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (valuelen > 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ptr[1] = 0x81;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ptr[2] = (u8) valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) memcpy(ptr + 3, pvalue, valuelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return 3 + valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) ptr[1] = (u8) valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) memcpy(ptr + 2, pvalue, valuelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return 2 + valuelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* EP11 payload > 127 bytes starts with this struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct pl_head {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) u8 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) u8 lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) u8 func_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u8 func_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) u32 func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u8 dom_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) u8 dom_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) u32 dom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* prep ep11 payload head helper function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static inline void prep_head(struct pl_head *h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) size_t pl_size, int api, int func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) h->tag = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) h->lenfmt = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) h->len = pl_size - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) h->func_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) h->func_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) h->func = (api << 16) + func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) h->dom_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) h->dom_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* prep urb helper function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static inline void prep_urb(struct ep11_urb *u,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) struct ep11_target_dev *t, int nt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct ep11_cprb *req, size_t req_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) struct ep11_cprb *rep, size_t rep_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) u->targets = (u8 __user *) t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u->targets_num = nt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) u->req = (u8 __user *) req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) u->req_len = req_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) u->resp = (u8 __user *) rep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u->resp_len = rep_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Check ep11 reply payload, return 0 or suggested errno value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) static int check_reply_pl(const u8 *pl, const char *func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) u32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* start tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (*pl++ != 0x30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) DEBUG_ERR("%s reply start tag mismatch\n", func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* payload length format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (*pl < 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) len = *pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) pl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) } else if (*pl == 0x81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) pl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) len = *pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) pl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) } else if (*pl == 0x82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) pl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) len = *((u16 *)pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) pl += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) DEBUG_ERR("%s reply start tag lenfmt mismatch 0x%02hhx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) func, *pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /* len should cover at least 3 fields with 32 bit value each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (len < 3 * 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) DEBUG_ERR("%s reply length %d too small\n", func, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* function tag, length and value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (pl[0] != 0x04 || pl[1] != 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) DEBUG_ERR("%s function tag or length mismatch\n", func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) pl += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) /* dom tag, length and value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (pl[0] != 0x04 || pl[1] != 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) DEBUG_ERR("%s dom tag or length mismatch\n", func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) pl += 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) /* return value tag, length and value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (pl[0] != 0x04 || pl[1] != 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) DEBUG_ERR("%s return value tag or length mismatch\n", func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pl += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = *((u32 *)pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) DEBUG_ERR("%s return value 0x%04x != 0\n", func, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * Helper function which does an ep11 query with given query type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) size_t buflen, u8 *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct ep11_info_req_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u8 query_type_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) u8 query_type_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u32 query_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) u8 query_subtype_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) u8 query_subtype_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) u32 query_subtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) } __packed * req_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct ep11_info_rep_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) u8 rc_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u8 rc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) u32 rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u8 data_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u8 data_lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u16 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) } __packed * rep_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) struct ep11_cprb *req = NULL, *rep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct ep11_target_dev target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct ep11_urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int api = 1, rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* request cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) req = alloc_cprb(sizeof(struct ep11_info_req_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) req_pl = (struct ep11_info_req_pl *) (((u8 *) req) + sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) prep_head(&req_pl->head, sizeof(*req_pl), api, 38); /* get xcp info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) req_pl->query_type_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) req_pl->query_type_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) req_pl->query_type = query_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) req_pl->query_subtype_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) req_pl->query_subtype_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* reply cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) rep_pl = (struct ep11_info_rep_pl *) (((u8 *) rep) + sizeof(*rep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* urb and target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) target.ap_id = cardnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) target.dom_id = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) prep_urb(urb, &target, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) req, sizeof(*req) + sizeof(*req_pl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) rc = zcrypt_send_ep11_cprb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) rc = check_reply_pl((u8 *)rep_pl, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) DEBUG_ERR("%s unknown reply data format\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (rep_pl->data_len > buflen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) DEBUG_ERR("%s mismatch between reply data len and buffer len\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) rc = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) memcpy(buf, ((u8 *) rep_pl) + sizeof(*rep_pl), rep_pl->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) kfree(rep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) kfree(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * Provide information about an EP11 card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct ep11_module_query_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) u32 API_ord_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) u32 firmware_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) u8 FW_major_vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) u8 FW_minor_vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) u8 CSP_major_vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) u8 CSP_minor_vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) u8 fwid[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) u8 xcp_config_hash[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) u8 CSP_config_hash[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) u8 serial[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) u8 module_date_time[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) u64 op_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) u32 PKCS11_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) u32 ext_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) u32 domains;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) u32 sym_state_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) u32 digest_state_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) u32 pin_blob_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) u32 SPKI_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) u32 priv_key_blob_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) u32 sym_blob_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) u32 max_payload_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) u32 CP_profile_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) u32 max_CP_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) } __packed * pmqi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) rc = card_cache_fetch(card, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (rc || verify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (!pmqi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) rc = ep11_query_info(card, AUTOSEL_DOM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 0x01 /* module info query */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) sizeof(*pmqi), (u8 *) pmqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (rc == -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) card_cache_scrub(card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) memset(info, 0, sizeof(*info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) info->API_ord_nr = pmqi->API_ord_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) info->FW_version =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) (pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) memcpy(info->serial, pmqi->serial, sizeof(info->serial));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) info->op_mode = pmqi->op_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) card_cache_update(card, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) kfree(pmqi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) EXPORT_SYMBOL(ep11_get_card_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * Provide information about a domain within an EP11 card.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct ep11_domain_query_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) u32 dom_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) u8 cur_WK_VP[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) u8 new_WK_VP[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) u32 dom_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) u64 op_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) } __packed * p_dom_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (!p_dom_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) rc = ep11_query_info(card, domain, 0x03 /* domain info query */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) sizeof(*p_dom_info), (u8 *) p_dom_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) memset(info, 0, sizeof(*info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) info->cur_wk_state = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) info->new_wk_state = '0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) if (p_dom_info->dom_flags & 0x10 /* left imprint mode */) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (p_dom_info->dom_flags & 0x02 /* cur wk valid */) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) info->cur_wk_state = '1';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) memcpy(info->cur_wkvp, p_dom_info->cur_WK_VP, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (p_dom_info->dom_flags & 0x04 /* new wk present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) || p_dom_info->dom_flags & 0x08 /* new wk committed */) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) info->new_wk_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) p_dom_info->dom_flags & 0x08 ? '2' : '1';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) memcpy(info->new_wkvp, p_dom_info->new_WK_VP, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) info->op_mode = p_dom_info->op_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) kfree(p_dom_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) EXPORT_SYMBOL(ep11_get_domain_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * Default EP11 AES key generate attributes, used when no keygenflags given:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * XCP_BLOB_ENCRYPT | XCP_BLOB_DECRYPT | XCP_BLOB_PROTKEY_EXTRACTABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) #define KEY_ATTR_DEFAULTS 0x00200c00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) u8 *keybuf, size_t *keybufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) struct keygen_req_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) u8 var_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) u8 var_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) u32 var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) u8 keybytes_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) u8 keybytes_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) u32 keybytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) u8 mech_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) u8 mech_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) u32 mech;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) u8 attr_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) u8 attr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) u32 attr_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) u32 attr_bool_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) u32 attr_bool_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) u32 attr_val_len_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) u32 attr_val_len_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) u8 pin_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) u8 pin_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) } __packed * req_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct keygen_rep_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) u8 rc_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) u8 rc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) u32 rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) u8 data_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) u8 data_lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) u16 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) u8 data[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) } __packed * rep_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct ep11_cprb *req = NULL, *rep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct ep11_target_dev target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct ep11_urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct ep11keyblob *kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int api, rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) switch (keybitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case 128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) case 192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) case 256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) "%s unknown/unsupported keybitsize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) __func__, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) /* request cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) req = alloc_cprb(sizeof(struct keygen_req_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) req_pl = (struct keygen_req_pl *) (((u8 *) req) + sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) prep_head(&req_pl->head, sizeof(*req_pl), api, 21); /* GenerateKey */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) req_pl->var_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) req_pl->var_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) req_pl->keybytes_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) req_pl->keybytes_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) req_pl->keybytes = keybitsize / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) req_pl->mech_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) req_pl->mech_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) req_pl->mech = 0x00001080; /* CKM_AES_KEY_GEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) req_pl->attr_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) req_pl->attr_len = 5 * sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) req_pl->attr_header = 0x10010000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) req_pl->attr_val_len_type = 0x00000161; /* CKA_VALUE_LEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) req_pl->attr_val_len_value = keybitsize / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) req_pl->pin_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /* reply cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) rep = alloc_cprb(sizeof(struct keygen_rep_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) rep_pl = (struct keygen_rep_pl *) (((u8 *) rep) + sizeof(*rep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* urb and target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) target.ap_id = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) target.dom_id = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) prep_urb(urb, &target, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) req, sizeof(*req) + sizeof(*req_pl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) rep, sizeof(*rep) + sizeof(*rep_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) rc = zcrypt_send_ep11_cprb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) __func__, (int) card, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) rc = check_reply_pl((u8 *)rep_pl, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) DEBUG_ERR("%s unknown reply data format\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (rep_pl->data_len > *keybufsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) DEBUG_ERR("%s mismatch reply data len / key buffer len\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) rc = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* copy key blob and set header values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) memcpy(keybuf, rep_pl->data, rep_pl->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) *keybufsize = rep_pl->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) kb = (struct ep11keyblob *) keybuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) kb->head.type = TOKTYPE_NON_CCA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) kb->head.len = rep_pl->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) kb->head.version = TOKVER_EP11_AES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) kb->head.keybitlen = keybitsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) kfree(rep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) kfree(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) EXPORT_SYMBOL(ep11_genaeskey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static int ep11_cryptsingle(u16 card, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) u16 mode, u32 mech, const u8 *iv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) const u8 *key, size_t keysize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) const u8 *inbuf, size_t inbufsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) u8 *outbuf, size_t *outbufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) struct crypt_req_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) u8 var_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) u8 var_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) u32 var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) u8 mech_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) u8 mech_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) u32 mech;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * maybe followed by iv data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * followed by key tag + key blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * followed by plaintext tag + plaintext
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) } __packed * req_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct crypt_rep_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) u8 rc_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) u8 rc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) u32 rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) u8 data_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) u8 data_lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /* data follows */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) } __packed * rep_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) struct ep11_cprb *req = NULL, *rep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) struct ep11_target_dev target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct ep11_urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) size_t req_pl_size, rep_pl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) int n, api = 1, rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /* the simple asn1 coding used has length limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (keysize > 0xFFFF || inbufsize > 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* request cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) req_pl_size = sizeof(struct crypt_req_pl) + (iv ? 16 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) + ASN1TAGLEN(keysize) + ASN1TAGLEN(inbufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) req = alloc_cprb(req_pl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) req_pl = (struct crypt_req_pl *) (((u8 *) req) + sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) prep_head(&req_pl->head, req_pl_size, api, (mode ? 20 : 19));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) req_pl->var_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) req_pl->var_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* mech is mech + mech params (iv here) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) req_pl->mech_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) p = ((u8 *) req_pl) + sizeof(*req_pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (iv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) memcpy(p, iv, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) p += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* key and input data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) p += asn1tag_write(p, 0x04, key, keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) p += asn1tag_write(p, 0x04, inbuf, inbufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* reply cprb and payload, assume out data size <= in data size + 32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) rep_pl_size = sizeof(struct crypt_rep_pl) + ASN1TAGLEN(inbufsize + 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) rep = alloc_cprb(rep_pl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) rep_pl = (struct crypt_rep_pl *) (((u8 *) rep) + sizeof(*rep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* urb and target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) target.ap_id = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) target.dom_id = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) prep_urb(urb, &target, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) req, sizeof(*req) + req_pl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) rep, sizeof(*rep) + rep_pl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) rc = zcrypt_send_ep11_cprb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) __func__, (int) card, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) rc = check_reply_pl((u8 *)rep_pl, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (rep_pl->data_tag != 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) DEBUG_ERR("%s unknown reply data format\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) p = ((u8 *) rep_pl) + sizeof(*rep_pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (rep_pl->data_lenfmt <= 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) n = rep_pl->data_lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) else if (rep_pl->data_lenfmt == 0x81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) n = *p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) else if (rep_pl->data_lenfmt == 0x82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) n = *((u16 *) p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) DEBUG_ERR("%s unknown reply data length format 0x%02hhx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) __func__, rep_pl->data_lenfmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (n > *outbufsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) DEBUG_ERR("%s mismatch reply data len %d / output buffer %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) __func__, n, *outbufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) rc = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) memcpy(outbuf, p, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) *outbufsize = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) kfree(rep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) kfree(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) static int ep11_unwrapkey(u16 card, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) const u8 *kek, size_t keksize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) const u8 *enckey, size_t enckeysize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) u32 mech, const u8 *iv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) u32 keybitsize, u32 keygenflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) u8 *keybuf, size_t *keybufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct uw_req_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) u8 attr_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) u8 attr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) u32 attr_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) u32 attr_bool_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) u32 attr_bool_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) u32 attr_key_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) u32 attr_key_type_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) u32 attr_val_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) u32 attr_val_len_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) u8 mech_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) u8 mech_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) u32 mech;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * maybe followed by iv data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * followed by kek tag + kek blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * followed by empty mac tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * followed by empty pin tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) * followed by encryted key tag + bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) } __packed * req_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct uw_rep_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) u8 rc_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) u8 rc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) u32 rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) u8 data_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) u8 data_lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) u16 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) u8 data[512];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) } __packed * rep_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) struct ep11_cprb *req = NULL, *rep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) struct ep11_target_dev target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) struct ep11_urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct ep11keyblob *kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) size_t req_pl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) int api, rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) /* request cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) + ASN1TAGLEN(keksize) + 4 + ASN1TAGLEN(enckeysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) req = alloc_cprb(req_pl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) req_pl = (struct uw_req_pl *) (((u8 *) req) + sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) prep_head(&req_pl->head, req_pl_size, api, 34); /* UnwrapKey */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) req_pl->attr_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) req_pl->attr_len = 7 * sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) req_pl->attr_header = 0x10020000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) req_pl->attr_key_type = 0x00000100; /* CKA_KEY_TYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) req_pl->attr_key_type_value = 0x0000001f; /* CKK_AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) req_pl->attr_val_len = 0x00000161; /* CKA_VALUE_LEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) req_pl->attr_val_len_value = keybitsize / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /* mech is mech + mech params (iv here) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) req_pl->mech_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) p = ((u8 *) req_pl) + sizeof(*req_pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (iv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) memcpy(p, iv, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) p += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) /* kek */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) p += asn1tag_write(p, 0x04, kek, keksize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /* empty mac key tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) *p++ = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* empty pin tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) *p++ = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* encrypted key value tag and bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) p += asn1tag_write(p, 0x04, enckey, enckeysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /* reply cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) rep = alloc_cprb(sizeof(struct uw_rep_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) rep_pl = (struct uw_rep_pl *) (((u8 *) rep) + sizeof(*rep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* urb and target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) target.ap_id = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) target.dom_id = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) prep_urb(urb, &target, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) req, sizeof(*req) + req_pl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) rep, sizeof(*rep) + sizeof(*rep_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) rc = zcrypt_send_ep11_cprb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) __func__, (int) card, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) rc = check_reply_pl((u8 *)rep_pl, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) DEBUG_ERR("%s unknown reply data format\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (rep_pl->data_len > *keybufsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) DEBUG_ERR("%s mismatch reply data len / key buffer len\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) rc = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /* copy key blob and set header values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) memcpy(keybuf, rep_pl->data, rep_pl->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) *keybufsize = rep_pl->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) kb = (struct ep11keyblob *) keybuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) kb->head.type = TOKTYPE_NON_CCA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) kb->head.len = rep_pl->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) kb->head.version = TOKVER_EP11_AES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) kb->head.keybitlen = keybitsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) kfree(rep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) kfree(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static int ep11_wrapkey(u16 card, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) const u8 *key, size_t keysize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) u32 mech, const u8 *iv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) u8 *databuf, size_t *datasize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct wk_req_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) u8 var_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) u8 var_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) u32 var;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) u8 mech_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) u8 mech_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) u32 mech;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * followed by iv data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * followed by key tag + key blob
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) * followed by dummy kek param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * followed by dummy mac param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) } __packed * req_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct wk_rep_pl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct pl_head head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) u8 rc_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) u8 rc_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) u32 rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) u8 data_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) u8 data_lenfmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) u16 data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) u8 data[1024];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) } __packed * rep_pl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) struct ep11_cprb *req = NULL, *rep = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) struct ep11_target_dev target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) struct ep11_urb *urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct ep11keyblob *kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) size_t req_pl_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) int api, rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) bool has_header = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* maybe the session field holds a header with key info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) kb = (struct ep11keyblob *) key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (kb->head.type == TOKTYPE_NON_CCA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) kb->head.version == TOKVER_EP11_AES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) has_header = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) keysize = kb->head.len < keysize ? kb->head.len : keysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* request cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) + ASN1TAGLEN(keysize) + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) req = alloc_cprb(req_pl_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (!req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (!mech || mech == 0x80060001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) req->flags |= 0x20; /* CPACF_WRAP needs special bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) req_pl = (struct wk_req_pl *) (((u8 *) req) + sizeof(*req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) api = (!mech || mech == 0x80060001) ? 4 : 1; /* CKM_IBM_CPACF_WRAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) prep_head(&req_pl->head, req_pl_size, api, 33); /* WrapKey */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) req_pl->var_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) req_pl->var_len = sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /* mech is mech + mech params (iv here) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) req_pl->mech_tag = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) req_pl->mech = (mech ? mech : 0x80060001); /* CKM_IBM_CPACF_WRAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) p = ((u8 *) req_pl) + sizeof(*req_pl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (iv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) memcpy(p, iv, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) p += 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /* key blob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) p += asn1tag_write(p, 0x04, key, keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) /* maybe the key argument needs the head data cleaned out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (has_header) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) kb = (struct ep11keyblob *)(p - keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) memset(&kb->head, 0, sizeof(kb->head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /* empty kek tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) *p++ = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) /* empty mac tag */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) *p++ = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) *p++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) /* reply cprb and payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) rep = alloc_cprb(sizeof(struct wk_rep_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) rep_pl = (struct wk_rep_pl *) (((u8 *) rep) + sizeof(*rep));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) /* urb and target */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) if (!urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) target.ap_id = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) target.dom_id = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) prep_urb(urb, &target, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) req, sizeof(*req) + req_pl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) rep, sizeof(*rep) + sizeof(*rep_pl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) rc = zcrypt_send_ep11_cprb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) __func__, (int) card, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) rc = check_reply_pl((u8 *)rep_pl, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) DEBUG_ERR("%s unknown reply data format\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (rep_pl->data_len > *datasize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) DEBUG_ERR("%s mismatch reply data len / data buffer len\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) rc = -ENOSPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* copy the data from the cprb to the data buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) memcpy(databuf, rep_pl->data, rep_pl->data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) *datasize = rep_pl->data_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) kfree(req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) kfree(rep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) kfree(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) struct ep11keyblob *kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) u8 encbuf[64], *kek = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (keybitsize == 128 || keybitsize == 192 || keybitsize == 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) clrkeylen = keybitsize / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) "%s unknown/unsupported keybitsize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) __func__, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /* allocate memory for the temp kek */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) keklen = MAXEP11AESKEYBLOBSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) kek = kmalloc(keklen, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) if (!kek) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) /* Step 1: generate AES 256 bit random kek key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) rc = ep11_genaeskey(card, domain, 256,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 0x00006c00, /* EN/DECRYPT, WRAP/UNWRAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) kek, &keklen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) "%s generate kek key failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) kb = (struct ep11keyblob *) kek;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) memset(&kb->head, 0, sizeof(kb->head));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) /* Step 2: encrypt clear key value with the kek key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) clrkey, clrkeylen, encbuf, &encbuflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) "%s encrypting key value with kek key failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) /* Step 3: import the encrypted key value as a new key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) rc = ep11_unwrapkey(card, domain, kek, keklen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) encbuf, encbuflen, 0, def_iv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) keybitsize, 0, keybuf, keybufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) "%s importing key value as new key failed,, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) kfree(kek);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) EXPORT_SYMBOL(ep11_clr2keyblob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) int ep11_kblob2protkey(u16 card, u16 dom, const u8 *keyblob, size_t keybloblen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) u8 *protkey, u32 *protkeylen, u32 *protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) int rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) u8 *wkbuf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) size_t wkbuflen, keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct wk_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) u16 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) u8 res1[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) u32 pkeytype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) u32 pkeybitsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) u64 pkeysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) u8 res2[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) u8 pkey[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) } __packed * wki;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) const u8 *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) struct ep11kblob_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /* key with or without header ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) hdr = (struct ep11kblob_header *) keyblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (hdr->type == TOKTYPE_NON_CCA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) && (hdr->version == TOKVER_EP11_AES_WITH_HEADER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) || hdr->version == TOKVER_EP11_ECC_WITH_HEADER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) && is_ep11_keyblob(keyblob + sizeof(struct ep11kblob_header))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) /* EP11 AES or ECC key with header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) key = keyblob + sizeof(struct ep11kblob_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) keylen = hdr->len - sizeof(struct ep11kblob_header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) } else if (hdr->type == TOKTYPE_NON_CCA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) && hdr->version == TOKVER_EP11_AES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) && is_ep11_keyblob(keyblob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* EP11 AES key (old style) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) key = keyblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) keylen = hdr->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) } else if (is_ep11_keyblob(keyblob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) /* raw EP11 key blob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) key = keyblob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) keylen = keybloblen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) /* alloc temp working buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) wkbuflen = (keylen + AES_BLOCK_SIZE) & (~(AES_BLOCK_SIZE - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) wkbuf = kmalloc(wkbuflen, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (!wkbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) /* ep11 secure key -> protected key + info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) rc = ep11_wrapkey(card, dom, key, keylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 0, def_iv, wkbuf, &wkbuflen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) "%s rewrapping ep11 key to pkey failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) wki = (struct wk_info *) wkbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /* check struct version and pkey type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (wki->version != 1 || wki->pkeytype < 1 || wki->pkeytype > 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) DEBUG_ERR("%s wk info version %d or pkeytype %d mismatch.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) __func__, (int) wki->version, (int) wki->pkeytype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) /* check protected key type field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) switch (wki->pkeytype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) case 1: /* AES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) switch (wki->pkeysize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) case 16+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) /* AES 128 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) *protkeytype = PKEY_KEYTYPE_AES_128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) case 24+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /* AES 192 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) *protkeytype = PKEY_KEYTYPE_AES_192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) case 32+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /* AES 256 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) *protkeytype = PKEY_KEYTYPE_AES_256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) DEBUG_ERR("%s unknown/unsupported AES pkeysize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) __func__, (int) wki->pkeysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) case 3: /* EC-P */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) case 4: /* EC-ED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) case 5: /* EC-BP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) *protkeytype = PKEY_KEYTYPE_ECC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) case 2: /* TDES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) DEBUG_ERR("%s unknown/unsupported key type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) __func__, (int) wki->pkeytype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) /* copy the tanslated protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (wki->pkeysize > *protkeylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) DEBUG_ERR("%s wk info pkeysize %llu > protkeysize %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) __func__, wki->pkeysize, *protkeylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) memcpy(protkey, wki->pkey, wki->pkeysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) *protkeylen = wki->pkeysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) kfree(wkbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) EXPORT_SYMBOL(ep11_kblob2protkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) int minhwtype, int minapi, const u8 *wkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) struct zcrypt_device_status_ext *device_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) u32 *_apqns = NULL, _nr_apqns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) int i, card, dom, rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct ep11_domain_info edi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) struct ep11_card_info eci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) /* fetch status of all crypto cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) sizeof(struct zcrypt_device_status_ext),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (!device_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) zcrypt_device_status_mask_ext(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) /* allocate 1k space for up to 256 apqns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (!_apqns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) kvfree(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) /* walk through all the crypto apqnss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) card = AP_QID_CARD(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) dom = AP_QID_QUEUE(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* check online state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) if (!device_status[i].online)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /* check for ep11 functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) if (!(device_status[i].functions & 0x01))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* check cardnr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) if (cardnr != 0xFFFF && card != cardnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /* check domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (domain != 0xFFFF && dom != domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) /* check min hardware type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) if (minhwtype && device_status[i].hwtype < minhwtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /* check min api version if given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) if (minapi > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (ep11_get_card_info(card, &eci, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (minapi > eci.API_ord_nr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /* check wkvp if given */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (wkvp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) if (ep11_get_domain_info(card, dom, &edi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (edi.cur_wk_state != '1')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) if (memcmp(wkvp, edi.cur_wkvp, 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /* apqn passed all filtering criterons, add to the array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (_nr_apqns < 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16) dom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) /* nothing found ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (!_nr_apqns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) kfree(_apqns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) /* no re-allocation, simple return the _apqns array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) *apqns = _apqns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) *nr_apqns = _nr_apqns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) kvfree(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) EXPORT_SYMBOL(ep11_findcard2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) void __exit zcrypt_ep11misc_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) card_cache_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) }