in crypto/pkey_api.c [658:766]
static int pkey_verifykey2(const u8 *key, size_t keylen,
u16 *cardnr, u16 *domain,
enum pkey_key_type *ktype,
enum pkey_key_size *ksize, u32 *flags)
{
int rc;
u32 _nr_apqns, *_apqns = NULL;
struct keytoken_header *hdr = (struct keytoken_header *)key;
if (keylen < sizeof(struct keytoken_header))
return -EINVAL;
if (hdr->type == TOKTYPE_CCA_INTERNAL
&& hdr->version == TOKVER_CCA_AES) {
struct secaeskeytoken *t = (struct secaeskeytoken *)key;
rc = cca_check_secaeskeytoken(debug_info, 3, key, 0);
if (rc)
goto out;
if (ktype)
*ktype = PKEY_TYPE_CCA_DATA;
if (ksize)
*ksize = (enum pkey_key_size) t->bitsize;
rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
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, AES_MK_SET,
0, t->mkvp, 1);
if (rc == 0 && flags)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
if (rc)
goto out;
*cardnr = ((struct pkey_apqn *)_apqns)->card;
*domain = ((struct pkey_apqn *)_apqns)->domain;
} else if (hdr->type == TOKTYPE_CCA_INTERNAL
&& hdr->version == TOKVER_CCA_VLSC) {
struct cipherkeytoken *t = (struct cipherkeytoken *)key;
rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1);
if (rc)
goto out;
if (ktype)
*ktype = PKEY_TYPE_CCA_CIPHER;
if (ksize) {
*ksize = PKEY_SIZE_UNKNOWN;
if (!t->plfver && t->wpllen == 512)
*ksize = PKEY_SIZE_AES_128;
else if (!t->plfver && t->wpllen == 576)
*ksize = PKEY_SIZE_AES_192;
else if (!t->plfver && t->wpllen == 640)
*ksize = PKEY_SIZE_AES_256;
}
rc = cca_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
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, AES_MK_SET,
0, t->mkvp0, 1);
if (rc == 0 && flags)
*flags = PKEY_FLAGS_MATCH_ALT_MKVP;
}
if (rc)
goto out;
*cardnr = ((struct pkey_apqn *)_apqns)->card;
*domain = ((struct pkey_apqn *)_apqns)->domain;
} else if (hdr->type == TOKTYPE_NON_CCA
&& hdr->version == TOKVER_EP11_AES) {
struct ep11keyblob *kb = (struct ep11keyblob *)key;
rc = ep11_check_aes_key(debug_info, 3, key, keylen, 1);
if (rc)
goto out;
if (ktype)
*ktype = PKEY_TYPE_EP11;
if (ksize)
*ksize = kb->head.keybitlen;
rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
ZCRYPT_CEX7, EP11_API_V, kb->wkvp);
if (rc)
goto out;
if (flags)
*flags = PKEY_FLAGS_MATCH_CUR_MKVP;
*cardnr = ((struct pkey_apqn *)_apqns)->card;
*domain = ((struct pkey_apqn *)_apqns)->domain;
} else
rc = -EINVAL;
out:
kfree(_apqns);
return rc;
}