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
);
53 if (__test_and_set_bit(token
, &token_mask
))
65 params
->hash_algo
= q
;
77 * Interpret parameters. Callers must always call the free function
78 * on params, even if an error is returned.
80 static int keyctl_pkey_params_get(key_serial_t id
,
81 const char __user
*_info
,
82 struct kernel_pkey_params
*params
)
88 memset(params
, 0, sizeof(*params
));
89 params
->encoding
= "raw";
91 p
= strndup_user(_info
, PAGE_SIZE
);
96 ret
= keyctl_pkey_params_parse(params
);
100 key_ref
= lookup_user_key(id
, 0, KEY_NEED_SEARCH
);
102 return PTR_ERR(key_ref
);
103 params
->key
= key_ref_to_ptr(key_ref
);
105 if (!params
->key
->type
->asym_query
)
112 * Get parameters from userspace. Callers must always call the free function
113 * on params, even if an error is returned.
115 static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user
*_params
,
116 const char __user
*_info
,
118 struct kernel_pkey_params
*params
)
120 struct keyctl_pkey_params uparams
;
121 struct kernel_pkey_query info
;
124 memset(params
, 0, sizeof(*params
));
125 params
->encoding
= "raw";
127 if (copy_from_user(&uparams
, _params
, sizeof(uparams
)) != 0)
130 ret
= keyctl_pkey_params_get(uparams
.key_id
, _info
, params
);
134 ret
= params
->key
->type
->asym_query(params
, &info
);
139 case KEYCTL_PKEY_ENCRYPT
:
140 case KEYCTL_PKEY_DECRYPT
:
141 if (uparams
.in_len
> info
.max_enc_size
||
142 uparams
.out_len
> info
.max_dec_size
)
145 case KEYCTL_PKEY_SIGN
:
146 case KEYCTL_PKEY_VERIFY
:
147 if (uparams
.in_len
> info
.max_sig_size
||
148 uparams
.out_len
> info
.max_data_size
)
155 params
->in_len
= uparams
.in_len
;
156 params
->out_len
= uparams
.out_len
;
161 * Query information about an asymmetric key.
163 long keyctl_pkey_query(key_serial_t id
,
164 const char __user
*_info
,
165 struct keyctl_pkey_query __user
*_res
)
167 struct kernel_pkey_params params
;
168 struct kernel_pkey_query res
;
171 memset(¶ms
, 0, sizeof(params
));
173 ret
= keyctl_pkey_params_get(id
, _info
, ¶ms
);
177 ret
= params
.key
->type
->asym_query(¶ms
, &res
);
182 if (copy_to_user(_res
, &res
, sizeof(res
)) == 0 &&
183 clear_user(_res
->__spare
, sizeof(_res
->__spare
)) == 0)
187 keyctl_pkey_params_free(¶ms
);
192 * Encrypt/decrypt/sign
194 * Encrypt data, decrypt data or sign data using a public key.
196 * _info is a string of supplementary information in key=val format. For
197 * instance, it might contain:
199 * "enc=pkcs1 hash=sha256"
201 * where enc= specifies the encoding and hash= selects the OID to go in that
202 * particular encoding if required. If enc= isn't supplied, it's assumed that
203 * the caller is supplying raw values.
205 * If successful, the amount of data written into the output buffer is
208 long keyctl_pkey_e_d_s(int op
,
209 const struct keyctl_pkey_params __user
*_params
,
210 const char __user
*_info
,
211 const void __user
*_in
,
214 struct kernel_pkey_params params
;
218 ret
= keyctl_pkey_params_get_2(_params
, _info
, op
, ¶ms
);
223 if (!params
.key
->type
->asym_eds_op
)
227 case KEYCTL_PKEY_ENCRYPT
:
228 params
.op
= kernel_pkey_encrypt
;
230 case KEYCTL_PKEY_DECRYPT
:
231 params
.op
= kernel_pkey_decrypt
;
233 case KEYCTL_PKEY_SIGN
:
234 params
.op
= kernel_pkey_sign
;
240 in
= memdup_user(_in
, params
.in_len
);
247 out
= kmalloc(params
.out_len
, GFP_KERNEL
);
251 ret
= params
.key
->type
->asym_eds_op(¶ms
, in
, out
);
255 if (copy_to_user(_out
, out
, ret
) != 0)
263 keyctl_pkey_params_free(¶ms
);
268 * Verify a signature.
270 * Verify a public key signature using the given key, or if not given, search
271 * for a matching key.
273 * _info is a string of supplementary information in key=val format. For
274 * instance, it might contain:
276 * "enc=pkcs1 hash=sha256"
278 * where enc= specifies the signature blob encoding and hash= selects the OID
279 * to go in that particular encoding. If enc= isn't supplied, it's assumed
280 * that the caller is supplying raw values.
282 * If successful, 0 is returned.
284 long keyctl_pkey_verify(const struct keyctl_pkey_params __user
*_params
,
285 const char __user
*_info
,
286 const void __user
*_in
,
287 const void __user
*_in2
)
289 struct kernel_pkey_params params
;
293 ret
= keyctl_pkey_params_get_2(_params
, _info
, KEYCTL_PKEY_VERIFY
,
299 if (!params
.key
->type
->asym_verify_signature
)
302 in
= memdup_user(_in
, params
.in_len
);
308 in2
= memdup_user(_in2
, params
.in2_len
);
314 params
.op
= kernel_pkey_verify
;
315 ret
= params
.key
->type
->asym_verify_signature(¶ms
, in
, in2
);
321 keyctl_pkey_params_free(¶ms
);