Skip to content

Commit 6cec0b6

Browse files
committed
libceph: introduce ceph_crypto_key_prepare()
In preparation for bringing in a new encryption scheme/key type, decouple decoding or cloning the key from allocating required crypto API objects and setting them up. The rationale is that a) in some cases a shallow clone is sufficient and b) ceph_crypto_key_prepare() may grow additional parameters that would be inconvenient to provide at the point the key is originally decoded. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 0ee8bcc commit 6cec0b6

3 files changed

Lines changed: 56 additions & 42 deletions

File tree

net/ceph/auth_x.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ static int process_one_ticket(struct ceph_auth_client *ac,
221221
if (ret)
222222
goto out;
223223

224+
ret = ceph_crypto_key_prepare(&new_session_key);
225+
if (ret)
226+
goto out;
227+
224228
ceph_decode_need(&dp, dend, sizeof(struct ceph_timespec), bad);
225229
ceph_decode_timespec64(&validity, dp);
226230
dp += sizeof(struct ceph_timespec);
@@ -380,6 +384,10 @@ static int ceph_x_build_authorizer(struct ceph_auth_client *ac,
380384
if (ret)
381385
goto out_au;
382386

387+
ret = ceph_crypto_key_prepare(&au->session_key);
388+
if (ret)
389+
goto out_au;
390+
383391
maxlen = sizeof(*msg_a) + ticket_blob_len +
384392
ceph_x_encrypt_buflen(&au->session_key, sizeof(*msg_b));
385393
dout(" need len %d\n", maxlen);
@@ -1106,21 +1114,26 @@ int ceph_x_init(struct ceph_auth_client *ac)
11061114
int ret;
11071115

11081116
dout("ceph_x_init %p\n", ac);
1109-
ret = -ENOMEM;
11101117
xi = kzalloc(sizeof(*xi), GFP_NOFS);
11111118
if (!xi)
1112-
goto out;
1119+
return -ENOMEM;
11131120

11141121
ret = -EINVAL;
11151122
if (!ac->key) {
11161123
pr_err("no secret set (for auth_x protocol)\n");
1117-
goto out_nomem;
1124+
goto err_xi;
11181125
}
11191126

11201127
ret = ceph_crypto_key_clone(&xi->secret, ac->key);
11211128
if (ret < 0) {
11221129
pr_err("cannot clone key: %d\n", ret);
1123-
goto out_nomem;
1130+
goto err_xi;
1131+
}
1132+
1133+
ret = ceph_crypto_key_prepare(&xi->secret);
1134+
if (ret) {
1135+
pr_err("cannot prepare key: %d\n", ret);
1136+
goto err_secret;
11241137
}
11251138

11261139
xi->starting = true;
@@ -1131,8 +1144,9 @@ int ceph_x_init(struct ceph_auth_client *ac)
11311144
ac->ops = &ceph_x_ops;
11321145
return 0;
11331146

1134-
out_nomem:
1147+
err_secret:
1148+
ceph_crypto_key_destroy(&xi->secret);
1149+
err_xi:
11351150
kfree(xi);
1136-
out:
11371151
return ret;
11381152
}

net/ceph/crypto.c

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -16,65 +16,61 @@
1616
#include <linux/ceph/decode.h>
1717
#include "crypto.h"
1818

19-
/*
20-
* Set ->key and ->tfm. The rest of the key should be filled in before
21-
* this function is called.
22-
*/
23-
static int set_secret(struct ceph_crypto_key *key, void *buf)
19+
static int set_aes_tfm(struct ceph_crypto_key *key)
2420
{
2521
unsigned int noio_flag;
2622
int ret;
2723

28-
key->key = NULL;
29-
key->tfm = NULL;
30-
31-
switch (key->type) {
32-
case CEPH_CRYPTO_NONE:
33-
return 0; /* nothing to do */
34-
case CEPH_CRYPTO_AES:
35-
break;
36-
default:
37-
return -ENOTSUPP;
38-
}
39-
40-
key->key = kmemdup(buf, key->len, GFP_NOIO);
41-
if (!key->key) {
42-
ret = -ENOMEM;
43-
goto fail;
44-
}
45-
46-
/* crypto_alloc_sync_skcipher() allocates with GFP_KERNEL */
4724
noio_flag = memalloc_noio_save();
4825
key->tfm = crypto_alloc_sync_skcipher("cbc(aes)", 0, 0);
4926
memalloc_noio_restore(noio_flag);
5027
if (IS_ERR(key->tfm)) {
5128
ret = PTR_ERR(key->tfm);
5229
key->tfm = NULL;
53-
goto fail;
30+
return ret;
5431
}
5532

5633
ret = crypto_sync_skcipher_setkey(key->tfm, key->key, key->len);
5734
if (ret)
58-
goto fail;
35+
return ret;
5936

6037
return 0;
38+
}
6139

62-
fail:
63-
ceph_crypto_key_destroy(key);
64-
return ret;
40+
int ceph_crypto_key_prepare(struct ceph_crypto_key *key)
41+
{
42+
switch (key->type) {
43+
case CEPH_CRYPTO_NONE:
44+
return 0; /* nothing to do */
45+
case CEPH_CRYPTO_AES:
46+
return set_aes_tfm(key);
47+
default:
48+
return -ENOTSUPP;
49+
}
6550
}
6651

52+
/*
53+
* @dst should be zeroed before this function is called.
54+
*/
6755
int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
6856
const struct ceph_crypto_key *src)
6957
{
70-
memcpy(dst, src, sizeof(struct ceph_crypto_key));
71-
return set_secret(dst, src->key);
58+
dst->type = src->type;
59+
dst->created = src->created;
60+
dst->len = src->len;
61+
62+
dst->key = kmemdup(src->key, src->len, GFP_NOIO);
63+
if (!dst->key)
64+
return -ENOMEM;
65+
66+
return 0;
7267
}
7368

69+
/*
70+
* @key should be zeroed before this function is called.
71+
*/
7472
int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
7573
{
76-
int ret;
77-
7874
ceph_decode_need(p, end, 2*sizeof(u16) + sizeof(key->created), bad);
7975
key->type = ceph_decode_16(p);
8076
ceph_decode_copy(p, &key->created, sizeof(key->created));
@@ -85,10 +81,13 @@ int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end)
8581
return -EINVAL;
8682
}
8783

88-
ret = set_secret(key, *p);
84+
key->key = kmemdup(*p, key->len, GFP_NOIO);
85+
if (!key->key)
86+
return -ENOMEM;
87+
8988
memzero_explicit(*p, key->len);
9089
*p += key->len;
91-
return ret;
90+
return 0;
9291

9392
bad:
9493
dout("failed to decode crypto key\n");
@@ -322,7 +321,7 @@ static int ceph_key_preparse(struct key_preparsed_payload *prep)
322321
goto err;
323322

324323
ret = -ENOMEM;
325-
ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
324+
ckey = kzalloc(sizeof(*ckey), GFP_KERNEL);
326325
if (!ckey)
327326
goto err;
328327

net/ceph/crypto.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct ceph_crypto_key {
1919
struct crypto_sync_skcipher *tfm;
2020
};
2121

22+
int ceph_crypto_key_prepare(struct ceph_crypto_key *key);
2223
int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
2324
const struct ceph_crypto_key *src);
2425
int ceph_crypto_key_decode(struct ceph_crypto_key *key, void **p, void *end);

0 commit comments

Comments
 (0)