lib: crypto: add x509 parser
[platform/kernel/u-boot.git] / lib / crypto / public_key.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* In-software asymmetric public-key crypto subtype
3  *
4  * See Documentation/crypto/asymmetric-keys.txt
5  *
6  * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
7  * Written by David Howells (dhowells@redhat.com)
8  */
9
10 #define pr_fmt(fmt) "PKEY: "fmt
11 #ifdef __UBOOT__
12 #include <linux/compat.h>
13 #else
14 #include <linux/module.h>
15 #include <linux/export.h>
16 #endif
17 #include <linux/kernel.h>
18 #ifndef __UBOOT__
19 #include <linux/slab.h>
20 #include <linux/seq_file.h>
21 #include <linux/scatterlist.h>
22 #include <keys/asymmetric-subtype.h>
23 #endif
24 #include <crypto/public_key.h>
25 #ifndef __UBOOT__
26 #include <crypto/akcipher.h>
27 #endif
28
29 MODULE_DESCRIPTION("In-software asymmetric public-key subtype");
30 MODULE_AUTHOR("Red Hat, Inc.");
31 MODULE_LICENSE("GPL");
32
33 #ifndef __UBOOT__
34 /*
35  * Provide a part of a description of the key for /proc/keys.
36  */
37 static void public_key_describe(const struct key *asymmetric_key,
38                                 struct seq_file *m)
39 {
40         struct public_key *key = asymmetric_key->payload.data[asym_crypto];
41
42         if (key)
43                 seq_printf(m, "%s.%s", key->id_type, key->pkey_algo);
44 }
45 #endif
46
47 /*
48  * Destroy a public key algorithm key.
49  */
50 void public_key_free(struct public_key *key)
51 {
52         if (key) {
53                 kfree(key->key);
54                 kfree(key->params);
55                 kfree(key);
56         }
57 }
58 EXPORT_SYMBOL_GPL(public_key_free);
59
60 #ifdef __UBOOT__
61 /*
62  * from <linux>/crypto/asymmetric_keys/signature.c
63  *
64  * Destroy a public key signature.
65  */
66 void public_key_signature_free(struct public_key_signature *sig)
67 {
68         int i;
69
70         if (sig) {
71                 for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
72                         free(sig->auth_ids[i]);
73                 free(sig->s);
74                 free(sig->digest);
75                 free(sig);
76         }
77 }
78 EXPORT_SYMBOL_GPL(public_key_signature_free);
79
80 #else
81 /*
82  * Destroy a public key algorithm key.
83  */
84 static void public_key_destroy(void *payload0, void *payload3)
85 {
86         public_key_free(payload0);
87         public_key_signature_free(payload3);
88 }
89
90 /*
91  * Determine the crypto algorithm name.
92  */
93 static
94 int software_key_determine_akcipher(const char *encoding,
95                                     const char *hash_algo,
96                                     const struct public_key *pkey,
97                                     char alg_name[CRYPTO_MAX_ALG_NAME])
98 {
99         int n;
100
101         if (strcmp(encoding, "pkcs1") == 0) {
102                 /* The data wangled by the RSA algorithm is typically padded
103                  * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
104                  * sec 8.2].
105                  */
106                 if (!hash_algo)
107                         n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
108                                      "pkcs1pad(%s)",
109                                      pkey->pkey_algo);
110                 else
111                         n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
112                                      "pkcs1pad(%s,%s)",
113                                      pkey->pkey_algo, hash_algo);
114                 return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
115         }
116
117         if (strcmp(encoding, "raw") == 0) {
118                 strcpy(alg_name, pkey->pkey_algo);
119                 return 0;
120         }
121
122         return -ENOPKG;
123 }
124
125 static u8 *pkey_pack_u32(u8 *dst, u32 val)
126 {
127         memcpy(dst, &val, sizeof(val));
128         return dst + sizeof(val);
129 }
130
131 /*
132  * Query information about a key.
133  */
134 static int software_key_query(const struct kernel_pkey_params *params,
135                               struct kernel_pkey_query *info)
136 {
137         struct crypto_akcipher *tfm;
138         struct public_key *pkey = params->key->payload.data[asym_crypto];
139         char alg_name[CRYPTO_MAX_ALG_NAME];
140         u8 *key, *ptr;
141         int ret, len;
142
143         ret = software_key_determine_akcipher(params->encoding,
144                                               params->hash_algo,
145                                               pkey, alg_name);
146         if (ret < 0)
147                 return ret;
148
149         tfm = crypto_alloc_akcipher(alg_name, 0, 0);
150         if (IS_ERR(tfm))
151                 return PTR_ERR(tfm);
152
153         key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
154                       GFP_KERNEL);
155         if (!key)
156                 goto error_free_tfm;
157         memcpy(key, pkey->key, pkey->keylen);
158         ptr = key + pkey->keylen;
159         ptr = pkey_pack_u32(ptr, pkey->algo);
160         ptr = pkey_pack_u32(ptr, pkey->paramlen);
161         memcpy(ptr, pkey->params, pkey->paramlen);
162
163         if (pkey->key_is_private)
164                 ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
165         else
166                 ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
167         if (ret < 0)
168                 goto error_free_key;
169
170         len = crypto_akcipher_maxsize(tfm);
171         info->key_size = len * 8;
172         info->max_data_size = len;
173         info->max_sig_size = len;
174         info->max_enc_size = len;
175         info->max_dec_size = len;
176         info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |
177                                KEYCTL_SUPPORTS_VERIFY);
178         if (pkey->key_is_private)
179                 info->supported_ops |= (KEYCTL_SUPPORTS_DECRYPT |
180                                         KEYCTL_SUPPORTS_SIGN);
181         ret = 0;
182
183 error_free_key:
184         kfree(key);
185 error_free_tfm:
186         crypto_free_akcipher(tfm);
187         pr_devel("<==%s() = %d\n", __func__, ret);
188         return ret;
189 }
190
191 /*
192  * Do encryption, decryption and signing ops.
193  */
194 static int software_key_eds_op(struct kernel_pkey_params *params,
195                                const void *in, void *out)
196 {
197         const struct public_key *pkey = params->key->payload.data[asym_crypto];
198         struct akcipher_request *req;
199         struct crypto_akcipher *tfm;
200         struct crypto_wait cwait;
201         struct scatterlist in_sg, out_sg;
202         char alg_name[CRYPTO_MAX_ALG_NAME];
203         char *key, *ptr;
204         int ret;
205
206         pr_devel("==>%s()\n", __func__);
207
208         ret = software_key_determine_akcipher(params->encoding,
209                                               params->hash_algo,
210                                               pkey, alg_name);
211         if (ret < 0)
212                 return ret;
213
214         tfm = crypto_alloc_akcipher(alg_name, 0, 0);
215         if (IS_ERR(tfm))
216                 return PTR_ERR(tfm);
217
218         req = akcipher_request_alloc(tfm, GFP_KERNEL);
219         if (!req)
220                 goto error_free_tfm;
221
222         key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
223                       GFP_KERNEL);
224         if (!key)
225                 goto error_free_req;
226
227         memcpy(key, pkey->key, pkey->keylen);
228         ptr = key + pkey->keylen;
229         ptr = pkey_pack_u32(ptr, pkey->algo);
230         ptr = pkey_pack_u32(ptr, pkey->paramlen);
231         memcpy(ptr, pkey->params, pkey->paramlen);
232
233         if (pkey->key_is_private)
234                 ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
235         else
236                 ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
237         if (ret)
238                 goto error_free_key;
239
240         sg_init_one(&in_sg, in, params->in_len);
241         sg_init_one(&out_sg, out, params->out_len);
242         akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
243                                    params->out_len);
244         crypto_init_wait(&cwait);
245         akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
246                                       CRYPTO_TFM_REQ_MAY_SLEEP,
247                                       crypto_req_done, &cwait);
248
249         /* Perform the encryption calculation. */
250         switch (params->op) {
251         case kernel_pkey_encrypt:
252                 ret = crypto_akcipher_encrypt(req);
253                 break;
254         case kernel_pkey_decrypt:
255                 ret = crypto_akcipher_decrypt(req);
256                 break;
257         case kernel_pkey_sign:
258                 ret = crypto_akcipher_sign(req);
259                 break;
260         default:
261                 BUG();
262         }
263
264         ret = crypto_wait_req(ret, &cwait);
265         if (ret == 0)
266                 ret = req->dst_len;
267
268 error_free_key:
269         kfree(key);
270 error_free_req:
271         akcipher_request_free(req);
272 error_free_tfm:
273         crypto_free_akcipher(tfm);
274         pr_devel("<==%s() = %d\n", __func__, ret);
275         return ret;
276 }
277
278 /*
279  * Verify a signature using a public key.
280  */
281 int public_key_verify_signature(const struct public_key *pkey,
282                                 const struct public_key_signature *sig)
283 {
284         struct crypto_wait cwait;
285         struct crypto_akcipher *tfm;
286         struct akcipher_request *req;
287         struct scatterlist src_sg[2];
288         char alg_name[CRYPTO_MAX_ALG_NAME];
289         char *key, *ptr;
290         int ret;
291
292         pr_devel("==>%s()\n", __func__);
293
294         BUG_ON(!pkey);
295         BUG_ON(!sig);
296         BUG_ON(!sig->s);
297
298         ret = software_key_determine_akcipher(sig->encoding,
299                                               sig->hash_algo,
300                                               pkey, alg_name);
301         if (ret < 0)
302                 return ret;
303
304         tfm = crypto_alloc_akcipher(alg_name, 0, 0);
305         if (IS_ERR(tfm))
306                 return PTR_ERR(tfm);
307
308         ret = -ENOMEM;
309         req = akcipher_request_alloc(tfm, GFP_KERNEL);
310         if (!req)
311                 goto error_free_tfm;
312
313         key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
314                       GFP_KERNEL);
315         if (!key)
316                 goto error_free_req;
317
318         memcpy(key, pkey->key, pkey->keylen);
319         ptr = key + pkey->keylen;
320         ptr = pkey_pack_u32(ptr, pkey->algo);
321         ptr = pkey_pack_u32(ptr, pkey->paramlen);
322         memcpy(ptr, pkey->params, pkey->paramlen);
323
324         if (pkey->key_is_private)
325                 ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
326         else
327                 ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
328         if (ret)
329                 goto error_free_key;
330
331         sg_init_table(src_sg, 2);
332         sg_set_buf(&src_sg[0], sig->s, sig->s_size);
333         sg_set_buf(&src_sg[1], sig->digest, sig->digest_size);
334         akcipher_request_set_crypt(req, src_sg, NULL, sig->s_size,
335                                    sig->digest_size);
336         crypto_init_wait(&cwait);
337         akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
338                                       CRYPTO_TFM_REQ_MAY_SLEEP,
339                                       crypto_req_done, &cwait);
340         ret = crypto_wait_req(crypto_akcipher_verify(req), &cwait);
341
342 error_free_key:
343         kfree(key);
344 error_free_req:
345         akcipher_request_free(req);
346 error_free_tfm:
347         crypto_free_akcipher(tfm);
348         pr_devel("<==%s() = %d\n", __func__, ret);
349         if (WARN_ON_ONCE(ret > 0))
350                 ret = -EINVAL;
351         return ret;
352 }
353 EXPORT_SYMBOL_GPL(public_key_verify_signature);
354
355 static int public_key_verify_signature_2(const struct key *key,
356                                          const struct public_key_signature *sig)
357 {
358         const struct public_key *pk = key->payload.data[asym_crypto];
359         return public_key_verify_signature(pk, sig);
360 }
361
362 /*
363  * Public key algorithm asymmetric key subtype
364  */
365 struct asymmetric_key_subtype public_key_subtype = {
366         .owner                  = THIS_MODULE,
367         .name                   = "public_key",
368         .name_len               = sizeof("public_key") - 1,
369         .describe               = public_key_describe,
370         .destroy                = public_key_destroy,
371         .query                  = software_key_query,
372         .eds_op                 = software_key_eds_op,
373         .verify_signature       = public_key_verify_signature_2,
374 };
375 EXPORT_SYMBOL_GPL(public_key_subtype);
376 #endif /* !__UBOOT__ */