File Index
Files and directories
Sign in
FILE

zcrypt_ccamisc.c

File preview with syntax highlighting.

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