1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Public-key operation keyctls
4 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
8 #include <linux/slab.h>
10 #include <linux/key.h>
11 #include <linux/keyctl.h>
12 #include <linux/parser.h>
13 #include <linux/uaccess.h>
14 #include <keys/user-type.h>
17 static void keyctl_pkey_params_free(struct kernel_pkey_params
*params
)
25 Opt_enc
, /* "enc=<encoding>" eg. "enc=oaep" */
26 Opt_hash
, /* "hash=<digest-name>" eg. "hash=sha1" */
29 static const match_table_t param_keys
= {
30 { Opt_enc
, "enc=%s" },
31 { Opt_hash
, "hash=%s" },
36 * Parse the information string which consists of key=val pairs.
38 static int keyctl_pkey_params_parse(struct kernel_pkey_params
*params
)
40 unsigned long token_mask
= 0;
41 substring_t args
[MAX_OPT_ARGS
];
42 char *c
= params
->info
, *p
, *q
;
45 while ((p
= strsep(&c
, " \t"))) {
46 if (*p
== '\0' || *p
== ' ' || *p
== '\t')
48 token
= match_token(p
, param_keys
, args
);
51 if (__test_and_set_bit(token
, &token_mask
))
63 params
->hash_algo
= q
;
75 * Interpret parameters. Callers must always call the free function
76 * on params, even if an error is returned.
78 static int keyctl_pkey_params_get(key_serial_t id
,
79 const char __user
*_info
,
80 struct kernel_pkey_params
*params
)
86 memset(params
, 0, sizeof(*params
));
87 params
->encoding
= "raw";
89 p
= strndup_user(_info
, PAGE_SIZE
);
94 ret
= keyctl_pkey_params_parse(params
);
98 key_ref
= lookup_user_key(id
, 0, KEY_NEED_SEARCH
);
100 return PTR_ERR(key_ref
);
101 params
->key
= key_ref_to_ptr(key_ref
);
103 if (!params
->key
->type
->asym_query
)
110 * Get parameters from userspace. Callers must always call the free function
111 * on params, even if an error is returned.
113 static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user
*_params
,
114 const char __user
*_info
,
116 struct kernel_pkey_params
*params
)
118 struct keyctl_pkey_params uparams
;
119 struct kernel_pkey_query info
;
122 memset(params
, 0, sizeof(*params
));
123 params
->encoding
= "raw";
125 if (copy_from_user(&uparams
, _params
, sizeof(uparams
)) != 0)
128 ret
= keyctl_pkey_params_get(uparams
.key_id
, _info
, params
);
132 ret
= params
->key
->type
->asym_query(params
, &info
);
137 case KEYCTL_PKEY_ENCRYPT
:
138 case KEYCTL_PKEY_DECRYPT
:
139 if (uparams
.in_len
> info
.max_enc_size
||
140 uparams
.out_len
> info
.max_dec_size
)
143 case KEYCTL_PKEY_SIGN
:
144 case KEYCTL_PKEY_VERIFY
:
145 if (uparams
.in_len
> info
.max_sig_size
||
146 uparams
.out_len
> info
.max_data_size
)
153 params
->in_len
= uparams
.in_len
;
154 params
->out_len
= uparams
.out_len
;
159 * Query information about an asymmetric key.
161 long keyctl_pkey_query(key_serial_t id
,
162 const char __user
*_info
,
163 struct keyctl_pkey_query __user
*_res
)
165 struct kernel_pkey_params params
;
166 struct kernel_pkey_query res
;
169 memset(¶ms
, 0, sizeof(params
));
171 ret
= keyctl_pkey_params_get(id
, _info
, ¶ms
);
175 ret
= params
.key
->type
->asym_query(¶ms
, &res
);
180 if (copy_to_user(_res
, &res
, sizeof(res
)) == 0 &&
181 clear_user(_res
->__spare
, sizeof(_res
->__spare
)) == 0)
185 keyctl_pkey_params_free(¶ms
);
190 * Encrypt/decrypt/sign
192 * Encrypt data, decrypt data or sign data using a public key.
194 * _info is a string of supplementary information in key=val format. For
195 * instance, it might contain:
197 * "enc=pkcs1 hash=sha256"
199 * where enc= specifies the encoding and hash= selects the OID to go in that
200 * particular encoding if required. If enc= isn't supplied, it's assumed that
201 * the caller is supplying raw values.
203 * If successful, the amount of data written into the output buffer is
206 long keyctl_pkey_e_d_s(int op
,
207 const struct keyctl_pkey_params __user
*_params
,
208 const char __user
*_info
,
209 const void __user
*_in
,
212 struct kernel_pkey_params params
;
216 ret
= keyctl_pkey_params_get_2(_params
, _info
, op
, ¶ms
);
221 if (!params
.key
->type
->asym_eds_op
)
225 case KEYCTL_PKEY_ENCRYPT
:
226 params
.op
= kernel_pkey_encrypt
;
228 case KEYCTL_PKEY_DECRYPT
:
229 params
.op
= kernel_pkey_decrypt
;
231 case KEYCTL_PKEY_SIGN
:
232 params
.op
= kernel_pkey_sign
;
238 in
= memdup_user(_in
, params
.in_len
);
245 out
= kmalloc(params
.out_len
, GFP_KERNEL
);
249 ret
= params
.key
->type
->asym_eds_op(¶ms
, in
, out
);
253 if (copy_to_user(_out
, out
, ret
) != 0)
261 keyctl_pkey_params_free(¶ms
);
266 * Verify a signature.
268 * Verify a public key signature using the given key, or if not given, search
269 * for a matching key.
271 * _info is a string of supplementary information in key=val format. For
272 * instance, it might contain:
274 * "enc=pkcs1 hash=sha256"
276 * where enc= specifies the signature blob encoding and hash= selects the OID
277 * to go in that particular encoding. If enc= isn't supplied, it's assumed
278 * that the caller is supplying raw values.
280 * If successful, 0 is returned.
282 long keyctl_pkey_verify(const struct keyctl_pkey_params __user
*_params
,
283 const char __user
*_info
,
284 const void __user
*_in
,
285 const void __user
*_in2
)
287 struct kernel_pkey_params params
;
291 ret
= keyctl_pkey_params_get_2(_params
, _info
, KEYCTL_PKEY_VERIFY
,
297 if (!params
.key
->type
->asym_verify_signature
)
300 in
= memdup_user(_in
, params
.in_len
);
306 in2
= memdup_user(_in2
, params
.in2_len
);
312 params
.op
= kernel_pkey_verify
;
313 ret
= params
.key
->type
->asym_verify_signature(¶ms
, in
, in2
);
319 keyctl_pkey_params_free(¶ms
);