drivers/s390/crypto/pkey_sysfs.c

Source file repositories/reference/linux-study-clean/drivers/s390/crypto/pkey_sysfs.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/crypto/pkey_sysfs.c
Extension
.c
Size
18186 bytes
Lines
647
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 *  pkey module sysfs related functions
 *
 *  Copyright IBM Corp. 2024
 */

#define pr_fmt(fmt) "pkey: " fmt

#include <linux/sysfs.h>

#include "zcrypt_ccamisc.h"
#include "zcrypt_ep11misc.h"

#include "pkey_base.h"

/*
 * Wrapper around pkey_handler_gen_key() which deals with the
 * ENODEV return code and then tries to enforce a pkey handler
 * module load.
 */
static int sys_pkey_handler_gen_key(u32 keytype, u32 keysubtype,
				    u32 keybitsize, u32 flags,
				    u8 *keybuf, u32 *keybuflen, u32 *keyinfo)
{
	int rc;

	rc = pkey_handler_gen_key(NULL, 0,
				  keytype, keysubtype,
				  keybitsize, flags,
				  keybuf, keybuflen, keyinfo, 0);
	if (rc == -ENODEV) {
		pkey_handler_request_modules();
		rc = pkey_handler_gen_key(NULL, 0,
					  keytype, keysubtype,
					  keybitsize, flags,
					  keybuf, keybuflen, keyinfo, 0);
	}

	return rc;
}

/*
 * Sysfs attribute read function for all protected key binary attributes.
 * The implementation can not deal with partial reads, because a new random
 * protected key blob is generated with each read. In case of partial reads
 * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
 */
static ssize_t pkey_protkey_aes_attr_read(u32 keytype, bool is_xts, char *buf,
					  loff_t off, size_t count)
{
	struct protaeskeytoken protkeytoken;
	struct pkey_protkey protkey;
	int rc;

	if (off != 0 || count < sizeof(protkeytoken))
		return -EINVAL;
	if (is_xts)
		if (count < 2 * sizeof(protkeytoken))
			return -EINVAL;

	memset(&protkeytoken, 0, sizeof(protkeytoken));
	protkeytoken.type = TOKTYPE_NON_CCA;
	protkeytoken.version = TOKVER_PROTECTED_KEY;
	protkeytoken.keytype = keytype;

	protkey.len = sizeof(protkey.protkey);
	rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
				      protkey.protkey, &protkey.len,
				      &protkey.type);
	if (rc)
		return rc;

	protkeytoken.len = protkey.len;
	memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len);

	memcpy(buf, &protkeytoken, sizeof(protkeytoken));

	if (is_xts) {
		/* xts needs a second protected key, reuse protkey struct */
		protkey.len = sizeof(protkey.protkey);
		rc = sys_pkey_handler_gen_key(keytype, PKEY_TYPE_PROTKEY, 0, 0,
					      protkey.protkey, &protkey.len,
					      &protkey.type);
		if (rc)
			return rc;

		protkeytoken.len = protkey.len;
		memcpy(&protkeytoken.protkey, &protkey.protkey, protkey.len);

Annotation

Implementation Notes