1
2#include <linux/ceph/ceph_debug.h>
3
4#include <linux/err.h>
5#include <linux/scatterlist.h>
6#include <linux/slab.h>
7#include <crypto/hash.h>
8#include <linux/key-type.h>
9
10#include <keys/ceph-type.h>
11#include <linux/ceph/decode.h>
12#include "crypto.h"
13
14int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
15			  const struct ceph_crypto_key *src)
16{
17	memcpy(dst, src, sizeof(struct ceph_crypto_key));
18	dst->key = kmemdup(src->key, src->len, GFP_NOFS);
19	if (!dst->key)
20		return -ENOMEM;
21	return 0;
22}
23
24int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
25{
26	if (*p + sizeof(u16) + sizeof(key->created) +
27	    sizeof(u16) + key->len > end)
28		return -ERANGE;
29	ceph_encode_16(p, key->type);
30	ceph_encode_copy(p, &key->created, sizeof(key->created));
31	ceph_encode_16(p, key->len);
32	ceph_encode_copy(p, key->key, key->len);
33	return 0;
34}
35
36int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
37{
38	ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
39	key->type = ceph_decode_16(p);
40	ceph_decode_copy(p, &key->created, sizeof(key->created));
41	key->len = ceph_decode_16(p);
42	ceph_decode_need(p, end, key->len, bad);
43	key->key = kmalloc(key->len, GFP_NOFS);
44	if (!key->key)
45		return -ENOMEM;
46	ceph_decode_copy(p, key->key, key->len);
47	return 0;
48
49bad:
50	dout("failed to decode crypto key\n");
51	return -EINVAL;
52}
53
54int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
55{
56	int inlen = strlen(inkey);
57	int blen = inlen * 3 / 4;
58	void *buf, *p;
59	int ret;
60
61	dout("crypto_key_unarmor %s\n", inkey);
62	buf = kmalloc(blen, GFP_NOFS);
63	if (!buf)
64		return -ENOMEM;
65	blen = ceph_unarmor(buf, inkey, inkey+inlen);
66	if (blen < 0) {
67		kfree(buf);
68		return blen;
69	}
70
71	p = buf;
72	ret = ceph_crypto_key_decode(key, &p, p + blen);
73	kfree(buf);
74	if (ret)
75		return ret;
76	dout("crypto_key_unarmor key %p type %d len %d\n", key,
77	     key->type, key->len);
78	return 0;
79}
80
81
82
83#define AES_KEY_SIZE 16
84
85static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
86{
87	return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
88}
89
90static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
91
92static int ceph_aes_encrypt(const void *key, int key_len,
93			    void *dst, size_t *dst_len,
94			    const void *src, size_t src_len)
95{
96	struct scatterlist sg_in[2], sg_out[1];
97	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
98	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
99	int ret;
100	void *iv;
101	int ivsize;
102	size_t zero_padding = (0x10 - (src_len & 0x0f));
103	char pad[16];
104
105	if (IS_ERR(tfm))
106		return PTR_ERR(tfm);
107
108	memset(pad, zero_padding, zero_padding);
109
110	*dst_len = src_len + zero_padding;
111
112	crypto_blkcipher_setkey((void *)tfm, key, key_len);
113	sg_init_table(sg_in, 2);
114	sg_set_buf(&sg_in[0], src, src_len);
115	sg_set_buf(&sg_in[1], pad, zero_padding);
116	sg_init_table(sg_out, 1);
117	sg_set_buf(sg_out, dst, *dst_len);
118	iv = crypto_blkcipher_crt(tfm)->iv;
119	ivsize = crypto_blkcipher_ivsize(tfm);
120
121	memcpy(iv, aes_iv, ivsize);
122	/*
123	print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
124		       key, key_len, 1);
125	print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
126			src, src_len, 1);
127	print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
128			pad, zero_padding, 1);
129	*/
130	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
131				     src_len + zero_padding);
132	crypto_free_blkcipher(tfm);
133	if (ret < 0)
134		pr_err("ceph_aes_crypt failed %d\n", ret);
135	/*
136	print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
137		       dst, *dst_len, 1);
138	*/
139	return 0;
140}
141
142static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
143			     size_t *dst_len,
144			     const void *src1, size_t src1_len,
145			     const void *src2, size_t src2_len)
146{
147	struct scatterlist sg_in[3], sg_out[1];
148	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
149	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
150	int ret;
151	void *iv;
152	int ivsize;
153	size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
154	char pad[16];
155
156	if (IS_ERR(tfm))
157		return PTR_ERR(tfm);
158
159	memset(pad, zero_padding, zero_padding);
160
161	*dst_len = src1_len + src2_len + zero_padding;
162
163	crypto_blkcipher_setkey((void *)tfm, key, key_len);
164	sg_init_table(sg_in, 3);
165	sg_set_buf(&sg_in[0], src1, src1_len);
166	sg_set_buf(&sg_in[1], src2, src2_len);
167	sg_set_buf(&sg_in[2], pad, zero_padding);
168	sg_init_table(sg_out, 1);
169	sg_set_buf(sg_out, dst, *dst_len);
170	iv = crypto_blkcipher_crt(tfm)->iv;
171	ivsize = crypto_blkcipher_ivsize(tfm);
172
173	memcpy(iv, aes_iv, ivsize);
174	/*
175	print_hex_dump(KERN_ERR, "enc  key: ", DUMP_PREFIX_NONE, 16, 1,
176		       key, key_len, 1);
177	print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
178			src1, src1_len, 1);
179	print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
180			src2, src2_len, 1);
181	print_hex_dump(KERN_ERR, "enc  pad: ", DUMP_PREFIX_NONE, 16, 1,
182			pad, zero_padding, 1);
183	*/
184	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
185				     src1_len + src2_len + zero_padding);
186	crypto_free_blkcipher(tfm);
187	if (ret < 0)
188		pr_err("ceph_aes_crypt2 failed %d\n", ret);
189	/*
190	print_hex_dump(KERN_ERR, "enc  out: ", DUMP_PREFIX_NONE, 16, 1,
191		       dst, *dst_len, 1);
192	*/
193	return 0;
194}
195
196static int ceph_aes_decrypt(const void *key, int key_len,
197			    void *dst, size_t *dst_len,
198			    const void *src, size_t src_len)
199{
200	struct scatterlist sg_in[1], sg_out[2];
201	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
202	struct blkcipher_desc desc = { .tfm = tfm };
203	char pad[16];
204	void *iv;
205	int ivsize;
206	int ret;
207	int last_byte;
208
209	if (IS_ERR(tfm))
210		return PTR_ERR(tfm);
211
212	crypto_blkcipher_setkey((void *)tfm, key, key_len);
213	sg_init_table(sg_in, 1);
214	sg_init_table(sg_out, 2);
215	sg_set_buf(sg_in, src, src_len);
216	sg_set_buf(&sg_out[0], dst, *dst_len);
217	sg_set_buf(&sg_out[1], pad, sizeof(pad));
218
219	iv = crypto_blkcipher_crt(tfm)->iv;
220	ivsize = crypto_blkcipher_ivsize(tfm);
221
222	memcpy(iv, aes_iv, ivsize);
223
224	/*
225	print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
226		       key, key_len, 1);
227	print_hex_dump(KERN_ERR, "dec  in: ", DUMP_PREFIX_NONE, 16, 1,
228		       src, src_len, 1);
229	*/
230
231	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
232	crypto_free_blkcipher(tfm);
233	if (ret < 0) {
234		pr_err("ceph_aes_decrypt failed %d\n", ret);
235		return ret;
236	}
237
238	if (src_len <= *dst_len)
239		last_byte = ((char *)dst)[src_len - 1];
240	else
241		last_byte = pad[src_len - *dst_len - 1];
242	if (last_byte <= 16 && src_len >= last_byte) {
243		*dst_len = src_len - last_byte;
244	} else {
245		pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
246		       last_byte, (int)src_len);
247		return -EPERM;  /* bad padding */
248	}
249	/*
250	print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
251		       dst, *dst_len, 1);
252	*/
253	return 0;
254}
255
256static int ceph_aes_decrypt2(const void *key, int key_len,
257			     void *dst1, size_t *dst1_len,
258			     void *dst2, size_t *dst2_len,
259			     const void *src, size_t src_len)
260{
261	struct scatterlist sg_in[1], sg_out[3];
262	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
263	struct blkcipher_desc desc = { .tfm = tfm };
264	char pad[16];
265	void *iv;
266	int ivsize;
267	int ret;
268	int last_byte;
269
270	if (IS_ERR(tfm))
271		return PTR_ERR(tfm);
272
273	sg_init_table(sg_in, 1);
274	sg_set_buf(sg_in, src, src_len);
275	sg_init_table(sg_out, 3);
276	sg_set_buf(&sg_out[0], dst1, *dst1_len);
277	sg_set_buf(&sg_out[1], dst2, *dst2_len);
278	sg_set_buf(&sg_out[2], pad, sizeof(pad));
279
280	crypto_blkcipher_setkey((void *)tfm, key, key_len);
281	iv = crypto_blkcipher_crt(tfm)->iv;
282	ivsize = crypto_blkcipher_ivsize(tfm);
283
284	memcpy(iv, aes_iv, ivsize);
285
286	/*
287	print_hex_dump(KERN_ERR, "dec  key: ", DUMP_PREFIX_NONE, 16, 1,
288		       key, key_len, 1);
289	print_hex_dump(KERN_ERR, "dec   in: ", DUMP_PREFIX_NONE, 16, 1,
290		       src, src_len, 1);
291	*/
292
293	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
294	crypto_free_blkcipher(tfm);
295	if (ret < 0) {
296		pr_err("ceph_aes_decrypt failed %d\n", ret);
297		return ret;
298	}
299
300	if (src_len <= *dst1_len)
301		last_byte = ((char *)dst1)[src_len - 1];
302	else if (src_len <= *dst1_len + *dst2_len)
303		last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
304	else
305		last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
306	if (last_byte <= 16 && src_len >= last_byte) {
307		src_len -= last_byte;
308	} else {
309		pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
310		       last_byte, (int)src_len);
311		return -EPERM;  /* bad padding */
312	}
313
314	if (src_len < *dst1_len) {
315		*dst1_len = src_len;
316		*dst2_len = 0;
317	} else {
318		*dst2_len = src_len - *dst1_len;
319	}
320	/*
321	print_hex_dump(KERN_ERR, "dec  out1: ", DUMP_PREFIX_NONE, 16, 1,
322		       dst1, *dst1_len, 1);
323	print_hex_dump(KERN_ERR, "dec  out2: ", DUMP_PREFIX_NONE, 16, 1,
324		       dst2, *dst2_len, 1);
325	*/
326
327	return 0;
328}
329
330
331int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
332		 const void *src, size_t src_len)
333{
334	switch (secret->type) {
335	case CEPH_CRYPTO_NONE:
336		if (*dst_len < src_len)
337			return -ERANGE;
338		memcpy(dst, src, src_len);
339		*dst_len = src_len;
340		return 0;
341
342	case CEPH_CRYPTO_AES:
343		return ceph_aes_decrypt(secret->key, secret->len, dst,
344					dst_len, src, src_len);
345
346	default:
347		return -EINVAL;
348	}
349}
350
351int ceph_decrypt2(struct ceph_crypto_key *secret,
352			void *dst1, size_t *dst1_len,
353			void *dst2, size_t *dst2_len,
354			const void *src, size_t src_len)
355{
356	size_t t;
357
358	switch (secret->type) {
359	case CEPH_CRYPTO_NONE:
360		if (*dst1_len + *dst2_len < src_len)
361			return -ERANGE;
362		t = min(*dst1_len, src_len);
363		memcpy(dst1, src, t);
364		*dst1_len = t;
365		src += t;
366		src_len -= t;
367		if (src_len) {
368			t = min(*dst2_len, src_len);
369			memcpy(dst2, src, t);
370			*dst2_len = t;
371		}
372		return 0;
373
374	case CEPH_CRYPTO_AES:
375		return ceph_aes_decrypt2(secret->key, secret->len,
376					 dst1, dst1_len, dst2, dst2_len,
377					 src, src_len);
378
379	default:
380		return -EINVAL;
381	}
382}
383
384int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
385		 const void *src, size_t src_len)
386{
387	switch (secret->type) {
388	case CEPH_CRYPTO_NONE:
389		if (*dst_len < src_len)
390			return -ERANGE;
391		memcpy(dst, src, src_len);
392		*dst_len = src_len;
393		return 0;
394
395	case CEPH_CRYPTO_AES:
396		return ceph_aes_encrypt(secret->key, secret->len, dst,
397					dst_len, src, src_len);
398
399	default:
400		return -EINVAL;
401	}
402}
403
404int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
405		  const void *src1, size_t src1_len,
406		  const void *src2, size_t src2_len)
407{
408	switch (secret->type) {
409	case CEPH_CRYPTO_NONE:
410		if (*dst_len < src1_len + src2_len)
411			return -ERANGE;
412		memcpy(dst, src1, src1_len);
413		memcpy(dst + src1_len, src2, src2_len);
414		*dst_len = src1_len + src2_len;
415		return 0;
416
417	case CEPH_CRYPTO_AES:
418		return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
419					 src1, src1_len, src2, src2_len);
420
421	default:
422		return -EINVAL;
423	}
424}
425
426static int ceph_key_instantiate(struct key *key,
427				struct key_preparsed_payload *prep)
428{
429	struct ceph_crypto_key *ckey;
430	size_t datalen = prep->datalen;
431	int ret;
432	void *p;
433
434	ret = -EINVAL;
435	if (datalen <= 0 || datalen > 32767 || !prep->data)
436		goto err;
437
438	ret = key_payload_reserve(key, datalen);
439	if (ret < 0)
440		goto err;
441
442	ret = -ENOMEM;
443	ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
444	if (!ckey)
445		goto err;
446
447	/* TODO ceph_crypto_key_decode should really take const input */
448	p = (void *)prep->data;
449	ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->data+datalen);
450	if (ret < 0)
451		goto err_ckey;
452
453	key->payload.data = ckey;
454	return 0;
455
456err_ckey:
457	kfree(ckey);
458err:
459	return ret;
460}
461
462static int ceph_key_match(const struct key *key, const void *description)
463{
464	return strcmp(key->description, description) == 0;
465}
466
467static void ceph_key_destroy(struct key *key) {
468	struct ceph_crypto_key *ckey = key->payload.data;
469
470	ceph_crypto_key_destroy(ckey);
471	kfree(ckey);
472}
473
474struct key_type key_type_ceph = {
475	.name		= "ceph",
476	.instantiate	= ceph_key_instantiate,
477	.match		= ceph_key_match,
478	.destroy	= ceph_key_destroy,
479};
480
481int ceph_crypto_init(void) {
482	return register_key_type(&key_type_ceph);
483}
484
485void ceph_crypto_shutdown(void) {
486	unregister_key_type(&key_type_ceph);
487}
488