xref: /openbmc/linux/security/keys/dh.c (revision 867e6d38)
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  }
424