int asymmetric_verify(struct key *keyring, const char *sig, int siglen, const char *data, int datalen) { struct public_key_signature pks; struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig; struct key *key; int ret = -ENOMEM; if (siglen <= sizeof(*hdr)) return -EBADMSG; siglen -= sizeof(*hdr); if (siglen != __be16_to_cpu(hdr->sig_size)) return -EBADMSG; if (hdr->hash_algo >= PKEY_HASH__LAST) return -ENOPKG; key = request_asymmetric_key(keyring, __be32_to_cpu(hdr->keyid)); if (IS_ERR(key)) return PTR_ERR(key); memset(&pks, 0, sizeof(pks)); pks.pkey_hash_algo = hdr->hash_algo; pks.digest = (u8 *)data; pks.digest_size = datalen; pks.nr_mpi = 1; pks.rsa.s = mpi_read_raw_data(hdr->sig, siglen); if (pks.rsa.s) ret = verify_signature(key, &pks); mpi_free(pks.rsa.s); key_put(key); pr_debug("%s() = %d\n", __func__, ret); return ret; }
/* * Verify the signature on a module. */ int mod_verify_sig(const void *mod, unsigned long *_modlen) { struct public_key_signature *pks; struct module_signature ms; struct key *key; const void *sig; size_t modlen = *_modlen, sig_len; int ret; pr_devel("==>%s(,%zu)\n", __func__, modlen); if (modlen <= sizeof(ms)) return -EBADMSG; memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); modlen -= sizeof(ms); sig_len = be32_to_cpu(ms.sig_len); if (sig_len >= modlen) return -EBADMSG; modlen -= sig_len; if ((size_t)ms.signer_len + ms.key_id_len >= modlen) return -EBADMSG; modlen -= (size_t)ms.signer_len + ms.key_id_len; *_modlen = modlen; sig = mod + modlen; /* For the moment, only support RSA and X.509 identifiers */ if (ms.algo != PKEY_ALGO_RSA || ms.id_type != PKEY_ID_X509) return -ENOPKG; if (ms.hash >= PKEY_HASH__LAST || !pkey_hash_algo[ms.hash]) return -ENOPKG; key = request_asymmetric_key(sig, ms.signer_len, sig + ms.signer_len, ms.key_id_len); if (IS_ERR(key)) return PTR_ERR(key); pks = mod_make_digest(ms.hash, mod, modlen); if (IS_ERR(pks)) { ret = PTR_ERR(pks); goto error_put_key; } ret = mod_extract_mpi_array(pks, sig + ms.signer_len + ms.key_id_len, sig_len); if (ret < 0) goto error_free_pks; ret = verify_signature(key, pks); pr_devel("verify_signature() = %d\n", ret); error_free_pks: mpi_free(pks->rsa.s); kfree(pks); error_put_key: key_put(key); pr_devel("<==%s() = %d\n", __func__, ret); return ret; }