diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-04-04 03:41:07 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2007-05-02 00:38:30 -0400 |
commit | 6158efc09016d3186263f6fd3a50667446ec4008 (patch) | |
tree | b9656346dd6cce6b78fc52bd3bcb84c7bcc77947 | |
parent | 32e3983fe590ac4cd70c7728eb330d43cef031a7 (diff) |
[CRYPTO] tcrypt: Use async blkcipher interface
This patch converts the tcrypt module to use the asynchronous block cipher
interface. As all synchronous block ciphers can be used through the async
interface, tcrypt is still able to test them.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | crypto/tcrypt.c | 121 |
1 files changed, 82 insertions, 39 deletions
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 8eaa5aa210b..f0aed0106ad 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
@@ -57,6 +57,11 @@ | |||
57 | #define ENCRYPT 1 | 57 | #define ENCRYPT 1 |
58 | #define DECRYPT 0 | 58 | #define DECRYPT 0 |
59 | 59 | ||
60 | struct tcrypt_result { | ||
61 | struct completion completion; | ||
62 | int err; | ||
63 | }; | ||
64 | |||
60 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; | 65 | static unsigned int IDX[8] = { IDX1, IDX2, IDX3, IDX4, IDX5, IDX6, IDX7, IDX8 }; |
61 | 66 | ||
62 | /* | 67 | /* |
@@ -84,6 +89,17 @@ static void hexdump(unsigned char *buf, unsigned int len) | |||
84 | printk("\n"); | 89 | printk("\n"); |
85 | } | 90 | } |
86 | 91 | ||
92 | static void tcrypt_complete(struct crypto_async_request *req, int err) | ||
93 | { | ||
94 | struct tcrypt_result *res = req->data; | ||
95 | |||
96 | if (err == -EINPROGRESS) | ||
97 | return; | ||
98 | |||
99 | res->err = err; | ||
100 | complete(&res->completion); | ||
101 | } | ||
102 | |||
87 | static void test_hash(char *algo, struct hash_testvec *template, | 103 | static void test_hash(char *algo, struct hash_testvec *template, |
88 | unsigned int tcount) | 104 | unsigned int tcount) |
89 | { | 105 | { |
@@ -203,15 +219,14 @@ static void test_cipher(char *algo, int enc, | |||
203 | { | 219 | { |
204 | unsigned int ret, i, j, k, temp; | 220 | unsigned int ret, i, j, k, temp; |
205 | unsigned int tsize; | 221 | unsigned int tsize; |
206 | unsigned int iv_len; | ||
207 | unsigned int len; | ||
208 | char *q; | 222 | char *q; |
209 | struct crypto_blkcipher *tfm; | 223 | struct crypto_ablkcipher *tfm; |
210 | char *key; | 224 | char *key; |
211 | struct cipher_testvec *cipher_tv; | 225 | struct cipher_testvec *cipher_tv; |
212 | struct blkcipher_desc desc; | 226 | struct ablkcipher_request *req; |
213 | struct scatterlist sg[8]; | 227 | struct scatterlist sg[8]; |
214 | const char *e; | 228 | const char *e; |
229 | struct tcrypt_result result; | ||
215 | 230 | ||
216 | if (enc == ENCRYPT) | 231 | if (enc == ENCRYPT) |
217 | e = "encryption"; | 232 | e = "encryption"; |
@@ -232,15 +247,24 @@ static void test_cipher(char *algo, int enc, | |||
232 | memcpy(tvmem, template, tsize); | 247 | memcpy(tvmem, template, tsize); |
233 | cipher_tv = (void *)tvmem; | 248 | cipher_tv = (void *)tvmem; |
234 | 249 | ||
235 | tfm = crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC); | 250 | init_completion(&result.completion); |
251 | |||
252 | tfm = crypto_alloc_ablkcipher(algo, 0, 0); | ||
236 | 253 | ||
237 | if (IS_ERR(tfm)) { | 254 | if (IS_ERR(tfm)) { |
238 | printk("failed to load transform for %s: %ld\n", algo, | 255 | printk("failed to load transform for %s: %ld\n", algo, |
239 | PTR_ERR(tfm)); | 256 | PTR_ERR(tfm)); |
240 | return; | 257 | return; |
241 | } | 258 | } |
242 | desc.tfm = tfm; | 259 | |
243 | desc.flags = 0; | 260 | req = ablkcipher_request_alloc(tfm, GFP_KERNEL); |
261 | if (!req) { | ||
262 | printk("failed to allocate request for %s\n", algo); | ||
263 | goto out; | ||
264 | } | ||
265 | |||
266 | ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, | ||
267 | tcrypt_complete, &result); | ||
244 | 268 | ||
245 | j = 0; | 269 | j = 0; |
246 | for (i = 0; i < tcount; i++) { | 270 | for (i = 0; i < tcount; i++) { |
@@ -249,17 +273,17 @@ static void test_cipher(char *algo, int enc, | |||
249 | printk("test %u (%d bit key):\n", | 273 | printk("test %u (%d bit key):\n", |
250 | j, cipher_tv[i].klen * 8); | 274 | j, cipher_tv[i].klen * 8); |
251 | 275 | ||
252 | crypto_blkcipher_clear_flags(tfm, ~0); | 276 | crypto_ablkcipher_clear_flags(tfm, ~0); |
253 | if (cipher_tv[i].wk) | 277 | if (cipher_tv[i].wk) |
254 | crypto_blkcipher_set_flags( | 278 | crypto_ablkcipher_set_flags( |
255 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); | 279 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
256 | key = cipher_tv[i].key; | 280 | key = cipher_tv[i].key; |
257 | 281 | ||
258 | ret = crypto_blkcipher_setkey(tfm, key, | 282 | ret = crypto_ablkcipher_setkey(tfm, key, |
259 | cipher_tv[i].klen); | 283 | cipher_tv[i].klen); |
260 | if (ret) { | 284 | if (ret) { |
261 | printk("setkey() failed flags=%x\n", | 285 | printk("setkey() failed flags=%x\n", |
262 | crypto_blkcipher_get_flags(tfm)); | 286 | crypto_ablkcipher_get_flags(tfm)); |
263 | 287 | ||
264 | if (!cipher_tv[i].fail) | 288 | if (!cipher_tv[i].fail) |
265 | goto out; | 289 | goto out; |
@@ -268,19 +292,28 @@ static void test_cipher(char *algo, int enc, | |||
268 | sg_set_buf(&sg[0], cipher_tv[i].input, | 292 | sg_set_buf(&sg[0], cipher_tv[i].input, |
269 | cipher_tv[i].ilen); | 293 | cipher_tv[i].ilen); |
270 | 294 | ||
271 | iv_len = crypto_blkcipher_ivsize(tfm); | 295 | ablkcipher_request_set_crypt(req, sg, sg, |
272 | if (iv_len) | 296 | cipher_tv[i].ilen, |
273 | crypto_blkcipher_set_iv(tfm, cipher_tv[i].iv, | 297 | cipher_tv[i].iv); |
274 | iv_len); | ||
275 | 298 | ||
276 | len = cipher_tv[i].ilen; | ||
277 | ret = enc ? | 299 | ret = enc ? |
278 | crypto_blkcipher_encrypt(&desc, sg, sg, len) : | 300 | crypto_ablkcipher_encrypt(req) : |
279 | crypto_blkcipher_decrypt(&desc, sg, sg, len); | 301 | crypto_ablkcipher_decrypt(req); |
280 | 302 | ||
281 | if (ret) { | 303 | switch (ret) { |
282 | printk("%s () failed flags=%x\n", e, | 304 | case 0: |
283 | desc.flags); | 305 | break; |
306 | case -EINPROGRESS: | ||
307 | case -EBUSY: | ||
308 | ret = wait_for_completion_interruptible( | ||
309 | &result.completion); | ||
310 | if (!ret && !((ret = result.err))) { | ||
311 | INIT_COMPLETION(result.completion); | ||
312 | break; | ||
313 | } | ||
314 | /* fall through */ | ||
315 | default: | ||
316 | printk("%s () failed err=%d\n", e, -ret); | ||
284 | goto out; | 317 | goto out; |
285 | } | 318 | } |
286 | 319 | ||
@@ -303,17 +336,17 @@ static void test_cipher(char *algo, int enc, | |||
303 | printk("test %u (%d bit key):\n", | 336 | printk("test %u (%d bit key):\n", |
304 | j, cipher_tv[i].klen * 8); | 337 | j, cipher_tv[i].klen * 8); |
305 | 338 | ||
306 | crypto_blkcipher_clear_flags(tfm, ~0); | 339 | crypto_ablkcipher_clear_flags(tfm, ~0); |
307 | if (cipher_tv[i].wk) | 340 | if (cipher_tv[i].wk) |
308 | crypto_blkcipher_set_flags( | 341 | crypto_ablkcipher_set_flags( |
309 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); | 342 | tfm, CRYPTO_TFM_REQ_WEAK_KEY); |
310 | key = cipher_tv[i].key; | 343 | key = cipher_tv[i].key; |
311 | 344 | ||
312 | ret = crypto_blkcipher_setkey(tfm, key, | 345 | ret = crypto_ablkcipher_setkey(tfm, key, |
313 | cipher_tv[i].klen); | 346 | cipher_tv[i].klen); |
314 | if (ret) { | 347 | if (ret) { |
315 | printk("setkey() failed flags=%x\n", | 348 | printk("setkey() failed flags=%x\n", |
316 | crypto_blkcipher_get_flags(tfm)); | 349 | crypto_ablkcipher_get_flags(tfm)); |
317 | 350 | ||
318 | if (!cipher_tv[i].fail) | 351 | if (!cipher_tv[i].fail) |
319 | goto out; | 352 | goto out; |
@@ -329,19 +362,28 @@ static void test_cipher(char *algo, int enc, | |||
329 | cipher_tv[i].tap[k]); | 362 | cipher_tv[i].tap[k]); |
330 | } | 363 | } |
331 | 364 | ||
332 | iv_len = crypto_blkcipher_ivsize(tfm); | 365 | ablkcipher_request_set_crypt(req, sg, sg, |
333 | if (iv_len) | 366 | cipher_tv[i].ilen, |
334 | crypto_blkcipher_set_iv(tfm, cipher_tv[i].iv, | 367 | cipher_tv[i].iv); |
335 | iv_len); | ||
336 | 368 | ||
337 | len = cipher_tv[i].ilen; | ||
338 | ret = enc ? | 369 | ret = enc ? |
339 | crypto_blkcipher_encrypt(&desc, sg, sg, len) : | 370 | crypto_ablkcipher_encrypt(req) : |
340 | crypto_blkcipher_decrypt(&desc, sg, sg, len); | 371 | crypto_ablkcipher_decrypt(req); |
341 | 372 | ||
342 | if (ret) { | 373 | switch (ret) { |
343 | printk("%s () failed flags=%x\n", e, | 374 | case 0: |
344 | desc.flags); | 375 | break; |
376 | case -EINPROGRESS: | ||
377 | case -EBUSY: | ||
378 | ret = wait_for_completion_interruptible( | ||
379 | &result.completion); | ||
380 | if (!ret && !((ret = result.err))) { | ||
381 | INIT_COMPLETION(result.completion); | ||
382 | break; | ||
383 | } | ||
384 | /* fall through */ | ||
385 | default: | ||
386 | printk("%s () failed err=%d\n", e, -ret); | ||
345 | goto out; | 387 | goto out; |
346 | } | 388 | } |
347 | 389 | ||
@@ -360,7 +402,8 @@ static void test_cipher(char *algo, int enc, | |||
360 | } | 402 | } |
361 | 403 | ||
362 | out: | 404 | out: |
363 | crypto_free_blkcipher(tfm); | 405 | crypto_free_ablkcipher(tfm); |
406 | ablkcipher_request_free(req); | ||
364 | } | 407 | } |
365 | 408 | ||
366 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, | 409 | static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p, |
@@ -832,7 +875,7 @@ static void test_available(void) | |||
832 | 875 | ||
833 | while (*name) { | 876 | while (*name) { |
834 | printk("alg %s ", *name); | 877 | printk("alg %s ", *name); |
835 | printk(crypto_has_alg(*name, 0, CRYPTO_ALG_ASYNC) ? | 878 | printk(crypto_has_alg(*name, 0, 0) ? |
836 | "found\n" : "not found\n"); | 879 | "found\n" : "not found\n"); |
837 | name++; | 880 | name++; |
838 | } | 881 | } |