diff options
Diffstat (limited to 'net/ceph/crypto.c')
| -rw-r--r-- | net/ceph/crypto.c | 73 | 
1 files changed, 73 insertions, 0 deletions
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index 7b505b0c983..5a8009c9e0c 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c @@ -5,10 +5,23 @@  #include <linux/scatterlist.h>  #include <linux/slab.h>  #include <crypto/hash.h> +#include <linux/key-type.h> +#include <keys/ceph-type.h>  #include <linux/ceph/decode.h>  #include "crypto.h" +int ceph_crypto_key_clone(struct ceph_crypto_key *dst, +			  const struct ceph_crypto_key *src) +{ +	memcpy(dst, src, sizeof(struct ceph_crypto_key)); +	dst->key = kmalloc(src->len, GFP_NOFS); +	if (!dst->key) +		return -ENOMEM; +	memcpy(dst->key, src->key, src->len); +	return 0; +} +  int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)  {  	if (*p + sizeof(u16) + sizeof(key->created) + @@ -410,3 +423,63 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,  		return -EINVAL;  	}  } + +int ceph_key_instantiate(struct key *key, const void *data, size_t datalen) +{ +	struct ceph_crypto_key *ckey; +	int ret; +	void *p; + +	ret = -EINVAL; +	if (datalen <= 0 || datalen > 32767 || !data) +		goto err; + +	ret = key_payload_reserve(key, datalen); +	if (ret < 0) +		goto err; + +	ret = -ENOMEM; +	ckey = kmalloc(sizeof(*ckey), GFP_KERNEL); +	if (!ckey) +		goto err; + +	/* TODO ceph_crypto_key_decode should really take const input */ +	p = (void*)data; +	ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen); +	if (ret < 0) +		goto err_ckey; + +	key->payload.data = ckey; +	return 0; + +err_ckey: +	kfree(ckey); +err: +	return ret; +} + +int ceph_key_match(const struct key *key, const void *description) +{ +	return strcmp(key->description, description) == 0; +} + +void ceph_key_destroy(struct key *key) { +	struct ceph_crypto_key *ckey = key->payload.data; + +	ceph_crypto_key_destroy(ckey); +} + +struct key_type key_type_ceph = { +	.name		= "ceph", +	.instantiate	= ceph_key_instantiate, +	.match		= ceph_key_match, +	.destroy	= ceph_key_destroy, +}; + +int ceph_crypto_init(void) { +	return register_key_type(&key_type_ceph); +} + +void ceph_crypto_shutdown(void) { +	unregister_key_type(&key_type_ceph); +}  |