diff options
Diffstat (limited to 'crypto/asymmetric_keys/public_key.c')
-rw-r--r-- | crypto/asymmetric_keys/public_key.c | 64 |
1 files changed, 42 insertions, 22 deletions
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index b383629b9e62..6db4c01c6503 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -18,16 +18,24 @@ #include <linux/slab.h> #include <linux/seq_file.h> #include <keys/asymmetric-subtype.h> -#include <crypto/public_key.h> +#include "public_key.h" MODULE_LICENSE("GPL"); const char *const pkey_algo_name[PKEY_ALGO__LAST] = { - [PKEY_ALGO_DSA] = "dsa", - [PKEY_ALGO_RSA] = "rsa", + [PKEY_ALGO_DSA] = "DSA", + [PKEY_ALGO_RSA] = "RSA", }; EXPORT_SYMBOL_GPL(pkey_algo_name); +const struct public_key_algorithm *pkey_algo[PKEY_ALGO__LAST] = { +#if defined(CONFIG_PUBLIC_KEY_ALGO_RSA) || \ + defined(CONFIG_PUBLIC_KEY_ALGO_RSA_MODULE) + [PKEY_ALGO_RSA] = &RSA_public_key_algorithm, +#endif +}; +EXPORT_SYMBOL_GPL(pkey_algo); + const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { [PKEY_ID_PGP] = "PGP", [PKEY_ID_X509] = "X509", @@ -35,12 +43,6 @@ const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = { }; EXPORT_SYMBOL_GPL(pkey_id_type_name); -static int (*alg_verify[PKEY_ALGO__LAST])(const struct public_key *pkey, - const struct public_key_signature *sig) = { - NULL, - rsa_verify_signature -}; - /* * Provide a part of a description of the key for /proc/keys. */ @@ -51,8 +53,7 @@ static void public_key_describe(const struct key *asymmetric_key, if (key) seq_printf(m, "%s.%s", - pkey_id_type_name[key->id_type], - pkey_algo_name[key->pkey_algo]); + pkey_id_type_name[key->id_type], key->algo->name); } /* @@ -61,31 +62,50 @@ static void public_key_describe(const struct key *asymmetric_key, void public_key_destroy(void *payload) { struct public_key *key = payload; + int i; - if (key) - kfree(key->key); - kfree(key); + if (key) { + for (i = 0; i < ARRAY_SIZE(key->mpi); i++) + mpi_free(key->mpi[i]); + kfree(key); + } } EXPORT_SYMBOL_GPL(public_key_destroy); /* * Verify a signature using a public key. */ -int public_key_verify_signature(const struct public_key *pkey, +int public_key_verify_signature(const struct public_key *pk, const struct public_key_signature *sig) { - BUG_ON(!pkey); + const struct public_key_algorithm *algo; + + BUG_ON(!pk); + BUG_ON(!pk->mpi[0]); + BUG_ON(!pk->mpi[1]); BUG_ON(!sig); BUG_ON(!sig->digest); - BUG_ON(!sig->s); + BUG_ON(!sig->mpi[0]); + + algo = pk->algo; + if (!algo) { + if (pk->pkey_algo >= PKEY_ALGO__LAST) + return -ENOPKG; + algo = pkey_algo[pk->pkey_algo]; + if (!algo) + return -ENOPKG; + } - if (pkey->pkey_algo >= PKEY_ALGO__LAST) - return -ENOPKG; + if (!algo->verify_signature) + return -ENOTSUPP; - if (!alg_verify[pkey->pkey_algo]) - return -ENOPKG; + if (sig->nr_mpi != algo->n_sig_mpi) { + pr_debug("Signature has %u MPI not %u\n", + sig->nr_mpi, algo->n_sig_mpi); + return -EINVAL; + } - return alg_verify[pkey->pkey_algo](pkey, sig); + return algo->verify_signature(pk, sig); } EXPORT_SYMBOL_GPL(public_key_verify_signature); |