Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
crypto.c
Go to the documentation of this file.
1 
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 
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 
24 int 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 
36 int 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 
49 bad:
50  dout("failed to decode crypto key\n");
51  return -EINVAL;
52 }
53 
54 int 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 
85 static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
86 {
87  return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
88 }
89 
90 static const u8 *aes_iv = (u8 *)CEPH_AES_IV;
91 
92 static 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 
142 static 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 
196 static 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 
256 static 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 
331 int 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 
351 int 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 
384 int 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 
404 int 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 
426 int ceph_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
427 {
428  struct ceph_crypto_key *ckey;
429  size_t datalen = prep->datalen;
430  int ret;
431  void *p;
432 
433  ret = -EINVAL;
434  if (datalen <= 0 || datalen > 32767 || !prep->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 *)prep->data;
448  ret = ceph_crypto_key_decode(ckey, &p, (char*)prep->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  kfree(ckey);
471 }
472 
473 struct key_type key_type_ceph = {
474  .name = "ceph",
475  .instantiate = ceph_key_instantiate,
476  .match = ceph_key_match,
477  .destroy = ceph_key_destroy,
478 };
479 
480 int ceph_crypto_init(void) {
481  return register_key_type(&key_type_ceph);
482 }
483 
485  unregister_key_type(&key_type_ceph);
486 }