13
13
#include <linux/ceph/decode.h>
14
14
#include "crypto.h"
15
15
16
+ /*
17
+ * Set ->key and ->tfm. The rest of the key should be filled in before
18
+ * this function is called.
19
+ */
20
+ static int set_secret (struct ceph_crypto_key * key , void * buf )
21
+ {
22
+ unsigned int noio_flag ;
23
+ int ret ;
24
+
25
+ key -> key = NULL ;
26
+ key -> tfm = NULL ;
27
+
28
+ switch (key -> type ) {
29
+ case CEPH_CRYPTO_NONE :
30
+ return 0 ; /* nothing to do */
31
+ case CEPH_CRYPTO_AES :
32
+ break ;
33
+ default :
34
+ return - ENOTSUPP ;
35
+ }
36
+
37
+ WARN_ON (!key -> len );
38
+ key -> key = kmemdup (buf , key -> len , GFP_NOIO );
39
+ if (!key -> key ) {
40
+ ret = - ENOMEM ;
41
+ goto fail ;
42
+ }
43
+
44
+ /* crypto_alloc_skcipher() allocates with GFP_KERNEL */
45
+ noio_flag = memalloc_noio_save ();
46
+ key -> tfm = crypto_alloc_skcipher ("cbc(aes)" , 0 , CRYPTO_ALG_ASYNC );
47
+ memalloc_noio_restore (noio_flag );
48
+ if (IS_ERR (key -> tfm )) {
49
+ ret = PTR_ERR (key -> tfm );
50
+ key -> tfm = NULL ;
51
+ goto fail ;
52
+ }
53
+
54
+ ret = crypto_skcipher_setkey (key -> tfm , key -> key , key -> len );
55
+ if (ret )
56
+ goto fail ;
57
+
58
+ return 0 ;
59
+
60
+ fail :
61
+ ceph_crypto_key_destroy (key );
62
+ return ret ;
63
+ }
64
+
16
65
int ceph_crypto_key_clone (struct ceph_crypto_key * dst ,
17
66
const struct ceph_crypto_key * src )
18
67
{
19
68
memcpy (dst , src , sizeof (struct ceph_crypto_key ));
20
- dst -> key = kmemdup (src -> key , src -> len , GFP_NOFS );
21
- if (!dst -> key )
22
- return - ENOMEM ;
23
- return 0 ;
69
+ return set_secret (dst , src -> key );
24
70
}
25
71
26
72
int ceph_crypto_key_encode (struct ceph_crypto_key * key , void * * p , void * end )
@@ -37,16 +83,16 @@ int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
37
83
38
84
int ceph_crypto_key_decode (struct ceph_crypto_key * key , void * * p , void * end )
39
85
{
86
+ int ret ;
87
+
40
88
ceph_decode_need (p , end , 2 * sizeof (u16 ) + sizeof (key -> created ), bad );
41
89
key -> type = ceph_decode_16 (p );
42
90
ceph_decode_copy (p , & key -> created , sizeof (key -> created ));
43
91
key -> len = ceph_decode_16 (p );
44
92
ceph_decode_need (p , end , key -> len , bad );
45
- key -> key = kmalloc (key -> len , GFP_NOFS );
46
- if (!key -> key )
47
- return - ENOMEM ;
48
- ceph_decode_copy (p , key -> key , key -> len );
49
- return 0 ;
93
+ ret = set_secret (key , * p );
94
+ * p += key -> len ;
95
+ return ret ;
50
96
51
97
bad :
52
98
dout ("failed to decode crypto key\n" );
@@ -85,14 +131,11 @@ void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
85
131
if (key ) {
86
132
kfree (key -> key );
87
133
key -> key = NULL ;
134
+ crypto_free_skcipher (key -> tfm );
135
+ key -> tfm = NULL ;
88
136
}
89
137
}
90
138
91
- static struct crypto_skcipher * ceph_crypto_alloc_cipher (void )
92
- {
93
- return crypto_alloc_skcipher ("cbc(aes)" , 0 , CRYPTO_ALG_ASYNC );
94
- }
95
-
96
139
static const u8 * aes_iv = (u8 * )CEPH_AES_IV ;
97
140
98
141
/*
@@ -168,29 +211,23 @@ static void teardown_sgtable(struct sg_table *sgt)
168
211
static int ceph_aes_crypt (const struct ceph_crypto_key * key , bool encrypt ,
169
212
void * buf , int buf_len , int in_len , int * pout_len )
170
213
{
171
- struct crypto_skcipher * tfm = ceph_crypto_alloc_cipher ();
172
- SKCIPHER_REQUEST_ON_STACK (req , tfm );
214
+ SKCIPHER_REQUEST_ON_STACK (req , key -> tfm );
173
215
struct sg_table sgt ;
174
216
struct scatterlist prealloc_sg ;
175
217
char iv [AES_BLOCK_SIZE ];
176
218
int pad_byte = AES_BLOCK_SIZE - (in_len & (AES_BLOCK_SIZE - 1 ));
177
219
int crypt_len = encrypt ? in_len + pad_byte : in_len ;
178
220
int ret ;
179
221
180
- if (IS_ERR (tfm ))
181
- return PTR_ERR (tfm );
182
-
183
222
WARN_ON (crypt_len > buf_len );
184
223
if (encrypt )
185
224
memset (buf + in_len , pad_byte , pad_byte );
186
225
ret = setup_sgtable (& sgt , & prealloc_sg , buf , crypt_len );
187
226
if (ret )
188
- goto out_tfm ;
227
+ return ret ;
189
228
190
- crypto_skcipher_setkey ((void * )tfm , key -> key , key -> len );
191
229
memcpy (iv , aes_iv , AES_BLOCK_SIZE );
192
-
193
- skcipher_request_set_tfm (req , tfm );
230
+ skcipher_request_set_tfm (req , key -> tfm );
194
231
skcipher_request_set_callback (req , 0 , NULL , NULL );
195
232
skcipher_request_set_crypt (req , sgt .sgl , sgt .sgl , crypt_len , iv );
196
233
@@ -232,8 +269,6 @@ static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
232
269
233
270
out_sgt :
234
271
teardown_sgtable (& sgt );
235
- out_tfm :
236
- crypto_free_skcipher (tfm );
237
272
return ret ;
238
273
}
239
274
0 commit comments