diff options
| -rw-r--r-- | include/keys/ceph-type.h | 8 | ||||
| -rw-r--r-- | net/ceph/ceph_common.c | 21 | ||||
| -rw-r--r-- | net/ceph/crypto.c | 62 | ||||
| -rw-r--r-- | net/ceph/crypto.h | 2 |
4 files changed, 85 insertions, 8 deletions
diff --git a/include/keys/ceph-type.h b/include/keys/ceph-type.h new file mode 100644 index 000000000000..f69c4ac197a0 --- /dev/null +++ b/include/keys/ceph-type.h | |||
| @@ -0,0 +1,8 @@ | |||
| 1 | #ifndef _KEYS_CEPH_TYPE_H | ||
| 2 | #define _KEYS_CEPH_TYPE_H | ||
| 3 | |||
| 4 | #include <linux/key.h> | ||
| 5 | |||
| 6 | extern struct key_type key_type_ceph; | ||
| 7 | |||
| 8 | #endif | ||
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c index c92bc8d50597..132963abc266 100644 --- a/net/ceph/ceph_common.c +++ b/net/ceph/ceph_common.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | #include <linux/inet.h> | 6 | #include <linux/inet.h> |
| 7 | #include <linux/in6.h> | 7 | #include <linux/in6.h> |
| 8 | #include <linux/key.h> | 8 | #include <linux/key.h> |
| 9 | #include <keys/user-type.h> | 9 | #include <keys/ceph-type.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/mount.h> | 11 | #include <linux/mount.h> |
| 12 | #include <linux/parser.h> | 12 | #include <linux/parser.h> |
| @@ -241,10 +241,9 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) { | |||
| 241 | struct key *ukey; | 241 | struct key *ukey; |
| 242 | int key_err; | 242 | int key_err; |
| 243 | int err = 0; | 243 | int err = 0; |
| 244 | struct user_key_payload *payload; | 244 | struct ceph_crypto_key *ckey; |
| 245 | void *p; | ||
| 246 | 245 | ||
| 247 | ukey = request_key(&key_type_user, name, NULL); | 246 | ukey = request_key(&key_type_ceph, name, NULL); |
| 248 | if (!ukey || IS_ERR(ukey)) { | 247 | if (!ukey || IS_ERR(ukey)) { |
| 249 | /* request_key errors don't map nicely to mount(2) | 248 | /* request_key errors don't map nicely to mount(2) |
| 250 | errors; don't even try, but still printk */ | 249 | errors; don't even try, but still printk */ |
| @@ -267,9 +266,8 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) { | |||
| 267 | goto out; | 266 | goto out; |
| 268 | } | 267 | } |
| 269 | 268 | ||
| 270 | payload = ukey->payload.data; | 269 | ckey = ukey->payload.data; |
| 271 | p = payload->data; | 270 | err = ceph_crypto_key_clone(dst, ckey); |
| 272 | err = ceph_crypto_key_decode(dst, &p, p + payload->datalen); | ||
| 273 | if (err) | 271 | if (err) |
| 274 | goto out_key; | 272 | goto out_key; |
| 275 | /* pass through, err is 0 */ | 273 | /* pass through, err is 0 */ |
| @@ -583,10 +581,14 @@ static int __init init_ceph_lib(void) | |||
| 583 | if (ret < 0) | 581 | if (ret < 0) |
| 584 | goto out; | 582 | goto out; |
| 585 | 583 | ||
| 586 | ret = ceph_msgr_init(); | 584 | ret = ceph_crypto_init(); |
| 587 | if (ret < 0) | 585 | if (ret < 0) |
| 588 | goto out_debugfs; | 586 | goto out_debugfs; |
| 589 | 587 | ||
| 588 | ret = ceph_msgr_init(); | ||
| 589 | if (ret < 0) | ||
| 590 | goto out_crypto; | ||
| 591 | |||
| 590 | pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n", | 592 | pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n", |
| 591 | CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL, | 593 | CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL, |
| 592 | CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, | 594 | CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT, |
| @@ -594,6 +596,8 @@ static int __init init_ceph_lib(void) | |||
| 594 | 596 | ||
| 595 | return 0; | 597 | return 0; |
| 596 | 598 | ||
| 599 | out_crypto: | ||
| 600 | ceph_crypto_shutdown(); | ||
| 597 | out_debugfs: | 601 | out_debugfs: |
| 598 | ceph_debugfs_cleanup(); | 602 | ceph_debugfs_cleanup(); |
| 599 | out: | 603 | out: |
| @@ -604,6 +608,7 @@ static void __exit exit_ceph_lib(void) | |||
| 604 | { | 608 | { |
| 605 | dout("exit_ceph_lib\n"); | 609 | dout("exit_ceph_lib\n"); |
| 606 | ceph_msgr_exit(); | 610 | ceph_msgr_exit(); |
| 611 | ceph_crypto_shutdown(); | ||
| 607 | ceph_debugfs_cleanup(); | 612 | ceph_debugfs_cleanup(); |
| 608 | } | 613 | } |
| 609 | 614 | ||
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 75f0893fa11f..5a8009c9e0cd 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c | |||
| @@ -5,7 +5,9 @@ | |||
| 5 | #include <linux/scatterlist.h> | 5 | #include <linux/scatterlist.h> |
| 6 | #include <linux/slab.h> | 6 | #include <linux/slab.h> |
| 7 | #include <crypto/hash.h> | 7 | #include <crypto/hash.h> |
| 8 | #include <linux/key-type.h> | ||
| 8 | 9 | ||
| 10 | #include <keys/ceph-type.h> | ||
| 9 | #include <linux/ceph/decode.h> | 11 | #include <linux/ceph/decode.h> |
| 10 | #include "crypto.h" | 12 | #include "crypto.h" |
| 11 | 13 | ||
| @@ -421,3 +423,63 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, | |||
| 421 | return -EINVAL; | 423 | return -EINVAL; |
| 422 | } | 424 | } |
| 423 | } | 425 | } |
| 426 | |||
| 427 | int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) | ||
| 428 | { | ||
| 429 | struct ceph_crypto_key *ckey; | ||
| 430 | int ret; | ||
| 431 | void *p; | ||
| 432 | |||
| 433 | ret = -EINVAL; | ||
| 434 | if (datalen <= 0 || datalen > 32767 || !data) | ||
| 435 | goto err; | ||
| 436 | |||
| 437 | ret = key_payload_reserve(key, datalen); | ||
| 438 | if (ret < 0) | ||
| 439 | goto err; | ||
| 440 | |||
| 441 | ret = -ENOMEM; | ||
| 442 | ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); | ||
| 443 | if (!ckey) | ||
| 444 | goto err; | ||
| 445 | |||
| 446 | /* TODO ceph_crypto_key_decode should really take const input */ | ||
| 447 | p = (void*)data; | ||
| 448 | ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); | ||
| 449 | if (ret < 0) | ||
| 450 | goto err_ckey; | ||
| 451 | |||
| 452 | key->payload.data = ckey; | ||
| 453 | return 0; | ||
| 454 | |||
| 455 | err_ckey: | ||
| 456 | kfree(ckey); | ||
| 457 | err: | ||
| 458 | return ret; | ||
| 459 | } | ||
| 460 | |||
| 461 | int ceph_key_match(const struct key *key, const void *description) | ||
| 462 | { | ||
| 463 | return strcmp(key->description, description) == 0; | ||
| 464 | } | ||
| 465 | |||
| 466 | void ceph_key_destroy(struct key *key) { | ||
| 467 | struct ceph_crypto_key *ckey = key->payload.data; | ||
| 468 | |||
| 469 | ceph_crypto_key_destroy(ckey); | ||
| 470 | } | ||
| 471 | |||
| 472 | struct key_type key_type_ceph = { | ||
| 473 | .name = "ceph", | ||
| 474 | .instantiate = ceph_key_instantiate, | ||
| 475 | .match = ceph_key_match, | ||
| 476 | .destroy = ceph_key_destroy, | ||
| 477 | }; | ||
| 478 | |||
| 479 | int ceph_crypto_init(void) { | ||
| 480 | return register_key_type(&key_type_ceph); | ||
| 481 | } | ||
| 482 | |||
| 483 | void ceph_crypto_shutdown(void) { | ||
| 484 | unregister_key_type(&key_type_ceph); | ||
| 485 | } | ||
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index 6cf6edc91ec4..1919d1550d75 100644 --- a/net/ceph/crypto.h +++ b/net/ceph/crypto.h | |||
| @@ -42,6 +42,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret, | |||
| 42 | void *dst, size_t *dst_len, | 42 | void *dst, size_t *dst_len, |
| 43 | const void *src1, size_t src1_len, | 43 | const void *src1, size_t src1_len, |
| 44 | const void *src2, size_t src2_len); | 44 | const void *src2, size_t src2_len); |
| 45 | extern int ceph_crypto_init(void); | ||
| 46 | extern void ceph_crypto_shutdown(void); | ||
| 45 | 47 | ||
| 46 | /* armor.c */ | 48 | /* armor.c */ |
| 47 | extern int ceph_armor(char *dst, const char *src, const char *end); | 49 | extern int ceph_armor(char *dst, const char *src, const char *end); |
