xref: /linux/crypto/asymmetric_keys/signature.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
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 		if (sig->m_free)
32 			kfree(sig->m);
33 		kfree(sig);
34 	}
35 }
36 EXPORT_SYMBOL_GPL(public_key_signature_free);
37 
38 /**
39  * query_asymmetric_key - Get information about an asymmetric key.
40  * @params: Various parameters.
41  * @info: Where to put the information.
42  */
43 int query_asymmetric_key(const struct kernel_pkey_params *params,
44 			 struct kernel_pkey_query *info)
45 {
46 	const struct asymmetric_key_subtype *subtype;
47 	struct key *key = params->key;
48 	int ret;
49 
50 	pr_devel("==>%s()\n", __func__);
51 
52 	if (key->type != &key_type_asymmetric)
53 		return -EINVAL;
54 	subtype = asymmetric_key_subtype(key);
55 	if (!subtype ||
56 	    !key->payload.data[0])
57 		return -EINVAL;
58 	if (!subtype->query)
59 		return -ENOTSUPP;
60 
61 	ret = subtype->query(params, info);
62 
63 	pr_devel("<==%s() = %d\n", __func__, ret);
64 	return ret;
65 }
66 EXPORT_SYMBOL_GPL(query_asymmetric_key);
67 
68 /**
69  * verify_signature - Initiate the use of an asymmetric key to verify a signature
70  * @key: The asymmetric key to verify against
71  * @sig: The signature to check
72  *
73  * Returns 0 if successful or else an error.
74  */
75 int verify_signature(const struct key *key,
76 		     const struct public_key_signature *sig)
77 {
78 	const struct asymmetric_key_subtype *subtype;
79 	int ret;
80 
81 	pr_devel("==>%s()\n", __func__);
82 
83 	if (key->type != &key_type_asymmetric)
84 		return -EINVAL;
85 	subtype = asymmetric_key_subtype(key);
86 	if (!subtype ||
87 	    !key->payload.data[0])
88 		return -EINVAL;
89 	if (!subtype->verify_signature)
90 		return -ENOTSUPP;
91 
92 	ret = subtype->verify_signature(key, sig);
93 
94 	pr_devel("<==%s() = %d\n", __func__, ret);
95 	return ret;
96 }
97 EXPORT_SYMBOL_GPL(verify_signature);
98