SHA256
1
0
forked from pool/s390-tools
s390-tools/s390-tools-03-zkey-Add-PVSECRETS-AES-key-type.patch
Nikolay Gueorguiev 7869bc9d34 - Applied additional patches ( jsc#PED-9561 ( jsc#IBM-1447 ) )
* s390-tools-01-zkey-Add-support-for-retrieving-a-list-of-ultravisor-secrets.patch
  * s390-tools-02-zkey-Add-the--pvsecrets-list-command.patch
  * s390-tools-03-zkey-Add-PVSECRETS-AES-key-type.patch
  * s390-tools-04-zkey-Add-the-pvsecrets-import-command.patch
  * s390-tools-05-zkey-Reject-key-generation-and-APQN-association-for-PVSECRET-AES-keys.patch
  * s390-tools-06-zkey-Reject-re-enciphering-of-PVSECRET-AES-keys.patch
  * s390-tools-07-zkey-Support-validation-of-key-of-type-PVSECRET-AES.patch
- Revendored vendor.tar.gz

OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=245
2025-01-30 08:40:14 +00:00

341 lines
10 KiB
Diff

From fdf66dc148c09f1d3300cd3378e3f75a83c6214e Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@linux.ibm.com>
Date: Thu, 15 Feb 2024 16:56:04 +0100
Subject: [PATCH] zkey: Add PVSECRETS-AES key type
Add the definitions and utility functions for the PVSECRETS-AES key type.
A PVSECRETS-AES key token contains the secret id of a protected
virtualization secret. It does not contain the key material, just a
reference to the key in the ultravisor.
When such a key token is used to perform crypto operations later on, the
PAES kernel cipher will obtain the protected key belonging to this secret
id with the help of the pkey kernel module.
Signed-off-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Jorg Schmidbauer <jschmidb@de.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
---
zkey/keystore.c | 4 +-
zkey/pkey.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++-
zkey/pkey.h | 38 ++++++++++++----
zkey/pvsecrets.h | 4 +-
4 files changed, 143 insertions(+), 13 deletions(-)
diff --git a/zkey/keystore.c b/zkey/keystore.c
index 9589d82d..771bc08d 100644
--- a/zkey/keystore.c
+++ b/zkey/keystore.c
@@ -3,7 +3,7 @@
*
* Keystore handling functions
*
- * Copyright IBM Corp. 2018, 2020
+ * Copyright IBM Corp. 2018, 2024
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -360,6 +360,8 @@ static int _keystore_valid_key_type(const char *key_type)
return 1;
if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0)
return 1;
+ if (strcasecmp(key_type, KEY_TYPE_PVSECRET_AES) == 0)
+ return 1;
return 0;
}
diff --git a/zkey/pkey.c b/zkey/pkey.c
index 821978bd..53c0a550 100644
--- a/zkey/pkey.c
+++ b/zkey/pkey.c
@@ -1,7 +1,7 @@
/*
* zkey - Generate, re-encipher, and validate secure keys
*
- * Copyright IBM Corp. 2018
+ * Copyright IBM Corp. 2018, 2024
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -26,6 +26,7 @@
#include "lib/util_panic.h"
#include "pkey.h"
+#include "pvsecrets.h"
#include "utils.h"
#ifndef AF_ALG
@@ -1719,6 +1720,38 @@ bool is_ep11_key_session_bound(const u8 *key, size_t key_size)
}
}
+/**
+ * Check if the specified key is a PVSECRET-AES key token.
+ *
+ * @param[in] key the secure key token
+ * @param[in] key_size the size of the secure key
+ *
+ * @returns true if the key is a PVSECRET token type
+ */
+bool is_pvsecret_aes_key(const u8 *key, size_t key_size)
+{
+ struct pvsecrettoken *pvsecret = (struct pvsecrettoken *)key;
+
+ if (key == NULL || key_size < PVSECRET_KEY_SIZE)
+ return false;
+
+ if (pvsecret->hdr.type != TOKEN_TYPE_NON_CCA)
+ return false;
+ if (pvsecret->hdr.version != TOKEN_VERSION_PVSECRET)
+ return false;
+
+ switch (pvsecret->secret_type) {
+ case UV_SECRET_TYPE_AES_128:
+ case UV_SECRET_TYPE_AES_192:
+ case UV_SECRET_TYPE_AES_256:
+ case UV_SECRET_TYPE_AES_XTS_128:
+ case UV_SECRET_TYPE_AES_XTS_256:
+ return true;
+ default:
+ return false;
+ }
+}
+
/**
* Check if the specified key is an XTS type key
*
@@ -1729,6 +1762,8 @@ bool is_ep11_key_session_bound(const u8 *key, size_t key_size)
*/
bool is_xts_key(const u8 *key, size_t key_size)
{
+ struct pvsecrettoken *pvsecret = (struct pvsecrettoken *)key;
+
if (is_cca_aes_data_key(key, key_size)) {
if (key_size == 2 * AESDATA_KEY_SIZE &&
is_cca_aes_data_key(key + AESDATA_KEY_SIZE,
@@ -1749,11 +1784,41 @@ bool is_xts_key(const u8 *key, size_t key_size)
is_ep11_aes_key_with_header(key + EP11_AES_KEY_SIZE,
key_size - EP11_AES_KEY_SIZE))
return true;
+ } else if (is_pvsecret_aes_key(key, key_size)) {
+ switch (pvsecret->secret_type) {
+ case UV_SECRET_TYPE_AES_XTS_128:
+ case UV_SECRET_TYPE_AES_XTS_256:
+ return true;
+ default:
+ return false;
+ }
}
return false;
}
+/**
+ * Check if the specified key is a secure key type (i.e. requires a crypto card)
+ *
+ * @param[in] key the secure key token
+ * @param[in] key_size the size of the secure key
+ *
+ * @returns true if the key is a secure key type
+ */
+bool is_secure_key(const u8 *key, size_t key_size)
+{
+ if (is_cca_aes_data_key(key, key_size))
+ return true;
+ if (is_cca_aes_cipher_key(key, key_size))
+ return true;
+ if (is_ep11_aes_key(key, key_size))
+ return true;
+ if (is_ep11_aes_key_with_header(key, key_size))
+ return true;
+
+ return false;
+}
+
/**
* Gets the size in bits of the effective key of the specified secure key
*
@@ -1771,6 +1836,7 @@ int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize)
struct aescipherkeytoken *cipherkey = (struct aescipherkeytoken *)key;
struct ep11keytoken *ep11key = (struct ep11keytoken *)key;
struct ep11kblob_header *hdr = (struct ep11kblob_header *)key;
+ struct pvsecrettoken *pvsecret = (struct pvsecrettoken *)key;
util_assert(bitsize != NULL, "Internal error: bitsize is NULL");
@@ -1805,6 +1871,26 @@ int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize)
(key + EP11_AES_KEY_SIZE);
*bitsize += hdr->bitlen;
}
+ } else if (is_pvsecret_aes_key(key, key_size)) {
+ switch (pvsecret->secret_type) {
+ case UV_SECRET_TYPE_AES_128:
+ *bitsize = 128;
+ break;
+ case UV_SECRET_TYPE_AES_192:
+ *bitsize = 192;
+ break;
+ case UV_SECRET_TYPE_AES_256:
+ *bitsize = 256;
+ break;
+ case UV_SECRET_TYPE_AES_XTS_128:
+ *bitsize = 128 * 2;
+ break;
+ case UV_SECRET_TYPE_AES_XTS_256:
+ *bitsize = 256 * 2;
+ break;
+ default:
+ return -EINVAL;
+ }
} else {
return -EINVAL;
}
@@ -1830,9 +1916,31 @@ const char *get_key_type(const u8 *key, size_t key_size)
return KEY_TYPE_EP11_AES;
if (is_ep11_aes_key_with_header(key, key_size))
return KEY_TYPE_EP11_AES;
+ if (is_pvsecret_aes_key(key, key_size))
+ return KEY_TYPE_PVSECRET_AES;
+
return NULL;
}
+/**
+ * Returns true if the key type is a secure key type
+ *
+ * @param[in] key_type the type of the key
+ *
+ * @returns true if the key type is a secure key type, false otherwise
+ */
+bool is_secure_key_type(const char *key_type)
+{
+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESCIPHER) == 0)
+ return true;
+ if (strcasecmp(key_type, KEY_TYPE_CCA_AESDATA) == 0)
+ return true;
+ if (strcasecmp(key_type, KEY_TYPE_EP11_AES) == 0)
+ return true;
+
+ return false;
+}
+
/**
* Returns the minimum card level for a specific key type
*
diff --git a/zkey/pkey.h b/zkey/pkey.h
index 3b57c5f0..ce3bd8bd 100644
--- a/zkey/pkey.h
+++ b/zkey/pkey.h
@@ -4,7 +4,7 @@
* This header file defines the interface to the pkey kernel module.
* It defines a set of IOCTL commands with its associated structures.
*
- * Copyright IBM Corp. 2017, 2018
+ * Copyright IBM Corp. 2017, 2024
*
* s390-tools is free software; you can redistribute it and/or modify
* it under the terms of the MIT license. See LICENSE for details.
@@ -41,6 +41,8 @@ struct tokenheader {
#define TOKEN_VERSION_EP11_AES 0x03
#define TOKEN_VERSION_EP11_AES_WITH_HEADER 0x06
#define TOKEN_VERSION_EP11_ECC_WITH_HEADER 0x07
+/* 0x08 is reserved for internal use */
+#define TOKEN_VERSION_PVSECRET 0x09
struct aesdatakeytoken {
u8 type; /* TOKEN_TYPE_INTERNAL (0x01) for internal key token */
@@ -116,6 +118,15 @@ struct ep11keytoken {
u8 padding[64];
} __packed;
+#define UV_SECRET_ID_LEN 32
+
+struct pvsecrettoken {
+ struct tokenheader hdr;
+ u16 secret_type; /* the secret type as the UV told us */
+ u16 secret_len; /* length in bytes of the secret */
+ u8 secretid[UV_SECRET_ID_LEN]; /* the secret id for this secret */
+} __packed;
+
#define ZERO_SESSION \
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
@@ -124,21 +135,26 @@ struct ep11keytoken {
#define EP11_KEY_SIZE sizeof(struct ep11keytoken)
#define EP11_AES_KEY_SIZE (sizeof(struct ep11kblob_header) + \
sizeof(struct ep11keytoken))
+#define PVSECRET_KEY_SIZE sizeof(struct pvsecrettoken)
/* MAX/MIN from zt_common.h produces warnings for variable length arrays */
#define _MIN(a, b) ((a) < (b) ? (a) : (b))
#define _MAX(a, b) ((a) > (b) ? (a) : (b))
#define MAX_SECURE_KEY_SIZE _MAX( \
- _MAX(EP11_KEY_SIZE, \
- EP11_AES_KEY_SIZE), \
- _MAX(AESDATA_KEY_SIZE, \
- AESCIPHER_KEY_SIZE))
+ _MAX( \
+ _MAX(EP11_KEY_SIZE, \
+ EP11_AES_KEY_SIZE), \
+ _MAX(AESDATA_KEY_SIZE, \
+ AESCIPHER_KEY_SIZE)), \
+ PVSECRET_KEY_SIZE)
#define MIN_SECURE_KEY_SIZE _MIN( \
- _MIN(EP11_KEY_SIZE, \
- EP11_AES_KEY_SIZE), \
- _MIN(AESDATA_KEY_SIZE, \
- AESCIPHER_KEY_SIZE))
+ _MIN( \
+ _MIN(EP11_KEY_SIZE, \
+ EP11_AES_KEY_SIZE), \
+ _MIN(AESDATA_KEY_SIZE, \
+ AESCIPHER_KEY_SIZE)), \
+ PVSECRET_KEY_SIZE)
struct pkey_seckey {
u8 seckey[AESDATA_KEY_SIZE]; /* the secure key blob */
@@ -285,6 +301,7 @@ struct pkey_apqns4keytype {
#define KEY_TYPE_CCA_AESDATA "CCA-AESDATA"
#define KEY_TYPE_CCA_AESCIPHER "CCA-AESCIPHER"
#define KEY_TYPE_EP11_AES "EP11-AES"
+#define KEY_TYPE_PVSECRET_AES "PVSECRET-AES"
#define DEFAULT_KEYBITS 256
#define PAES_BLOCK_SIZE 16
@@ -342,9 +359,12 @@ bool is_cca_aes_cipher_key(const u8 *key, size_t key_size);
bool is_ep11_aes_key(const u8 *key, size_t key_size);
bool is_ep11_aes_key_with_header(const u8 *key, size_t key_size);
bool is_ep11_key_session_bound(const u8 *key, size_t key_size);
+bool is_pvsecret_aes_key(const u8 *key, size_t key_size);
bool is_xts_key(const u8 *key, size_t key_size);
+bool is_secure_key(const u8 *key, size_t key_size);
int get_key_bit_size(const u8 *key, size_t key_size, size_t *bitsize);
const char *get_key_type(const u8 *key, size_t key_size);
+bool is_secure_key_type(const char *key_type);
int get_min_card_level_for_keytype(const char *key_type);
const struct fw_version *get_min_fw_version_for_keytype(const char *key_type);
enum card_type get_card_type_for_keytype(const char *key_type);
diff --git a/zkey/pvsecrets.h b/zkey/pvsecrets.h
index 6acebfdd..ad844035 100644
--- a/zkey/pvsecrets.h
+++ b/zkey/pvsecrets.h
@@ -15,6 +15,8 @@
#include "lib/zt_common.h"
+#include "pkey.h"
+
/*
* Definitions for the /dev/uv kernel module interface
*/
@@ -60,8 +62,6 @@ struct uvio_ioctl_cb {
#define UV_SECRET_TYPE_EDDSA_ED25519 0x14
#define UV_SECRET_TYPE_EDDSA_ED448 0x15
-#define UV_SECRET_ID_LEN 32
-
#define UVIO_LIST_SECRETS_MAX_LEN 0x8000
struct uvio_list_secret_entry {