brintos

brintos / linux-shallow public Read only

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