// SPDX-License-Identifier: GPL-2.0
/*
 * DIAG 0x320 support and certificate store handling
 *
 * Copyright IBM Corp. 2023
 * Author(s):	Anastasia Eskova <anastasia.eskova@ibm.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/delay.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/key-type.h>
#include <linux/key.h>
#include <linux/keyctl.h>
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <crypto/sha2.h>
#include <keys/user-type.h>
#include <asm/debug.h>
#include <asm/diag.h>
#include <asm/ebcdic.h>
#include <asm/sclp.h>

#define DIAG_MAX_RETRIES		10

#define VCE_FLAGS_VALID_MASK		0x80

#define ISM_LEN_DWORDS			4
#define VCSSB_LEN_BYTES			128
#define VCSSB_LEN_NO_CERTS		4
#define VCB_LEN_NO_CERTS		64
#define VC_NAME_LEN_BYTES		64

#define CERT_STORE_KEY_TYPE_NAME	"cert_store_key"
#define CERT_STORE_KEYRING_NAME		"cert_store"

static debug_info_t *cert_store_dbf;
static debug_info_t *cert_store_hexdump;

#define pr_dbf_msg(fmt, ...) \
	debug_sprintf_event(cert_store_dbf, 3, fmt "\n", ## __VA_ARGS__)

enum diag320_subcode {
	DIAG320_SUBCODES	= 0,
	DIAG320_STORAGE		= 1,
	DIAG320_CERT_BLOCK	= 2,
};

enum diag320_rc {
	DIAG320_RC_OK		= 0x0001,
	DIAG320_RC_CS_NOMATCH	= 0x0306,
};

/* Verification Certificates Store Support Block (VCSSB). */
struct vcssb {
	u32 vcssb_length;
	u8  pad_0x04[3];
	u8  version;
	u8  pad_0x08[8];
	u32 cs_token;
	u8  pad_0x14[12];
	u16 total_vc_index_count;
	u16 max_vc_index_count;
	u8  pad_0x24[28];
	u32 max_vce_length;
	u32 max_vcxe_length;
	u8  pad_0x48[8];
	u32 max_single_vcb_length;
	u32 total_vcb_length;
	u32 max_single_vcxb_length;
	u32 total_vcxb_length;
	u8  pad_0x60[32];
} __packed __aligned(8);

/* Verification Certificate Entry (VCE) Header. */
struct vce_header {
	u32 vce_length;
	u8  flags;
	u8  key_type;
	u16 vc_index;
	u8  vc_name[VC_NAME_LEN_BYTES]; /* EBCDIC */
	u8  vc_format;
	u8  pad_0x49;
	u16 key_id_length;
	u8  pad_0x4c;
	u8  vc_hash_type;
	u16 vc_hash_length;
	u8  pad_0x50[4];
	u32 vc_length;
	u8  pad_0x58[8];
	u16 vc_hash_offset;
	u16 vc_offset;
	u8  pad_0x64[28];
} __packed __aligned(4);

/* Verification Certificate Block (VCB) Header. */
struct vcb_header {
	u32 vcb_input_length;
	u8  pad_0x04[4];
	u16 first_vc_index;
	u16 last_vc_index;
	u32 pad_0x0c;
	u32 cs_token;
	u8  pad_0x14[12];
	u32 vcb_output_length;
	u8  pad_0x24[3];
	u8  version;
	u16 stored_vc_count;
	u16 remaining_vc_count;
	u8  pad_0x2c[20];
} __packed __aligned(4);

/* Verification Certificate Block (VCB). */
struct vcb {
	struct vcb_header vcb_hdr;
	u8 vcb_buf[];
} __packed __aligned(4);

/* Verification Certificate Entry (VCE). */
struct vce {
	struct vce_header vce_hdr;
	u8 cert_data_buf[];
} __packed __aligned(4);

