@@ -90,11 +90,82 @@ static struct crypto_blkcipher *ceph_crypto_alloc_cipher(void)
90
90
91
91
static const u8 * aes_iv = (u8 * )CEPH_AES_IV ;
92
92
93
+ /*
94
+ * Should be used for buffers allocated with ceph_kvmalloc().
95
+ * Currently these are encrypt out-buffer (ceph_buffer) and decrypt
96
+ * in-buffer (msg front).
97
+ *
98
+ * Dispose of @sgt with teardown_sgtable().
99
+ *
100
+ * @prealloc_sg is to avoid memory allocation inside sg_alloc_table()
101
+ * in cases where a single sg is sufficient. No attempt to reduce the
102
+ * number of sgs by squeezing physically contiguous pages together is
103
+ * made though, for simplicity.
104
+ */
105
+ static int setup_sgtable (struct sg_table * sgt , struct scatterlist * prealloc_sg ,
106
+ const void * buf , unsigned int buf_len )
107
+ {
108
+ struct scatterlist * sg ;
109
+ const bool is_vmalloc = is_vmalloc_addr (buf );
110
+ unsigned int off = offset_in_page (buf );
111
+ unsigned int chunk_cnt = 1 ;
112
+ unsigned int chunk_len = PAGE_ALIGN (off + buf_len );
113
+ int i ;
114
+ int ret ;
115
+
116
+ if (buf_len == 0 ) {
117
+ memset (sgt , 0 , sizeof (* sgt ));
118
+ return - EINVAL ;
119
+ }
120
+
121
+ if (is_vmalloc ) {
122
+ chunk_cnt = chunk_len >> PAGE_SHIFT ;
123
+ chunk_len = PAGE_SIZE ;
124
+ }
125
+
126
+ if (chunk_cnt > 1 ) {
127
+ ret = sg_alloc_table (sgt , chunk_cnt , GFP_NOFS );
128
+ if (ret )
129
+ return ret ;
130
+ } else {
131
+ WARN_ON (chunk_cnt != 1 );
132
+ sg_init_table (prealloc_sg , 1 );
133
+ sgt -> sgl = prealloc_sg ;
134
+ sgt -> nents = sgt -> orig_nents = 1 ;
135
+ }
136
+
137
+ for_each_sg (sgt -> sgl , sg , sgt -> orig_nents , i ) {
138
+ struct page * page ;
139
+ unsigned int len = min (chunk_len - off , buf_len );
140
+
141
+ if (is_vmalloc )
142
+ page = vmalloc_to_page (buf );
143
+ else
144
+ page = virt_to_page (buf );
145
+
146
+ sg_set_page (sg , page , len , off );
147
+
148
+ off = 0 ;
149
+ buf += len ;
150
+ buf_len -= len ;
151
+ }
152
+ WARN_ON (buf_len != 0 );
153
+
154
+ return 0 ;
155
+ }
156
+
157
+ static void teardown_sgtable (struct sg_table * sgt )
158
+ {
159
+ if (sgt -> orig_nents > 1 )
160
+ sg_free_table (sgt );
161
+ }
162
+
93
163
static int ceph_aes_encrypt (const void * key , int key_len ,
94
164
void * dst , size_t * dst_len ,
95
165
const void * src , size_t src_len )
96
166
{
97
- struct scatterlist sg_in [2 ], sg_out [1 ];
167
+ struct scatterlist sg_in [2 ], prealloc_sg ;
168
+ struct sg_table sg_out ;
98
169
struct crypto_blkcipher * tfm = ceph_crypto_alloc_cipher ();
99
170
struct blkcipher_desc desc = { .tfm = tfm , .flags = 0 };
100
171
int ret ;
@@ -110,16 +181,18 @@ static int ceph_aes_encrypt(const void *key, int key_len,
110
181
111
182
* dst_len = src_len + zero_padding ;
112
183
113
- crypto_blkcipher_setkey ((void * )tfm , key , key_len );
114
184
sg_init_table (sg_in , 2 );
115
185
sg_set_buf (& sg_in [0 ], src , src_len );
116
186
sg_set_buf (& sg_in [1 ], pad , zero_padding );
117
- sg_init_table (sg_out , 1 );
118
- sg_set_buf (sg_out , dst , * dst_len );
187
+ ret = setup_sgtable (& sg_out , & prealloc_sg , dst , * dst_len );
188
+ if (ret )
189
+ goto out_tfm ;
190
+
191
+ crypto_blkcipher_setkey ((void * )tfm , key , key_len );
119
192
iv = crypto_blkcipher_crt (tfm )-> iv ;
120
193
ivsize = crypto_blkcipher_ivsize (tfm );
121
-
122
194
memcpy (iv , aes_iv , ivsize );
195
+
123
196
/*
124
197
print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
125
198
key, key_len, 1);
@@ -128,24 +201,31 @@ static int ceph_aes_encrypt(const void *key, int key_len,
128
201
print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
129
202
pad, zero_padding, 1);
130
203
*/
131
- ret = crypto_blkcipher_encrypt (& desc , sg_out , sg_in ,
204
+ ret = crypto_blkcipher_encrypt (& desc , sg_out . sgl , sg_in ,
132
205
src_len + zero_padding );
133
- crypto_free_blkcipher (tfm );
134
- if (ret < 0 )
206
+ if (ret < 0 ) {
135
207
pr_err ("ceph_aes_crypt failed %d\n" , ret );
208
+ goto out_sg ;
209
+ }
136
210
/*
137
211
print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
138
212
dst, *dst_len, 1);
139
213
*/
140
- return 0 ;
214
+
215
+ out_sg :
216
+ teardown_sgtable (& sg_out );
217
+ out_tfm :
218
+ crypto_free_blkcipher (tfm );
219
+ return ret ;
141
220
}
142
221
143
222
static int ceph_aes_encrypt2 (const void * key , int key_len , void * dst ,
144
223
size_t * dst_len ,
145
224
const void * src1 , size_t src1_len ,
146
225
const void * src2 , size_t src2_len )
147
226
{
148
- struct scatterlist sg_in [3 ], sg_out [1 ];
227
+ struct scatterlist sg_in [3 ], prealloc_sg ;
228
+ struct sg_table sg_out ;
149
229
struct crypto_blkcipher * tfm = ceph_crypto_alloc_cipher ();
150
230
struct blkcipher_desc desc = { .tfm = tfm , .flags = 0 };
151
231
int ret ;
@@ -161,17 +241,19 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
161
241
162
242
* dst_len = src1_len + src2_len + zero_padding ;
163
243
164
- crypto_blkcipher_setkey ((void * )tfm , key , key_len );
165
244
sg_init_table (sg_in , 3 );
166
245
sg_set_buf (& sg_in [0 ], src1 , src1_len );
167
246
sg_set_buf (& sg_in [1 ], src2 , src2_len );
168
247
sg_set_buf (& sg_in [2 ], pad , zero_padding );
169
- sg_init_table (sg_out , 1 );
170
- sg_set_buf (sg_out , dst , * dst_len );
248
+ ret = setup_sgtable (& sg_out , & prealloc_sg , dst , * dst_len );
249
+ if (ret )
250
+ goto out_tfm ;
251
+
252
+ crypto_blkcipher_setkey ((void * )tfm , key , key_len );
171
253
iv = crypto_blkcipher_crt (tfm )-> iv ;
172
254
ivsize = crypto_blkcipher_ivsize (tfm );
173
-
174
255
memcpy (iv , aes_iv , ivsize );
256
+
175
257
/*
176
258
print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1,
177
259
key, key_len, 1);
@@ -182,23 +264,30 @@ static int ceph_aes_encrypt2(const void *key, int key_len, void *dst,
182
264
print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1,
183
265
pad, zero_padding, 1);
184
266
*/
185
- ret = crypto_blkcipher_encrypt (& desc , sg_out , sg_in ,
267
+ ret = crypto_blkcipher_encrypt (& desc , sg_out . sgl , sg_in ,
186
268
src1_len + src2_len + zero_padding );
187
- crypto_free_blkcipher (tfm );
188
- if (ret < 0 )
269
+ if (ret < 0 ) {
189
270
pr_err ("ceph_aes_crypt2 failed %d\n" , ret );
271
+ goto out_sg ;
272
+ }
190
273
/*
191
274
print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1,
192
275
dst, *dst_len, 1);
193
276
*/
194
- return 0 ;
277
+
278
+ out_sg :
279
+ teardown_sgtable (& sg_out );
280
+ out_tfm :
281
+ crypto_free_blkcipher (tfm );
282
+ return ret ;
195
283
}
196
284
197
285
static int ceph_aes_decrypt (const void * key , int key_len ,
198
286
void * dst , size_t * dst_len ,
199
287
const void * src , size_t src_len )
200
288
{
201
- struct scatterlist sg_in [1 ], sg_out [2 ];
289
+ struct sg_table sg_in ;
290
+ struct scatterlist sg_out [2 ], prealloc_sg ;
202
291
struct crypto_blkcipher * tfm = ceph_crypto_alloc_cipher ();
203
292
struct blkcipher_desc desc = { .tfm = tfm };
204
293
char pad [16 ];
@@ -210,16 +299,16 @@ static int ceph_aes_decrypt(const void *key, int key_len,
210
299
if (IS_ERR (tfm ))
211
300
return PTR_ERR (tfm );
212
301
213
- crypto_blkcipher_setkey ((void * )tfm , key , key_len );
214
- sg_init_table (sg_in , 1 );
215
302
sg_init_table (sg_out , 2 );
216
- sg_set_buf (sg_in , src , src_len );
217
303
sg_set_buf (& sg_out [0 ], dst , * dst_len );
218
304
sg_set_buf (& sg_out [1 ], pad , sizeof (pad ));
305
+ ret = setup_sgtable (& sg_in , & prealloc_sg , src , src_len );
306
+ if (ret )
307
+ goto out_tfm ;
219
308
309
+ crypto_blkcipher_setkey ((void * )tfm , key , key_len );
220
310
iv = crypto_blkcipher_crt (tfm )-> iv ;
221
311
ivsize = crypto_blkcipher_ivsize (tfm );
222
-
223
312
memcpy (iv , aes_iv , ivsize );
224
313
225
314
/*
@@ -228,12 +317,10 @@ static int ceph_aes_decrypt(const void *key, int key_len,
228
317
print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
229
318
src, src_len, 1);
230
319
*/
231
-
232
- ret = crypto_blkcipher_decrypt (& desc , sg_out , sg_in , src_len );
233
- crypto_free_blkcipher (tfm );
320
+ ret = crypto_blkcipher_decrypt (& desc , sg_out , sg_in .sgl , src_len );
234
321
if (ret < 0 ) {
235
322
pr_err ("ceph_aes_decrypt failed %d\n" , ret );
236
- return ret ;
323
+ goto out_sg ;
237
324
}
238
325
239
326
if (src_len <= * dst_len )
@@ -251,15 +338,21 @@ static int ceph_aes_decrypt(const void *key, int key_len,
251
338
print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1,
252
339
dst, *dst_len, 1);
253
340
*/
254
- return 0 ;
341
+
342
+ out_sg :
343
+ teardown_sgtable (& sg_in );
344
+ out_tfm :
345
+ crypto_free_blkcipher (tfm );
346
+ return ret ;
255
347
}
256
348
257
349
static int ceph_aes_decrypt2 (const void * key , int key_len ,
258
350
void * dst1 , size_t * dst1_len ,
259
351
void * dst2 , size_t * dst2_len ,
260
352
const void * src , size_t src_len )
261
353
{
262
- struct scatterlist sg_in [1 ], sg_out [3 ];
354
+ struct sg_table sg_in ;
355
+ struct scatterlist sg_out [3 ], prealloc_sg ;
263
356
struct crypto_blkcipher * tfm = ceph_crypto_alloc_cipher ();
264
357
struct blkcipher_desc desc = { .tfm = tfm };
265
358
char pad [16 ];
@@ -271,17 +364,17 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
271
364
if (IS_ERR (tfm ))
272
365
return PTR_ERR (tfm );
273
366
274
- sg_init_table (sg_in , 1 );
275
- sg_set_buf (sg_in , src , src_len );
276
367
sg_init_table (sg_out , 3 );
277
368
sg_set_buf (& sg_out [0 ], dst1 , * dst1_len );
278
369
sg_set_buf (& sg_out [1 ], dst2 , * dst2_len );
279
370
sg_set_buf (& sg_out [2 ], pad , sizeof (pad ));
371
+ ret = setup_sgtable (& sg_in , & prealloc_sg , src , src_len );
372
+ if (ret )
373
+ goto out_tfm ;
280
374
281
375
crypto_blkcipher_setkey ((void * )tfm , key , key_len );
282
376
iv = crypto_blkcipher_crt (tfm )-> iv ;
283
377
ivsize = crypto_blkcipher_ivsize (tfm );
284
-
285
378
memcpy (iv , aes_iv , ivsize );
286
379
287
380
/*
@@ -290,12 +383,10 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
290
383
print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1,
291
384
src, src_len, 1);
292
385
*/
293
-
294
- ret = crypto_blkcipher_decrypt (& desc , sg_out , sg_in , src_len );
295
- crypto_free_blkcipher (tfm );
386
+ ret = crypto_blkcipher_decrypt (& desc , sg_out , sg_in .sgl , src_len );
296
387
if (ret < 0 ) {
297
388
pr_err ("ceph_aes_decrypt failed %d\n" , ret );
298
- return ret ;
389
+ goto out_sg ;
299
390
}
300
391
301
392
if (src_len <= * dst1_len )
@@ -325,7 +416,11 @@ static int ceph_aes_decrypt2(const void *key, int key_len,
325
416
dst2, *dst2_len, 1);
326
417
*/
327
418
328
- return 0 ;
419
+ out_sg :
420
+ teardown_sgtable (& sg_in );
421
+ out_tfm :
422
+ crypto_free_blkcipher (tfm );
423
+ return ret ;
329
424
}
330
425
331
426
0 commit comments