GNU Linux-libre 5.10.219-gnu1
[releases.git] / crypto / asymmetric_keys / signature.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Signature verification with an asymmetric key
3  *
4  * See Documentation/crypto/asymmetric-keys.rst
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) "SIG: "fmt
11 #include <keys/asymmetric-subtype.h>
12 #include <linux/export.h>
13 #include <linux/err.h>
14 #include <linux/slab.h>
15 #include <linux/keyctl.h>
16 #include <crypto/public_key.h>
17 #include <keys/user-type.h>
18 #include "asymmetric_keys.h"
19
20 /*
21  * Destroy a public key signature.
22  */
23 void public_key_signature_free(struct public_key_signature *sig)
24 {
25         int i;
26
27         if (sig) {
28                 for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
29                         kfree(sig->auth_ids[i]);
30                 kfree(sig->s);
31                 kfree(sig->digest);
32                 kfree(sig);
33         }
34 }
35 EXPORT_SYMBOL_GPL(public_key_signature_free);
36
37 /**
38  * query_asymmetric_key - Get information about an aymmetric key.
39  * @params: Various parameters.
40  * @info: Where to put the information.
41  */
42 int query_asymmetric_key(const struct kernel_pkey_params *params,
43                          struct kernel_pkey_query *info)
44 {
45         const struct asymmetric_key_subtype *subtype;
46         struct key *key = params->key;
47         int ret;
48
49         pr_devel("==>%s()\n", __func__);
50
51         if (key->type != &key_type_asymmetric)
52                 return -EINVAL;
53         subtype = asymmetric_key_subtype(key);
54         if (!subtype ||
55             !key->payload.data[0])
56                 return -EINVAL;
57         if (!subtype->query)
58                 return -ENOTSUPP;
59
60         ret = subtype->query(params, info);
61
62         pr_devel("<==%s() = %d\n", __func__, ret);
63         return ret;
64 }
65 EXPORT_SYMBOL_GPL(query_asymmetric_key);
66
67 /**
68  * encrypt_blob - Encrypt data using an asymmetric key
69  * @params: Various parameters
70  * @data: Data blob to be encrypted, length params->data_len
71  * @enc: Encrypted data buffer, length params->enc_len
72  *
73  * Encrypt the specified data blob using the private key specified by
74  * params->key.  The encrypted data is wrapped in an encoding if
75  * params->encoding is specified (eg. "pkcs1").
76  *
77  * Returns the length of the data placed in the encrypted data buffer or an
78  * error.
79  */
80 int encrypt_blob(struct kernel_pkey_params *params,
81                  const void *data, void *enc)
82 {
83         params->op = kernel_pkey_encrypt;
84         return asymmetric_key_eds_op(params, data, enc);
85 }
86 EXPORT_SYMBOL_GPL(encrypt_blob);
87
88 /**
89  * decrypt_blob - Decrypt data using an asymmetric key
90  * @params: Various parameters
91  * @enc: Encrypted data to be decrypted, length params->enc_len
92  * @data: Decrypted data buffer, length params->data_len
93  *
94  * Decrypt the specified data blob using the private key specified by
95  * params->key.  The decrypted data is wrapped in an encoding if
96  * params->encoding is specified (eg. "pkcs1").
97  *
98  * Returns the length of the data placed in the decrypted data buffer or an
99  * error.
100  */
101 int decrypt_blob(struct kernel_pkey_params *params,
102                  const void *enc, void *data)
103 {
104         params->op = kernel_pkey_decrypt;
105         return asymmetric_key_eds_op(params, enc, data);
106 }
107 EXPORT_SYMBOL_GPL(decrypt_blob);
108
109 /**
110  * create_signature - Sign some data using an asymmetric key
111  * @params: Various parameters
112  * @data: Data blob to be signed, length params->data_len
113  * @enc: Signature buffer, length params->enc_len
114  *
115  * Sign the specified data blob using the private key specified by params->key.
116  * The signature is wrapped in an encoding if params->encoding is specified
117  * (eg. "pkcs1").  If the encoding needs to know the digest type, this can be
118  * passed through params->hash_algo (eg. "sha1").
119  *
120  * Returns the length of the data placed in the signature buffer or an error.
121  */
122 int create_signature(struct kernel_pkey_params *params,
123                      const void *data, void *enc)
124 {
125         params->op = kernel_pkey_sign;
126         return asymmetric_key_eds_op(params, data, enc);
127 }
128 EXPORT_SYMBOL_GPL(create_signature);
129
130 /**
131  * verify_signature - Initiate the use of an asymmetric key to verify a signature
132  * @key: The asymmetric key to verify against
133  * @sig: The signature to check
134  *
135  * Returns 0 if successful or else an error.
136  */
137 int verify_signature(const struct key *key,
138                      const struct public_key_signature *sig)
139 {
140         const struct asymmetric_key_subtype *subtype;
141         int ret;
142
143         pr_devel("==>%s()\n", __func__);
144
145         if (key->type != &key_type_asymmetric)
146                 return -EINVAL;
147         subtype = asymmetric_key_subtype(key);
148         if (!subtype ||
149             !key->payload.data[0])
150                 return -EINVAL;
151         if (!subtype->verify_signature)
152                 return -ENOTSUPP;
153
154         ret = subtype->verify_signature(key, sig);
155
156         pr_devel("<==%s() = %d\n", __func__, ret);
157         return ret;
158 }
159 EXPORT_SYMBOL_GPL(verify_signature);