static void cert_store_key_describe(const struct key *key, struct seq_file *m)
{
	char ascii[VC_NAME_LEN_BYTES + 1];

	/*
	 * First 64 bytes of the key description is key name in EBCDIC CP 500.
	 * Convert it to ASCII for displaying in /proc/keys.
	 */
	strscpy(ascii, key->description, sizeof(ascii));
	EBCASC_500(ascii, VC_NAME_LEN_BYTES);
	seq_puts(m, ascii);

	seq_puts(m, &key->description[VC_NAME_LEN_BYTES]);
	if (key_is_positive(key))
		seq_printf(m, ": %u", key->datalen);
}

/*
 * Certificate store key type takes over properties of
 * user key but cannot be updated.
 */
static struct key_type key_type_cert_store_key = {
	.name		= CERT_STORE_KEY_TYPE_NAME,
	.preparse	= user_preparse,
	.free_preparse	= user_free_preparse,
	.instantiate	= generic_key_instantiate,
	.revoke		= user_revoke,
	.destroy	= user_destroy,
	.describe	= cert_store_key_describe,
	.read		= user_read,
};

/* Logging functions. */
static void pr_dbf_vcb(const struct vcb *b)
{
	pr_dbf_msg("VCB Header:");
	pr_dbf_msg("vcb_input_length: %d", b->vcb_hdr.vcb_input_length);
	pr_dbf_msg("first_vc_index: %d", b->vcb_hdr.first_vc_index);
	pr_dbf_msg("last_vc_index: %d", b->vcb_hdr.last_vc_index);
	pr_dbf_msg("cs_token: %d", b->vcb_hdr.cs_token);
	pr_dbf_msg("vcb_output_length: %d", b->vcb_hdr.vcb_output_length);
	pr_dbf_msg("version: %d", b->vcb_hdr.version);
	pr_dbf_msg("stored_vc_count: %d", b->vcb_hdr.stored_vc_count);
	pr_dbf_msg("remaining_vc_count: %d", b->vcb_hdr.remaining_vc_count);
}

static void pr_dbf_vce(const struct vce *e)
{
	unsigned char vc_name[VC_NAME_LEN_BYTES + 1];
	char log_string[VC_NAME_LEN_BYTES + 40];

	pr_dbf_msg("VCE Header:");
	pr_dbf_msg("vce_hdr.vce_length: %d", e->vce_hdr.vce_length);
	pr_dbf_msg("vce_hdr.flags: %d", e->vce_hdr.flags);
	pr_dbf_msg("vce_hdr.key_type: %d", e->vce_hdr.key_type);
	pr_dbf_msg("vce_hdr.vc_index: %d", e->vce_hdr.vc_index);
	pr_dbf_msg("vce_hdr.vc_format: %d", e->vce_hdr.vc_format);
	pr_dbf_msg("vce_hdr.key_id_length: %d", e->vce_hdr.key_id_length);
	pr_dbf_msg("vce_hdr.vc_hash_type: %d", e->vce_hdr.vc_hash_type);
	pr_dbf_msg("vce_hdr.vc_hash_length: %d", e->vce_hdr.vc_hash_length);
	pr_dbf_msg("vce_hdr.vc_hash_offset: %d", e->vce_hdr.vc_hash_offset);
	pr_dbf_msg("vce_hdr.vc_length: %d", e->vce_hdr.vc_length);
	pr_dbf_msg("vce_hdr.vc_offset: %d", e->vce_hdr.vc_offset);

	/* Certificate name in ASCII. */
	memcpy(vc_name, e->vce_hdr.vc_name, VC_NAME_LEN_BYTES);
	EBCASC_500(vc_name, VC_NAME_LEN_BYTES);
	vc_name[VC_NAME_LEN_BYTES] = '\0';

	snprintf(log_string, sizeof(log_string),
		 "index: %d vce_hdr.vc_name (ASCII): %s",
		 e->vce_hdr.vc_index, vc_name);
	debug_text_event(cert_store_hexdump, 3, log_string);

	/* Certificate data. */
	debug_text_event(cert_store_hexdump, 3, "VCE: Certificate data start");
	debug_event(cert_store_hexdump, 3, (u8 *)e->cert_data_buf, 128);
	debug_text_event(cert_store_hexdump, 3, "VCE: Certificate data end");
	debug_event(cert_store_hexdump, 3,
		    (u8 *)e->cert_data_buf + e->vce_hdr.vce_length - 128, 128);
}

