crypto.c revision 5a0e3ad6af8660be21ca98a971cd00f331318c05
18b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
28b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#include "ceph_debug.h"
38b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
48b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#include <linux/err.h>
58b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#include <linux/scatterlist.h>
65a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
78b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#include <crypto/hash.h>
88b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
98b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#include "crypto.h"
108b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#include "decode.h"
118b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
128b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
138b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
148b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (*p + sizeof(u16) + sizeof(key->created) +
158b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	    sizeof(u16) + key->len > end)
168b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -ERANGE;
178b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_encode_16(p, key->type);
188b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_encode_copy(p, &key->created, sizeof(key->created));
198b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_encode_16(p, key->len);
208b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_encode_copy(p, key->key, key->len);
218b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
228b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
238b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
248b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
258b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
268b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
278b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	key->type = ceph_decode_16(p);
288b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_decode_copy(p, &key->created, sizeof(key->created));
298b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	key->len = ceph_decode_16(p);
308b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_decode_need(p, end, key->len, bad);
318b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	key->key = kmalloc(key->len, GFP_NOFS);
328b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (!key->key)
338b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -ENOMEM;
348b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ceph_decode_copy(p, key->key, key->len);
358b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
368b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
378b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilbad:
388b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	dout("failed to decode crypto key\n");
398b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return -EINVAL;
408b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
418b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
428b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *inkey)
438b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
448b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int inlen = strlen(inkey);
458b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int blen = inlen * 3 / 4;
468b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	void *buf, *p;
478b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ret;
488b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
498b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	dout("crypto_key_unarmor %s\n", inkey);
508b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	buf = kmalloc(blen, GFP_NOFS);
518b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (!buf)
528b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -ENOMEM;
538b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	blen = ceph_unarmor(buf, inkey, inkey+inlen);
548b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (blen < 0) {
558b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		kfree(buf);
568b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return blen;
578b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
588b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
598b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	p = buf;
608b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ret = ceph_crypto_key_decode(key, &p, p + blen);
618b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	kfree(buf);
628b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (ret)
638b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ret;
648b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	dout("crypto_key_unarmor key %p type %d len %d\n", key,
658b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	     key->type, key->len);
668b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
678b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
688b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
698b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
708b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
718b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil#define AES_KEY_SIZE 16
728b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
738b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilstatic struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
748b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
758b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return crypto_alloc_blkcipher("cbc(aes)", 0, CRYPTO_ALG_ASYNC);
768b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
778b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
788b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilconst u8 *aes_iv = "cephsageyudagreg";
798b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
808b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_aes_encrypt(const void *key, int key_len, void *dst, size_t *dst_len,
818b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		     const void *src, size_t src_len)
828b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
838b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct scatterlist sg_in[2], sg_out[1];
848b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
858b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
868b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ret;
878b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	void *iv;
888b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ivsize;
898b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	size_t zero_padding = (0x10 - (src_len & 0x0f));
908b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	char pad[16];
918b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
928b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (IS_ERR(tfm))
938b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return PTR_ERR(tfm);
948b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
958b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	memset(pad, zero_padding, zero_padding);
968b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
978b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*dst_len = src_len + zero_padding;
988b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
998b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_blkcipher_setkey((void *)tfm, key, key_len);
1008b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_in, 2);
1018b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_in[0], src, src_len);
1028b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_in[1], pad, zero_padding);
1038b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_out, 1);
1048b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(sg_out, dst, *dst_len);
1058b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	iv = crypto_blkcipher_crt(tfm)->iv;
1068b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ivsize = crypto_blkcipher_ivsize(tfm);
1078b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1088b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	memcpy(iv, aes_iv, ivsize);
1098b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
1108b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
1118b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       key, key_len, 1);
1128b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1,
1138b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			src, src_len, 1);
1148b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
1158b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			pad, zero_padding, 1);
1168b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
1178b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
1188b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil				     src_len + zero_padding);
1198b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_free_blkcipher(tfm);
1208b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (ret < 0)
1218b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		pr_err("ceph_aes_crypt failed %d\n", ret);
1228b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
1238b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
1248b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       dst, *dst_len, 1);
1258b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
1268b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
1278b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
1288b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1298b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_aes_encrypt2(const void *key, int key_len, void *dst, size_t *dst_len,
1308b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		      const void *src1, size_t src1_len,
1318b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		      const void *src2, size_t src2_len)
1328b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
1338b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct scatterlist sg_in[3], sg_out[1];
1348b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
1358b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct blkcipher_desc desc = { .tfm = tfm, .flags = 0 };
1368b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ret;
1378b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	void *iv;
1388b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ivsize;
1398b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f));
1408b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	char pad[16];
1418b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1428b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (IS_ERR(tfm))
1438b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return PTR_ERR(tfm);
1448b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1458b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	memset(pad, zero_padding, zero_padding);
1468b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1478b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*dst_len = src1_len + src2_len + zero_padding;
1488b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1498b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_blkcipher_setkey((void *)tfm, key, key_len);
1508b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_in, 3);
1518b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_in[0], src1, src1_len);
1528b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_in[1], src2, src2_len);
1538b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_in[2], pad, zero_padding);
1548b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_out, 1);
1558b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(sg_out, dst, *dst_len);
1568b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	iv = crypto_blkcipher_crt(tfm)->iv;
1578b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ivsize = crypto_blkcipher_ivsize(tfm);
1588b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1598b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	memcpy(iv, aes_iv, ivsize);
1608b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
1618b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc  key: ", DUMP_PREFIX_NONE, 16, 1,
1628b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       key, key_len, 1);
1638b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1,
1648b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			src1, src1_len, 1);
1658b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1,
1668b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			src2, src2_len, 1);
1678b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc  pad: ", DUMP_PREFIX_NONE, 16, 1,
1688b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			pad, zero_padding, 1);
1698b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
1708b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ret = crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
1718b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil				     src1_len + src2_len + zero_padding);
1728b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_free_blkcipher(tfm);
1738b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (ret < 0)
1748b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		pr_err("ceph_aes_crypt2 failed %d\n", ret);
1758b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
1768b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "enc  out: ", DUMP_PREFIX_NONE, 16, 1,
1778b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       dst, *dst_len, 1);
1788b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
1798b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
1808b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
1818b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1828b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_aes_decrypt(const void *key, int key_len, void *dst, size_t *dst_len,
1838b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		     const void *src, size_t src_len)
1848b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
1858b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct scatterlist sg_in[1], sg_out[2];
1868b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
1878b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct blkcipher_desc desc = { .tfm = tfm };
1888b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	char pad[16];
1898b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	void *iv;
1908b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ivsize;
1918b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ret;
1928b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int last_byte;
1938b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1948b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (IS_ERR(tfm))
1958b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return PTR_ERR(tfm);
1968b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
1978b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_blkcipher_setkey((void *)tfm, key, key_len);
1988b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_in, 1);
1998b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_out, 2);
2008b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(sg_in, src, src_len);
2018b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_out[0], dst, *dst_len);
2028b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_out[1], pad, sizeof(pad));
2038b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2048b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	iv = crypto_blkcipher_crt(tfm)->iv;
2058b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ivsize = crypto_blkcipher_ivsize(tfm);
2068b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2078b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	memcpy(iv, aes_iv, ivsize);
2088b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2098b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
2108b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1,
2118b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       key, key_len, 1);
2128b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec  in: ", DUMP_PREFIX_NONE, 16, 1,
2138b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       src, src_len, 1);
2148b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
2158b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2168b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
2178b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_free_blkcipher(tfm);
2188b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (ret < 0) {
2198b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		pr_err("ceph_aes_decrypt failed %d\n", ret);
2208b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ret;
2218b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
2228b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2238b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (src_len <= *dst_len)
2248b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		last_byte = ((char *)dst)[src_len - 1];
2258b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	else
2268b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		last_byte = pad[src_len - *dst_len - 1];
2278b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (last_byte <= 16 && src_len >= last_byte) {
2288b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst_len = src_len - last_byte;
2298b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	} else {
2308b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
2318b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       last_byte, (int)src_len);
2328b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -EPERM;  /* bad padding */
2338b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
2348b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
2358b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
2368b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       dst, *dst_len, 1);
2378b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
2388b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
2398b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
2408b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2418b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_aes_decrypt2(const void *key, int key_len,
2428b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		      void *dst1, size_t *dst1_len,
2438b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		      void *dst2, size_t *dst2_len,
2448b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		      const void *src, size_t src_len)
2458b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
2468b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct scatterlist sg_in[1], sg_out[3];
2478b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct crypto_blkcipher *tfm = ceph_crypto_alloc_cipher();
2488b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	struct blkcipher_desc desc = { .tfm = tfm };
2498b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	char pad[16];
2508b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	void *iv;
2518b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ivsize;
2528b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int ret;
2538b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	int last_byte;
2548b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2558b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (IS_ERR(tfm))
2568b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return PTR_ERR(tfm);
2578b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2588b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_in, 1);
2598b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(sg_in, src, src_len);
2608b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_init_table(sg_out, 3);
2618b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_out[0], dst1, *dst1_len);
2628b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_out[1], dst2, *dst2_len);
2638b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	sg_set_buf(&sg_out[2], pad, sizeof(pad));
2648b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2658b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_blkcipher_setkey((void *)tfm, key, key_len);
2668b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	iv = crypto_blkcipher_crt(tfm)->iv;
2678b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ivsize = crypto_blkcipher_ivsize(tfm);
2688b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2698b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	memcpy(iv, aes_iv, ivsize);
2708b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2718b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
2728b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec  key: ", DUMP_PREFIX_NONE, 16, 1,
2738b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       key, key_len, 1);
2748b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec   in: ", DUMP_PREFIX_NONE, 16, 1,
2758b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       src, src_len, 1);
2768b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
2778b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2788b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	ret = crypto_blkcipher_decrypt(&desc, sg_out, sg_in, src_len);
2798b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	crypto_free_blkcipher(tfm);
2808b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (ret < 0) {
2818b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		pr_err("ceph_aes_decrypt failed %d\n", ret);
2828b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ret;
2838b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
2848b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2858b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (src_len <= *dst1_len)
2868b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		last_byte = ((char *)dst1)[src_len - 1];
2878b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	else if (src_len <= *dst1_len + *dst2_len)
2888b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		last_byte = ((char *)dst2)[src_len - *dst1_len - 1];
2898b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	else
2908b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		last_byte = pad[src_len - *dst1_len - *dst2_len - 1];
2918b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (last_byte <= 16 && src_len >= last_byte) {
2928b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		src_len -= last_byte;
2938b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	} else {
2948b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n",
2958b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       last_byte, (int)src_len);
2968b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -EPERM;  /* bad padding */
2978b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
2988b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
2998b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	if (src_len < *dst1_len) {
3008b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst1_len = src_len;
3018b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst2_len = 0;
3028b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	} else {
3038b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst2_len = src_len - *dst1_len;
3048b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
3058b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	/*
3068b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec  out1: ", DUMP_PREFIX_NONE, 16, 1,
3078b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       dst1, *dst1_len, 1);
3088b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	print_hex_dump(KERN_ERR, "dec  out2: ", DUMP_PREFIX_NONE, 16, 1,
3098b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		       dst2, *dst2_len, 1);
3108b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	*/
3118b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3128b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	return 0;
3138b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
3148b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3158b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3168b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
3178b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		 const void *src, size_t src_len)
3188b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
3198b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	switch (secret->type) {
3208b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_NONE:
3218b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		if (*dst_len < src_len)
3228b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			return -ERANGE;
3238b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		memcpy(dst, src, src_len);
3248b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst_len = src_len;
3258b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return 0;
3268b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3278b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_AES:
3288b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ceph_aes_decrypt(secret->key, secret->len, dst,
3298b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil					dst_len, src, src_len);
3308b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3318b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	default:
3328b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -EINVAL;
3338b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
3348b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
3358b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3368b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_decrypt2(struct ceph_crypto_key *secret,
3378b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			void *dst1, size_t *dst1_len,
3388b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			void *dst2, size_t *dst2_len,
3398b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			const void *src, size_t src_len)
3408b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
3418b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	size_t t;
3428b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3438b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	switch (secret->type) {
3448b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_NONE:
3458b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		if (*dst1_len + *dst2_len < src_len)
3468b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			return -ERANGE;
3478b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		t = min(*dst1_len, src_len);
3488b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		memcpy(dst1, src, t);
3498b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst1_len = t;
3508b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		src += t;
3518b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		src_len -= t;
3528b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		if (src_len) {
3538b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			t = min(*dst2_len, src_len);
3548b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			memcpy(dst2, src, t);
3558b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			*dst2_len = t;
3568b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		}
3578b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return 0;
3588b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3598b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_AES:
3608b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ceph_aes_decrypt2(secret->key, secret->len,
3618b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil					 dst1, dst1_len, dst2, dst2_len,
3628b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil					 src, src_len);
3638b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3648b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	default:
3658b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -EINVAL;
3668b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
3678b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
3688b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3698b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
3708b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		 const void *src, size_t src_len)
3718b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
3728b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	switch (secret->type) {
3738b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_NONE:
3748b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		if (*dst_len < src_len)
3758b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			return -ERANGE;
3768b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		memcpy(dst, src, src_len);
3778b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst_len = src_len;
3788b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return 0;
3798b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3808b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_AES:
3818b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ceph_aes_encrypt(secret->key, secret->len, dst,
3828b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil					dst_len, src, src_len);
3838b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3848b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	default:
3858b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -EINVAL;
3868b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
3878b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
3888b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
3898b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weilint ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
3908b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		  const void *src1, size_t src1_len,
3918b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		  const void *src2, size_t src2_len)
3928b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil{
3938b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	switch (secret->type) {
3948b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_NONE:
3958b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		if (*dst_len < src1_len + src2_len)
3968b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil			return -ERANGE;
3978b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		memcpy(dst, src1, src1_len);
3988b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		memcpy(dst + src1_len, src2, src2_len);
3998b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		*dst_len = src1_len + src2_len;
4008b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return 0;
4018b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
4028b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	case CEPH_CRYPTO_AES:
4038b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len,
4048b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil					 src1, src1_len, src2, src2_len);
4058b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil
4068b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	default:
4078b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil		return -EINVAL;
4088b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil	}
4098b6e4f2d8b21c25225b1ce8d53a2e03b92cc8522Sage Weil}
410