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 if (uparams
.in_len
> info
.max_dec_size
||
139 uparams
.out_len
> info
.max_enc_size
)
142 case KEYCTL_PKEY_DECRYPT
:
143 if (uparams
.in_len
> info
.max_enc_size
||
144 uparams
.out_len
> info
.max_dec_size
)
147 case KEYCTL_PKEY_SIGN
:
148 if (uparams
.in_len
> info
.max_data_size
||
149 uparams
.out_len
> info
.max_sig_size
)
152 case KEYCTL_PKEY_VERIFY
:
153 if (uparams
.in_len
> info
.max_data_size
||
154 uparams
.in2_len
> info
.max_sig_size
)
161 params
->in_len
= uparams
.in_len
;
162 params
->out_len
= uparams
.out_len
; /* Note: same as in2_len */
167 * Query information about an asymmetric key.
169 long keyctl_pkey_query(key_serial_t id
,
170 const char __user
*_info
,
171 struct keyctl_pkey_query __user
*_res
)
173 struct kernel_pkey_params params
;
174 struct kernel_pkey_query res
;
177 ret
= keyctl_pkey_params_get(id
, _info
, ¶ms
);
181 ret
= params
.key
->type
->asym_query(¶ms
, &res
);
186 if (copy_to_user(_res
, &res
, sizeof(res
)) == 0 &&
187 clear_user(_res
->__spare
, sizeof(_res
->__spare
)) == 0)
191 keyctl_pkey_params_free(¶ms
);
196 * Encrypt/decrypt/sign
198 * Encrypt data, decrypt data or sign data using a public key.
200 * _info is a string of supplementary information in key=val format. For
201 * instance, it might contain:
203 * "enc=pkcs1 hash=sha256"
205 * where enc= specifies the encoding and hash= selects the OID to go in that
206 * particular encoding if required. If enc= isn't supplied, it's assumed that
207 * the caller is supplying raw values.
209 * If successful, the amount of data written into the output buffer is
212 long keyctl_pkey_e_d_s(int op
,
213 const struct keyctl_pkey_params __user
*_params
,
214 const char __user
*_info
,
215 const void __user
*_in
,
218 struct kernel_pkey_params params
;
222 ret
= keyctl_pkey_params_get_2(_params
, _info
, op
, ¶ms
);
227 if (!params
.key
->type
->asym_eds_op
)
231 case KEYCTL_PKEY_ENCRYPT
:
232 params
.op
= kernel_pkey_encrypt
;
234 case KEYCTL_PKEY_DECRYPT
:
235 params
.op
= kernel_pkey_decrypt
;
237 case KEYCTL_PKEY_SIGN
:
238 params
.op
= kernel_pkey_sign
;
244 in
= memdup_user(_in
, params
.in_len
);
251 out
= kmalloc(params
.out_len
, GFP_KERNEL
);
255 ret
= params
.key
->type
->asym_eds_op(¶ms
, in
, out
);
259 if (copy_to_user(_out
, out
, ret
) != 0)
267 keyctl_pkey_params_free(¶ms
);
272 * Verify a signature.
274 * Verify a public key signature using the given key, or if not given, search
275 * for a matching key.
277 * _info is a string of supplementary information in key=val format. For
278 * instance, it might contain:
280 * "enc=pkcs1 hash=sha256"
282 * where enc= specifies the signature blob encoding and hash= selects the OID
283 * to go in that particular encoding. If enc= isn't supplied, it's assumed
284 * that the caller is supplying raw values.
286 * If successful, 0 is returned.
288 long keyctl_pkey_verify(const struct keyctl_pkey_params __user
*_params
,
289 const char __user
*_info
,
290 const void __user
*_in
,
291 const void __user
*_in2
)
293 struct kernel_pkey_params params
;
297 ret
= keyctl_pkey_params_get_2(_params
, _info
, KEYCTL_PKEY_VERIFY
,
303 if (!params
.key
->type
->asym_verify_signature
)
306 in
= memdup_user(_in
, params
.in_len
);
312 in2
= memdup_user(_in2
, params
.in2_len
);
318 params
.op
= kernel_pkey_verify
;
319 ret
= params
.key
->type
->asym_verify_signature(¶ms
, in
, in2
);
325 keyctl_pkey_params_free(¶ms
);