static void pr_dbf_vcssb(const struct vcssb *s)
{
	debug_text_event(cert_store_hexdump, 3, "DIAG320 Subcode1");
	debug_event(cert_store_hexdump, 3, (u8 *)s, VCSSB_LEN_BYTES);

	pr_dbf_msg("VCSSB:");
	pr_dbf_msg("vcssb_length: %u", s->vcssb_length);
	pr_dbf_msg("version: %u", s->version);
	pr_dbf_msg("cs_token: %u", s->cs_token);
	pr_dbf_msg("total_vc_index_count: %u", s->total_vc_index_count);
	pr_dbf_msg("max_vc_index_count: %u", s->max_vc_index_count);
	pr_dbf_msg("max_vce_length: %u", s->max_vce_length);
	pr_dbf_msg("max_vcxe_length: %u", s->max_vce_length);
	pr_dbf_msg("max_single_vcb_length: %u", s->max_single_vcb_length);
	pr_dbf_msg("total_vcb_length: %u", s->total_vcb_length);
	pr_dbf_msg("max_single_vcxb_length: %u", s->max_single_vcxb_length);
	pr_dbf_msg("total_vcxb_length: %u", s->total_vcxb_length);
}

static int __diag320(unsigned long subcode, void *addr)
{
	union register_pair rp = { .even = (unsigned long)addr, };

	asm volatile(
		"	diag	%[rp],%[subcode],0x320\n"
		"0:	nopr	%%r7\n"
		EX_TABLE(0b, 0b)
		: [rp] "+d" (rp.pair)
		: [subcode] "d" (subcode)
		: "cc", "memory");

	return rp.odd;
}

static int diag320(unsigned long subcode, void *addr)
{
	diag_stat_inc(DIAG_STAT_X320);

	return __diag320(subcode, addr);
}

/*
 * Calculate SHA256 hash of the VCE certificate and compare it to hash stored in
 * VCE. Return -EINVAL if hashes don't match.
 */
static int check_certificate_hash(const struct vce *vce)
{
	u8 hash[SHA256_DIGEST_SIZE];
	u16 vc_hash_length;
	u8 *vce_hash;

	vce_hash = (u8 *)vce + vce->vce_hdr.vc_hash_offset;
	vc_hash_length = vce->vce_hdr.vc_hash_length;
	sha256((u8 *)vce + vce->vce_hdr.vc_offset, vce->vce_hdr.vc_length, hash);
	if (memcmp(vce_hash, hash, vc_hash_length) == 0)
		return 0;

	pr_dbf_msg("SHA256 hash of received certificate does not match");
	debug_text_event(cert_store_hexdump, 3, "VCE hash:");
	debug_event(cert_store_hexdump, 3, vce_hash, SHA256_DIGEST_SIZE);
	debug_text_event(cert_store_hexdump, 3, "Calculated hash:");
	debug_event(cert_store_hexdump, 3, hash, SHA256_DIGEST_SIZE);

	return -EINVAL;
}

static int check_certificate_valid(const struct vce *vce)
{
	if (!(vce->vce_hdr.flags & VCE_FLAGS_VALID_MASK)) {
		pr_dbf_msg("Certificate entry is invalid");
		return -EINVAL;
	}
	if (vce->vce_hdr.vc_format != 1) {
		pr_dbf_msg("Certificate format is not supported");
		return -EINVAL;
	}
	if (vce->vce_hdr.vc_hash_type != 1) {
		pr_dbf_msg("Hash type is not supported");
		return -EINVAL;
	}

	return check_certificate_hash(vce);
}

static struct key *get_user_session_keyring(void)
{
	key_ref_t us_keyring_ref;

	us_keyring_ref = lookup_user_key(KEY_SPEC_USER_SESSION_KEYRING,
					 KEY_LOOKUP_CREATE, KEY_NEED_LINK);
	if (IS_ERR(us_keyring_ref)) {
		pr_dbf_msg("Couldn't get user session keyring: %ld",
			   PTR_ERR(us_keyring_ref));
		return ERR_PTR(-ENOKEY);
	}
	key_ref_put(us_keyring_ref);
	return key_ref_to_ptr(us_keyring_ref);
}

