aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/cipher.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-15 19:50:46 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-15 19:50:46 -0400
commitd3502d7f25b22cfc9762bf1781faa9db1bb3be2e (patch)
treee1d0195704efaafa14caf6965c8f2b6b00cbcb83 /crypto/cipher.c
parentd2a9a8ded48bec153f08ee87a40626c8d0737f79 (diff)
parent0a9f2a467d8dacaf7e97469dba99ed2d07287d80 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (53 commits) [TCP]: Verify the presence of RETRANS bit when leaving FRTO [IPV6]: Call inet6addr_chain notifiers on link down [NET_SCHED]: Kill CONFIG_NET_CLS_POLICE [NET_SCHED]: act_api: qdisc internal reclassify support [NET_SCHED]: sch_dsmark: act_api support [NET_SCHED]: sch_atm: act_api support [NET_SCHED]: sch_atm: Lindent [IPV6]: MSG_ERRQUEUE messages do not pass to connected raw sockets [IPV4]: Cleanup call to __neigh_lookup() [NET_SCHED]: Revert "avoid transmit softirq on watchdog wakeup" optimization [NETFILTER]: nf_conntrack: UDPLITE support [NETFILTER]: nf_conntrack: mark protocols __read_mostly [NETFILTER]: x_tables: add connlimit match [NETFILTER]: Lower *tables printk severity [NETFILTER]: nf_conntrack: Don't track locally generated special ICMP error [NETFILTER]: nf_conntrack: Introduces nf_ct_get_tuplepr and uses it [NETFILTER]: nf_conntrack: make l3proto->prepare() generic and renames it [NETFILTER]: nf_conntrack: Increment error count on parsing IPv4 header [NET]: Add ethtool support for NETIF_F_IPV6_CSUM devices. [AF_IUCV]: Add lock when updating accept_q ...
Diffstat (limited to 'crypto/cipher.c')
-rw-r--r--crypto/cipher.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/crypto/cipher.c b/crypto/cipher.c
index 333aab2f0277..0b2650c2014b 100644
--- a/crypto/cipher.c
+++ b/crypto/cipher.c
@@ -20,16 +20,43 @@
20#include <linux/string.h> 20#include <linux/string.h>
21#include "internal.h" 21#include "internal.h"
22 22
23static int setkey_unaligned(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
24{
25 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
26 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
27 int ret;
28 u8 *buffer, *alignbuffer;
29 unsigned long absize;
30
31 absize = keylen + alignmask;
32 buffer = kmalloc(absize, GFP_ATOMIC);
33 if (!buffer)
34 return -ENOMEM;
35
36 alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
37 memcpy(alignbuffer, key, keylen);
38 ret = cia->cia_setkey(tfm, alignbuffer, keylen);
39 memset(alignbuffer, 0, absize);
40 kfree(buffer);
41 return ret;
42
43}
44
23static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) 45static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
24{ 46{
25 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher; 47 struct cipher_alg *cia = &tfm->__crt_alg->cra_cipher;
26 48 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
49
27 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK; 50 tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
28 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) { 51 if (keylen < cia->cia_min_keysize || keylen > cia->cia_max_keysize) {
29 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; 52 tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
30 return -EINVAL; 53 return -EINVAL;
31 } else 54 }
32 return cia->cia_setkey(tfm, key, keylen); 55
56 if ((unsigned long)key & alignmask)
57 return setkey_unaligned(tfm, key, keylen);
58
59 return cia->cia_setkey(tfm, key, keylen);
33} 60}
34 61
35static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *, 62static void cipher_crypt_unaligned(void (*fn)(struct crypto_tfm *, u8 *,