Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
[platform/kernel/linux-starfive.git] / security / keys / dh.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Crypto operations using stored keys
3  *
4  * Copyright (c) 2016, Intel Corporation
5  */
6
7 #include <linux/slab.h>
8 #include <linux/uaccess.h>
9 #include <linux/scatterlist.h>
10 #include <linux/crypto.h>
11 #include <crypto/hash.h>
12 #include <crypto/kpp.h>
13 #include <crypto/dh.h>
14 #include <keys/user-type.h>
15 #include "internal.h"
16
17 static ssize_t dh_data_from_key(key_serial_t keyid, void **data)
18 {
19         struct key *key;
20         key_ref_t key_ref;
21         long status;
22         ssize_t ret;
23
24         key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
25         if (IS_ERR(key_ref)) {
26                 ret = -ENOKEY;
27                 goto error;
28         }
29
30         key = key_ref_to_ptr(key_ref);
31
32         ret = -EOPNOTSUPP;
33         if (key->type == &key_type_user) {
34                 down_read(&key->sem);
35                 status = key_validate(key);
36                 if (status == 0) {
37                         const struct user_key_payload *payload;
38                         uint8_t *duplicate;
39
40                         payload = user_key_payload_locked(key);
41
42                         duplicate = kmemdup(payload->data, payload->datalen,
43                                             GFP_KERNEL);
44                         if (duplicate) {
45                                 *data = duplicate;
46                                 ret = payload->datalen;
47                         } else {
48                                 ret = -ENOMEM;
49                         }
50                 }
51                 up_read(&key->sem);
52         }
53
54         key_put(key);
55 error:
56         return ret;
57 }
58
59 static void dh_free_data(struct dh *dh)
60 {
61         kfree_sensitive(dh->key);
62         kfree_sensitive(dh->p);
63         kfree_sensitive(dh->g);
64 }
65
66 struct dh_completion {
67         struct completion completion;
68         int err;
69 };
70
71 static void dh_crypto_done(struct crypto_async_request *req, int err)
72 {
73         struct dh_completion *compl = req->data;
74
75         if (err == -EINPROGRESS)
76                 return;
77
78         compl->err = err;
79         complete(&compl->completion);
80 }
81
82 struct kdf_sdesc {
83         struct shash_desc shash;
84         char ctx[];
85 };
86
87 static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
88 {
89         struct crypto_shash *tfm;
90         struct kdf_sdesc *sdesc;
91         int size;
92         int err;
93
94         /* allocate synchronous hash */
95         tfm = crypto_alloc_shash(hashname, 0, 0);
96         if (IS_ERR(tfm)) {
97                 pr_info("could not allocate digest TFM handle %s\n", hashname);
98                 return PTR_ERR(tfm);
99         }
100
101         err = -EINVAL;
102         if (crypto_shash_digestsize(tfm) == 0)
103                 goto out_free_tfm;
104
105         err = -ENOMEM;
106         size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
107         sdesc = kmalloc(size, GFP_KERNEL);
108         if (!sdesc)
109                 goto out_free_tfm;
110         sdesc->shash.tfm = tfm;
111
112         *sdesc_ret = sdesc;
113
114         return 0;
115
116 out_free_tfm:
117         crypto_free_shash(tfm);
118         return err;
119 }
120
121 static void kdf_dealloc(struct kdf_sdesc *sdesc)
122 {
123         if (!sdesc)
124                 return;
125
126         if (sdesc->shash.tfm)
127                 crypto_free_shash(sdesc->shash.tfm);
128
129         kfree_sensitive(sdesc);
130 }
131
132 /*
133  * Implementation of the KDF in counter mode according to SP800-108 section 5.1
134  * as well as SP800-56A section 5.8.1 (Single-step KDF).
135  *
136  * SP800-56A:
137  * The src pointer is defined as Z || other info where Z is the shared secret
138  * from DH and other info is an arbitrary string (see SP800-56A section
139  * 5.8.1.2).
140  *
141  * 'dlen' must be a multiple of the digest size.
142  */
143 static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
144                    u8 *dst, unsigned int dlen, unsigned int zlen)
145 {
146         struct shash_desc *desc = &sdesc->shash;
147         unsigned int h = crypto_shash_digestsize(desc->tfm);
148         int err = 0;
149         u8 *dst_orig = dst;
150         __be32 counter = cpu_to_be32(1);
151
152         while (dlen) {
153                 err = crypto_shash_init(desc);
154                 if (err)
155                         goto err;
156
157                 err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32));
158                 if (err)
159                         goto err;
160
161                 if (zlen && h) {
162                         u8 tmpbuffer[32];
163                         size_t chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
164                         memset(tmpbuffer, 0, chunk);
165
166                         do {
167                                 err = crypto_shash_update(desc, tmpbuffer,
168                                                           chunk);
169                                 if (err)
170                                         goto err;
171
172                                 zlen -= chunk;
173                                 chunk = min_t(size_t, zlen, sizeof(tmpbuffer));
174                         } while (zlen);
175                 }
176
177                 if (src && slen) {
178                         err = crypto_shash_update(desc, src, slen);
179                         if (err)
180                                 goto err;
181                 }
182
183                 err = crypto_shash_final(desc, dst);
184                 if (err)
185                         goto err;
186
187                 dlen -= h;
188                 dst += h;
189                 counter = cpu_to_be32(be32_to_cpu(counter) + 1);
190         }
191
192         return 0;
193
194 err:
195         memzero_explicit(dst_orig, dlen);
196         return err;
197 }
198
199 static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
200                                  char __user *buffer, size_t buflen,
201                                  uint8_t *kbuf, size_t kbuflen, size_t lzero)
202 {
203         uint8_t *outbuf = NULL;
204         int ret;
205         size_t outbuf_len = roundup(buflen,
206                                     crypto_shash_digestsize(sdesc->shash.tfm));
207
208         outbuf = kmalloc(outbuf_len, GFP_KERNEL);
209         if (!outbuf) {
210                 ret = -ENOMEM;
211                 goto err;
212         }
213
214         ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, outbuf_len, lzero);
215         if (ret)
216                 goto err;
217
218         ret = buflen;
219         if (copy_to_user(buffer, outbuf, buflen) != 0)
220                 ret = -EFAULT;
221
222 err:
223         kfree_sensitive(outbuf);
224         return ret;
225 }
226
227 long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
228                          char __user *buffer, size_t buflen,
229                          struct keyctl_kdf_params *kdfcopy)
230 {
231         long ret;
232         ssize_t dlen;
233         int secretlen;
234         int outlen;
235         struct keyctl_dh_params pcopy;
236         struct dh dh_inputs;
237         struct scatterlist outsg;
238         struct dh_completion compl;
239         struct crypto_kpp *tfm;
240         struct kpp_request *req;
241         uint8_t *secret;
242         uint8_t *outbuf;
243         struct kdf_sdesc *sdesc = NULL;
244
245         if (!params || (!buffer && buflen)) {
246                 ret = -EINVAL;
247                 goto out1;
248         }
249         if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
250                 ret = -EFAULT;
251                 goto out1;
252         }
253
254         if (kdfcopy) {
255                 char *hashname;
256
257                 if (memchr_inv(kdfcopy->__spare, 0, sizeof(kdfcopy->__spare))) {
258                         ret = -EINVAL;
259                         goto out1;
260                 }
261
262                 if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN ||
263                     kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) {
264                         ret = -EMSGSIZE;
265                         goto out1;
266                 }
267
268                 /* get KDF name string */
269                 hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME);
270                 if (IS_ERR(hashname)) {
271                         ret = PTR_ERR(hashname);
272                         goto out1;
273                 }
274
275                 /* allocate KDF from the kernel crypto API */
276                 ret = kdf_alloc(&sdesc, hashname);
277                 kfree(hashname);
278                 if (ret)
279                         goto out1;
280         }
281
282         memset(&dh_inputs, 0, sizeof(dh_inputs));
283
284         dlen = dh_data_from_key(pcopy.prime, &dh_inputs.p);
285         if (dlen < 0) {
286                 ret = dlen;
287                 goto out1;
288         }
289         dh_inputs.p_size = dlen;
290
291         dlen = dh_data_from_key(pcopy.base, &dh_inputs.g);
292         if (dlen < 0) {
293                 ret = dlen;
294                 goto out2;
295         }
296         dh_inputs.g_size = dlen;
297
298         dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
299         if (dlen < 0) {
300                 ret = dlen;
301                 goto out2;
302         }
303         dh_inputs.key_size = dlen;
304
305         secretlen = crypto_dh_key_len(&dh_inputs);
306         secret = kmalloc(secretlen, GFP_KERNEL);
307         if (!secret) {
308                 ret = -ENOMEM;
309                 goto out2;
310         }
311         ret = crypto_dh_encode_key(secret, secretlen, &dh_inputs);
312         if (ret)
313                 goto out3;
314
315         tfm = crypto_alloc_kpp("dh", 0, 0);
316         if (IS_ERR(tfm)) {
317                 ret = PTR_ERR(tfm);
318                 goto out3;
319         }
320
321         ret = crypto_kpp_set_secret(tfm, secret, secretlen);
322         if (ret)
323                 goto out4;
324
325         outlen = crypto_kpp_maxsize(tfm);
326
327         if (!kdfcopy) {
328                 /*
329                  * When not using a KDF, buflen 0 is used to read the
330                  * required buffer length
331                  */
332                 if (buflen == 0) {
333                         ret = outlen;
334                         goto out4;
335                 } else if (outlen > buflen) {
336                         ret = -EOVERFLOW;
337                         goto out4;
338                 }
339         }
340
341         outbuf = kzalloc(kdfcopy ? (outlen + kdfcopy->otherinfolen) : outlen,
342                          GFP_KERNEL);
343         if (!outbuf) {
344                 ret = -ENOMEM;
345                 goto out4;
346         }
347
348         sg_init_one(&outsg, outbuf, outlen);
349
350         req = kpp_request_alloc(tfm, GFP_KERNEL);
351         if (!req) {
352                 ret = -ENOMEM;
353                 goto out5;
354         }
355
356         kpp_request_set_input(req, NULL, 0);
357         kpp_request_set_output(req, &outsg, outlen);
358         init_completion(&compl.completion);
359         kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
360                                  CRYPTO_TFM_REQ_MAY_SLEEP,
361                                  dh_crypto_done, &compl);
362
363         /*
364          * For DH, generate_public_key and generate_shared_secret are
365          * the same calculation
366          */
367         ret = crypto_kpp_generate_public_key(req);
368         if (ret == -EINPROGRESS) {
369                 wait_for_completion(&compl.completion);
370                 ret = compl.err;
371                 if (ret)
372                         goto out6;
373         }
374
375         if (kdfcopy) {
376                 /*
377                  * Concatenate SP800-56A otherinfo past DH shared secret -- the
378                  * input to the KDF is (DH shared secret || otherinfo)
379                  */
380                 if (copy_from_user(outbuf + req->dst_len, kdfcopy->otherinfo,
381                                    kdfcopy->otherinfolen) != 0) {
382                         ret = -EFAULT;
383                         goto out6;
384                 }
385
386                 ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf,
387                                             req->dst_len + kdfcopy->otherinfolen,
388                                             outlen - req->dst_len);
389         } else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) {
390                 ret = req->dst_len;
391         } else {
392                 ret = -EFAULT;
393         }
394
395 out6:
396         kpp_request_free(req);
397 out5:
398         kfree_sensitive(outbuf);
399 out4:
400         crypto_free_kpp(tfm);
401 out3:
402         kfree_sensitive(secret);
403 out2:
404         dh_free_data(&dh_inputs);
405 out1:
406         kdf_dealloc(sdesc);
407         return ret;
408 }
409
410 long keyctl_dh_compute(struct keyctl_dh_params __user *params,
411                        char __user *buffer, size_t buflen,
412                        struct keyctl_kdf_params __user *kdf)
413 {
414         struct keyctl_kdf_params kdfcopy;
415
416         if (!kdf)
417                 return __keyctl_dh_compute(params, buffer, buflen, NULL);
418
419         if (copy_from_user(&kdfcopy, kdf, sizeof(kdfcopy)) != 0)
420                 return -EFAULT;
421
422         return __keyctl_dh_compute(params, buffer, buflen, &kdfcopy);
423 }