1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* In-software asymmetric public-key crypto subtype
4 * See Documentation/crypto/asymmetric-keys.txt
6 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
7 * Written by David Howells (dhowells@redhat.com)
10 #define pr_fmt(fmt) "PKEY: "fmt
11 #include <linux/module.h>
12 #include <linux/export.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/seq_file.h>
16 #include <linux/scatterlist.h>
17 #include <keys/asymmetric-subtype.h>
18 #include <crypto/public_key.h>
19 #include <crypto/akcipher.h>
21 MODULE_DESCRIPTION("In-software asymmetric public-key subtype");
22 MODULE_AUTHOR("Red Hat, Inc.");
23 MODULE_LICENSE("GPL");
26 * Provide a part of a description of the key for /proc/keys.
28 static void public_key_describe(const struct key
*asymmetric_key
,
31 struct public_key
*key
= asymmetric_key
->payload
.data
[asym_crypto
];
34 seq_printf(m
, "%s.%s", key
->id_type
, key
->pkey_algo
);
38 * Destroy a public key algorithm key.
40 void public_key_free(struct public_key
*key
)
48 EXPORT_SYMBOL_GPL(public_key_free
);
51 * Destroy a public key algorithm key.
53 static void public_key_destroy(void *payload0
, void *payload3
)
55 public_key_free(payload0
);
56 public_key_signature_free(payload3
);
60 * Determine the crypto algorithm name.
63 int software_key_determine_akcipher(const char *encoding
,
64 const char *hash_algo
,
65 const struct public_key
*pkey
,
66 char alg_name
[CRYPTO_MAX_ALG_NAME
])
70 if (strcmp(encoding
, "pkcs1") == 0) {
71 /* The data wangled by the RSA algorithm is typically padded
72 * and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447
76 n
= snprintf(alg_name
, CRYPTO_MAX_ALG_NAME
,
80 n
= snprintf(alg_name
, CRYPTO_MAX_ALG_NAME
,
82 pkey
->pkey_algo
, hash_algo
);
83 return n
>= CRYPTO_MAX_ALG_NAME
? -EINVAL
: 0;
86 if (strcmp(encoding
, "raw") == 0) {
87 strcpy(alg_name
, pkey
->pkey_algo
);
94 static u8
*pkey_pack_u32(u8
*dst
, u32 val
)
96 memcpy(dst
, &val
, sizeof(val
));
97 return dst
+ sizeof(val
);
101 * Query information about a key.
103 static int software_key_query(const struct kernel_pkey_params
*params
,
104 struct kernel_pkey_query
*info
)
106 struct crypto_akcipher
*tfm
;
107 struct public_key
*pkey
= params
->key
->payload
.data
[asym_crypto
];
108 char alg_name
[CRYPTO_MAX_ALG_NAME
];
112 ret
= software_key_determine_akcipher(params
->encoding
,
118 tfm
= crypto_alloc_akcipher(alg_name
, 0, 0);
122 key
= kmalloc(pkey
->keylen
+ sizeof(u32
) * 2 + pkey
->paramlen
,
126 memcpy(key
, pkey
->key
, pkey
->keylen
);
127 ptr
= key
+ pkey
->keylen
;
128 ptr
= pkey_pack_u32(ptr
, pkey
->algo
);
129 ptr
= pkey_pack_u32(ptr
, pkey
->paramlen
);
130 memcpy(ptr
, pkey
->params
, pkey
->paramlen
);
132 if (pkey
->key_is_private
)
133 ret
= crypto_akcipher_set_priv_key(tfm
, key
, pkey
->keylen
);
135 ret
= crypto_akcipher_set_pub_key(tfm
, key
, pkey
->keylen
);
139 len
= crypto_akcipher_maxsize(tfm
);
140 info
->key_size
= len
* 8;
141 info
->max_data_size
= len
;
142 info
->max_sig_size
= len
;
143 info
->max_enc_size
= len
;
144 info
->max_dec_size
= len
;
145 info
->supported_ops
= (KEYCTL_SUPPORTS_ENCRYPT
|
146 KEYCTL_SUPPORTS_VERIFY
);
147 if (pkey
->key_is_private
)
148 info
->supported_ops
|= (KEYCTL_SUPPORTS_DECRYPT
|
149 KEYCTL_SUPPORTS_SIGN
);
155 crypto_free_akcipher(tfm
);
156 pr_devel("<==%s() = %d\n", __func__
, ret
);
161 * Do encryption, decryption and signing ops.
163 static int software_key_eds_op(struct kernel_pkey_params
*params
,
164 const void *in
, void *out
)
166 const struct public_key
*pkey
= params
->key
->payload
.data
[asym_crypto
];
167 struct akcipher_request
*req
;
168 struct crypto_akcipher
*tfm
;
169 struct crypto_wait cwait
;
170 struct scatterlist in_sg
, out_sg
;
171 char alg_name
[CRYPTO_MAX_ALG_NAME
];
175 pr_devel("==>%s()\n", __func__
);
177 ret
= software_key_determine_akcipher(params
->encoding
,
183 tfm
= crypto_alloc_akcipher(alg_name
, 0, 0);
187 req
= akcipher_request_alloc(tfm
, GFP_KERNEL
);
191 key
= kmalloc(pkey
->keylen
+ sizeof(u32
) * 2 + pkey
->paramlen
,
196 memcpy(key
, pkey
->key
, pkey
->keylen
);
197 ptr
= key
+ pkey
->keylen
;
198 ptr
= pkey_pack_u32(ptr
, pkey
->algo
);
199 ptr
= pkey_pack_u32(ptr
, pkey
->paramlen
);
200 memcpy(ptr
, pkey
->params
, pkey
->paramlen
);
202 if (pkey
->key_is_private
)
203 ret
= crypto_akcipher_set_priv_key(tfm
, key
, pkey
->keylen
);
205 ret
= crypto_akcipher_set_pub_key(tfm
, key
, pkey
->keylen
);
209 sg_init_one(&in_sg
, in
, params
->in_len
);
210 sg_init_one(&out_sg
, out
, params
->out_len
);
211 akcipher_request_set_crypt(req
, &in_sg
, &out_sg
, params
->in_len
,
213 crypto_init_wait(&cwait
);
214 akcipher_request_set_callback(req
, CRYPTO_TFM_REQ_MAY_BACKLOG
|
215 CRYPTO_TFM_REQ_MAY_SLEEP
,
216 crypto_req_done
, &cwait
);
218 /* Perform the encryption calculation. */
219 switch (params
->op
) {
220 case kernel_pkey_encrypt
:
221 ret
= crypto_akcipher_encrypt(req
);
223 case kernel_pkey_decrypt
:
224 ret
= crypto_akcipher_decrypt(req
);
226 case kernel_pkey_sign
:
227 ret
= crypto_akcipher_sign(req
);
233 ret
= crypto_wait_req(ret
, &cwait
);
240 akcipher_request_free(req
);
242 crypto_free_akcipher(tfm
);
243 pr_devel("<==%s() = %d\n", __func__
, ret
);
248 * Verify a signature using a public key.
250 int public_key_verify_signature(const struct public_key
*pkey
,
251 const struct public_key_signature
*sig
)
253 struct crypto_wait cwait
;
254 struct crypto_akcipher
*tfm
;
255 struct akcipher_request
*req
;
256 struct scatterlist src_sg
[2];
257 char alg_name
[CRYPTO_MAX_ALG_NAME
];
261 pr_devel("==>%s()\n", __func__
);
267 ret
= software_key_determine_akcipher(sig
->encoding
,
273 tfm
= crypto_alloc_akcipher(alg_name
, 0, 0);
278 req
= akcipher_request_alloc(tfm
, GFP_KERNEL
);
282 key
= kmalloc(pkey
->keylen
+ sizeof(u32
) * 2 + pkey
->paramlen
,
287 memcpy(key
, pkey
->key
, pkey
->keylen
);
288 ptr
= key
+ pkey
->keylen
;
289 ptr
= pkey_pack_u32(ptr
, pkey
->algo
);
290 ptr
= pkey_pack_u32(ptr
, pkey
->paramlen
);
291 memcpy(ptr
, pkey
->params
, pkey
->paramlen
);
293 if (pkey
->key_is_private
)
294 ret
= crypto_akcipher_set_priv_key(tfm
, key
, pkey
->keylen
);
296 ret
= crypto_akcipher_set_pub_key(tfm
, key
, pkey
->keylen
);
300 sg_init_table(src_sg
, 2);
301 sg_set_buf(&src_sg
[0], sig
->s
, sig
->s_size
);
302 sg_set_buf(&src_sg
[1], sig
->digest
, sig
->digest_size
);
303 akcipher_request_set_crypt(req
, src_sg
, NULL
, sig
->s_size
,
305 crypto_init_wait(&cwait
);
306 akcipher_request_set_callback(req
, CRYPTO_TFM_REQ_MAY_BACKLOG
|
307 CRYPTO_TFM_REQ_MAY_SLEEP
,
308 crypto_req_done
, &cwait
);
309 ret
= crypto_wait_req(crypto_akcipher_verify(req
), &cwait
);
314 akcipher_request_free(req
);
316 crypto_free_akcipher(tfm
);
317 pr_devel("<==%s() = %d\n", __func__
, ret
);
318 if (WARN_ON_ONCE(ret
> 0))
322 EXPORT_SYMBOL_GPL(public_key_verify_signature
);
324 static int public_key_verify_signature_2(const struct key
*key
,
325 const struct public_key_signature
*sig
)
327 const struct public_key
*pk
= key
->payload
.data
[asym_crypto
];
328 return public_key_verify_signature(pk
, sig
);
332 * Public key algorithm asymmetric key subtype
334 struct asymmetric_key_subtype public_key_subtype
= {
335 .owner
= THIS_MODULE
,
336 .name
= "public_key",
337 .name_len
= sizeof("public_key") - 1,
338 .describe
= public_key_describe
,
339 .destroy
= public_key_destroy
,
340 .query
= software_key_query
,
341 .eds_op
= software_key_eds_op
,
342 .verify_signature
= public_key_verify_signature_2
,
344 EXPORT_SYMBOL_GPL(public_key_subtype
);