aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2005-09-01 20:43:05 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-01 20:43:05 -0400
commit64baf3cfea974d2b9e671ccfdbc03e030ea5ebc6 (patch)
tree2bae23bf3d7378ba2d60be8aee6b0178d1d9c721
parentfb4f10ed50f01b0f953068456bfb6e2885921b01 (diff)
[CRYPTO]: Added CRYPTO_TFM_REQ_MAY_SLEEP flag
The crypto layer currently uses in_atomic() to determine whether it is allowed to sleep. This is incorrect since spin locks don't always cause in_atomic() to return true. Instead of that, this patch returns to an earlier idea of a per-tfm flag which determines whether sleeping is allowed. Unlike the earlier version, the default is to not allow sleeping. This ensures that no existing code can break. As usual, this flag may either be set through crypto_alloc_tfm(), or just before a specific crypto operation. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--crypto/api.c3
-rw-r--r--crypto/cipher.c4
-rw-r--r--crypto/internal.h3
-rw-r--r--include/linux/crypto.h1
4 files changed, 5 insertions, 6 deletions
diff --git a/crypto/api.c b/crypto/api.c
index b4728811ce3..959c4e5f264 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -66,7 +66,8 @@ static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
66 66
67static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) 67static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags)
68{ 68{
69 tfm->crt_flags = 0; 69 tfm->crt_flags = flags & CRYPTO_TFM_REQ_MASK;
70 flags &= ~CRYPTO_TFM_REQ_MASK;
70 71
71 switch (crypto_tfm_alg_type(tfm)) { 72 switch (crypto_tfm_alg_type(tfm)) {
72 case CRYPTO_ALG_TYPE_CIPHER: 73 case CRYPTO_ALG_TYPE_CIPHER:
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 8da644364cb..3df47f93c9d 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -377,11 +377,7 @@ static int nocrypt_iv(struct crypto_tfm *tfm,
377int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags) 377int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags)
378{ 378{
379 u32 mode = flags & CRYPTO_TFM_MODE_MASK; 379 u32 mode = flags & CRYPTO_TFM_MODE_MASK;
380
381 tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB; 380 tfm->crt_cipher.cit_mode = mode ? mode : CRYPTO_TFM_MODE_ECB;
382 if (flags & CRYPTO_TFM_REQ_WEAK_KEY)
383 tfm->crt_flags = CRYPTO_TFM_REQ_WEAK_KEY;
384
385 return 0; 381 return 0;
386} 382}
387 383
diff --git a/crypto/internal.h b/crypto/internal.h
index 37515beafc8..37aa652ce5c 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -17,6 +17,7 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/slab.h>
20#include <asm/kmap_types.h> 21#include <asm/kmap_types.h>
21 22
22extern enum km_type crypto_km_types[]; 23extern enum km_type crypto_km_types[];
@@ -38,7 +39,7 @@ static inline void crypto_kunmap(void *vaddr, int out)
38 39
39static inline void crypto_yield(struct crypto_tfm *tfm) 40static inline void crypto_yield(struct crypto_tfm *tfm)
40{ 41{
41 if (!in_atomic()) 42 if (tfm->crt_flags & CRYPTO_TFM_REQ_MAY_SLEEP)
42 cond_resched(); 43 cond_resched();
43} 44}
44 45
diff --git a/include/linux/crypto.h b/include/linux/crypto.h
index 5e2bcc636a0..3c89df6e776 100644
--- a/include/linux/crypto.h
+++ b/include/linux/crypto.h
@@ -45,6 +45,7 @@
45#define CRYPTO_TFM_MODE_CTR 0x00000008 45#define CRYPTO_TFM_MODE_CTR 0x00000008
46 46
47#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 47#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
48#define CRYPTO_TFM_REQ_MAY_SLEEP 0x00000200
48#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 49#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
49#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 50#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
50#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 51#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000