1 /* Public-key operation keyctls
3 * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
12 #include <linux/slab.h>
13 #include <linux/err.h>
14 #include <linux/key.h>
15 #include <linux/keyctl.h>
16 #include <linux/parser.h>
17 #include <linux/uaccess.h>
18 #include <keys/user-type.h>
21 static void keyctl_pkey_params_free(struct kernel_pkey_params
*params
)
29 Opt_enc
, /* "enc=<encoding>" eg. "enc=oaep" */
30 Opt_hash
, /* "hash=<digest-name>" eg. "hash=sha1" */
33 static const match_table_t param_keys
= {
34 { Opt_enc
, "enc=%s" },
35 { Opt_hash
, "hash=%s" },
40 * Parse the information string which consists of key=val pairs.
42 static int keyctl_pkey_params_parse(struct kernel_pkey_params
*params
)
44 unsigned long token_mask
= 0;
45 substring_t args
[MAX_OPT_ARGS
];
46 char *c
= params
->info
, *p
, *q
;
49 while ((p
= strsep(&c
, " \t"))) {
50 if (*p
== '\0' || *p
== ' ' || *p
== '\t')
52 token
= match_token(p
, param_keys
, args
);
55 if (__test_and_set_bit(token
, &token_mask
))
67 params
->hash_algo
= q
;
79 * Interpret parameters. Callers must always call the free function
80 * on params, even if an error is returned.
82 static int keyctl_pkey_params_get(key_serial_t id
,
83 const char __user
*_info
,
84 struct kernel_pkey_params
*params
)
90 memset(params
, 0, sizeof(*params
));
91 params
->encoding
= "raw";
93 p
= strndup_user(_info
, PAGE_SIZE
);
98 ret
= keyctl_pkey_params_parse(params
);
102 key_ref
= lookup_user_key(id
, 0, KEY_NEED_SEARCH
);
104 return PTR_ERR(key_ref
);
105 params
->key
= key_ref_to_ptr(key_ref
);
107 if (!params
->key
->type
->asym_query
)
114 * Get parameters from userspace. Callers must always call the free function
115 * on params, even if an error is returned.
117 static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user
*_params
,
118 const char __user
*_info
,
120 struct kernel_pkey_params
*params
)
122 struct keyctl_pkey_params uparams
;
123 struct kernel_pkey_query info
;
126 memset(params
, 0, sizeof(*params
));
127 params
->encoding
= "raw";
129 if (copy_from_user(&uparams
, _params
, sizeof(uparams
)) != 0)
132 ret
= keyctl_pkey_params_get(uparams
.key_id
, _info
, params
);
136 ret
= params
->key
->type
->asym_query(params
, &info
);
141 case KEYCTL_PKEY_ENCRYPT
:
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 case KEYCTL_PKEY_VERIFY
:
149 if (uparams
.in_len
> info
.max_sig_size
||
150 uparams
.out_len
> info
.max_data_size
)
157 params
->in_len
= uparams
.in_len
;
158 params
->out_len
= uparams
.out_len
;
163 * Query information about an asymmetric key.
165 long keyctl_pkey_query(key_serial_t id
,
166 const char __user
*_info
,
167 struct keyctl_pkey_query __user
*_res
)
169 struct kernel_pkey_params params
;
170 struct kernel_pkey_query res
;
173 memset(¶ms
, 0, sizeof(params
));
175 ret
= keyctl_pkey_params_get(id
, _info
, ¶ms
);
179 ret
= params
.key
->type
->asym_query(¶ms
, &res
);
184 if (copy_to_user(_res
, &res
, sizeof(res
)) == 0 &&
185 clear_user(_res
->__spare
, sizeof(_res
->__spare
)) == 0)
189 keyctl_pkey_params_free(¶ms
);
194 * Encrypt/decrypt/sign
196 * Encrypt data, decrypt data or sign data using a public key.
198 * _info is a string of supplementary information in key=val format. For
199 * instance, it might contain:
201 * "enc=pkcs1 hash=sha256"
203 * where enc= specifies the encoding and hash= selects the OID to go in that
204 * particular encoding if required. If enc= isn't supplied, it's assumed that
205 * the caller is supplying raw values.
207 * If successful, the amount of data written into the output buffer is
210 long keyctl_pkey_e_d_s(int op
,
211 const struct keyctl_pkey_params __user
*_params
,
212 const char __user
*_info
,
213 const void __user
*_in
,
216 struct kernel_pkey_params params
;
220 ret
= keyctl_pkey_params_get_2(_params
, _info
, op
, ¶ms
);
225 if (!params
.key
->type
->asym_eds_op
)
229 case KEYCTL_PKEY_ENCRYPT
:
230 params
.op
= kernel_pkey_encrypt
;
232 case KEYCTL_PKEY_DECRYPT
:
233 params
.op
= kernel_pkey_decrypt
;
235 case KEYCTL_PKEY_SIGN
:
236 params
.op
= kernel_pkey_sign
;
242 in
= memdup_user(_in
, params
.in_len
);
249 out
= kmalloc(params
.out_len
, GFP_KERNEL
);
253 ret
= params
.key
->type
->asym_eds_op(¶ms
, in
, out
);
257 if (copy_to_user(_out
, out
, ret
) != 0)
265 keyctl_pkey_params_free(¶ms
);
270 * Verify a signature.
272 * Verify a public key signature using the given key, or if not given, search
273 * for a matching key.
275 * _info is a string of supplementary information in key=val format. For
276 * instance, it might contain:
278 * "enc=pkcs1 hash=sha256"
280 * where enc= specifies the signature blob encoding and hash= selects the OID
281 * to go in that particular encoding. If enc= isn't supplied, it's assumed
282 * that the caller is supplying raw values.
284 * If successful, 0 is returned.
286 long keyctl_pkey_verify(const struct keyctl_pkey_params __user
*_params
,
287 const char __user
*_info
,
288 const void __user
*_in
,
289 const void __user
*_in2
)
291 struct kernel_pkey_params params
;
295 ret
= keyctl_pkey_params_get_2(_params
, _info
, KEYCTL_PKEY_VERIFY
,
301 if (!params
.key
->type
->asym_verify_signature
)
304 in
= memdup_user(_in
, params
.in_len
);
310 in2
= memdup_user(_in2
, params
.in2_len
);
316 params
.op
= kernel_pkey_verify
;
317 ret
= params
.key
->type
->asym_verify_signature(¶ms
, in
, in2
);
323 keyctl_pkey_params_free(¶ms
);