diff options
-rw-r--r-- | drivers/s390/crypto/pkey_api.c | 18 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_ccamisc.c | 85 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_ccamisc.h | 30 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex2c.c | 39 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex4.c | 39 |
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; } |