xref: /linux/crypto/asymmetric_keys/signature.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
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 asymmetric 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  * verify_signature - Initiate the use of an asymmetric key to verify a signature
69  * @key: The asymmetric key to verify against
70  * @sig: The signature to check
71  *
72  * Returns 0 if successful or else an error.
73  */
74 int verify_signature(const struct key *key,
75 		     const struct public_key_signature *sig)
76 {
77 	const struct asymmetric_key_subtype *subtype;
78 	int ret;
79 
80 	pr_devel("==>%s()\n", __func__);
81 
82 	if (key->type != &key_type_asymmetric)
83 		return -EINVAL;
84 	subtype = asymmetric_key_subtype(key);
85 	if (!subtype ||
86 	    !key->payload.data[0])
87 		return -EINVAL;
88 	if (!subtype->verify_signature)
89 		return -ENOTSUPP;
90 
91 	ret = subtype->verify_signature(key, sig);
92 
93 	pr_devel("<==%s() = %d\n", __func__, ret);
94 	return ret;
95 }
96 EXPORT_SYMBOL_GPL(verify_signature);
97