crypto: KEYS: convert public key and digsig asym to the akcipher api
[linux-2.6-block.git] / crypto / asymmetric_keys / public_key.c
1 /* In-software asymmetric public-key crypto subtype
2  *
3  * See Documentation/crypto/asymmetric-keys.txt
4  *
5  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
6  * Written by David Howells (dhowells@redhat.com)
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public Licence
10  * as published by the Free Software Foundation; either version
11  * 2 of the Licence, or (at your option) any later version.
12  */
13
14 #define pr_fmt(fmt) "PKEY: "fmt
15 #include <linux/module.h>
16 #include <linux/export.h>
17 #include <linux/kernel.h>
18 #include <linux/slab.h>
19 #include <linux/seq_file.h>
20 #include <keys/asymmetric-subtype.h>
21 #include <crypto/public_key.h>
22
23 MODULE_LICENSE("GPL");
24
25 const char *const pkey_algo_name[PKEY_ALGO__LAST] = {
26         [PKEY_ALGO_DSA]         = "dsa",
27         [PKEY_ALGO_RSA]         = "rsa",
28 };
29 EXPORT_SYMBOL_GPL(pkey_algo_name);
30
31 const char *const pkey_id_type_name[PKEY_ID_TYPE__LAST] = {
32         [PKEY_ID_PGP]           = "PGP",
33         [PKEY_ID_X509]          = "X509",
34         [PKEY_ID_PKCS7]         = "PKCS#7",
35 };
36 EXPORT_SYMBOL_GPL(pkey_id_type_name);
37
38 static int (*alg_verify[PKEY_ALGO__LAST])(const struct public_key *pkey,
39         const struct public_key_signature *sig) = {
40         NULL,
41         rsa_verify_signature
42 };
43
44 /*
45  * Provide a part of a description of the key for /proc/keys.
46  */
47 static void public_key_describe(const struct key *asymmetric_key,
48                                 struct seq_file *m)
49 {
50         struct public_key *key = asymmetric_key->payload.data[asym_crypto];
51
52         if (key)
53                 seq_printf(m, "%s.%s",
54                            pkey_id_type_name[key->id_type],
55                            pkey_algo_name[key->pkey_algo]);
56 }
57
58 /*
59  * Destroy a public key algorithm key.
60  */
61 void public_key_destroy(void *payload)
62 {
63         struct public_key *key = payload;
64
65         if (key)
66                 kfree(key->key);
67         kfree(key);
68 }
69 EXPORT_SYMBOL_GPL(public_key_destroy);
70
71 /*
72  * Verify a signature using a public key.
73  */
74 int public_key_verify_signature(const struct public_key *pkey,
75                                 const struct public_key_signature *sig)
76 {
77         BUG_ON(!pkey);
78         BUG_ON(!sig);
79         BUG_ON(!sig->digest);
80         BUG_ON(!sig->s);
81
82         if (pkey->pkey_algo >= PKEY_ALGO__LAST)
83                 return -ENOPKG;
84
85         if (!alg_verify[pkey->pkey_algo])
86                 return -ENOPKG;
87
88         return alg_verify[pkey->pkey_algo](pkey, sig);
89 }
90 EXPORT_SYMBOL_GPL(public_key_verify_signature);
91
92 static int public_key_verify_signature_2(const struct key *key,
93                                          const struct public_key_signature *sig)
94 {
95         const struct public_key *pk = key->payload.data[asym_crypto];
96         return public_key_verify_signature(pk, sig);
97 }
98
99 /*
100  * Public key algorithm asymmetric key subtype
101  */
102 struct asymmetric_key_subtype public_key_subtype = {
103         .owner                  = THIS_MODULE,
104         .name                   = "public_key",
105         .name_len               = sizeof("public_key") - 1,
106         .describe               = public_key_describe,
107         .destroy                = public_key_destroy,
108         .verify_signature       = public_key_verify_signature_2,
109 };
110 EXPORT_SYMBOL_GPL(public_key_subtype);