From: Harald Freudenberger Date: Wed, 18 Mar 2026 16:41:31 +0000 (+0100) Subject: s390/zcrypt: Rework MKVP fields and handling X-Git-Tag: v7.1-rc1~50^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=227a9197bace4871c64ccd43b4946fc2886083b8;p=thirdparty%2Fkernel%2Flinux.git 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 Acked-by: Heiko Carstens Signed-off-by: Vasily Gorbik --- 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; }