Blame view

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