/* Invalidate all keys from cert_store keyring. */
static int invalidate_keyring_keys(struct key *keyring)
{
	unsigned long num_keys, key_index;
	size_t keyring_payload_len;
	key_serial_t *key_array;
	struct key *current_key;
	int rc;

	keyring_payload_len = key_type_keyring.read(keyring, NULL, 0);
	num_keys = keyring_payload_len / sizeof(key_serial_t);
	key_array = kcalloc(num_keys, sizeof(key_serial_t), GFP_KERNEL);
	if (!key_array)
		return -ENOMEM;

	rc = key_type_keyring.read(keyring, (char *)key_array, keyring_payload_len);
	if (rc != keyring_payload_len) {
		pr_dbf_msg("Couldn't read keyring payload");
		goto out;
	}

	for (key_index = 0; key_index < num_keys; key_index++) {
		current_key = key_lookup(key_array[key_index]);
		pr_dbf_msg("Invalidating key %08x", current_key->serial);

		key_invalidate(current_key);
		key_put(current_key);
		rc = key_unlink(keyring, current_key);
		if (rc) {
			pr_dbf_msg("Couldn't unlink key %08x: %d", current_key->serial, rc);
			break;
		}
	}
out:
	kfree(key_array);
	return rc;
}

static struct key *find_cs_keyring(void)
{
	key_ref_t cs_keyring_ref;
	struct key *cs_keyring;

	cs_keyring_ref = keyring_search(make_key_ref(get_user_session_keyring(), true),
					&key_type_keyring, CERT_STORE_KEYRING_NAME,
					false);
	if (!IS_ERR(cs_keyring_ref)) {
		cs_keyring = key_ref_to_ptr(cs_keyring_ref);
		key_ref_put(cs_keyring_ref);
		goto found;
	}
	/* Search default locations: thread, process, session keyrings */
	cs_keyring = request_key(&key_type_keyring, CERT_STORE_KEYRING_NAME, NULL);
	if (IS_ERR(cs_keyring))
		return NULL;
	key_put(cs_keyring);
found:
	return cs_keyring;
}

static void cleanup_cs_keys(void)
{
	struct key *cs_keyring;

	cs_keyring = find_cs_keyring();
	if (!cs_keyring)
		return;

	pr_dbf_msg("Found cert_store keyring. Purging...");
	/*
	 * Remove cert_store_key_type in case invalidation
	 * of old cert_store keys failed (= severe error).
	 */
	if (invalidate_keyring_keys(cs_keyring))
		unregister_key_type(&key_type_cert_store_key);

	keyring_clear(cs_keyring);
	key_invalidate(cs_keyring);
	key_put(cs_keyring);
	key_unlink(get_user_session_keyring(), cs_keyring);
}

static struct key *create_cs_keyring(void)
{
	static struct key *cs_keyring;

	/* Cleanup previous cs_keyring and all associated keys if any. */
	cleanup_cs_keys();
	cs_keyring = keyring_alloc(CERT_STORE_KEYRING_NAME, GLOBAL_ROOT_UID,
				   GLOBAL_ROOT_GID, current_cred(),
				   (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ,
				   KEY_ALLOC_NOT_IN_QUOTA | KEY_ALLOC_SET_KEEP,
				   NULL, get_user_session_keyring());
	if (IS_ERR(cs_keyring)) {
		pr_dbf_msg("Can't allocate cert_store keyring");
		return NULL;
	}

	pr_dbf_msg("Successfully allocated cert_store keyring: %08x", cs_keyring->serial);

	/*
	 * In case a previous clean-up ran into an
	 * error and unregistered key type.
	 */
	register_key_type(&key_type_cert_store_key);

	return cs_keyring;
}

/*
 * Allocate memory and create key description in format
 * [key name in EBCDIC]:[VCE index]:[CS token].
 * Return a pointer to key description or NULL if memory
 * allocation failed. Memory should be freed by caller.
 */
static char *get_key_description(struct vcssb *vcssb, const struct vce *vce)
{
	size_t len, name_len;
	u32 cs_token;
	char *desc;

	cs_token = vcssb->cs_token;
	/* Description string contains "%64s:%05u:%010u\0". */
	name_len = sizeof(vce->vce_hdr.vc_name);
	len = name_len + 1 + 5 + 1 + 10 + 1;
	desc = kmalloc(len, GFP_KERNEL);
	if (!desc)
		return NULL;

	memcpy(desc, vce->vce_hdr.vc_name, name_len);
	snprintf(desc + name_len, len - name_len, ":%05u:%010u",
		 vce->vce_hdr.vc_index, cs_token);

	return desc;
}

/*
 * Create a key of type "cert_store_key" using the data from VCE for key
 * payload and key description. Link the key to "cert_store" keyring.
 */
static int create_key_from_vce(struct vcssb *vcssb, struct vce *vce,
			       struct key *keyring)
{
	key_ref_t newkey;
	char *desc;
	int rc;

