summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.ibm.com>2026-03-18 19:41:31 +0300
committerVasily Gorbik <gor@linux.ibm.com>2026-03-24 23:00:42 +0300
commit227a9197bace4871c64ccd43b4946fc2886083b8 (patch)
tree947347de6141460052949a6c2c09da7859907fee
parentecd2fd113e89978ca750a81dea033a2e9f3347df (diff)
downloadlinux-227a9197bace4871c64ccd43b4946fc2886083b8.tar.xz
s390/zcrypt: Rework MKVP fields and handling
In general all MKVPs (Master Key Verification Pattern) are binary data - usually some kind of shortened hash value e.g. sha256. Some code parts however used some u64 type which made compares a little bit easier. Anyway this is binary data and so all fields related to MKVP are now u8[] and function parameters use (const) u8 * now. The sysfs emit for the MKVPs also has been adapted to first format the MKVP as hex string into a buffer and then use %s with sysfs_emit_at() to generate the sysfs output. The patch also include a simple whitespace fix. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
-rw-r--r--drivers/s390/crypto/pkey_cca.c48
-rw-r--r--drivers/s390/crypto/zcrypt_ccamisc.c26
-rw-r--r--drivers/s390/crypto/zcrypt_ccamisc.h24
-rw-r--r--drivers/s390/crypto/zcrypt_cex4.c110
4 files changed, 123 insertions, 85 deletions
diff --git a/drivers/s390/crypto/pkey_cca.c b/drivers/s390/crypto/pkey_cca.c
index 9bfb518db893..4bc47952324e 100644
--- a/drivers/s390/crypto/pkey_cca.c
+++ b/drivers/s390/crypto/pkey_cca.c
@@ -87,50 +87,52 @@ static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
zcrypt_wait_api_operational();
if (hdr->type == TOKTYPE_CCA_INTERNAL) {
- u64 cur_mkvp = 0, old_mkvp = 0;
+ const u8 *ptr_cur_mkvp = NULL;
+ const u8 *ptr_old_mkvp = NULL;
int minhwtype = ZCRYPT_CEX3C;
if (hdr->version == TOKVER_CCA_AES) {
struct secaeskeytoken *t = (struct secaeskeytoken *)key;
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
- cur_mkvp = t->mkvp;
+ ptr_cur_mkvp = t->mkvp;
if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
- old_mkvp = t->mkvp;
+ ptr_old_mkvp = t->mkvp;
} else if (hdr->version == TOKVER_CCA_VLSC) {
struct cipherkeytoken *t = (struct cipherkeytoken *)key;
minhwtype = ZCRYPT_CEX6;
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
- cur_mkvp = t->mkvp0;
+ ptr_cur_mkvp = t->mkvp0;
if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
- old_mkvp = t->mkvp0;
+ ptr_old_mkvp = t->mkvp0;
} else {
/* unknown CCA internal token type */
return -EINVAL;
}
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, AES_MK_SET,
- cur_mkvp, old_mkvp, xflags);
+ ptr_cur_mkvp, ptr_old_mkvp, xflags);
if (rc)
goto out;
} else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
struct eccprivkeytoken *t = (struct eccprivkeytoken *)key;
- u64 cur_mkvp = 0, old_mkvp = 0;
+ const u8 *ptr_cur_mkvp = NULL;
+ const u8 *ptr_old_mkvp = NULL;
if (t->secid == 0x20) {
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
- cur_mkvp = t->mkvp;
+ ptr_cur_mkvp = t->mkvp;
if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
- old_mkvp = t->mkvp;
+ ptr_old_mkvp = t->mkvp;
} else {
/* unknown CCA internal 2 token type */
return -EINVAL;
}
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, APKA_MK_SET,
- cur_mkvp, old_mkvp, xflags);
+ ptr_cur_mkvp, ptr_old_mkvp, xflags);
if (rc)
goto out;
@@ -167,31 +169,33 @@ static int cca_apqns4type(enum pkey_key_type ktype,
zcrypt_wait_api_operational();
if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) {
- u64 cur_mkvp = 0, old_mkvp = 0;
+ const u8 *ptr_cur_mkvp = NULL;
+ const u8 *ptr_old_mkvp = NULL;
int minhwtype = ZCRYPT_CEX3C;
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
- cur_mkvp = *((u64 *)cur_mkvp);
+ ptr_cur_mkvp = cur_mkvp;
if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
- old_mkvp = *((u64 *)alt_mkvp);
+ ptr_old_mkvp = alt_mkvp;
if (ktype == PKEY_TYPE_CCA_CIPHER)
minhwtype = ZCRYPT_CEX6;
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
minhwtype, AES_MK_SET,
- cur_mkvp, old_mkvp, xflags);
+ ptr_cur_mkvp, ptr_old_mkvp, xflags);
if (rc)
goto out;
} else if (ktype == PKEY_TYPE_CCA_ECC) {
- u64 cur_mkvp = 0, old_mkvp = 0;
+ const u8 *ptr_cur_mkvp = NULL;
+ const u8 *ptr_old_mkvp = NULL;
if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
- cur_mkvp = *((u64 *)cur_mkvp);
+ ptr_cur_mkvp = cur_mkvp;
if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
- old_mkvp = *((u64 *)alt_mkvp);
+ ptr_old_mkvp = alt_mkvp;
rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
ZCRYPT_CEX7, APKA_MK_SET,
- cur_mkvp, old_mkvp, xflags);
+ ptr_cur_mkvp, ptr_old_mkvp, xflags);
if (rc)
goto out;
@@ -487,14 +491,14 @@ static int cca_verifykey(const u8 *key, u32 keylen,
*keybitsize = t->bitsize;
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX3C, AES_MK_SET,
- t->mkvp, 0, xflags);
+ t->mkvp, NULL, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
nr_apqns = ARRAY_SIZE(apqns);
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX3C, AES_MK_SET,
- 0, t->mkvp, xflags);
+ NULL, t->mkvp, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
@@ -521,14 +525,14 @@ static int cca_verifykey(const u8 *key, u32 keylen,
*keybitsize = PKEY_SIZE_AES_256;
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX6, AES_MK_SET,
- t->mkvp0, 0, xflags);
+ t->mkvp0, NULL, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
nr_apqns = ARRAY_SIZE(apqns);
rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
ZCRYPT_CEX6, AES_MK_SET,
- 0, t->mkvp0, xflags);
+ NULL, t->mkvp0, xflags);
if (!rc)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 573bad1d6d86..3727e0df9827 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -1708,8 +1708,8 @@ out:
EXPORT_SYMBOL(cca_get_info);
int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
- int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
- u32 xflags)
+ int minhwtype, int mktype,
+ const u8 *ptr_cur_mkvp, const u8 *ptr_old_mkvp, u32 xflags)
{
struct zcrypt_device_status_ext *device_status;
int i, card, dom, curmatch, oldmatch;
@@ -1753,20 +1753,28 @@ int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
/* check min hardware type */
if (minhwtype > 0 && minhwtype > ci.hwtype)
continue;
- if (cur_mkvp || old_mkvp) {
+ if (ptr_cur_mkvp || ptr_old_mkvp) {
/* check mkvps */
curmatch = oldmatch = 0;
if (mktype == AES_MK_SET) {
- if (cur_mkvp && cur_mkvp == ci.cur_aes_mkvp)
+ if (ptr_cur_mkvp &&
+ !memcmp(ptr_cur_mkvp, ci.cur_aes_mkvp,
+ sizeof(ci.cur_aes_mkvp)))
curmatch = 1;
- if (old_mkvp && ci.old_aes_mk_state == '2' &&
- old_mkvp == ci.old_aes_mkvp)
+ if (ptr_old_mkvp &&
+ ci.old_aes_mk_state == '2' &&
+ !memcmp(ptr_old_mkvp, ci.old_aes_mkvp,
+ sizeof(ci.old_aes_mkvp)))
oldmatch = 1;
} else {
- if (cur_mkvp && cur_mkvp == ci.cur_apka_mkvp)
+ if (ptr_cur_mkvp &&
+ !memcmp(ptr_cur_mkvp, ci.cur_apka_mkvp,
+ sizeof(ci.cur_apka_mkvp)))
curmatch = 1;
- if (old_mkvp && ci.old_apka_mk_state == '2' &&
- old_mkvp == ci.old_apka_mkvp)
+ if (ptr_old_mkvp &&
+ ci.old_apka_mk_state == '2' &&
+ !memcmp(ptr_old_mkvp, ci.old_apka_mkvp,
+ sizeof(ci.old_apka_mkvp)))
oldmatch = 1;
}
if (curmatch + oldmatch < 1)
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
index 1ecc4e37e9ad..06507363947b 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.h
+++ b/drivers/s390/crypto/zcrypt_ccamisc.h
@@ -47,7 +47,7 @@ struct secaeskeytoken {
u8 res1[1];
u8 flag; /* key flags */
u8 res2[1];
- u64 mkvp; /* master key verification pattern */
+ u8 mkvp[8]; /* master key verification pattern */
u8 key[32]; /* key value (encrypted) */
u8 cv[8]; /* control vector */
u16 bitsize; /* key bit size */
@@ -64,8 +64,8 @@ struct cipherkeytoken {
u8 res1[3];
u8 kms; /* key material state, 0x03 means wrapped with MK */
u8 kvpt; /* key verification pattern type, should be 0x01 */
- u64 mkvp0; /* master key verification pattern, lo part */
- u64 mkvp1; /* master key verification pattern, hi part (unused) */
+ u8 mkvp0[8]; /* master key verification pattern, lo part */
+ u8 mkvp1[8]; /* master key verification pattern, hi part (unused) */
u8 eskwm; /* encrypted section key wrapping method */
u8 hashalg; /* hash algorithmus used for wrapping key */
u8 plfver; /* pay load format version */
@@ -113,7 +113,7 @@ struct eccprivkeytoken {
u8 ksrc; /* key source */
u16 pbitlen; /* length of prime p in bits */
u16 ibmadlen; /* IBM associated data length in bytes */
- u64 mkvp; /* master key verification pattern */
+ u8 mkvp[8]; /* master key verification pattern */
u8 opk[48]; /* encrypted object protection key data */
u16 adatalen; /* associated data length in bytes */
u16 fseclen; /* formatted section length in bytes */
@@ -227,8 +227,8 @@ int cca_query_crypto_facility(u16 cardnr, u16 domain,
* If no apqn meeting the criteria is found, -ENODEV is returned.
*/
int cca_findcard2(u32 *apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
- int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
- u32 xflags);
+ int minhwtype, int mktype,
+ const u8 *cur_mkvp, const u8 *old_mkvp, u32 xflags);
#define AES_MK_SET 0
#define APKA_MK_SET 1
@@ -245,12 +245,12 @@ struct cca_info {
char new_asym_mk_state; /* '1' empty, '2' partially full, '3' full */
char cur_asym_mk_state; /* '1' invalid, '2' valid */
char old_asym_mk_state; /* '1' invalid, '2' valid */
- u64 new_aes_mkvp; /* truncated sha256 of new aes master key */
- u64 cur_aes_mkvp; /* truncated sha256 of current aes master key */
- u64 old_aes_mkvp; /* truncated sha256 of old aes master key */
- u64 new_apka_mkvp; /* truncated sha256 of new apka master key */
- u64 cur_apka_mkvp; /* truncated sha256 of current apka mk */
- u64 old_apka_mkvp; /* truncated sha256 of old apka mk */
+ u8 new_aes_mkvp[8]; /* truncated sha256 of new aes master key */
+ u8 cur_aes_mkvp[8]; /* truncated sha256 of current aes master key */
+ u8 old_aes_mkvp[8]; /* truncated sha256 of old aes master key */
+ u8 new_apka_mkvp[8]; /* truncated sha256 of new apka master key */
+ u8 cur_apka_mkvp[8]; /* truncated sha256 of current apka mk */
+ u8 old_apka_mkvp[8]; /* truncated sha256 of old apka mk */
u8 new_asym_mkvp[16]; /* verify pattern of new asym master key */
u8 cur_asym_mkvp[16]; /* verify pattern of current asym master key */
u8 old_asym_mkvp[16]; /* verify pattern of old asym master key */
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
index e9a984903bff..7080de18ff7b 100644
--- a/drivers/s390/crypto/zcrypt_cex4.c
+++ b/drivers/s390/crypto/zcrypt_cex4.c
@@ -103,9 +103,19 @@ static const struct attribute_group cca_card_attr_grp = {
.attrs = cca_card_attrs,
};
- /*
- * CCA queue additional device attributes
- */
+/*
+ * Simple helper macro to format raw mkvp byte array into hex
+ */
+#define MKVP_TO_HEXBUF(mkvp, buf) \
+ do { \
+ BUILD_BUG_ON(sizeof(buf) <= 2 * sizeof(mkvp)); \
+ bin2hex(buf, mkvp, sizeof(mkvp)); \
+ buf[2 * sizeof(mkvp)] = '\0'; \
+ } while (0)
+
+/*
+ * CCA queue additional device attributes
+ */
static ssize_t cca_mkvps_show(struct device *dev,
struct device_attribute *attr,
char *buf)
@@ -114,6 +124,7 @@ static ssize_t cca_mkvps_show(struct device *dev,
static const char * const cao_state[] = { "invalid", "valid" };
struct zcrypt_queue *zq = dev_get_drvdata(dev);
struct cca_info ci;
+ char hexbuf[2 * 16 + 1];
int n = 0;
memset(&ci, 0, sizeof(ci));
@@ -122,71 +133,86 @@ static ssize_t cca_mkvps_show(struct device *dev,
AP_QID_QUEUE(zq->queue->qid),
&ci, 0);
- if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
- n += sysfs_emit_at(buf, n, "AES NEW: %s 0x%016llx\n",
+ if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3') {
+ MKVP_TO_HEXBUF(ci.new_aes_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "AES NEW: %s 0x%s\n",
new_state[ci.new_aes_mk_state - '1'],
- ci.new_aes_mkvp);
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "AES NEW: - -\n");
+ }
- if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')
- n += sysfs_emit_at(buf, n, "AES CUR: %s 0x%016llx\n",
+ if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2') {
+ MKVP_TO_HEXBUF(ci.cur_aes_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "AES CUR: %s 0x%s\n",
cao_state[ci.cur_aes_mk_state - '1'],
- ci.cur_aes_mkvp);
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "AES CUR: - -\n");
+ }
- if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2')
- n += sysfs_emit_at(buf, n, "AES OLD: %s 0x%016llx\n",
+ if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2') {
+ MKVP_TO_HEXBUF(ci.old_aes_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "AES OLD: %s 0x%s\n",
cao_state[ci.old_aes_mk_state - '1'],
- ci.old_aes_mkvp);
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "AES OLD: - -\n");
+ }
- if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')
- n += sysfs_emit_at(buf, n, "APKA NEW: %s 0x%016llx\n",
+ if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3') {
+ MKVP_TO_HEXBUF(ci.new_apka_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "APKA NEW: %s 0x%s\n",
new_state[ci.new_apka_mk_state - '1'],
- ci.new_apka_mkvp);
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "APKA NEW: - -\n");
+ }
- if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')
- n += sysfs_emit_at(buf, n, "APKA CUR: %s 0x%016llx\n",
+ if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2') {
+ MKVP_TO_HEXBUF(ci.cur_apka_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "APKA CUR: %s 0x%s\n",
cao_state[ci.cur_apka_mk_state - '1'],
- ci.cur_apka_mkvp);
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "APKA CUR: - -\n");
+ }
- if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')
- n += sysfs_emit_at(buf, n, "APKA OLD: %s 0x%016llx\n",
+ if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2') {
+ MKVP_TO_HEXBUF(ci.old_apka_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "APKA OLD: %s 0x%s\n",
cao_state[ci.old_apka_mk_state - '1'],
- ci.old_apka_mkvp);
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "APKA OLD: - -\n");
+ }
- if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3')
- n += sysfs_emit_at(buf, n, "ASYM NEW: %s 0x%016llx%016llx\n",
+ if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3') {
+ MKVP_TO_HEXBUF(ci.new_asym_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "ASYM NEW: %s 0x%s\n",
new_state[ci.new_asym_mk_state - '1'],
- *((u64 *)(ci.new_asym_mkvp)),
- *((u64 *)(ci.new_asym_mkvp + sizeof(u64))));
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "ASYM NEW: - -\n");
+ }
- if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2')
- n += sysfs_emit_at(buf, n, "ASYM CUR: %s 0x%016llx%016llx\n",
+ if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2') {
+ MKVP_TO_HEXBUF(ci.cur_asym_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "ASYM CUR: %s 0x%s\n",
cao_state[ci.cur_asym_mk_state - '1'],
- *((u64 *)(ci.cur_asym_mkvp)),
- *((u64 *)(ci.cur_asym_mkvp + sizeof(u64))));
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "ASYM CUR: - -\n");
+ }
- if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2')
- n += sysfs_emit_at(buf, n, "ASYM OLD: %s 0x%016llx%016llx\n",
+ if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2') {
+ MKVP_TO_HEXBUF(ci.old_asym_mkvp, hexbuf);
+ n += sysfs_emit_at(buf, n, "ASYM OLD: %s 0x%s\n",
cao_state[ci.old_asym_mk_state - '1'],
- *((u64 *)(ci.old_asym_mkvp)),
- *((u64 *)(ci.old_asym_mkvp + sizeof(u64))));
- else
+ hexbuf);
+ } else {
n += sysfs_emit_at(buf, n, "ASYM OLD: - -\n");
+ }
return n;
}