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
= kmalloc(src
->len
, GFP_NOFS
);
21 memcpy(dst
->key
, src
->key
, src
->len
);
25 int ceph_crypto_key_encode(struct ceph_crypto_key
*key
, void **p
, void *end
)
27 if (*p
+ sizeof(u16
) + sizeof(key
->created
) +
28 sizeof(u16
) + key
->len
> end
)
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
);
37 int ceph_crypto_key_decode(struct ceph_crypto_key
*key
, void **p
, void *end
)
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
);
47 ceph_decode_copy(p
, key
->key
, key
->len
);
51 dout("failed to decode crypto key\n");
55 int ceph_crypto_key_unarmor(struct ceph_crypto_key
*key
, const char *inkey
)
57 int inlen
= strlen(inkey
);
58 int blen
= inlen
* 3 / 4;
62 dout("crypto_key_unarmor %s\n", inkey
);
63 buf
= kmalloc(blen
, GFP_NOFS
);
66 blen
= ceph_unarmor(buf
, inkey
, inkey
+inlen
);
73 ret
= ceph_crypto_key_decode(key
, &p
, p
+ blen
);
77 dout("crypto_key_unarmor key %p type %d len %d\n", key
,
84 #define AES_KEY_SIZE 16
86 static struct crypto_blkcipher
*ceph_crypto_alloc_cipher(void)
88 return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC
);
91 static const u8
*aes_iv
= (u8
*)CEPH_AES_IV
;
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
)
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 };
103 size_t zero_padding
= (0x10 - (src_len
& 0x0f));
109 memset(pad
, zero_padding
, zero_padding
);
111 *dst_len
= src_len
+ zero_padding
;
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
);
122 memcpy(iv
, aes_iv
, ivsize
);
124 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
126 print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
128 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
129 pad, zero_padding, 1);
131 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
132 src_len
+ zero_padding
);
133 crypto_free_blkcipher(tfm
);
135 pr_err("ceph_aes_crypt failed %d\n", ret
);
137 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
143 static int ceph_aes_encrypt2(const void *key
, int key_len
, void *dst
,
145 const void *src1
, size_t src1_len
,
146 const void *src2
, size_t src2_len
)
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 };
154 size_t zero_padding
= (0x10 - ((src1_len
+ src2_len
) & 0x0f));
160 memset(pad
, zero_padding
, zero_padding
);
162 *dst_len
= src1_len
+ src2_len
+ zero_padding
;
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
);
174 memcpy(iv
, aes_iv
, ivsize
);
176 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
178 print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
180 print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
182 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
183 pad, zero_padding, 1);
185 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
186 src1_len
+ src2_len
+ zero_padding
);
187 crypto_free_blkcipher(tfm
);
189 pr_err("ceph_aes_crypt2 failed %d\n", ret
);
191 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
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
)
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
};
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
));
220 iv
= crypto_blkcipher_crt(tfm
)->iv
;
221 ivsize
= crypto_blkcipher_ivsize(tfm
);
223 memcpy(iv
, aes_iv
, ivsize
);
226 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
228 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
232 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
233 crypto_free_blkcipher(tfm
);
235 pr_err("ceph_aes_decrypt failed %d\n", ret
);
239 if (src_len
<= *dst_len
)
240 last_byte
= ((char *)dst
)[src_len
- 1];
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
;
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 */
251 print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
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
)
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
};
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
));
281 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
282 iv
= crypto_blkcipher_crt(tfm
)->iv
;
283 ivsize
= crypto_blkcipher_ivsize(tfm
);
285 memcpy(iv
, aes_iv
, ivsize
);
288 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
290 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
294 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
295 crypto_free_blkcipher(tfm
);
297 pr_err("ceph_aes_decrypt failed %d\n", ret
);
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];
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
;
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 */
315 if (src_len
< *dst1_len
) {
319 *dst2_len
= src_len
- *dst1_len
;
322 print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
324 print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
332 int ceph_decrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
333 const void *src
, size_t src_len
)
335 switch (secret
->type
) {
336 case CEPH_CRYPTO_NONE
:
337 if (*dst_len
< src_len
)
339 memcpy(dst
, src
, src_len
);
343 case CEPH_CRYPTO_AES
:
344 return ceph_aes_decrypt(secret
->key
, secret
->len
, dst
,
345 dst_len
, src
, src_len
);
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
)
359 switch (secret
->type
) {
360 case CEPH_CRYPTO_NONE
:
361 if (*dst1_len
+ *dst2_len
< src_len
)
363 t
= min(*dst1_len
, src_len
);
364 memcpy(dst1
, src
, t
);
369 t
= min(*dst2_len
, src_len
);
370 memcpy(dst2
, src
, t
);
375 case CEPH_CRYPTO_AES
:
376 return ceph_aes_decrypt2(secret
->key
, secret
->len
,
377 dst1
, dst1_len
, dst2
, dst2_len
,
385 int ceph_encrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
386 const void *src
, size_t src_len
)
388 switch (secret
->type
) {
389 case CEPH_CRYPTO_NONE
:
390 if (*dst_len
< src_len
)
392 memcpy(dst
, src
, src_len
);
396 case CEPH_CRYPTO_AES
:
397 return ceph_aes_encrypt(secret
->key
, secret
->len
, dst
,
398 dst_len
, src
, src_len
);
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
)
409 switch (secret
->type
) {
410 case CEPH_CRYPTO_NONE
:
411 if (*dst_len
< src1_len
+ src2_len
)
413 memcpy(dst
, src1
, src1_len
);
414 memcpy(dst
+ src1_len
, src2
, src2_len
);
415 *dst_len
= src1_len
+ src2_len
;
418 case CEPH_CRYPTO_AES
:
419 return ceph_aes_encrypt2(secret
->key
, secret
->len
, dst
, dst_len
,
420 src1
, src1_len
, src2
, src2_len
);
427 int ceph_key_instantiate(struct key
*key
, const void *data
, size_t datalen
)
429 struct ceph_crypto_key
*ckey
;
434 if (datalen
<= 0 || datalen
> 32767 || !data
)
437 ret
= key_payload_reserve(key
, datalen
);
442 ckey
= kmalloc(sizeof(*ckey
), GFP_KERNEL
);
446 /* TODO ceph_crypto_key_decode should really take const input */
448 ret
= ceph_crypto_key_decode(ckey
, &p
, (char*)data
+datalen
);
452 key
->payload
.data
= ckey
;
461 int ceph_key_match(const struct key
*key
, const void *description
)
463 return strcmp(key
->description
, description
) == 0;
466 void ceph_key_destroy(struct key
*key
) {
467 struct ceph_crypto_key
*ckey
= key
->payload
.data
;
469 ceph_crypto_key_destroy(ckey
);
472 struct key_type key_type_ceph
= {
474 .instantiate
= ceph_key_instantiate
,
475 .match
= ceph_key_match
,
476 .destroy
= ceph_key_destroy
,
479 int ceph_crypto_init(void) {
480 return register_key_type(&key_type_ceph
);
483 void ceph_crypto_shutdown(void) {
484 unregister_key_type(&key_type_ceph
);