drivers/s390/crypto/pkey_uv.c

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

File Facts

System
Linux kernel
Corpus path
drivers/s390/crypto/pkey_uv.c
Extension
.c
Size
7026 bytes
Lines
318
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

struct uvsecrettoken {
	u8  type;		/* 0x00 = TOKTYPE_NON_CCA */
	u8  res0[3];
	u8  version;		/* 0x09 = TOKVER_UV_SECRET */
	u8  res1[3];
	u16 secret_type;	/* one of enum uv_secret_types from uv.h */
	u16 secret_len;		/* length in bytes of the secret */
	u8  secret_id[UV_SECRET_ID_LEN]; /* the secret id for this secret */
} __packed;

/*
 * Check key blob for known and supported UV key.
 */
static bool is_uv_key(const u8 *key, u32 keylen)
{
	struct uvsecrettoken *t = (struct uvsecrettoken *)key;

	if (keylen < sizeof(*t))
		return false;

	switch (t->type) {
	case TOKTYPE_NON_CCA:
		switch (t->version) {
		case TOKVER_UV_SECRET:
			switch (t->secret_type) {
			case UV_SECRET_AES_128:
			case UV_SECRET_AES_192:
			case UV_SECRET_AES_256:
			case UV_SECRET_AES_XTS_128:
			case UV_SECRET_AES_XTS_256:
			case UV_SECRET_HMAC_SHA_256:
			case UV_SECRET_HMAC_SHA_512:
			case UV_SECRET_ECDSA_P256:
			case UV_SECRET_ECDSA_P384:
			case UV_SECRET_ECDSA_P521:
			case UV_SECRET_ECDSA_ED25519:
			case UV_SECRET_ECDSA_ED448:
				return true;
			default:
				return false;
			}
		default:
			return false;
		}
	default:
		return false;
	}
}

static bool is_uv_keytype(enum pkey_key_type keytype)
{
	switch (keytype) {
	case PKEY_TYPE_UVSECRET:
		return true;
	default:
		return false;
	}
}

static int get_secret_metadata(const u8 secret_id[UV_SECRET_ID_LEN],
			       struct uv_secret_list_item_hdr *secret)
{
	int rc;

	mutex_lock(&uv_list_mutex);
	memset(uv_list, 0, sizeof(*uv_list));
	rc = uv_find_secret(secret_id, uv_list, secret);
	mutex_unlock(&uv_list_mutex);

	return rc;
}

static int retrieve_secret(const u8 secret_id[UV_SECRET_ID_LEN],
			   u16 *secret_type, u8 *buf, u32 *buflen)
{
	struct uv_secret_list_item_hdr secret_meta_data;
	int rc;

	rc = get_secret_metadata(secret_id, &secret_meta_data);
	if (rc)
		return rc;

	if (*buflen < secret_meta_data.length)
		return -EINVAL;

	rc = uv_retrieve_secret(secret_meta_data.index,
				buf, secret_meta_data.length);
	if (rc)
		return rc;

Annotation

Implementation Notes