xref: /openbmc/linux/security/keys/dh.c (revision 020c5260)
1 /* Crypto operations using stored keys
2  *
3  * Copyright (c) 2016, Intel Corporation
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version
8  * 2 of the License, or (at your option) any later version.
9  */
10 
11 #include <linux/mpi.h>
12 #include <linux/slab.h>
13 #include <linux/uaccess.h>
14 #include <linux/crypto.h>
15 #include <crypto/hash.h>
16 #include <keys/user-type.h>
17 #include "internal.h"
18 
19 /*
20  * Public key or shared secret generation function [RFC2631 sec 2.1.1]
21  *
22  * ya = g^xa mod p;
23  * or
24  * ZZ = yb^xa mod p;
25  *
26  * where xa is the local private key, ya is the local public key, g is
27  * the generator, p is the prime, yb is the remote public key, and ZZ
28  * is the shared secret.
29  *
30  * Both are the same calculation, so g or yb are the "base" and ya or
31  * ZZ are the "result".
32  */
33 static int do_dh(MPI result, MPI base, MPI xa, MPI p)
34 {
35 	return mpi_powm(result, base, xa, p);
36 }
37 
38 static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi)
39 {
40 	struct key *key;
41 	key_ref_t key_ref;
42 	long status;
43 	ssize_t ret;
44 
45 	key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
46 	if (IS_ERR(key_ref)) {
47 		ret = -ENOKEY;
48 		goto error;
49 	}
50 
51 	key = key_ref_to_ptr(key_ref);
52 
53 	ret = -EOPNOTSUPP;
54 	if (key->type == &key_type_user) {
55 		down_read(&key->sem);
56 		status = key_validate(key);
57 		if (status == 0) {
58 			const struct user_key_payload *payload;
59 
60 			payload = user_key_payload_locked(key);
61 
62 			if (maxlen == 0) {
63 				*mpi = NULL;
64 				ret = payload->datalen;
65 			} else if (payload->datalen <= maxlen) {
66 				*mpi = mpi_read_raw_data(payload->data,
67 							 payload->datalen);
68 				if (*mpi)
69 					ret = payload->datalen;
70 			} else {
71 				ret = -EINVAL;
72 			}
73 		}
74 		up_read(&key->sem);
75 	}
76 
77 	key_put(key);
78 error:
79 	return ret;
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 
93 	/* allocate synchronous hash */
94 	tfm = crypto_alloc_shash(hashname, 0, 0);
95 	if (IS_ERR(tfm)) {
96 		pr_info("could not allocate digest TFM handle %s\n", hashname);
97 		return PTR_ERR(tfm);
98 	}
99 
100 	size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
101 	sdesc = kmalloc(size, GFP_KERNEL);
102 	if (!sdesc)
103 		return -ENOMEM;
104 	sdesc->shash.tfm = tfm;
105 	sdesc->shash.flags = 0x0;
106 
107 	*sdesc_ret = sdesc;
108 
109 	return 0;
110 }
111 
112 static void kdf_dealloc(struct kdf_sdesc *sdesc)
113 {
114 	if (!sdesc)
115 		return;
116 
117 	if (sdesc->shash.tfm)
118 		crypto_free_shash(sdesc->shash.tfm);
119 
120 	kzfree(sdesc);
121 }
122 
123 /* convert 32 bit integer into its string representation */
124 static inline void crypto_kw_cpu_to_be32(u32 val, u8 *buf)
125 {
126 	__be32 *a = (__be32 *)buf;
127 
128 	*a = cpu_to_be32(val);
129 }
130 
131 /*
132  * Implementation of the KDF in counter mode according to SP800-108 section 5.1
133  * as well as SP800-56A section 5.8.1 (Single-step KDF).
134  *
135  * SP800-56A:
136  * The src pointer is defined as Z || other info where Z is the shared secret
137  * from DH and other info is an arbitrary string (see SP800-56A section
138  * 5.8.1.2).
139  */
140 static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
141 		   u8 *dst, unsigned int dlen)
142 {
143 	struct shash_desc *desc = &sdesc->shash;
144 	unsigned int h = crypto_shash_digestsize(desc->tfm);
145 	int err = 0;
146 	u8 *dst_orig = dst;
147 	u32 i = 1;
148 	u8 iteration[sizeof(u32)];
149 
150 	while (dlen) {
151 		err = crypto_shash_init(desc);
152 		if (err)
153 			goto err;
154 
155 		crypto_kw_cpu_to_be32(i, iteration);
156 		err = crypto_shash_update(desc, iteration, sizeof(u32));
157 		if (err)
158 			goto err;
159 
160 		if (src && slen) {
161 			err = crypto_shash_update(desc, src, slen);
162 			if (err)
163 				goto err;
164 		}
165 
166 		if (dlen < h) {
167 			u8 tmpbuffer[h];
168 
169 			err = crypto_shash_final(desc, tmpbuffer);
170 			if (err)
171 				goto err;
172 			memcpy(dst, tmpbuffer, dlen);
173 			memzero_explicit(tmpbuffer, h);
174 			return 0;
175 		} else {
176 			err = crypto_shash_final(desc, dst);
177 			if (err)
178 				goto err;
179 
180 			dlen -= h;
181 			dst += h;
182 			i++;
183 		}
184 	}
185 
186 	return 0;
187 
188 err:
189 	memzero_explicit(dst_orig, dlen);
190 	return err;
191 }
192 
193 static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
194 				 char __user *buffer, size_t buflen,
195 				 uint8_t *kbuf, size_t kbuflen)
196 {
197 	uint8_t *outbuf = NULL;
198 	int ret;
199 
200 	outbuf = kmalloc(buflen, GFP_KERNEL);
201 	if (!outbuf) {
202 		ret = -ENOMEM;
203 		goto err;
204 	}
205 
206 	ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen);
207 	if (ret)
208 		goto err;
209 
210 	ret = buflen;
211 	if (copy_to_user(buffer, outbuf, buflen) != 0)
212 		ret = -EFAULT;
213 
214 err:
215 	kzfree(outbuf);
216 	return ret;
217 }
218 
219 long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
220 			 char __user *buffer, size_t buflen,
221 			 struct keyctl_kdf_params *kdfcopy)
222 {
223 	long ret;
224 	MPI base, private, prime, result;
225 	unsigned nbytes;
226 	struct keyctl_dh_params pcopy;
227 	uint8_t *kbuf;
228 	ssize_t keylen;
229 	size_t resultlen;
230 	struct kdf_sdesc *sdesc = NULL;
231 
232 	if (!params || (!buffer && buflen)) {
233 		ret = -EINVAL;
234 		goto out;
235 	}
236 	if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
237 		ret = -EFAULT;
238 		goto out;
239 	}
240 
241 	if (kdfcopy) {
242 		char *hashname;
243 
244 		if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN ||
245 		    kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) {
246 			ret = -EMSGSIZE;
247 			goto out;
248 		}
249 
250 		/* get KDF name string */
251 		hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME);
252 		if (IS_ERR(hashname)) {
253 			ret = PTR_ERR(hashname);
254 			goto out;
255 		}
256 
257 		/* allocate KDF from the kernel crypto API */
258 		ret = kdf_alloc(&sdesc, hashname);
259 		kfree(hashname);
260 		if (ret)
261 			goto out;
262 	}
263 
264 	/*
265 	 * If the caller requests postprocessing with a KDF, allow an
266 	 * arbitrary output buffer size since the KDF ensures proper truncation.
267 	 */
268 	keylen = mpi_from_key(pcopy.prime, kdfcopy ? SIZE_MAX : buflen, &prime);
269 	if (keylen < 0 || !prime) {
270 		/* buflen == 0 may be used to query the required buffer size,
271 		 * which is the prime key length.
272 		 */
273 		ret = keylen;
274 		goto out;
275 	}
276 
277 	/* The result is never longer than the prime */
278 	resultlen = keylen;
279 
280 	keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base);
281 	if (keylen < 0 || !base) {
282 		ret = keylen;
283 		goto error1;
284 	}
285 
286 	keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private);
287 	if (keylen < 0 || !private) {
288 		ret = keylen;
289 		goto error2;
290 	}
291 
292 	result = mpi_alloc(0);
293 	if (!result) {
294 		ret = -ENOMEM;
295 		goto error3;
296 	}
297 
298 	/* allocate space for DH shared secret and SP800-56A otherinfo */
299 	kbuf = kmalloc(kdfcopy ? (resultlen + kdfcopy->otherinfolen) : resultlen,
300 		       GFP_KERNEL);
301 	if (!kbuf) {
302 		ret = -ENOMEM;
303 		goto error4;
304 	}
305 
306 	/*
307 	 * Concatenate SP800-56A otherinfo past DH shared secret -- the
308 	 * input to the KDF is (DH shared secret || otherinfo)
309 	 */
310 	if (kdfcopy && kdfcopy->otherinfo &&
311 	    copy_from_user(kbuf + resultlen, kdfcopy->otherinfo,
312 			   kdfcopy->otherinfolen) != 0) {
313 		ret = -EFAULT;
314 		goto error5;
315 	}
316 
317 	ret = do_dh(result, base, private, prime);
318 	if (ret)
319 		goto error5;
320 
321 	ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL);
322 	if (ret != 0)
323 		goto error5;
324 
325 	if (kdfcopy) {
326 		ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, kbuf,
327 					    resultlen + kdfcopy->otherinfolen);
328 	} else {
329 		ret = nbytes;
330 		if (copy_to_user(buffer, kbuf, nbytes) != 0)
331 			ret = -EFAULT;
332 	}
333 
334 error5:
335 	kzfree(kbuf);
336 error4:
337 	mpi_free(result);
338 error3:
339 	mpi_free(private);
340 error2:
341 	mpi_free(base);
342 error1:
343 	mpi_free(prime);
344 out:
345 	kdf_dealloc(sdesc);
346 	return ret;
347 }
348 
349 long keyctl_dh_compute(struct keyctl_dh_params __user *params,
350 		       char __user *buffer, size_t buflen,
351 		       struct keyctl_kdf_params __user *kdf)
352 {
353 	struct keyctl_kdf_params kdfcopy;
354 
355 	if (!kdf)
356 		return __keyctl_dh_compute(params, buffer, buflen, NULL);
357 
358 	if (copy_from_user(&kdfcopy, kdf, sizeof(kdfcopy)) != 0)
359 		return -EFAULT;
360 
361 	return __keyctl_dh_compute(params, buffer, buflen, &kdfcopy);
362 }
363