2 #include "ceph_debug.h"
5 #include <linux/scatterlist.h>
6 #include <crypto/hash.h>
11 int ceph_crypto_key_encode(struct ceph_crypto_key
*key
, void **p
, void *end
)
13 if (*p
+ sizeof(u16
) + sizeof(key
->created
) +
14 sizeof(u16
) + key
->len
> end
)
16 ceph_encode_16(p
, key
->type
);
17 ceph_encode_copy(p
, &key
->created
, sizeof(key
->created
));
18 ceph_encode_16(p
, key
->len
);
19 ceph_encode_copy(p
, key
->key
, key
->len
);
23 int ceph_crypto_key_decode(struct ceph_crypto_key
*key
, void **p
, void *end
)
25 ceph_decode_need(p
, end
, 2*sizeof(u16
) + sizeof(key
->created
), bad
);
26 key
->type
= ceph_decode_16(p
);
27 ceph_decode_copy(p
, &key
->created
, sizeof(key
->created
));
28 key
->len
= ceph_decode_16(p
);
29 ceph_decode_need(p
, end
, key
->len
, bad
);
30 key
->key
= kmalloc(key
->len
, GFP_NOFS
);
33 ceph_decode_copy(p
, key
->key
, key
->len
);
37 dout("failed to decode crypto key\n");
41 int ceph_crypto_key_unarmor(struct ceph_crypto_key
*key
, const char *inkey
)
43 int inlen
= strlen(inkey
);
44 int blen
= inlen
* 3 / 4;
48 dout("crypto_key_unarmor %s\n", inkey
);
49 buf
= kmalloc(blen
, GFP_NOFS
);
52 blen
= ceph_unarmor(buf
, inkey
, inkey
+inlen
);
59 ret
= ceph_crypto_key_decode(key
, &p
, p
+ blen
);
63 dout("crypto_key_unarmor key %p type %d len %d\n", key
,
70 #define AES_KEY_SIZE 16
72 static struct crypto_blkcipher
*ceph_crypto_alloc_cipher(void)
74 return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC
);
77 const u8
*aes_iv
= "cephsageyudagreg";
79 int ceph_aes_encrypt(const void *key
, int key_len
, void *dst
, size_t *dst_len
,
80 const void *src
, size_t src_len
)
82 struct scatterlist sg_in
[2], sg_out
[1];
83 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
84 struct blkcipher_desc desc
= { .tfm
= tfm
, .flags
= 0 };
88 size_t zero_padding
= (0x10 - (src_len
& 0x0f));
94 memset(pad
, zero_padding
, zero_padding
);
96 *dst_len
= src_len
+ zero_padding
;
98 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
99 sg_init_table(sg_in
, 2);
100 sg_set_buf(&sg_in
[0], src
, src_len
);
101 sg_set_buf(&sg_in
[1], pad
, zero_padding
);
102 sg_init_table(sg_out
, 1);
103 sg_set_buf(sg_out
, dst
, *dst_len
);
104 iv
= crypto_blkcipher_crt(tfm
)->iv
;
105 ivsize
= crypto_blkcipher_ivsize(tfm
);
107 memcpy(iv
, aes_iv
, ivsize
);
109 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
111 print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
113 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
114 pad, zero_padding, 1);
116 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
117 src_len
+ zero_padding
);
118 crypto_free_blkcipher(tfm
);
120 pr_err("ceph_aes_crypt failed %d\n", ret
);
122 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
128 int ceph_aes_encrypt2(const void *key
, int key_len
, void *dst
, size_t *dst_len
,
129 const void *src1
, size_t src1_len
,
130 const void *src2
, size_t src2_len
)
132 struct scatterlist sg_in
[3], sg_out
[1];
133 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
134 struct blkcipher_desc desc
= { .tfm
= tfm
, .flags
= 0 };
138 size_t zero_padding
= (0x10 - ((src1_len
+ src2_len
) & 0x0f));
144 memset(pad
, zero_padding
, zero_padding
);
146 *dst_len
= src1_len
+ src2_len
+ zero_padding
;
148 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
149 sg_init_table(sg_in
, 3);
150 sg_set_buf(&sg_in
[0], src1
, src1_len
);
151 sg_set_buf(&sg_in
[1], src2
, src2_len
);
152 sg_set_buf(&sg_in
[2], pad
, zero_padding
);
153 sg_init_table(sg_out
, 1);
154 sg_set_buf(sg_out
, dst
, *dst_len
);
155 iv
= crypto_blkcipher_crt(tfm
)->iv
;
156 ivsize
= crypto_blkcipher_ivsize(tfm
);
158 memcpy(iv
, aes_iv
, ivsize
);
160 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
162 print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
164 print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
166 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
167 pad, zero_padding, 1);
169 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
170 src1_len
+ src2_len
+ zero_padding
);
171 crypto_free_blkcipher(tfm
);
173 pr_err("ceph_aes_crypt2 failed %d\n", ret
);
175 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
181 int ceph_aes_decrypt(const void *key
, int key_len
, void *dst
, size_t *dst_len
,
182 const void *src
, size_t src_len
)
184 struct scatterlist sg_in
[1], sg_out
[2];
185 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
186 struct blkcipher_desc desc
= { .tfm
= tfm
};
196 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
197 sg_init_table(sg_in
, 1);
198 sg_init_table(sg_out
, 2);
199 sg_set_buf(sg_in
, src
, src_len
);
200 sg_set_buf(&sg_out
[0], dst
, *dst_len
);
201 sg_set_buf(&sg_out
[1], pad
, sizeof(pad
));
203 iv
= crypto_blkcipher_crt(tfm
)->iv
;
204 ivsize
= crypto_blkcipher_ivsize(tfm
);
206 memcpy(iv
, aes_iv
, ivsize
);
209 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
211 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
215 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
216 crypto_free_blkcipher(tfm
);
218 pr_err("ceph_aes_decrypt failed %d\n", ret
);
222 if (src_len
<= *dst_len
)
223 last_byte
= ((char *)dst
)[src_len
- 1];
225 last_byte
= pad
[src_len
- *dst_len
- 1];
226 if (last_byte
<= 16 && src_len
>= last_byte
) {
227 *dst_len
= src_len
- last_byte
;
229 pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
230 last_byte
, (int)src_len
);
231 return -EPERM
; /* bad padding */
234 print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
240 int ceph_aes_decrypt2(const void *key
, int key_len
,
241 void *dst1
, size_t *dst1_len
,
242 void *dst2
, size_t *dst2_len
,
243 const void *src
, size_t src_len
)
245 struct scatterlist sg_in
[1], sg_out
[3];
246 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
247 struct blkcipher_desc desc
= { .tfm
= tfm
};
257 sg_init_table(sg_in
, 1);
258 sg_set_buf(sg_in
, src
, src_len
);
259 sg_init_table(sg_out
, 3);
260 sg_set_buf(&sg_out
[0], dst1
, *dst1_len
);
261 sg_set_buf(&sg_out
[1], dst2
, *dst2_len
);
262 sg_set_buf(&sg_out
[2], pad
, sizeof(pad
));
264 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
265 iv
= crypto_blkcipher_crt(tfm
)->iv
;
266 ivsize
= crypto_blkcipher_ivsize(tfm
);
268 memcpy(iv
, aes_iv
, ivsize
);
271 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
273 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
277 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
278 crypto_free_blkcipher(tfm
);
280 pr_err("ceph_aes_decrypt failed %d\n", ret
);
284 if (src_len
<= *dst1_len
)
285 last_byte
= ((char *)dst1
)[src_len
- 1];
286 else if (src_len
<= *dst1_len
+ *dst2_len
)
287 last_byte
= ((char *)dst2
)[src_len
- *dst1_len
- 1];
289 last_byte
= pad
[src_len
- *dst1_len
- *dst2_len
- 1];
290 if (last_byte
<= 16 && src_len
>= last_byte
) {
291 src_len
-= last_byte
;
293 pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
294 last_byte
, (int)src_len
);
295 return -EPERM
; /* bad padding */
298 if (src_len
< *dst1_len
) {
302 *dst2_len
= src_len
- *dst1_len
;
305 print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
307 print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
315 int ceph_decrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
316 const void *src
, size_t src_len
)
318 switch (secret
->type
) {
319 case CEPH_CRYPTO_NONE
:
320 if (*dst_len
< src_len
)
322 memcpy(dst
, src
, src_len
);
326 case CEPH_CRYPTO_AES
:
327 return ceph_aes_decrypt(secret
->key
, secret
->len
, dst
,
328 dst_len
, src
, src_len
);
335 int ceph_decrypt2(struct ceph_crypto_key
*secret
,
336 void *dst1
, size_t *dst1_len
,
337 void *dst2
, size_t *dst2_len
,
338 const void *src
, size_t src_len
)
342 switch (secret
->type
) {
343 case CEPH_CRYPTO_NONE
:
344 if (*dst1_len
+ *dst2_len
< src_len
)
346 t
= min(*dst1_len
, src_len
);
347 memcpy(dst1
, src
, t
);
352 t
= min(*dst2_len
, src_len
);
353 memcpy(dst2
, src
, t
);
358 case CEPH_CRYPTO_AES
:
359 return ceph_aes_decrypt2(secret
->key
, secret
->len
,
360 dst1
, dst1_len
, dst2
, dst2_len
,
368 int ceph_encrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
369 const void *src
, size_t src_len
)
371 switch (secret
->type
) {
372 case CEPH_CRYPTO_NONE
:
373 if (*dst_len
< src_len
)
375 memcpy(dst
, src
, src_len
);
379 case CEPH_CRYPTO_AES
:
380 return ceph_aes_encrypt(secret
->key
, secret
->len
, dst
,
381 dst_len
, src
, src_len
);
388 int ceph_encrypt2(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
389 const void *src1
, size_t src1_len
,
390 const void *src2
, size_t src2_len
)
392 switch (secret
->type
) {
393 case CEPH_CRYPTO_NONE
:
394 if (*dst_len
< src1_len
+ src2_len
)
396 memcpy(dst
, src1
, src1_len
);
397 memcpy(dst
+ src1_len
, src2
, src2_len
);
398 *dst_len
= src1_len
+ src2_len
;
401 case CEPH_CRYPTO_AES
:
402 return ceph_aes_encrypt2(secret
->key
, secret
->len
, dst
, dst_len
,
403 src1
, src1_len
, src2
, src2_len
);