Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/crypto/asymmetric_keys/public_key.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* In-software asymmetric public-key crypto subtype
3
*
4
* See Documentation/crypto/asymmetric-keys.rst
5
*
6
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
7
* Written by David Howells ([email protected])
8
*/
9
10
#define pr_fmt(fmt) "PKEY: "fmt
11
#include <crypto/akcipher.h>
12
#include <crypto/public_key.h>
13
#include <crypto/sig.h>
14
#include <keys/asymmetric-subtype.h>
15
#include <linux/asn1.h>
16
#include <linux/err.h>
17
#include <linux/kernel.h>
18
#include <linux/module.h>
19
#include <linux/seq_file.h>
20
#include <linux/slab.h>
21
#include <linux/string.h>
22
23
MODULE_DESCRIPTION("In-software asymmetric public-key subtype");
24
MODULE_AUTHOR("Red Hat, Inc.");
25
MODULE_LICENSE("GPL");
26
27
/*
28
* Provide a part of a description of the key for /proc/keys.
29
*/
30
static void public_key_describe(const struct key *asymmetric_key,
31
struct seq_file *m)
32
{
33
struct public_key *key = asymmetric_key->payload.data[asym_crypto];
34
35
if (key)
36
seq_printf(m, "%s.%s", key->id_type, key->pkey_algo);
37
}
38
39
/*
40
* Destroy a public key algorithm key.
41
*/
42
void public_key_free(struct public_key *key)
43
{
44
if (key) {
45
kfree_sensitive(key->key);
46
kfree(key->params);
47
kfree(key);
48
}
49
}
50
EXPORT_SYMBOL_GPL(public_key_free);
51
52
/*
53
* Destroy a public key algorithm key.
54
*/
55
static void public_key_destroy(void *payload0, void *payload3)
56
{
57
public_key_free(payload0);
58
public_key_signature_free(payload3);
59
}
60
61
/*
62
* Given a public_key, and an encoding and hash_algo to be used for signing
63
* and/or verification with that key, determine the name of the corresponding
64
* akcipher algorithm. Also check that encoding and hash_algo are allowed.
65
*/
66
static int
67
software_key_determine_akcipher(const struct public_key *pkey,
68
const char *encoding, const char *hash_algo,
69
char alg_name[CRYPTO_MAX_ALG_NAME], bool *sig,
70
enum kernel_pkey_operation op)
71
{
72
int n;
73
74
*sig = true;
75
76
if (!encoding)
77
return -EINVAL;
78
79
if (strcmp(pkey->pkey_algo, "rsa") == 0) {
80
/*
81
* RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2].
82
*/
83
if (strcmp(encoding, "pkcs1") == 0) {
84
*sig = op == kernel_pkey_sign ||
85
op == kernel_pkey_verify;
86
if (!*sig) {
87
/*
88
* For encrypt/decrypt, hash_algo is not used
89
* but allowed to be set for historic reasons.
90
*/
91
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
92
"pkcs1pad(%s)",
93
pkey->pkey_algo);
94
} else {
95
if (!hash_algo)
96
hash_algo = "none";
97
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME,
98
"pkcs1(%s,%s)",
99
pkey->pkey_algo, hash_algo);
100
}
101
return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
102
}
103
if (strcmp(encoding, "raw") != 0)
104
return -EINVAL;
105
/*
106
* Raw RSA cannot differentiate between different hash
107
* algorithms.
108
*/
109
if (hash_algo)
110
return -EINVAL;
111
*sig = false;
112
} else if (strncmp(pkey->pkey_algo, "ecdsa", 5) == 0) {
113
if (strcmp(encoding, "x962") != 0 &&
114
strcmp(encoding, "p1363") != 0)
115
return -EINVAL;
116
/*
117
* ECDSA signatures are taken over a raw hash, so they don't
118
* differentiate between different hash algorithms. That means
119
* that the verifier should hard-code a specific hash algorithm.
120
* Unfortunately, in practice ECDSA is used with multiple SHAs,
121
* so we have to allow all of them and not just one.
122
*/
123
if (!hash_algo)
124
return -EINVAL;
125
if (strcmp(hash_algo, "sha1") != 0 &&
126
strcmp(hash_algo, "sha224") != 0 &&
127
strcmp(hash_algo, "sha256") != 0 &&
128
strcmp(hash_algo, "sha384") != 0 &&
129
strcmp(hash_algo, "sha512") != 0 &&
130
strcmp(hash_algo, "sha3-256") != 0 &&
131
strcmp(hash_algo, "sha3-384") != 0 &&
132
strcmp(hash_algo, "sha3-512") != 0)
133
return -EINVAL;
134
n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
135
encoding, pkey->pkey_algo);
136
return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0;
137
} else if (strcmp(pkey->pkey_algo, "ecrdsa") == 0) {
138
if (strcmp(encoding, "raw") != 0)
139
return -EINVAL;
140
if (!hash_algo)
141
return -EINVAL;
142
if (strcmp(hash_algo, "streebog256") != 0 &&
143
strcmp(hash_algo, "streebog512") != 0)
144
return -EINVAL;
145
} else {
146
/* Unknown public key algorithm */
147
return -ENOPKG;
148
}
149
if (strscpy(alg_name, pkey->pkey_algo, CRYPTO_MAX_ALG_NAME) < 0)
150
return -EINVAL;
151
return 0;
152
}
153
154
static u8 *pkey_pack_u32(u8 *dst, u32 val)
155
{
156
memcpy(dst, &val, sizeof(val));
157
return dst + sizeof(val);
158
}
159
160
/*
161
* Query information about a key.
162
*/
163
static int software_key_query(const struct kernel_pkey_params *params,
164
struct kernel_pkey_query *info)
165
{
166
struct public_key *pkey = params->key->payload.data[asym_crypto];
167
char alg_name[CRYPTO_MAX_ALG_NAME];
168
u8 *key, *ptr;
169
int ret, len;
170
bool issig;
171
172
ret = software_key_determine_akcipher(pkey, params->encoding,
173
params->hash_algo, alg_name,
174
&issig, kernel_pkey_sign);
175
if (ret < 0)
176
return ret;
177
178
key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
179
GFP_KERNEL);
180
if (!key)
181
return -ENOMEM;
182
183
memcpy(key, pkey->key, pkey->keylen);
184
ptr = key + pkey->keylen;
185
ptr = pkey_pack_u32(ptr, pkey->algo);
186
ptr = pkey_pack_u32(ptr, pkey->paramlen);
187
memcpy(ptr, pkey->params, pkey->paramlen);
188
189
memset(info, 0, sizeof(*info));
190
191
if (issig) {
192
struct crypto_sig *sig;
193
194
sig = crypto_alloc_sig(alg_name, 0, 0);
195
if (IS_ERR(sig)) {
196
ret = PTR_ERR(sig);
197
goto error_free_key;
198
}
199
200
if (pkey->key_is_private)
201
ret = crypto_sig_set_privkey(sig, key, pkey->keylen);
202
else
203
ret = crypto_sig_set_pubkey(sig, key, pkey->keylen);
204
if (ret < 0)
205
goto error_free_sig;
206
207
len = crypto_sig_keysize(sig);
208
info->key_size = len;
209
info->max_sig_size = crypto_sig_maxsize(sig);
210
info->max_data_size = crypto_sig_digestsize(sig);
211
212
info->supported_ops = KEYCTL_SUPPORTS_VERIFY;
213
if (pkey->key_is_private)
214
info->supported_ops |= KEYCTL_SUPPORTS_SIGN;
215
216
if (strcmp(params->encoding, "pkcs1") == 0) {
217
info->max_enc_size = len / BITS_PER_BYTE;
218
info->max_dec_size = len / BITS_PER_BYTE;
219
220
info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT;
221
if (pkey->key_is_private)
222
info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT;
223
}
224
225
error_free_sig:
226
crypto_free_sig(sig);
227
} else {
228
struct crypto_akcipher *tfm;
229
230
tfm = crypto_alloc_akcipher(alg_name, 0, 0);
231
if (IS_ERR(tfm)) {
232
ret = PTR_ERR(tfm);
233
goto error_free_key;
234
}
235
236
if (pkey->key_is_private)
237
ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
238
else
239
ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
240
if (ret < 0)
241
goto error_free_akcipher;
242
243
len = crypto_akcipher_maxsize(tfm);
244
info->key_size = len * BITS_PER_BYTE;
245
info->max_sig_size = len;
246
info->max_data_size = len;
247
info->max_enc_size = len;
248
info->max_dec_size = len;
249
250
info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT;
251
if (pkey->key_is_private)
252
info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT;
253
254
error_free_akcipher:
255
crypto_free_akcipher(tfm);
256
}
257
258
error_free_key:
259
kfree_sensitive(key);
260
pr_devel("<==%s() = %d\n", __func__, ret);
261
return ret;
262
}
263
264
/*
265
* Do encryption, decryption and signing ops.
266
*/
267
static int software_key_eds_op(struct kernel_pkey_params *params,
268
const void *in, void *out)
269
{
270
const struct public_key *pkey = params->key->payload.data[asym_crypto];
271
char alg_name[CRYPTO_MAX_ALG_NAME];
272
struct crypto_akcipher *tfm;
273
struct crypto_sig *sig;
274
char *key, *ptr;
275
bool issig;
276
int ret;
277
278
pr_devel("==>%s()\n", __func__);
279
280
ret = software_key_determine_akcipher(pkey, params->encoding,
281
params->hash_algo, alg_name,
282
&issig, params->op);
283
if (ret < 0)
284
return ret;
285
286
key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
287
GFP_KERNEL);
288
if (!key)
289
return -ENOMEM;
290
291
memcpy(key, pkey->key, pkey->keylen);
292
ptr = key + pkey->keylen;
293
ptr = pkey_pack_u32(ptr, pkey->algo);
294
ptr = pkey_pack_u32(ptr, pkey->paramlen);
295
memcpy(ptr, pkey->params, pkey->paramlen);
296
297
if (issig) {
298
sig = crypto_alloc_sig(alg_name, 0, 0);
299
if (IS_ERR(sig)) {
300
ret = PTR_ERR(sig);
301
goto error_free_key;
302
}
303
304
if (pkey->key_is_private)
305
ret = crypto_sig_set_privkey(sig, key, pkey->keylen);
306
else
307
ret = crypto_sig_set_pubkey(sig, key, pkey->keylen);
308
if (ret)
309
goto error_free_tfm;
310
} else {
311
tfm = crypto_alloc_akcipher(alg_name, 0, 0);
312
if (IS_ERR(tfm)) {
313
ret = PTR_ERR(tfm);
314
goto error_free_key;
315
}
316
317
if (pkey->key_is_private)
318
ret = crypto_akcipher_set_priv_key(tfm, key, pkey->keylen);
319
else
320
ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
321
if (ret)
322
goto error_free_tfm;
323
}
324
325
ret = -EINVAL;
326
327
/* Perform the encryption calculation. */
328
switch (params->op) {
329
case kernel_pkey_encrypt:
330
if (issig)
331
break;
332
ret = crypto_akcipher_sync_encrypt(tfm, in, params->in_len,
333
out, params->out_len);
334
break;
335
case kernel_pkey_decrypt:
336
if (issig)
337
break;
338
ret = crypto_akcipher_sync_decrypt(tfm, in, params->in_len,
339
out, params->out_len);
340
break;
341
case kernel_pkey_sign:
342
if (!issig)
343
break;
344
ret = crypto_sig_sign(sig, in, params->in_len,
345
out, params->out_len);
346
break;
347
default:
348
BUG();
349
}
350
351
if (!issig && ret == 0)
352
ret = crypto_akcipher_maxsize(tfm);
353
354
error_free_tfm:
355
if (issig)
356
crypto_free_sig(sig);
357
else
358
crypto_free_akcipher(tfm);
359
error_free_key:
360
kfree_sensitive(key);
361
pr_devel("<==%s() = %d\n", __func__, ret);
362
return ret;
363
}
364
365
/*
366
* Verify a signature using a public key.
367
*/
368
int public_key_verify_signature(const struct public_key *pkey,
369
const struct public_key_signature *sig)
370
{
371
char alg_name[CRYPTO_MAX_ALG_NAME];
372
struct crypto_sig *tfm;
373
char *key, *ptr;
374
bool issig;
375
int ret;
376
377
pr_devel("==>%s()\n", __func__);
378
379
BUG_ON(!pkey);
380
BUG_ON(!sig);
381
BUG_ON(!sig->s);
382
383
/*
384
* If the signature specifies a public key algorithm, it *must* match
385
* the key's actual public key algorithm.
386
*
387
* Small exception: ECDSA signatures don't specify the curve, but ECDSA
388
* keys do. So the strings can mismatch slightly in that case:
389
* "ecdsa-nist-*" for the key, but "ecdsa" for the signature.
390
*/
391
if (sig->pkey_algo) {
392
if (strcmp(pkey->pkey_algo, sig->pkey_algo) != 0 &&
393
(strncmp(pkey->pkey_algo, "ecdsa-", 6) != 0 ||
394
strcmp(sig->pkey_algo, "ecdsa") != 0))
395
return -EKEYREJECTED;
396
}
397
398
ret = software_key_determine_akcipher(pkey, sig->encoding,
399
sig->hash_algo, alg_name,
400
&issig, kernel_pkey_verify);
401
if (ret < 0)
402
return ret;
403
404
tfm = crypto_alloc_sig(alg_name, 0, 0);
405
if (IS_ERR(tfm))
406
return PTR_ERR(tfm);
407
408
key = kmalloc(pkey->keylen + sizeof(u32) * 2 + pkey->paramlen,
409
GFP_KERNEL);
410
if (!key) {
411
ret = -ENOMEM;
412
goto error_free_tfm;
413
}
414
415
memcpy(key, pkey->key, pkey->keylen);
416
ptr = key + pkey->keylen;
417
ptr = pkey_pack_u32(ptr, pkey->algo);
418
ptr = pkey_pack_u32(ptr, pkey->paramlen);
419
memcpy(ptr, pkey->params, pkey->paramlen);
420
421
if (pkey->key_is_private)
422
ret = crypto_sig_set_privkey(tfm, key, pkey->keylen);
423
else
424
ret = crypto_sig_set_pubkey(tfm, key, pkey->keylen);
425
if (ret)
426
goto error_free_key;
427
428
ret = crypto_sig_verify(tfm, sig->s, sig->s_size,
429
sig->digest, sig->digest_size);
430
431
error_free_key:
432
kfree_sensitive(key);
433
error_free_tfm:
434
crypto_free_sig(tfm);
435
pr_devel("<==%s() = %d\n", __func__, ret);
436
if (WARN_ON_ONCE(ret > 0))
437
ret = -EINVAL;
438
return ret;
439
}
440
EXPORT_SYMBOL_GPL(public_key_verify_signature);
441
442
static int public_key_verify_signature_2(const struct key *key,
443
const struct public_key_signature *sig)
444
{
445
const struct public_key *pk = key->payload.data[asym_crypto];
446
return public_key_verify_signature(pk, sig);
447
}
448
449
/*
450
* Public key algorithm asymmetric key subtype
451
*/
452
struct asymmetric_key_subtype public_key_subtype = {
453
.owner = THIS_MODULE,
454
.name = "public_key",
455
.name_len = sizeof("public_key") - 1,
456
.describe = public_key_describe,
457
.destroy = public_key_destroy,
458
.query = software_key_query,
459
.eds_op = software_key_eds_op,
460
.verify_signature = public_key_verify_signature_2,
461
};
462
EXPORT_SYMBOL_GPL(public_key_subtype);
463
464