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