	desc = get_key_description(vcssb, vce);
	if (!desc)
		return -ENOMEM;

	newkey = key_create_or_update(
		make_key_ref(keyring, true), CERT_STORE_KEY_TYPE_NAME,
		desc, (u8 *)vce + vce->vce_hdr.vc_offset,
		vce->vce_hdr.vc_length,
		(KEY_POS_ALL & ~KEY_POS_SETATTR)  | KEY_USR_VIEW | KEY_USR_READ,
		KEY_ALLOC_NOT_IN_QUOTA);

	rc = PTR_ERR_OR_ZERO(newkey);
	if (rc) {
		pr_dbf_msg("Couldn't create a key from Certificate Entry (%d)", rc);
		rc = -ENOKEY;
		goto out;
	}

	key_ref_put(newkey);
out:
	kfree(desc);
	return rc;
}

/* Get Verification Certificate Storage Size block with DIAG320 subcode2. */
static int get_vcssb(struct vcssb *vcssb)
{
	int diag320_rc;

	memset(vcssb, 0, sizeof(*vcssb));
	vcssb->vcssb_length = VCSSB_LEN_BYTES;
	diag320_rc = diag320(DIAG320_STORAGE, vcssb);
	pr_dbf_vcssb(vcssb);

	if (diag320_rc != DIAG320_RC_OK) {
		pr_dbf_msg("Diag 320 Subcode 1 returned bad RC: %04x", diag320_rc);
		return -EIO;
	}
	if (vcssb->vcssb_length == VCSSB_LEN_NO_CERTS) {
		pr_dbf_msg("No certificates available for current configuration");
		return -ENOKEY;
	}

	return 0;
}

static u32 get_4k_mult_vcb_size(struct vcssb *vcssb)
{
	return round_up(vcssb->max_single_vcb_length, PAGE_SIZE);
}

/* Fill input fields of single-entry VCB that will be read by LPAR. */
static void fill_vcb_input(struct vcssb *vcssb, struct vcb *vcb, u16 index)
{
	memset(vcb, 0, sizeof(*vcb));
	vcb->vcb_hdr.vcb_input_length = get_4k_mult_vcb_size(vcssb);
	vcb->vcb_hdr.cs_token = vcssb->cs_token;

	/* Request single entry. */
	vcb->vcb_hdr.first_vc_index = index;
	vcb->vcb_hdr.last_vc_index = index;
}

static void extract_vce_from_sevcb(struct vcb *vcb, struct vce *vce)
{
	struct vce *extracted_vce;

	extracted_vce = (struct vce *)vcb->vcb_buf;
	memcpy(vce, vcb->vcb_buf, extracted_vce->vce_hdr.vce_length);
	pr_dbf_vce(vce);
}

static int get_sevcb(struct vcssb *vcssb, u16 index, struct vcb *vcb)
{
	int rc, diag320_rc;

	fill_vcb_input(vcssb, vcb, index);

	diag320_rc = diag320(DIAG320_CERT_BLOCK, vcb);
	pr_dbf_msg("Diag 320 Subcode2 RC %2x", diag320_rc);
	pr_dbf_vcb(vcb);

	switch (diag320_rc) {
	case DIAG320_RC_OK:
		rc = 0;
		if (vcb->vcb_hdr.vcb_output_length == VCB_LEN_NO_CERTS) {
			pr_dbf_msg("No certificate entry for index %u", index);
			rc = -ENOKEY;
		} else if (vcb->vcb_hdr.remaining_vc_count != 0) {
			/* Retry on insufficient space. */
			pr_dbf_msg("Couldn't get all requested certificates");
			rc = -EAGAIN;
		}
		break;
	case DIAG320_RC_CS_NOMATCH:
		pr_dbf_msg("Certificate Store token mismatch");
		rc = -EAGAIN;
		break;
	default:
		pr_dbf_msg("Diag 320 Subcode2 returned bad rc (0x%4x)", diag320_rc);
		rc = -EINVAL;
		break;
	}

	return rc;
}

/*
 * Allocate memory for single-entry VCB, get VCB via DIAG320 subcode 2 call,
 * extract VCE and create a key from its' certificate.
 */
static int create_key_from_sevcb(struct vcssb *vcssb, u16 index,
				 struct key *keyring)
{
	struct vcb *vcb;
	struct vce *vce;
	int rc;

