summaryrefslogtreecommitdiff
path: root/crypto/asymmetric_keys/public_key.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/asymmetric_keys/public_key.c')
-rw-r--r--crypto/asymmetric_keys/public_key.c64
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);