2 #include <linux/ceph/ceph_debug.h>
5 #include <linux/scatterlist.h>
6 #include <linux/slab.h>
7 #include <crypto/hash.h>
8 #include <linux/key-type.h>
10 #include <keys/ceph-type.h>
11 #include <linux/ceph/decode.h>
14 int ceph_crypto_key_clone(struct ceph_crypto_key
*dst
,
15 const struct ceph_crypto_key
*src
)
17 memcpy(dst
, src
, sizeof(struct ceph_crypto_key
));
18 dst
->key
= kmemdup(src
->key
, src
->len
, GFP_NOFS
);
24 int ceph_crypto_key_encode(struct ceph_crypto_key
*key
, void **p
, void *end
)
26 if (*p
+ sizeof(u16
) + sizeof(key
->created
) +
27 sizeof(u16
) + key
->len
> end
)
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
);
36 int ceph_crypto_key_decode(struct ceph_crypto_key
*key
, void **p
, void *end
)
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
);
46 ceph_decode_copy(p
, key
->key
, key
->len
);
50 dout("failed to decode crypto key\n");
54 int ceph_crypto_key_unarmor(struct ceph_crypto_key
*key
, const char *inkey
)
56 int inlen
= strlen(inkey
);
57 int blen
= inlen
* 3 / 4;
61 dout("crypto_key_unarmor %s\n", inkey
);
62 buf
= kmalloc(blen
, GFP_NOFS
);
65 blen
= ceph_unarmor(buf
, inkey
, inkey
+inlen
);
72 ret
= ceph_crypto_key_decode(key
, &p
, p
+ blen
);
76 dout("crypto_key_unarmor key %p type %d len %d\n", key
,
83 #define AES_KEY_SIZE 16
85 static struct crypto_blkcipher
*ceph_crypto_alloc_cipher(void)
87 return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC
);
90 static const u8
*aes_iv
= (u8
*)CEPH_AES_IV
;
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
)
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 };
102 size_t zero_padding
= (0x10 - (src_len
& 0x0f));
108 memset(pad
, zero_padding
, zero_padding
);
110 *dst_len
= src_len
+ zero_padding
;
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
);
121 memcpy(iv
, aes_iv
, ivsize
);
123 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
125 print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
127 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
128 pad, zero_padding, 1);
130 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
131 src_len
+ zero_padding
);
132 crypto_free_blkcipher(tfm
);
134 pr_err("ceph_aes_crypt failed %d\n", ret
);
136 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
142 static int ceph_aes_encrypt2(const void *key
, int key_len
, void *dst
,
144 const void *src1
, size_t src1_len
,
145 const void *src2
, size_t src2_len
)
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 };
153 size_t zero_padding
= (0x10 - ((src1_len
+ src2_len
) & 0x0f));
159 memset(pad
, zero_padding
, zero_padding
);
161 *dst_len
= src1_len
+ src2_len
+ zero_padding
;
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
);
173 memcpy(iv
, aes_iv
, ivsize
);
175 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
177 print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
179 print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
181 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
182 pad, zero_padding, 1);
184 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
185 src1_len
+ src2_len
+ zero_padding
);
186 crypto_free_blkcipher(tfm
);
188 pr_err("ceph_aes_crypt2 failed %d\n", ret
);
190 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
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
)
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
};
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
));
219 iv
= crypto_blkcipher_crt(tfm
)->iv
;
220 ivsize
= crypto_blkcipher_ivsize(tfm
);
222 memcpy(iv
, aes_iv
, ivsize
);
225 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
227 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
231 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
232 crypto_free_blkcipher(tfm
);
234 pr_err("ceph_aes_decrypt failed %d\n", ret
);
238 if (src_len
<= *dst_len
)
239 last_byte
= ((char *)dst
)[src_len
- 1];
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
;
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 */
250 print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
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
)
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
};
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
));
280 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
281 iv
= crypto_blkcipher_crt(tfm
)->iv
;
282 ivsize
= crypto_blkcipher_ivsize(tfm
);
284 memcpy(iv
, aes_iv
, ivsize
);
287 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
289 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
293 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
294 crypto_free_blkcipher(tfm
);
296 pr_err("ceph_aes_decrypt failed %d\n", ret
);
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];
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
;
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 */
314 if (src_len
< *dst1_len
) {
318 *dst2_len
= src_len
- *dst1_len
;
321 print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
323 print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
331 int ceph_decrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
332 const void *src
, size_t src_len
)
334 switch (secret
->type
) {
335 case CEPH_CRYPTO_NONE
:
336 if (*dst_len
< src_len
)
338 memcpy(dst
, src
, src_len
);
342 case CEPH_CRYPTO_AES
:
343 return ceph_aes_decrypt(secret
->key
, secret
->len
, dst
,
344 dst_len
, src
, src_len
);
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
)
358 switch (secret
->type
) {
359 case CEPH_CRYPTO_NONE
:
360 if (*dst1_len
+ *dst2_len
< src_len
)
362 t
= min(*dst1_len
, src_len
);
363 memcpy(dst1
, src
, t
);
368 t
= min(*dst2_len
, src_len
);
369 memcpy(dst2
, src
, t
);
374 case CEPH_CRYPTO_AES
:
375 return ceph_aes_decrypt2(secret
->key
, secret
->len
,
376 dst1
, dst1_len
, dst2
, dst2_len
,
384 int ceph_encrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
385 const void *src
, size_t src_len
)
387 switch (secret
->type
) {
388 case CEPH_CRYPTO_NONE
:
389 if (*dst_len
< src_len
)
391 memcpy(dst
, src
, src_len
);
395 case CEPH_CRYPTO_AES
:
396 return ceph_aes_encrypt(secret
->key
, secret
->len
, dst
,
397 dst_len
, src
, src_len
);
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
)
408 switch (secret
->type
) {
409 case CEPH_CRYPTO_NONE
:
410 if (*dst_len
< src1_len
+ src2_len
)
412 memcpy(dst
, src1
, src1_len
);
413 memcpy(dst
+ src1_len
, src2
, src2_len
);
414 *dst_len
= src1_len
+ src2_len
;
417 case CEPH_CRYPTO_AES
:
418 return ceph_aes_encrypt2(secret
->key
, secret
->len
, dst
, dst_len
,
419 src1
, src1_len
, src2
, src2_len
);
426 static int ceph_key_instantiate(struct key
*key
,
427 struct key_preparsed_payload
*prep
)
429 struct ceph_crypto_key
*ckey
;
430 size_t datalen
= prep
->datalen
;
435 if (datalen
<= 0 || datalen
> 32767 || !prep
->data
)
438 ret
= key_payload_reserve(key
, datalen
);
443 ckey
= kmalloc(sizeof(*ckey
), GFP_KERNEL
);
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
);
453 key
->payload
.data
= ckey
;
462 static int ceph_key_match(const struct key
*key
, const void *description
)
464 return strcmp(key
->description
, description
) == 0;
467 static void ceph_key_destroy(struct key
*key
) {
468 struct ceph_crypto_key
*ckey
= key
->payload
.data
;
470 ceph_crypto_key_destroy(ckey
);
474 struct key_type key_type_ceph
= {
476 .instantiate
= ceph_key_instantiate
,
477 .match
= ceph_key_match
,
478 .destroy
= ceph_key_destroy
,
481 int ceph_crypto_init(void) {
482 return register_key_type(&key_type_ceph
);
485 void ceph_crypto_shutdown(void) {
486 unregister_key_type(&key_type_ceph
);