^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) * Ingo Franzki <ifranzki@linux.ibm.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Collection of CCA misc functions used by zcrypt and pkey
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define KMSG_COMPONENT "zcrypt"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/random.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/zcrypt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/pkey.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_ccamisc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define DEBUG_DBG(...) ZCRYPT_DBF(DBF_DEBUG, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define DEBUG_INFO(...) ZCRYPT_DBF(DBF_INFO, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* Size of parameter block used for all cca requests/replies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define PARMBSIZE 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* Size of vardata block used for some of the cca requests/replies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define VARDATASIZE 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct cca_info_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) u16 domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct cca_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /* a list with cca_info_list_entry entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static LIST_HEAD(cca_info_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static DEFINE_SPINLOCK(cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * Simple check if the token is a valid CCA secure AES data key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * token. If keybitsize is given, the bitsize of the key is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * also checked. Returns 0 on success or errno value on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int cca_check_secaeskeytoken(debug_info_t *dbg, int dbflvl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) const u8 *token, int keybitsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) struct secaeskeytoken *t = (struct secaeskeytoken *) token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (t->type != TOKTYPE_CCA_INTERNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) DBF("%s token check failed, type 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) __func__, (int) t->type, TOKTYPE_CCA_INTERNAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (t->version != TOKVER_CCA_AES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) DBF("%s token check failed, version 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __func__, (int) t->version, TOKVER_CCA_AES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (keybitsize > 0 && t->bitsize != keybitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) DBF("%s token check failed, bitsize %d != %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) __func__, (int) t->bitsize, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #undef DBF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) EXPORT_SYMBOL(cca_check_secaeskeytoken);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * Simple check if the token is a valid CCA secure AES cipher key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * token. If keybitsize is given, the bitsize of the key is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * also checked. If checkcpacfexport is enabled, the key is also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * checked for the export flag to allow CPACF export.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Returns 0 on success or errno value on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) int cca_check_secaescipherkey(debug_info_t *dbg, int dbflvl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) const u8 *token, int keybitsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int checkcpacfexport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct cipherkeytoken *t = (struct cipherkeytoken *) token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) bool keybitsizeok = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (t->type != TOKTYPE_CCA_INTERNAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) DBF("%s token check failed, type 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) __func__, (int) t->type, TOKTYPE_CCA_INTERNAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (t->version != TOKVER_CCA_VLSC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) DBF("%s token check failed, version 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) __func__, (int) t->version, TOKVER_CCA_VLSC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (t->algtype != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) DBF("%s token check failed, algtype 0x%02x != 0x02\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) __func__, (int) t->algtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (t->keytype != 0x0001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) DBF("%s token check failed, keytype 0x%04x != 0x0001\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) __func__, (int) t->keytype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (t->plfver != 0x00 && t->plfver != 0x01) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) DBF("%s token check failed, unknown plfver 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) __func__, (int) t->plfver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (t->wpllen != 512 && t->wpllen != 576 && t->wpllen != 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) DBF("%s token check failed, unknown wpllen %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) __func__, (int) t->wpllen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (keybitsize > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) switch (keybitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case 128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (t->wpllen != (t->plfver ? 640 : 512))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) keybitsizeok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case 192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (t->wpllen != (t->plfver ? 640 : 576))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) keybitsizeok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case 256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (t->wpllen != 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) keybitsizeok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) keybitsizeok = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (!keybitsizeok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) DBF("%s token check failed, bitsize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) __func__, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (checkcpacfexport && !(t->kmf1 & KMF1_XPRT_CPAC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) DBF("%s token check failed, XPRT_CPAC bit is 0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #undef DBF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) EXPORT_SYMBOL(cca_check_secaescipherkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Simple check if the token is a valid CCA secure ECC private
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * key token. Returns 0 on success or errno value on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) int cca_check_sececckeytoken(debug_info_t *dbg, int dbflvl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) const u8 *token, size_t keysize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int checkcpacfexport)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct eccprivkeytoken *t = (struct eccprivkeytoken *) token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (t->type != TOKTYPE_CCA_INTERNAL_PKA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) DBF("%s token check failed, type 0x%02x != 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) __func__, (int) t->type, TOKTYPE_CCA_INTERNAL_PKA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (t->len > keysize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) DBF("%s token check failed, len %d > keysize %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) __func__, (int) t->len, keysize);
^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) if (t->secid != 0x20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) DBF("%s token check failed, secid 0x%02x != 0x20\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) __func__, (int) t->secid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (checkcpacfexport && !(t->kutc & 0x01)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (dbg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) DBF("%s token check failed, XPRTCPAC bit is 0\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #undef DBF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) EXPORT_SYMBOL(cca_check_sececckeytoken);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Allocate consecutive memory for request CPRB, request param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * block, reply CPRB and reply param block and fill in values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * for the common fields. Returns 0 on success or errno value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) static int alloc_and_prep_cprbmem(size_t paramblen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) u8 **pcprbmem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct CPRBX **preqCPRB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) struct CPRBX **prepCPRB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) u8 *cprbmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * allocate consecutive memory for request CPRB, request param
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * block, reply CPRB and reply param block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) cprbmem = kcalloc(2, cprbplusparamblen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!cprbmem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) preqcblk = (struct CPRBX *) cprbmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) prepcblk = (struct CPRBX *) (cprbmem + cprbplusparamblen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) preqcblk->cprb_len = sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) preqcblk->cprb_ver_id = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) memcpy(preqcblk->func_id, "T2", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) preqcblk->rpl_msgbl = cprbplusparamblen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (paramblen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) preqcblk->req_parmb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ((u8 __user *) preqcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) preqcblk->rpl_parmb =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ((u8 __user *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) *pcprbmem = cprbmem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) *preqCPRB = preqcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *prepCPRB = prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * Free the cprb memory allocated with the function above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * If the scrub value is not zero, the memory is filled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * with zeros before freeing (useful if there was some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * clear key material in there).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void free_cprbmem(void *mem, size_t paramblen, int scrub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (scrub)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) kfree(mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * Helper function to prepare the xcrb struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static inline void prep_xcrb(struct ica_xcRB *pxcrb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u16 cardnr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct CPRBX *preqcblk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct CPRBX *prepcblk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) memset(pxcrb, 0, sizeof(*pxcrb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) pxcrb->agent_ID = 0x4341; /* 'CA' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) pxcrb->user_defined = (cardnr == 0xFFFF ? AUTOSELECT : cardnr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) pxcrb->request_control_blk_length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) preqcblk->cprb_len + preqcblk->req_parml;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) pxcrb->request_control_blk_addr = (void __user *) preqcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) pxcrb->reply_control_blk_length = preqcblk->rpl_msgbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) pxcrb->reply_control_blk_addr = (void __user *) prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Generate (random) CCA AES DATA secure key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) int cca_genseckey(u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 keybitsize, u8 seckey[SECKEYBLOBSIZE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int i, rc, keysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int seckeysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct kgreqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct lv1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) char key_form[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) char key_length[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) char key_type1[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) char key_type2[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) } lv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct lv2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) struct keyid {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u16 attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) u8 data[SECKEYBLOBSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) } keyid[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) } lv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct kgrepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) struct lv3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u16 keyblocklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u16 toklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) u16 tokattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) u8 tok[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) /* ... some more data ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) } keyblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) } lv3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* fill request cprb param block with KG request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) preqparm = (struct kgreqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) memcpy(preqparm->subfunc_code, "KG", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) preqparm->rule_array_len = sizeof(preqparm->rule_array_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) preqparm->lv1.len = sizeof(struct lv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) memcpy(preqparm->lv1.key_form, "OP ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) switch (keybitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) case PKEY_SIZE_AES_128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) case PKEY_KEYTYPE_AES_128: /* older ioctls used this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) keysize = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) memcpy(preqparm->lv1.key_length, "KEYLN16 ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) case PKEY_SIZE_AES_192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case PKEY_KEYTYPE_AES_192: /* older ioctls used this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) keysize = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) memcpy(preqparm->lv1.key_length, "KEYLN24 ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) case PKEY_SIZE_AES_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) case PKEY_KEYTYPE_AES_256: /* older ioctls used this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) keysize = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) memcpy(preqparm->lv1.key_length, "KEYLN32 ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) DEBUG_ERR("%s unknown/unsupported keybitsize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) __func__, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) memcpy(preqparm->lv1.key_type1, "AESDATA ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) preqparm->lv2.len = sizeof(struct lv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) for (i = 0; i < 6; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) preqparm->lv2.keyid[i].len = sizeof(struct keyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) preqparm->lv2.keyid[i].attr = (i == 2 ? 0x30 : 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) preqcblk->req_parml = sizeof(struct kgreqparm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* fill xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, errno %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) DEBUG_ERR("%s secure key generate failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) prepparm = (struct kgrepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) /* check length of the returned secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) seckeysize = prepparm->lv3.keyblock.toklen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) - sizeof(prepparm->lv3.keyblock.toklen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) - sizeof(prepparm->lv3.keyblock.tokattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (seckeysize != SECKEYBLOBSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) DEBUG_ERR("%s secure token size mismatch %d != %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) __func__, seckeysize, SECKEYBLOBSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* check secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rc = cca_check_secaeskeytoken(zcrypt_dbf_info, DBF_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) prepparm->lv3.keyblock.tok, 8*keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* copy the generated secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) free_cprbmem(mem, PARMBSIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) EXPORT_SYMBOL(cca_genseckey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) * Generate an CCA AES DATA secure key with given key value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) int cca_clr2seckey(u16 cardnr, u16 domain, u32 keybitsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) const u8 *clrkey, u8 seckey[SECKEYBLOBSIZE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) int rc, keysize, seckeysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct cmreqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) char rule_array[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) struct lv1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) u8 clrkey[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) } lv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) struct lv2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) struct keyid {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) u16 attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) u8 data[SECKEYBLOBSIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) } keyid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) } lv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) struct lv2 *plv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct cmrepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct lv3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u16 keyblocklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) u16 toklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u16 tokattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u8 tok[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) /* ... some more data ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) } keyblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) } lv3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /* fill request cprb param block with CM request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) preqparm = (struct cmreqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) memcpy(preqparm->subfunc_code, "CM", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) memcpy(preqparm->rule_array, "AES ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) preqparm->rule_array_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) switch (keybitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) case PKEY_SIZE_AES_128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) case PKEY_KEYTYPE_AES_128: /* older ioctls used this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) keysize = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) case PKEY_SIZE_AES_192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) case PKEY_KEYTYPE_AES_192: /* older ioctls used this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) keysize = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) case PKEY_SIZE_AES_256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) case PKEY_KEYTYPE_AES_256: /* older ioctls used this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) keysize = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) DEBUG_ERR("%s unknown/unsupported keybitsize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) __func__, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) preqparm->lv1.len = sizeof(struct lv1) + keysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) memcpy(preqparm->lv1.clrkey, clrkey, keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) plv2 = (struct lv2 *) (((u8 *) &preqparm->lv2) + keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) plv2->len = sizeof(struct lv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) plv2->keyid.len = sizeof(struct keyid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) plv2->keyid.attr = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) preqcblk->req_parml = sizeof(struct cmreqparm) + keysize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* fill xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) DEBUG_ERR("%s clear key import failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) prepparm = (struct cmrepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* check length of the returned secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) seckeysize = prepparm->lv3.keyblock.toklen
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) - sizeof(prepparm->lv3.keyblock.toklen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) - sizeof(prepparm->lv3.keyblock.tokattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (seckeysize != SECKEYBLOBSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) DEBUG_ERR("%s secure token size mismatch %d != %d bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) __func__, seckeysize, SECKEYBLOBSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /* check secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) rc = cca_check_secaeskeytoken(zcrypt_dbf_info, DBF_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) prepparm->lv3.keyblock.tok, 8*keysize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* copy the generated secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (seckey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) memcpy(seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) free_cprbmem(mem, PARMBSIZE, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) EXPORT_SYMBOL(cca_clr2seckey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * Derive proteced key from an CCA AES DATA secure key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int cca_sec2protkey(u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) const u8 seckey[SECKEYBLOBSIZE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) u8 *protkey, u32 *protkeylen, u32 *protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct uskreqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct lv1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) u16 attr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) u16 attr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) } lv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) struct lv2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) u16 attr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) u16 attr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) u8 token[0]; /* cca secure key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) } lv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct uskrepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct lv3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) u16 attr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) u16 attr_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct cpacfkeyblock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u8 version; /* version of this struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) u8 flags[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) u8 algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) u8 form;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) u8 pad1[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) u8 key[64]; /* the key (len bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) u16 keyattrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) u8 keyattr[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) u8 pad2[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) u8 vptype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) u8 vp[32]; /* verification pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) } ckb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) } lv3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* fill request cprb param block with USK request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) preqparm = (struct uskreqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) memcpy(preqparm->subfunc_code, "US", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) preqparm->rule_array_len = sizeof(preqparm->rule_array_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) preqparm->lv1.len = sizeof(struct lv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) preqparm->lv1.attr_len = sizeof(struct lv1) - sizeof(preqparm->lv1.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) preqparm->lv1.attr_flags = 0x0001;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) preqparm->lv2.len = sizeof(struct lv2) + SECKEYBLOBSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) preqparm->lv2.attr_len = sizeof(struct lv2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) - sizeof(preqparm->lv2.len) + SECKEYBLOBSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) preqparm->lv2.attr_flags = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) memcpy(preqparm->lv2.token, seckey, SECKEYBLOBSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) preqcblk->req_parml = sizeof(struct uskreqparm) + SECKEYBLOBSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) /* fill xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) DEBUG_ERR("%s unwrap secure key failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (prepcblk->ccp_rscode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) DEBUG_WARN("%s unwrap secure key warning, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) prepparm = (struct uskrepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* check the returned keyblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (prepparm->lv3.ckb.version != 0x01 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) prepparm->lv3.ckb.version != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) __func__, (int) prepparm->lv3.ckb.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* copy the tanslated protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) switch (prepparm->lv3.ckb.len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) case 16+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* AES 128 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) *protkeytype = PKEY_KEYTYPE_AES_128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) case 24+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /* AES 192 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) *protkeytype = PKEY_KEYTYPE_AES_192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case 32+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* AES 256 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) *protkeytype = PKEY_KEYTYPE_AES_256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) DEBUG_ERR("%s unknown/unsupported keylen %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) __func__, prepparm->lv3.ckb.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) memcpy(protkey, prepparm->lv3.ckb.key, prepparm->lv3.ckb.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) if (protkeylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) *protkeylen = prepparm->lv3.ckb.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) free_cprbmem(mem, PARMBSIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) EXPORT_SYMBOL(cca_sec2protkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * AES cipher key skeleton created with CSNBKTB2 with these flags:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * INTERNAL, NO-KEY, AES, CIPHER, ANY-MODE, NOEX-SYM, NOEXAASY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * NOEXUASY, XPRTCPAC, NOEX-RAW, NOEX-DES, NOEX-AES, NOEX-RSA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * used by cca_gencipherkey() and cca_clr2cipherkey().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static const u8 aes_cipher_key_skeleton[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 0x01, 0x00, 0x00, 0x38, 0x05, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 0x00, 0x02, 0x00, 0x01, 0x02, 0xc0, 0x00, 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 0x00, 0x03, 0x08, 0xc8, 0x00, 0x00, 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) #define SIZEOF_SKELETON (sizeof(aes_cipher_key_skeleton))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * Generate (random) CCA AES CIPHER secure key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int cca_gencipherkey(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) u8 *keybuf, size_t *keybufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct gkreqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) char rule_array[2*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) u8 key_type_1[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) u8 key_type_2[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) u16 clear_key_bit_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) u16 key_name_1_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) u16 key_name_2_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) u16 user_data_1_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u16 user_data_2_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) u8 key_name_1[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) u8 key_name_2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) u8 user_data_1[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) u8 user_data_2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) u8 kek_id_1[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) } tlv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) u8 kek_id_2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) } tlv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) u8 gen_key_id_1[SIZEOF_SKELETON];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) } tlv3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) u8 gen_key_id_1_label[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) } tlv4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) u8 gen_key_id_2[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) } tlv5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) u8 gen_key_id_2_label[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) } tlv6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct gkrepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) u16 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) u8 gen_key[0]; /* 120-136 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) } tlv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct cipherkeytoken *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) preqcblk->req_parml = sizeof(struct gkreqparm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* prepare request param block with GK request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) preqparm = (struct gkreqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) memcpy(preqparm->subfunc_code, "GK", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) preqparm->rule_array_len = sizeof(uint16_t) + 2 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) memcpy(preqparm->rule_array, "AES OP ", 2*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /* prepare vud block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) preqparm->vud.len = sizeof(preqparm->vud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) switch (keybitsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case 128:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) case 192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case 256:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) "%s unknown/unsupported keybitsize %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) __func__, keybitsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) preqparm->vud.clear_key_bit_len = keybitsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) memcpy(preqparm->vud.key_type_1, "TOKEN ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) memset(preqparm->vud.key_type_2, ' ', sizeof(preqparm->vud.key_type_2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /* prepare kb block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) preqparm->kb.len = sizeof(preqparm->kb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) preqparm->kb.tlv1.len = sizeof(preqparm->kb.tlv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) preqparm->kb.tlv1.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) preqparm->kb.tlv2.len = sizeof(preqparm->kb.tlv2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) preqparm->kb.tlv2.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) preqparm->kb.tlv3.len = sizeof(preqparm->kb.tlv3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) preqparm->kb.tlv3.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) memcpy(preqparm->kb.tlv3.gen_key_id_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) aes_cipher_key_skeleton, SIZEOF_SKELETON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) preqparm->kb.tlv4.len = sizeof(preqparm->kb.tlv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) preqparm->kb.tlv4.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) preqparm->kb.tlv5.len = sizeof(preqparm->kb.tlv5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) preqparm->kb.tlv5.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) preqparm->kb.tlv6.len = sizeof(preqparm->kb.tlv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) preqparm->kb.tlv6.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /* patch the skeleton key token export flags inside the kb block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (keygenflags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) t = (struct cipherkeytoken *) preqparm->kb.tlv3.gen_key_id_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) t->kmf1 |= (u16) (keygenflags & 0x0000FF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) t->kmf1 &= (u16) ~(keygenflags & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) /* prepare xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) "%s cipher key generate failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) prepparm = (struct gkrepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /* do some plausibility checks on the key block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (prepparm->kb.len < 120 + 5 * sizeof(uint16_t) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) prepparm->kb.len > 136 + 5 * sizeof(uint16_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) DEBUG_ERR("%s reply with invalid or unknown key block\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* and some checks on the generated key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) rc = cca_check_secaescipherkey(zcrypt_dbf_info, DBF_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) prepparm->kb.tlv1.gen_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) keybitsize, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* copy the generated vlsc key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) t = (struct cipherkeytoken *) prepparm->kb.tlv1.gen_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (keybuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (*keybufsize >= t->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) memcpy(keybuf, t, t->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) *keybufsize = t->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) free_cprbmem(mem, PARMBSIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) EXPORT_SYMBOL(cca_gencipherkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * Helper function, does a the CSNBKPI2 CPRB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int _ip_cprb_helper(u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) const char *rule_array_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) const char *rule_array_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) const char *rule_array_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) const u8 *clr_key_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) int clr_key_bit_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) u8 *key_token,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) int *key_token_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) int rc, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct rule_array_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) char rule_array[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) } __packed * preq_ra_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct vud_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) u16 flag; /* 0x0064 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) u16 clr_key_bit_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) } tlv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) u16 flag; /* 0x0063 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) u8 clr_key[0]; /* clear key value bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) } tlv2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) } __packed * preq_vud_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct key_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) u16 flag; /* 0x0030 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) u8 key_token[0]; /* key skeleton */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) } tlv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) } __packed * preq_key_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct iprepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) u16 flag; /* 0x0030 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) u8 key_token[0]; /* key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) } tlv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct cipherkeytoken *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) int complete = strncmp(rule_array_2, "COMPLETE", 8) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) preqcblk->req_parml = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) /* prepare request param block with IP request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) preq_ra_block = (struct rule_array_block __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) memcpy(preq_ra_block->subfunc_code, "IP", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) preq_ra_block->rule_array_len = sizeof(uint16_t) + 2 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) memcpy(preq_ra_block->rule_array, rule_array_1, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) memcpy(preq_ra_block->rule_array + 8, rule_array_2, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) preqcblk->req_parml = sizeof(struct rule_array_block) + 2 * 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) if (rule_array_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) preq_ra_block->rule_array_len += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) memcpy(preq_ra_block->rule_array + 16, rule_array_3, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) preqcblk->req_parml += 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* prepare vud block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) preq_vud_block = (struct vud_block __force *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) (preqcblk->req_parmb + preqcblk->req_parml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) n = complete ? 0 : (clr_key_bit_size + 7) / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) preq_vud_block->len = sizeof(struct vud_block) + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) preq_vud_block->tlv1.len = sizeof(preq_vud_block->tlv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) preq_vud_block->tlv1.flag = 0x0064;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) preq_vud_block->tlv1.clr_key_bit_len = complete ? 0 : clr_key_bit_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) preq_vud_block->tlv2.len = sizeof(preq_vud_block->tlv2) + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) preq_vud_block->tlv2.flag = 0x0063;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) memcpy(preq_vud_block->tlv2.clr_key, clr_key_value, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) preqcblk->req_parml += preq_vud_block->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) /* prepare key block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) preq_key_block = (struct key_block __force *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) (preqcblk->req_parmb + preqcblk->req_parml);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) n = *key_token_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) preq_key_block->len = sizeof(struct key_block) + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) preq_key_block->tlv1.len = sizeof(preq_key_block->tlv1) + n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) preq_key_block->tlv1.flag = 0x0030;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) memcpy(preq_key_block->tlv1.key_token, key_token, *key_token_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) preqcblk->req_parml += preq_key_block->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* prepare xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) "%s CSNBKPI2 failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) prepparm = (struct iprepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) /* do some plausibility checks on the key block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (prepparm->kb.len < 120 + 3 * sizeof(uint16_t) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) prepparm->kb.len > 136 + 3 * sizeof(uint16_t)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) DEBUG_ERR("%s reply with invalid or unknown key block\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* do not check the key here, it may be incomplete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) /* copy the vlsc key token back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) t = (struct cipherkeytoken *) prepparm->kb.tlv1.key_token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) memcpy(key_token, t, t->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) *key_token_size = t->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) free_cprbmem(mem, PARMBSIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * Build CCA AES CIPHER secure key with a given clear key value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) int cca_clr2cipherkey(u16 card, u16 dom, u32 keybitsize, u32 keygenflags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) u8 *token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) int tokensize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) u8 exorbuf[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) struct cipherkeytoken *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) /* fill exorbuf with random data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) get_random_bytes(exorbuf, sizeof(exorbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) /* allocate space for the key token to build */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) token = kmalloc(MAXCCAVLSCTOKENSIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (!token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) /* prepare the token with the key skeleton */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) tokensize = SIZEOF_SKELETON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) memcpy(token, aes_cipher_key_skeleton, tokensize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) /* patch the skeleton key token export flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (keygenflags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) t = (struct cipherkeytoken *) token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) t->kmf1 |= (u16) (keygenflags & 0x0000FF00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) t->kmf1 &= (u16) ~(keygenflags & 0x000000FF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * Do the key import with the clear key value in 4 steps:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) * 1/4 FIRST import with only random data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * 2/4 EXOR the clear key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * 3/4 EXOR the very same random data again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) * 4/4 COMPLETE the secure cipher key import
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) rc = _ip_cprb_helper(card, dom, "AES ", "FIRST ", "MIN3PART",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) exorbuf, keybitsize, token, &tokensize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) "%s clear key import 1/4 with CSNBKPI2 failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) rc = _ip_cprb_helper(card, dom, "AES ", "ADD-PART", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) clrkey, keybitsize, token, &tokensize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) "%s clear key import 2/4 with CSNBKPI2 failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) rc = _ip_cprb_helper(card, dom, "AES ", "ADD-PART", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) exorbuf, keybitsize, token, &tokensize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) "%s clear key import 3/4 with CSNBKPI2 failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) rc = _ip_cprb_helper(card, dom, "AES ", "COMPLETE", NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) NULL, keybitsize, token, &tokensize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) "%s clear key import 4/4 with CSNBKPI2 failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) /* copy the generated key token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (keybuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (tokensize > *keybufsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) memcpy(keybuf, token, tokensize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) *keybufsize = tokensize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) kfree(token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) EXPORT_SYMBOL(cca_clr2cipherkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) * Derive proteced key from CCA AES cipher secure key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) int cca_cipher2protkey(u16 cardnr, u16 domain, const u8 *ckey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) u8 *protkey, u32 *protkeylen, u32 *protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct aureqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) u8 rule_array[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) u16 tk_blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) u16 tk_blob_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) u8 tk_blob[66];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) u16 cca_key_token_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) u16 cca_key_token_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) u8 cca_key_token[0]; // 64 or more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) struct aurepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) u16 sublen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) u16 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) struct cpacfkeyblock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) u8 version; /* version of this struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) u8 flags[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) u8 algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) u8 form;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) u8 pad1[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) u16 keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) u8 key[64]; /* the key (keylen bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) u16 keyattrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) u8 keyattr[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) u8 pad2[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) u8 vptype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) u8 vp[32]; /* verification pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) } ckb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int keytoklen = ((struct cipherkeytoken *)ckey)->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) /* fill request cprb param block with AU request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) preqparm = (struct aureqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) memcpy(preqparm->subfunc_code, "AU", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) preqparm->rule_array_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) sizeof(preqparm->rule_array_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) + sizeof(preqparm->rule_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) memcpy(preqparm->rule_array, "EXPT-SK ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) /* vud, tk blob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) preqparm->vud.len = sizeof(preqparm->vud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) preqparm->vud.tk_blob_len = sizeof(preqparm->vud.tk_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) + 2 * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) preqparm->vud.tk_blob_tag = 0x00C2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /* kb, cca token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) preqparm->kb.len = keytoklen + 3 * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) preqparm->kb.cca_key_token_len = keytoklen + 2 * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) memcpy(preqparm->kb.cca_key_token, ckey, keytoklen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) /* now fill length of param block into cprb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) preqcblk->req_parml = sizeof(struct aureqparm) + keytoklen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /* fill xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) "%s unwrap secure key failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (prepcblk->ccp_rscode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) DEBUG_WARN(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) "%s unwrap secure key warning, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) prepparm = (struct aurepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) /* check the returned keyblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (prepparm->vud.ckb.version != 0x01 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) prepparm->vud.ckb.version != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) __func__, (int) prepparm->vud.ckb.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (prepparm->vud.ckb.algo != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) "%s reply param keyblock algo mismatch 0x%02x != 0x02\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) __func__, (int) prepparm->vud.ckb.algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) /* copy the translated protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) switch (prepparm->vud.ckb.keylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) case 16+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /* AES 128 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) *protkeytype = PKEY_KEYTYPE_AES_128;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) case 24+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) /* AES 192 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) *protkeytype = PKEY_KEYTYPE_AES_192;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) case 32+32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /* AES 256 protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) *protkeytype = PKEY_KEYTYPE_AES_256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) DEBUG_ERR("%s unknown/unsupported keylen %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) __func__, prepparm->vud.ckb.keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) memcpy(protkey, prepparm->vud.ckb.key, prepparm->vud.ckb.keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (protkeylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) *protkeylen = prepparm->vud.ckb.keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) free_cprbmem(mem, PARMBSIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) EXPORT_SYMBOL(cca_cipher2protkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) * Derive protected key from CCA ECC secure private key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) int cca_ecc2protkey(u16 cardnr, u16 domain, const u8 *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) u8 *protkey, u32 *protkeylen, u32 *protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct aureqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) u8 rule_array[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) u16 tk_blob_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) u16 tk_blob_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) u8 tk_blob[66];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) u16 cca_key_token_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) u16 cca_key_token_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) u8 cca_key_token[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) struct aurepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) u16 sublen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) u16 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) struct cpacfkeyblock {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) u8 version; /* version of this struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) u8 flags[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) u8 algo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) u8 form;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) u8 pad1[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) u16 keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) u8 key[0]; /* the key (keylen bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) u16 keyattrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) u8 keyattr[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) u8 pad2[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) u8 vptype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) u8 vp[32]; /* verification pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) } ckb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) } vud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) } kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int keylen = ((struct eccprivkeytoken *)key)->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /* fill request cprb param block with AU request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) preqparm = (struct aureqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) memcpy(preqparm->subfunc_code, "AU", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) preqparm->rule_array_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) sizeof(preqparm->rule_array_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) + sizeof(preqparm->rule_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) memcpy(preqparm->rule_array, "EXPT-SK ", 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) /* vud, tk blob */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) preqparm->vud.len = sizeof(preqparm->vud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) preqparm->vud.tk_blob_len = sizeof(preqparm->vud.tk_blob)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) + 2 * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) preqparm->vud.tk_blob_tag = 0x00C2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) /* kb, cca token */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) preqparm->kb.len = keylen + 3 * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) preqparm->kb.cca_key_token_len = keylen + 2 * sizeof(uint16_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) memcpy(preqparm->kb.cca_key_token, key, keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) /* now fill length of param block into cprb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) preqcblk->req_parml = sizeof(struct aureqparm) + keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* fill xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) "%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) "%s unwrap secure key failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (prepcblk->ccp_rscode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) DEBUG_WARN(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) "%s unwrap secure key warning, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) prepparm = (struct aurepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /* check the returned keyblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) if (prepparm->vud.ckb.version != 0x02) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) DEBUG_ERR("%s reply param keyblock version mismatch 0x%02x != 0x02\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) __func__, (int) prepparm->vud.ckb.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) if (prepparm->vud.ckb.algo != 0x81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) DEBUG_ERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) "%s reply param keyblock algo mismatch 0x%02x != 0x81\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) __func__, (int) prepparm->vud.ckb.algo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* copy the translated protected key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (prepparm->vud.ckb.keylen > *protkeylen) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) DEBUG_ERR("%s prot keylen mismatch %d > buffersize %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) __func__, prepparm->vud.ckb.keylen, *protkeylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) memcpy(protkey, prepparm->vud.ckb.key, prepparm->vud.ckb.keylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) *protkeylen = prepparm->vud.ckb.keylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (protkeytype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) *protkeytype = PKEY_KEYTYPE_ECC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) free_cprbmem(mem, PARMBSIZE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) EXPORT_SYMBOL(cca_ecc2protkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * query cryptographic facility from CCA adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) int cca_query_crypto_facility(u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) const char *keyword,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) u8 *rarray, size_t *rarraylen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) u8 *varray, size_t *varraylen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) u8 *mem, *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct CPRBX *preqcblk, *prepcblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct ica_xcRB xcrb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) struct fqreqparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) u16 rule_array_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) char rule_array[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) struct lv1 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) u16 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) u8 data[VARDATASIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) } lv1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) u16 dummylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) } __packed * preqparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) size_t parmbsize = sizeof(struct fqreqparm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) struct fqrepparm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) u8 subfunc_code[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) u8 lvdata[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) } __packed * prepparm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /* get already prepared memory for 2 cprbs with param block each */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) /* fill request cprb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) preqcblk->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) /* fill request cprb param block with FQ request */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) preqparm = (struct fqreqparm __force *) preqcblk->req_parmb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) memcpy(preqparm->subfunc_code, "FQ", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) memcpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) preqparm->rule_array_len =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) preqparm->lv1.len = sizeof(preqparm->lv1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) preqparm->dummylen = sizeof(preqparm->dummylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) preqcblk->req_parml = parmbsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) /* fill xcrb struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) rc = zcrypt_send_cprb(&xcrb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) DEBUG_ERR("%s zcrypt_send_cprb (cardnr=%d domain=%d) failed, rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) __func__, (int) cardnr, (int) domain, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /* check response returncode and reasoncode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (prepcblk->ccp_rtcode != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) DEBUG_ERR("%s unwrap secure key failure, card response %d/%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) (int) prepcblk->ccp_rtcode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) (int) prepcblk->ccp_rscode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) /* process response cprb param block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ptr = ((u8 *) prepcblk) + sizeof(struct CPRBX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) prepcblk->rpl_parmb = (u8 __user *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) prepparm = (struct fqrepparm *) ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) ptr = prepparm->lvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) /* check and possibly copy reply rule array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) len = *((u16 *) ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (len > sizeof(u16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) ptr += sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) len -= sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (rarray && rarraylen && *rarraylen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) *rarraylen = (len > *rarraylen ? *rarraylen : len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) memcpy(rarray, ptr, *rarraylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) ptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /* check and possible copy reply var array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) len = *((u16 *) ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) if (len > sizeof(u16)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) ptr += sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) len -= sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) if (varray && varraylen && *varraylen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) *varraylen = (len > *varraylen ? *varraylen : len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) memcpy(varray, ptr, *varraylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) ptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) free_cprbmem(mem, parmbsize, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) EXPORT_SYMBOL(cca_query_crypto_facility);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) static int cca_info_cache_fetch(u16 cardnr, u16 domain, struct cca_info *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) struct cca_info_list_entry *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) spin_lock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) list_for_each_entry(ptr, &cca_info_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (ptr->cardnr == cardnr && ptr->domain == domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) memcpy(ci, &ptr->info, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) spin_unlock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) static void cca_info_cache_update(u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) const struct cca_info *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) struct cca_info_list_entry *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) spin_lock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) list_for_each_entry(ptr, &cca_info_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) if (ptr->cardnr == cardnr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) ptr->domain == domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) memcpy(&ptr->info, ci, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (!ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) spin_unlock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) ptr->cardnr = cardnr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) ptr->domain = domain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) memcpy(&ptr->info, ci, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) list_add(&ptr->list, &cca_info_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) spin_unlock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static void cca_info_cache_scrub(u16 cardnr, u16 domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) struct cca_info_list_entry *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) spin_lock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) list_for_each_entry(ptr, &cca_info_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (ptr->cardnr == cardnr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) ptr->domain == domain) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) list_del(&ptr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) kfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) spin_unlock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static void __exit mkvp_cache_free(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) struct cca_info_list_entry *ptr, *pnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) spin_lock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) list_for_each_entry_safe(ptr, pnext, &cca_info_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) list_del(&ptr->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) kfree(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) spin_unlock_bh(&cca_info_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) * Fetch cca_info values via query_crypto_facility from adapter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) int rc, found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) size_t rlen, vlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) u8 *rarray, *varray, *pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) struct zcrypt_device_status_ext devstat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) memset(ci, 0, sizeof(*ci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /* get first info from zcrypt device driver about this apqn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) rc = zcrypt_device_status_ext(cardnr, domain, &devstat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) ci->hwtype = devstat.hwtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /* prep page for rule array and var array use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) pg = (u8 *) __get_free_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (!pg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) rarray = pg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) varray = pg + PAGE_SIZE/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) rlen = vlen = PAGE_SIZE/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) /* QF for this card/domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) rc = cca_query_crypto_facility(cardnr, domain, "STATICSA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) rarray, &rlen, varray, &vlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (rc == 0 && rlen >= 10*8 && vlen >= 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) memcpy(ci->serial, rarray, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) ci->new_aes_mk_state = (char) rarray[7*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) ci->cur_aes_mk_state = (char) rarray[8*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) ci->old_aes_mk_state = (char) rarray[9*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (ci->old_aes_mk_state == '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) memcpy(&ci->old_aes_mkvp, varray + 172, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) if (ci->cur_aes_mk_state == '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) memcpy(&ci->cur_aes_mkvp, varray + 184, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) if (ci->new_aes_mk_state == '3')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) memcpy(&ci->new_aes_mkvp, varray + 196, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) found++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (!found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) rlen = vlen = PAGE_SIZE/2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) rc = cca_query_crypto_facility(cardnr, domain, "STATICSB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) rarray, &rlen, varray, &vlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (rc == 0 && rlen >= 13*8 && vlen >= 240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) ci->new_apka_mk_state = (char) rarray[10*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) ci->cur_apka_mk_state = (char) rarray[11*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) ci->old_apka_mk_state = (char) rarray[12*8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) if (ci->old_apka_mk_state == '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) memcpy(&ci->old_apka_mkvp, varray + 208, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) if (ci->cur_apka_mk_state == '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) memcpy(&ci->cur_apka_mkvp, varray + 220, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) if (ci->new_apka_mk_state == '3')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) memcpy(&ci->new_apka_mkvp, varray + 232, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) found++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) free_page((unsigned long) pg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) return found == 2 ? 0 : -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) * Fetch cca information about a CCA queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) int cca_get_info(u16 card, u16 dom, struct cca_info *ci, int verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) rc = cca_info_cache_fetch(card, dom, ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (rc || verify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) rc = fetch_cca_info(card, dom, ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) if (rc == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) cca_info_cache_update(card, dom, ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) EXPORT_SYMBOL(cca_get_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) * Search for a matching crypto card based on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) * Master Key Verification Pattern given.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) int verify, int minhwtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) struct zcrypt_device_status_ext *device_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) u16 card, dom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct cca_info ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) int i, rc, oi = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) /* mkvp must not be zero, minhwtype needs to be >= 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (mkvp == 0 || minhwtype < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /* fetch status of all crypto cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) sizeof(struct zcrypt_device_status_ext),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (!device_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) zcrypt_device_status_mask_ext(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /* walk through all crypto cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) card = AP_QID_CARD(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) dom = AP_QID_QUEUE(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (device_status[i].online &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) device_status[i].functions & 0x04) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /* enabled CCA card, check current mkvp from cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) if (cca_info_cache_fetch(card, dom, &ci) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) ci.hwtype >= minhwtype &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) ci.cur_aes_mk_state == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) ci.cur_aes_mkvp == mkvp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) if (!verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) /* verify: refresh card info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) if (fetch_cca_info(card, dom, &ci) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) cca_info_cache_update(card, dom, &ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) if (ci.hwtype >= minhwtype &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) ci.cur_aes_mk_state == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ci.cur_aes_mkvp == mkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) /* Card is offline and/or not a CCA card. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) /* del mkvp entry from cache if it exists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) cca_info_cache_scrub(card, dom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (i >= MAX_ZDEV_ENTRIES_EXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) /* nothing found, so this time without cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) if (!(device_status[i].online &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) device_status[i].functions & 0x04))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) card = AP_QID_CARD(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) dom = AP_QID_QUEUE(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) /* fresh fetch mkvp from adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) if (fetch_cca_info(card, dom, &ci) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) cca_info_cache_update(card, dom, &ci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) if (ci.hwtype >= minhwtype &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) ci.cur_aes_mk_state == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) ci.cur_aes_mkvp == mkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (ci.hwtype >= minhwtype &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) ci.old_aes_mk_state == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) ci.old_aes_mkvp == mkvp &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) oi < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) oi = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) /* old mkvp matched, use this card then */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) card = AP_QID_CARD(device_status[oi].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) dom = AP_QID_QUEUE(device_status[oi].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) if (pcardnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) *pcardnr = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (pdomain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) *pdomain = dom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) rc = (i < MAX_ZDEV_ENTRIES_EXT ? 0 : 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) kvfree(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) * Search for a matching crypto card based on the Master Key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) * Verification Pattern provided inside a secure key token.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) u64 mkvp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) int minhwtype = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) const struct keytoken_header *hdr = (struct keytoken_header *) key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (hdr->type != TOKTYPE_CCA_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) switch (hdr->version) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) case TOKVER_CCA_AES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) mkvp = ((struct secaeskeytoken *)key)->mkvp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) case TOKVER_CCA_VLSC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) mkvp = ((struct cipherkeytoken *)key)->mkvp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) minhwtype = AP_DEVICE_TYPE_CEX6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) return findcard(mkvp, pcardnr, pdomain, verify, minhwtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) EXPORT_SYMBOL(cca_findcard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) int verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) struct zcrypt_device_status_ext *device_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) u32 *_apqns = NULL, _nr_apqns = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) int i, card, dom, curmatch, oldmatch, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) struct cca_info ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) /* fetch status of all crypto cards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) device_status = kvmalloc_array(MAX_ZDEV_ENTRIES_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) sizeof(struct zcrypt_device_status_ext),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (!device_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) zcrypt_device_status_mask_ext(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) /* allocate 1k space for up to 256 apqns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) if (!_apqns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) kvfree(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /* walk through all the crypto apqnss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) card = AP_QID_CARD(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) dom = AP_QID_QUEUE(device_status[i].qid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) /* check online state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) if (!device_status[i].online)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) /* check for cca functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (!(device_status[i].functions & 0x04))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /* check cardnr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) if (cardnr != 0xFFFF && card != cardnr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) /* check domain */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (domain != 0xFFFF && dom != domain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) /* get cca info on this apqn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) if (cca_get_info(card, dom, &ci, verify))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) /* current master key needs to be valid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (mktype == AES_MK_SET && ci.cur_aes_mk_state != '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (mktype == APKA_MK_SET && ci.cur_apka_mk_state != '2')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) /* check min hardware type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) if (minhwtype > 0 && minhwtype > ci.hwtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) if (cur_mkvp || old_mkvp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) /* check mkvps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) curmatch = oldmatch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (mktype == AES_MK_SET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (cur_mkvp && cur_mkvp == ci.cur_aes_mkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) curmatch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) if (old_mkvp && ci.old_aes_mk_state == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) old_mkvp == ci.old_aes_mkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) oldmatch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) if (cur_mkvp && cur_mkvp == ci.cur_apka_mkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) curmatch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (old_mkvp && ci.old_apka_mk_state == '2' &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) old_mkvp == ci.old_apka_mkvp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) oldmatch = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (curmatch + oldmatch < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) /* apqn passed all filtering criterons, add to the array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (_nr_apqns < 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16) dom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) /* nothing found ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) if (!_nr_apqns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) kfree(_apqns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) /* no re-allocation, simple return the _apqns array */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) *apqns = _apqns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) *nr_apqns = _nr_apqns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) kvfree(device_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) EXPORT_SYMBOL(cca_findcard2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) void __exit zcrypt_ccamisc_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) mkvp_cache_free();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) }