summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/crypto/pkey_api.c18
-rw-r--r--drivers/s390/crypto/zcrypt_ccamisc.c85
-rw-r--r--drivers/s390/crypto/zcrypt_ccamisc.h30
-rw-r--r--drivers/s390/crypto/zcrypt_cex2c.c39
-rw-r--r--drivers/s390/crypto/zcrypt_cex4.c39
5 files changed, 154 insertions, 57 deletions
diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c
index 5896e5282a4e..e48c13acc5da 100644
--- a/drivers/s390/crypto/pkey_api.c
+++ b/drivers/s390/crypto/pkey_api.c
@@ -661,13 +661,14 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
*ksize = (enum pkey_key_size) t->bitsize;
rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
- ZCRYPT_CEX3C, t->mkvp, 0, 1);
+ ZCRYPT_CEX3C, AES_MK_SET, t->mkvp, 0, 1);
if (rc == 0 && flags)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
rc = cca_findcard2(&_apqns, &_nr_apqns,
*cardnr, *domain,
- ZCRYPT_CEX3C, 0, t->mkvp, 1);
+ ZCRYPT_CEX3C, AES_MK_SET,
+ 0, t->mkvp, 1);
if (rc == 0 && flags)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
@@ -697,13 +698,14 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
}
rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
- ZCRYPT_CEX6, t->mkvp0, 0, 1);
+ ZCRYPT_CEX6, AES_MK_SET, t->mkvp0, 0, 1);
if (rc == 0 && flags)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
if (rc == -ENODEV) {
rc = cca_findcard2(&_apqns, &_nr_apqns,
*cardnr, *domain,
- ZCRYPT_CEX6, 0, t->mkvp0, 1);
+ ZCRYPT_CEX6, AES_MK_SET,
+ 0, t->mkvp0, 1);
if (rc == 0 && flags)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
@@ -863,7 +865,8 @@ static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
return -EINVAL;
}
rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
- minhwtype, cur_mkvp, old_mkvp, 1);
+ minhwtype, AES_MK_SET,
+ cur_mkvp, old_mkvp, 1);
if (rc)
goto out;
} else
@@ -900,7 +903,8 @@ static int pkey_apqns4keytype(enum pkey_key_type ktype,
if (ktype == PKEY_TYPE_CCA_CIPHER)
minhwtype = ZCRYPT_CEX6;
rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
- minhwtype, cur_mkvp, old_mkvp, 1);
+ minhwtype, AES_MK_SET,
+ cur_mkvp, old_mkvp, 1);
if (rc)
goto out;
} else if (ktype == PKEY_TYPE_EP11) {
@@ -1589,7 +1593,7 @@ static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
/* build a list of apqns able to generate an cipher key */
rc = cca_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
- ZCRYPT_CEX6, 0, 0, 0);
+ ZCRYPT_CEX6, 0, 0, 0, 0);
if (rc)
return rc;
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.c b/drivers/s390/crypto/zcrypt_ccamisc.c
index 40b59a77ec0c..e969188a1ec4 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.c
+++ b/drivers/s390/crypto/zcrypt_ccamisc.c
@@ -1506,21 +1506,38 @@ static int fetch_cca_info(u16 cardnr, u16 domain, struct cca_info *ci)
rarray, &rlen, varray, &vlen);
if (rc == 0 && rlen >= 10*8 && vlen >= 204) {
memcpy(ci->serial, rarray, 8);
- ci->new_mk_state = (char) rarray[7*8];
- ci->cur_mk_state = (char) rarray[8*8];
- ci->old_mk_state = (char) rarray[9*8];
- if (ci->old_mk_state == '2')
- memcpy(&ci->old_mkvp, varray + 172, 8);
- if (ci->cur_mk_state == '2')
- memcpy(&ci->cur_mkvp, varray + 184, 8);
- if (ci->new_mk_state == '3')
- memcpy(&ci->new_mkvp, varray + 196, 8);
- found = 1;
+ ci->new_aes_mk_state = (char) rarray[7*8];
+ ci->cur_aes_mk_state = (char) rarray[8*8];
+ ci->old_aes_mk_state = (char) rarray[9*8];
+ if (ci->old_aes_mk_state == '2')
+ memcpy(&ci->old_aes_mkvp, varray + 172, 8);
+ if (ci->cur_aes_mk_state == '2')
+ memcpy(&ci->cur_aes_mkvp, varray + 184, 8);
+ if (ci->new_aes_mk_state == '3')
+ memcpy(&ci->new_aes_mkvp, varray + 196, 8);
+ found++;
+ }
+ if (!found)
+ goto out;
+ rlen = vlen = PAGE_SIZE/2;
+ rc = cca_query_crypto_facility(cardnr, domain, "STATICSB",
+ rarray, &rlen, varray, &vlen);
+ if (rc == 0 && rlen >= 10*8 && vlen >= 240) {
+ ci->new_apka_mk_state = (char) rarray[7*8];
+ ci->cur_apka_mk_state = (char) rarray[8*8];
+ ci->old_apka_mk_state = (char) rarray[9*8];
+ if (ci->old_apka_mk_state == '2')
+ memcpy(&ci->old_apka_mkvp, varray + 208, 8);
+ if (ci->cur_apka_mk_state == '2')
+ memcpy(&ci->cur_apka_mkvp, varray + 220, 8);
+ if (ci->new_apka_mk_state == '3')
+ memcpy(&ci->new_apka_mkvp, varray + 232, 8);
+ found++;
}
+out:
free_page((unsigned long) pg);
-
- return found ? 0 : -ENOENT;
+ return found == 2 ? 0 : -ENOENT;
}
/*
@@ -1574,16 +1591,16 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
/* enabled CCA card, check current mkvp from cache */
if (cca_info_cache_fetch(card, dom, &ci) == 0 &&
ci.hwtype >= minhwtype &&
- ci.cur_mk_state == '2' &&
- ci.cur_mkvp == mkvp) {
+ ci.cur_aes_mk_state == '2' &&
+ ci.cur_aes_mkvp == mkvp) {
if (!verify)
break;
/* verify: refresh card info */
if (fetch_cca_info(card, dom, &ci) == 0) {
cca_info_cache_update(card, dom, &ci);
if (ci.hwtype >= minhwtype &&
- ci.cur_mk_state == '2' &&
- ci.cur_mkvp == mkvp)
+ ci.cur_aes_mk_state == '2' &&
+ ci.cur_aes_mkvp == mkvp)
break;
}
}
@@ -1605,12 +1622,12 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
if (fetch_cca_info(card, dom, &ci) == 0) {
cca_info_cache_update(card, dom, &ci);
if (ci.hwtype >= minhwtype &&
- ci.cur_mk_state == '2' &&
- ci.cur_mkvp == mkvp)
+ ci.cur_aes_mk_state == '2' &&
+ ci.cur_aes_mkvp == mkvp)
break;
if (ci.hwtype >= minhwtype &&
- ci.old_mk_state == '2' &&
- ci.old_mkvp == mkvp &&
+ ci.old_aes_mk_state == '2' &&
+ ci.old_aes_mkvp == mkvp &&
oi < 0)
oi = i;
}
@@ -1664,7 +1681,8 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify)
EXPORT_SYMBOL(cca_findcard);
int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
- int minhwtype, u64 cur_mkvp, u64 old_mkvp, int verify)
+ int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
+ int verify)
{
struct zcrypt_device_status_ext *device_status;
u32 *_apqns = NULL, _nr_apqns = 0;
@@ -1706,7 +1724,9 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
if (cca_get_info(card, dom, &ci, verify))
continue;
/* current master key needs to be valid */
- if (ci.cur_mk_state != '2')
+ if (mktype == AES_MK_SET && ci.cur_aes_mk_state != '2')
+ continue;
+ if (mktype == APKA_MK_SET && ci.cur_apka_mk_state != '2')
continue;
/* check min hardware type */
if (minhwtype > 0 && minhwtype > ci.hwtype)
@@ -1714,13 +1734,20 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
if (cur_mkvp || old_mkvp) {
/* check mkvps */
curmatch = oldmatch = 0;
- if (cur_mkvp && cur_mkvp == ci.cur_mkvp)
- curmatch = 1;
- if (old_mkvp && ci.old_mk_state == '2' &&
- old_mkvp == ci.old_mkvp)
- oldmatch = 1;
- if ((cur_mkvp || old_mkvp) &&
- (curmatch + oldmatch < 1))
+ if (mktype == AES_MK_SET) {
+ if (cur_mkvp && cur_mkvp == ci.cur_aes_mkvp)
+ curmatch = 1;
+ if (old_mkvp && ci.old_aes_mk_state == '2' &&
+ old_mkvp == ci.old_aes_mkvp)
+ oldmatch = 1;
+ } else {
+ if (cur_mkvp && cur_mkvp == ci.cur_apka_mkvp)
+ curmatch = 1;
+ if (old_mkvp && ci.old_apka_mk_state == '2' &&
+ old_mkvp == ci.old_apka_mkvp)
+ oldmatch = 1;
+ }
+ if (curmatch + oldmatch < 1)
continue;
}
/* apqn passed all filtering criterons, add to the array */
diff --git a/drivers/s390/crypto/zcrypt_ccamisc.h b/drivers/s390/crypto/zcrypt_ccamisc.h
index 8b7a641671c9..4d88a1d6af21 100644
--- a/drivers/s390/crypto/zcrypt_ccamisc.h
+++ b/drivers/s390/crypto/zcrypt_ccamisc.h
@@ -186,6 +186,8 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify);
* - if verify is enabled and a cur_mkvp and/or old_mkvp
* value is given, then refetch the cca_info and make sure the current
* cur_mkvp or old_mkvp values of the apqn are used.
+ * The mktype determines which set of master keys to use:
+ * 0 = AES_MK_SET - AES MK set, 1 = APKA MK_SET - APKA MK set
* The array of apqn entries is allocated with kmalloc and returned in *apqns;
* the number of apqns stored into the list is returned in *nr_apqns. One apqn
* entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
@@ -194,18 +196,28 @@ int cca_findcard(const u8 *key, u16 *pcardnr, u16 *pdomain, int verify);
* -ENODEV is returned.
*/
int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
- int minhwtype, u64 cur_mkvp, u64 old_mkvp, int verify);
+ int minhwtype, int mktype, u64 cur_mkvp, u64 old_mkvp,
+ int verify);
+
+#define AES_MK_SET 0
+#define APKA_MK_SET 1
/* struct to hold info for each CCA queue */
struct cca_info {
- int hwtype; /* one of the defined AP_DEVICE_TYPE_* */
- char new_mk_state; /* '1' empty, '2' partially full, '3' full */
- char cur_mk_state; /* '1' invalid, '2' valid */
- char old_mk_state; /* '1' invalid, '2' valid */
- u64 new_mkvp; /* truncated sha256 hash of new master key */
- u64 cur_mkvp; /* truncated sha256 hash of current master key */
- u64 old_mkvp; /* truncated sha256 hash of old master key */
- char serial[9]; /* serial number string (8 ascii numbers + 0x00) */
+ int hwtype; /* one of the defined AP_DEVICE_TYPE_* */
+ char new_aes_mk_state; /* '1' empty, '2' partially full, '3' full */
+ char cur_aes_mk_state; /* '1' invalid, '2' valid */
+ char old_aes_mk_state; /* '1' invalid, '2' valid */
+ char new_apka_mk_state; /* '1' empty, '2' partially full, '3' full */
+ char cur_apka_mk_state; /* '1' invalid, '2' valid */
+ char old_apka_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 */
+ char serial[9]; /* serial number (8 ascii numbers + 0x00) */
};
/*
diff --git a/drivers/s390/crypto/zcrypt_cex2c.c b/drivers/s390/crypto/zcrypt_cex2c.c
index f00127a78bab..146eb9f24694 100644
--- a/drivers/s390/crypto/zcrypt_cex2c.c
+++ b/drivers/s390/crypto/zcrypt_cex2c.c
@@ -109,26 +109,53 @@ static ssize_t cca_mkvps_show(struct device *dev,
AP_QID_QUEUE(zq->queue->qid),
&ci, zq->online);
- if (ci.new_mk_state >= '1' && ci.new_mk_state <= '3')
+ if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
n = scnprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n",
- new_state[ci.new_mk_state - '1'], ci.new_mkvp);
+ new_state[ci.new_aes_mk_state - '1'],
+ ci.new_aes_mkvp);
else
n = scnprintf(buf, PAGE_SIZE, "AES NEW: - -\n");
- if (ci.cur_mk_state >= '1' && ci.cur_mk_state <= '2')
+ if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
"AES CUR: %s 0x%016llx\n",
- cao_state[ci.cur_mk_state - '1'], ci.cur_mkvp);
+ cao_state[ci.cur_aes_mk_state - '1'],
+ ci.cur_aes_mkvp);
else
n += scnprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n");
- if (ci.old_mk_state >= '1' && ci.old_mk_state <= '2')
+ if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
"AES OLD: %s 0x%016llx\n",
- cao_state[ci.old_mk_state - '1'], ci.old_mkvp);
+ cao_state[ci.old_aes_mk_state - '1'],
+ ci.old_aes_mkvp);
else
n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n");
+ if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')
+ n += scnprintf(buf + n, PAGE_SIZE - n,
+ "APKA NEW: %s 0x%016llx\n",
+ new_state[ci.new_apka_mk_state - '1'],
+ ci.new_apka_mkvp);
+ else
+ n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n");
+
+ if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')
+ n += scnprintf(buf + n, PAGE_SIZE - n,
+ "APKA CUR: %s 0x%016llx\n",
+ cao_state[ci.cur_apka_mk_state - '1'],
+ ci.cur_apka_mkvp);
+ else
+ n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n");
+
+ if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')
+ n += scnprintf(buf + n, PAGE_SIZE - n,
+ "APKA OLD: %s 0x%016llx\n",
+ cao_state[ci.old_apka_mk_state - '1'],
+ ci.old_apka_mkvp);
+ else
+ n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n");
+
return n;
}
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c
index dc20d983e468..d9ebe3a3c210 100644
--- a/drivers/s390/crypto/zcrypt_cex4.c
+++ b/drivers/s390/crypto/zcrypt_cex4.c
@@ -121,26 +121,53 @@ static ssize_t cca_mkvps_show(struct device *dev,
AP_QID_QUEUE(zq->queue->qid),
&ci, zq->online);
- if (ci.new_mk_state >= '1' && ci.new_mk_state <= '3')
+ if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
n = scnprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n",
- new_state[ci.new_mk_state - '1'], ci.new_mkvp);
+ new_state[ci.new_aes_mk_state - '1'],
+ ci.new_aes_mkvp);
else
n = scnprintf(buf, PAGE_SIZE, "AES NEW: - -\n");
- if (ci.cur_mk_state >= '1' && ci.cur_mk_state <= '2')
+ if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
"AES CUR: %s 0x%016llx\n",
- cao_state[ci.cur_mk_state - '1'], ci.cur_mkvp);
+ cao_state[ci.cur_aes_mk_state - '1'],
+ ci.cur_aes_mkvp);
else
n += scnprintf(buf + n, PAGE_SIZE - n, "AES CUR: - -\n");
- if (ci.old_mk_state >= '1' && ci.old_mk_state <= '2')
+ if (ci.old_aes_mk_state >= '1' && ci.old_aes_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
"AES OLD: %s 0x%016llx\n",
- cao_state[ci.old_mk_state - '1'], ci.old_mkvp);
+ cao_state[ci.old_aes_mk_state - '1'],
+ ci.old_aes_mkvp);
else
n += scnprintf(buf + n, PAGE_SIZE - n, "AES OLD: - -\n");
+ if (ci.new_apka_mk_state >= '1' && ci.new_apka_mk_state <= '3')
+ n += scnprintf(buf + n, PAGE_SIZE - n,
+ "APKA NEW: %s 0x%016llx\n",
+ new_state[ci.new_apka_mk_state - '1'],
+ ci.new_apka_mkvp);
+ else
+ n += scnprintf(buf + n, PAGE_SIZE - n, "APKA NEW: - -\n");
+
+ if (ci.cur_apka_mk_state >= '1' && ci.cur_apka_mk_state <= '2')
+ n += scnprintf(buf + n, PAGE_SIZE - n,
+ "APKA CUR: %s 0x%016llx\n",
+ cao_state[ci.cur_apka_mk_state - '1'],
+ ci.cur_apka_mkvp);
+ else
+ n += scnprintf(buf + n, PAGE_SIZE - n, "APKA CUR: - -\n");
+
+ if (ci.old_apka_mk_state >= '1' && ci.old_apka_mk_state <= '2')
+ n += scnprintf(buf + n, PAGE_SIZE - n,
+ "APKA OLD: %s 0x%016llx\n",
+ cao_state[ci.old_apka_mk_state - '1'],
+ ci.old_apka_mkvp);
+ else
+ n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n");
+
return n;
}