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