	rc = -ENOMEM;
	vcb = vmalloc(get_4k_mult_vcb_size(vcssb));
	vce = vmalloc(vcssb->max_single_vcb_length - sizeof(vcb->vcb_hdr));
	if (!vcb || !vce)
		goto out;

	rc = get_sevcb(vcssb, index, vcb);
	if (rc)
		goto out;

	extract_vce_from_sevcb(vcb, vce);
	rc = check_certificate_valid(vce);
	if (rc)
		goto out;

	rc = create_key_from_vce(vcssb, vce, keyring);
	if (rc)
		goto out;

	pr_dbf_msg("Successfully created key from Certificate Entry %d", index);
out:
	vfree(vce);
	vfree(vcb);
	return rc;
}

/*
 * Request a single-entry VCB for each VCE available for the partition.
 * Create a key from it and link it to cert_store keyring. If no keys
 * could be created (i.e. VCEs were invalid) return -ENOKEY.
 */
static int add_certificates_to_keyring(struct vcssb *vcssb, struct key *keyring)
{
	int rc, index, count, added;

	count = 0;
	added = 0;
	/* Certificate Store entries indices start with 1 and have no gaps. */
	for (index = 1; index < vcssb->total_vc_index_count + 1; index++) {
		pr_dbf_msg("Creating key from VCE %u", index);
		rc = create_key_from_sevcb(vcssb, index, keyring);
		count++;

		if (rc == -EAGAIN)
			return rc;

		if (rc)
			pr_dbf_msg("Creating key from VCE %u failed (%d)", index, rc);
		else
			added++;
	}

	if (added == 0) {
		pr_dbf_msg("Processed %d entries. No keys created", count);
		return -ENOKEY;
	}

	pr_info("Added %d of %d keys to cert_store keyring", added, count);

	/*
	 * Do not allow to link more keys to certificate store keyring after all
	 * the VCEs were processed.
	 */
	rc = keyring_restrict(make_key_ref(keyring, true), NULL, NULL);
	if (rc)
		pr_dbf_msg("Failed to set restriction to cert_store keyring (%d)", rc);

	return 0;
}

/*
 * Check which DIAG320 subcodes are installed.
 * Return -ENOENT if subcodes 1 or 2 are not available.
 */
static int query_diag320_subcodes(void)
{
	unsigned long ism[ISM_LEN_DWORDS];
	int rc;

	rc = diag320(0, ism);
	if (rc != DIAG320_RC_OK) {
		pr_dbf_msg("DIAG320 subcode query returned %04x", rc);
		return -ENOENT;
	}

	debug_text_event(cert_store_hexdump, 3, "DIAG320 Subcode 0");
	debug_event(cert_store_hexdump, 3, ism, sizeof(ism));

	if (!test_bit_inv(1, ism) || !test_bit_inv(2, ism)) {
		pr_dbf_msg("Not all required DIAG320 subcodes are installed");
		return -ENOENT;
	}

	return 0;
}

/*
 * Check if Certificate Store is supported by the firmware and DIAG320 subcodes
 * 1 and 2 are installed. Create cert_store keyring and link all certificates
 * available for the current partition to it as "cert_store_key" type
 * keys. On refresh or error invalidate cert_store keyring and destroy
 * all keys of "cert_store_key" type.
 */
static int fill_cs_keyring(void)
{
	struct key *cs_keyring;
	struct vcssb *vcssb;
	int rc;

	rc = -ENOMEM;
	vcssb = kmalloc(VCSSB_LEN_BYTES, GFP_KERNEL);
	if (!vcssb)
		goto cleanup_keys;

	rc = -ENOENT;
	if (!sclp.has_diag320) {
		pr_dbf_msg("Certificate Store is not supported");
		goto cleanup_keys;
	}

	rc = query_diag320_subcodes();
	if (rc)
		goto cleanup_keys;

	rc = get_vcssb(vcssb);
	if (rc)
		goto cleanup_keys;

	rc = -ENOMEM;
	cs_keyring = create_cs_keyring();
	if (!cs_keyring)
		goto cleanup_keys;

	rc = add_certificates_to_keyring(vcssb, cs_keyring);
	if (rc)
		goto cleanup_cs_keyring;

	goto out;

cleanup_cs_keyring:
	key_put(cs_keyring);
cleanup_keys:
	cleanup_cs_keys();
out:
	kfree(vcssb);
	return rc;
}

static DEFINE_MUTEX(cs_refresh_lock);
static int cs_status_val = -1;

static ssize_t cs_status_show(struct kobject *kobj,
			      struct kobj_attribute *attr, char *buf)
{
	if (cs_status_val == -1)
		return sysfs_emit(buf, "uninitialized\n");
	else if (cs_status_val == 0)
		return sysfs_emit(buf, "ok\n");

