Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b2a58ab authored by Tommi Virtanen's avatar Tommi Virtanen Committed by Sage Weil
Browse files

libceph: Create a new key type "ceph".



This allows us to use existence of the key type as a feature test,
from userspace.

Signed-off-by: default avatarTommi Virtanen <tommi.virtanen@dreamhost.com>
Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent e2c3d29b
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
#ifndef _KEYS_CEPH_TYPE_H
#define _KEYS_CEPH_TYPE_H

#include <linux/key.h>

extern struct key_type key_type_ceph;

#endif
+13 −8
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#include <linux/inet.h>
#include <linux/in6.h>
#include <linux/key.h>
#include <keys/user-type.h>
#include <keys/ceph-type.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/parser.h>
@@ -241,10 +241,9 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
	struct key *ukey;
	int key_err;
	int err = 0;
	struct user_key_payload *payload;
	void *p;
	struct ceph_crypto_key *ckey;

	ukey = request_key(&key_type_user, name, NULL);
	ukey = request_key(&key_type_ceph, name, NULL);
	if (!ukey || IS_ERR(ukey)) {
		/* request_key errors don't map nicely to mount(2)
		   errors; don't even try, but still printk */
@@ -267,9 +266,8 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
		goto out;
	}

	payload = ukey->payload.data;
	p = payload->data;
	err = ceph_crypto_key_decode(dst, &p, p + payload->datalen);
	ckey = ukey->payload.data;
	err = ceph_crypto_key_clone(dst, ckey);
	if (err)
		goto out_key;
	/* pass through, err is 0 */
@@ -583,10 +581,14 @@ static int __init init_ceph_lib(void)
	if (ret < 0)
		goto out;

	ret = ceph_msgr_init();
	ret = ceph_crypto_init();
	if (ret < 0)
		goto out_debugfs;

	ret = ceph_msgr_init();
	if (ret < 0)
		goto out_crypto;

	pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
		CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
		CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -594,6 +596,8 @@ static int __init init_ceph_lib(void)

	return 0;

out_crypto:
	ceph_crypto_shutdown();
out_debugfs:
	ceph_debugfs_cleanup();
out:
@@ -604,6 +608,7 @@ static void __exit exit_ceph_lib(void)
{
	dout("exit_ceph_lib\n");
	ceph_msgr_exit();
	ceph_crypto_shutdown();
	ceph_debugfs_cleanup();
}

+62 −0
Original line number Diff line number Diff line
@@ -5,7 +5,9 @@
#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"

@@ -421,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);
}
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret,
			 void *dst, size_t *dst_len,
			 const void *src1, size_t src1_len,
			 const void *src2, size_t src2_len);
extern int ceph_crypto_init(void);
extern void ceph_crypto_shutdown(void);

/* armor.c */
extern int ceph_armor(char *dst, const char *src, const char *end);