]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - net/ceph/crypto.c
2 #include <linux/ceph/ceph_debug.h>
5 #include <linux/scatterlist.h>
6 #include <linux/slab.h>
7 #include <crypto/hash.h>
9 #include <linux/ceph/decode.h>
12 int ceph_crypto_key_encode(struct ceph_crypto_key
*key
, void **p
, void *end
)
14 if (*p
+ sizeof(u16
) + sizeof(key
->created
) +
15 sizeof(u16
) + key
->len
> end
)
17 ceph_encode_16(p
, key
->type
);
18 ceph_encode_copy(p
, &key
->created
, sizeof(key
->created
));
19 ceph_encode_16(p
, key
->len
);
20 ceph_encode_copy(p
, key
->key
, key
->len
);
24 int ceph_crypto_key_decode(struct ceph_crypto_key
*key
, void **p
, void *end
)
26 ceph_decode_need(p
, end
, 2*sizeof(u16
) + sizeof(key
->created
), bad
);
27 key
->type
= ceph_decode_16(p
);
28 ceph_decode_copy(p
, &key
->created
, sizeof(key
->created
));
29 key
->len
= ceph_decode_16(p
);
30 ceph_decode_need(p
, end
, key
->len
, bad
);
31 key
->key
= kmalloc(key
->len
, GFP_NOFS
);
34 ceph_decode_copy(p
, key
->key
, key
->len
);
38 dout("failed to decode crypto key\n");
42 int ceph_crypto_key_unarmor(struct ceph_crypto_key
*key
, const char *inkey
)
44 int inlen
= strlen(inkey
);
45 int blen
= inlen
* 3 / 4;
49 dout("crypto_key_unarmor %s\n", inkey
);
50 buf
= kmalloc(blen
, GFP_NOFS
);
53 blen
= ceph_unarmor(buf
, inkey
, inkey
+inlen
);
60 ret
= ceph_crypto_key_decode(key
, &p
, p
+ blen
);
64 dout("crypto_key_unarmor key %p type %d len %d\n", key
,
71 #define AES_KEY_SIZE 16
73 static struct crypto_blkcipher
*ceph_crypto_alloc_cipher(void)
75 return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC
);
78 static const u8
*aes_iv
= (u8
*)CEPH_AES_IV
;
80 static int ceph_aes_encrypt(const void *key
, int key_len
,
81 void *dst
, size_t *dst_len
,
82 const void *src
, size_t src_len
)
84 struct scatterlist sg_in
[2], sg_out
[1];
85 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
86 struct blkcipher_desc desc
= { .tfm
= tfm
, .flags
= 0 };
90 size_t zero_padding
= (0x10 - (src_len
& 0x0f));
96 memset(pad
, zero_padding
, zero_padding
);
98 *dst_len
= src_len
+ zero_padding
;
100 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
101 sg_init_table(sg_in
, 2);
102 sg_set_buf(&sg_in
[0], src
, src_len
);
103 sg_set_buf(&sg_in
[1], pad
, zero_padding
);
104 sg_init_table(sg_out
, 1);
105 sg_set_buf(sg_out
, dst
, *dst_len
);
106 iv
= crypto_blkcipher_crt(tfm
)->iv
;
107 ivsize
= crypto_blkcipher_ivsize(tfm
);
109 memcpy(iv
, aes_iv
, ivsize
);
111 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
113 print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
115 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
116 pad, zero_padding, 1);
118 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
119 src_len
+ zero_padding
);
120 crypto_free_blkcipher(tfm
);
122 pr_err("ceph_aes_crypt failed %d\n", ret
);
124 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
130 static int ceph_aes_encrypt2(const void *key
, int key_len
, void *dst
,
132 const void *src1
, size_t src1_len
,
133 const void *src2
, size_t src2_len
)
135 struct scatterlist sg_in
[3], sg_out
[1];
136 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
137 struct blkcipher_desc desc
= { .tfm
= tfm
, .flags
= 0 };
141 size_t zero_padding
= (0x10 - ((src1_len
+ src2_len
) & 0x0f));
147 memset(pad
, zero_padding
, zero_padding
);
149 *dst_len
= src1_len
+ src2_len
+ zero_padding
;
151 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
152 sg_init_table(sg_in
, 3);
153 sg_set_buf(&sg_in
[0], src1
, src1_len
);
154 sg_set_buf(&sg_in
[1], src2
, src2_len
);
155 sg_set_buf(&sg_in
[2], pad
, zero_padding
);
156 sg_init_table(sg_out
, 1);
157 sg_set_buf(sg_out
, dst
, *dst_len
);
158 iv
= crypto_blkcipher_crt(tfm
)->iv
;
159 ivsize
= crypto_blkcipher_ivsize(tfm
);
161 memcpy(iv
, aes_iv
, ivsize
);
163 print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
165 print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
167 print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
169 print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
170 pad, zero_padding, 1);
172 ret
= crypto_blkcipher_encrypt(&desc
, sg_out
, sg_in
,
173 src1_len
+ src2_len
+ zero_padding
);
174 crypto_free_blkcipher(tfm
);
176 pr_err("ceph_aes_crypt2 failed %d\n", ret
);
178 print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
184 static int ceph_aes_decrypt(const void *key
, int key_len
,
185 void *dst
, size_t *dst_len
,
186 const void *src
, size_t src_len
)
188 struct scatterlist sg_in
[1], sg_out
[2];
189 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
190 struct blkcipher_desc desc
= { .tfm
= tfm
};
200 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
201 sg_init_table(sg_in
, 1);
202 sg_init_table(sg_out
, 2);
203 sg_set_buf(sg_in
, src
, src_len
);
204 sg_set_buf(&sg_out
[0], dst
, *dst_len
);
205 sg_set_buf(&sg_out
[1], pad
, sizeof(pad
));
207 iv
= crypto_blkcipher_crt(tfm
)->iv
;
208 ivsize
= crypto_blkcipher_ivsize(tfm
);
210 memcpy(iv
, aes_iv
, ivsize
);
213 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
215 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
219 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
220 crypto_free_blkcipher(tfm
);
222 pr_err("ceph_aes_decrypt failed %d\n", ret
);
226 if (src_len
<= *dst_len
)
227 last_byte
= ((char *)dst
)[src_len
- 1];
229 last_byte
= pad
[src_len
- *dst_len
- 1];
230 if (last_byte
<= 16 && src_len
>= last_byte
) {
231 *dst_len
= src_len
- last_byte
;
233 pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
234 last_byte
, (int)src_len
);
235 return -EPERM
; /* bad padding */
238 print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
244 static int ceph_aes_decrypt2(const void *key
, int key_len
,
245 void *dst1
, size_t *dst1_len
,
246 void *dst2
, size_t *dst2_len
,
247 const void *src
, size_t src_len
)
249 struct scatterlist sg_in
[1], sg_out
[3];
250 struct crypto_blkcipher
*tfm
= ceph_crypto_alloc_cipher();
251 struct blkcipher_desc desc
= { .tfm
= tfm
};
261 sg_init_table(sg_in
, 1);
262 sg_set_buf(sg_in
, src
, src_len
);
263 sg_init_table(sg_out
, 3);
264 sg_set_buf(&sg_out
[0], dst1
, *dst1_len
);
265 sg_set_buf(&sg_out
[1], dst2
, *dst2_len
);
266 sg_set_buf(&sg_out
[2], pad
, sizeof(pad
));
268 crypto_blkcipher_setkey((void *)tfm
, key
, key_len
);
269 iv
= crypto_blkcipher_crt(tfm
)->iv
;
270 ivsize
= crypto_blkcipher_ivsize(tfm
);
272 memcpy(iv
, aes_iv
, ivsize
);
275 print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
277 print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
281 ret
= crypto_blkcipher_decrypt(&desc
, sg_out
, sg_in
, src_len
);
282 crypto_free_blkcipher(tfm
);
284 pr_err("ceph_aes_decrypt failed %d\n", ret
);
288 if (src_len
<= *dst1_len
)
289 last_byte
= ((char *)dst1
)[src_len
- 1];
290 else if (src_len
<= *dst1_len
+ *dst2_len
)
291 last_byte
= ((char *)dst2
)[src_len
- *dst1_len
- 1];
293 last_byte
= pad
[src_len
- *dst1_len
- *dst2_len
- 1];
294 if (last_byte
<= 16 && src_len
>= last_byte
) {
295 src_len
-= last_byte
;
297 pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
298 last_byte
, (int)src_len
);
299 return -EPERM
; /* bad padding */
302 if (src_len
< *dst1_len
) {
306 *dst2_len
= src_len
- *dst1_len
;
309 print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1,
311 print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1,
319 int ceph_decrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
320 const void *src
, size_t src_len
)
322 switch (secret
->type
) {
323 case CEPH_CRYPTO_NONE
:
324 if (*dst_len
< src_len
)
326 memcpy(dst
, src
, src_len
);
330 case CEPH_CRYPTO_AES
:
331 return ceph_aes_decrypt(secret
->key
, secret
->len
, dst
,
332 dst_len
, src
, src_len
);
339 int ceph_decrypt2(struct ceph_crypto_key
*secret
,
340 void *dst1
, size_t *dst1_len
,
341 void *dst2
, size_t *dst2_len
,
342 const void *src
, size_t src_len
)
346 switch (secret
->type
) {
347 case CEPH_CRYPTO_NONE
:
348 if (*dst1_len
+ *dst2_len
< src_len
)
350 t
= min(*dst1_len
, src_len
);
351 memcpy(dst1
, src
, t
);
356 t
= min(*dst2_len
, src_len
);
357 memcpy(dst2
, src
, t
);
362 case CEPH_CRYPTO_AES
:
363 return ceph_aes_decrypt2(secret
->key
, secret
->len
,
364 dst1
, dst1_len
, dst2
, dst2_len
,
372 int ceph_encrypt(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
373 const void *src
, size_t src_len
)
375 switch (secret
->type
) {
376 case CEPH_CRYPTO_NONE
:
377 if (*dst_len
< src_len
)
379 memcpy(dst
, src
, src_len
);
383 case CEPH_CRYPTO_AES
:
384 return ceph_aes_encrypt(secret
->key
, secret
->len
, dst
,
385 dst_len
, src
, src_len
);
392 int ceph_encrypt2(struct ceph_crypto_key
*secret
, void *dst
, size_t *dst_len
,
393 const void *src1
, size_t src1_len
,
394 const void *src2
, size_t src2_len
)
396 switch (secret
->type
) {
397 case CEPH_CRYPTO_NONE
:
398 if (*dst_len
< src1_len
+ src2_len
)
400 memcpy(dst
, src1
, src1_len
);
401 memcpy(dst
+ src1_len
, src2
, src2_len
);
402 *dst_len
= src1_len
+ src2_len
;
405 case CEPH_CRYPTO_AES
:
406 return ceph_aes_encrypt2(secret
->key
, secret
->len
, dst
, dst_len
,
407 src1
, src1_len
, src2
, src2_len
);