1 2#include <linux/ceph/ceph_debug.h> 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 14int ceph_crypto_key_clone(struct ceph_crypto_key *dst, 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 24int 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 36int 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 49bad: 50 dout("failed to decode crypto key\n"); 51 return -EINVAL; 52} 53 54int 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 85static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void) 86{ 87 return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC); 88} 89 90static const u8 *aes_iv = (u8 *)CEPH_AES_IV; 91 92static 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 142static 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 196static 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 256static 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 331int 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 351int 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 384int 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 404int 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 426static int ceph_key_instantiate(struct key *key, 427 struct key_preparsed_payload *prep) 428{ 429 struct ceph_crypto_key *ckey; 430 size_t datalen = prep->datalen; 431 int ret; 432 void *p; 433 434 ret = -EINVAL; 435 if (datalen <= 0 || datalen > 32767 || !prep->data) 436 goto err; 437 438 ret = key_payload_reserve(key, datalen); 439 if (ret < 0) 440 goto err; 441 442 ret = -ENOMEM; 443 ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); 444 if (!ckey) 445 goto err; 446 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); 450 if (ret < 0) 451 goto err_ckey; 452 453 key->payload.data = ckey; 454 return 0; 455 456err_ckey: 457 kfree(ckey); 458err: 459 return ret; 460} 461 462static int ceph_key_match(const struct key *key, const void *description) 463{ 464 return strcmp(key->description, description) == 0; 465} 466 467static void ceph_key_destroy(struct key *key) { 468 struct ceph_crypto_key *ckey = key->payload.data; 469 470 ceph_crypto_key_destroy(ckey); 471 kfree(ckey); 472} 473 474struct key_type key_type_ceph = { 475 .name = "ceph", 476 .instantiate = ceph_key_instantiate, 477 .match = ceph_key_match, 478 .destroy = ceph_key_destroy, 479}; 480 481int ceph_crypto_init(void) { 482 return register_key_type(&key_type_ceph); 483} 484 485void ceph_crypto_shutdown(void) { 486 unregister_key_type(&key_type_ceph); 487} 488