	return sysfs_emit(buf, "failed (%d)\n", cs_status_val);
}

static struct kobj_attribute cs_status_attr = __ATTR_RO(cs_status);

static ssize_t refresh_store(struct kobject *kobj, struct kobj_attribute *attr,
			     const char *buf, size_t count)
{
	int rc, retries;

	pr_dbf_msg("Refresh certificate store information requested");
	rc = mutex_lock_interruptible(&cs_refresh_lock);
	if (rc)
		return rc;

	for (retries = 0; retries < DIAG_MAX_RETRIES; retries++) {
		/* Request certificates from certificate store. */
		rc = fill_cs_keyring();
		if (rc)
			pr_dbf_msg("Failed to refresh certificate store information (%d)", rc);
		if (rc != -EAGAIN)
			break;
	}
	cs_status_val = rc;
	mutex_unlock(&cs_refresh_lock);

	return rc ?: count;
}

static struct kobj_attribute refresh_attr = __ATTR_WO(refresh);

static const struct attribute *cert_store_attrs[] __initconst = {
	&cs_status_attr.attr,
	&refresh_attr.attr,
	NULL,
};

static struct kobject *cert_store_kobj;

static int __init cert_store_init(void)
{
	int rc = -ENOMEM;

	cert_store_dbf = debug_register("cert_store_msg", 10, 1, 64);
	if (!cert_store_dbf)
		goto cleanup_dbf;

	cert_store_hexdump = debug_register("cert_store_hexdump", 3, 1, 128);
	if (!cert_store_hexdump)
		goto cleanup_dbf;

	debug_register_view(cert_store_hexdump, &debug_hex_ascii_view);
	debug_register_view(cert_store_dbf, &debug_sprintf_view);

	/* Create directory /sys/firmware/cert_store. */
	cert_store_kobj = kobject_create_and_add("cert_store", firmware_kobj);
	if (!cert_store_kobj)
		goto cleanup_dbf;

	rc = sysfs_create_files(cert_store_kobj, cert_store_attrs);
	if (rc)
		goto cleanup_kobj;

	register_key_type(&key_type_cert_store_key);

	return rc;

cleanup_kobj:
	kobject_put(cert_store_kobj);
cleanup_dbf:
	debug_unregister(cert_store_dbf);
	debug_unregister(cert_store_hexdump);

	return rc;
}
device_initcall(cert_store_init);
