aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/esp6.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2006-07-30 01:41:01 -0400
committerHerbert Xu <herbert@gondor.apana.org.au>2006-09-20 21:46:14 -0400
commit6b7326c8497f954c2cfcb4c49fe42be5b80887bc (patch)
tree5739c37f7a72d1ef281fbbb5bbc1483226eec198 /net/ipv6/esp6.c
parent04ff12609445c7b462d7fc7f2d30dad442c922f3 (diff)
[IPSEC] ESP: Use block ciphers where applicable
This patch converts IPSec/ESP to use the new block cipher type where applicable. Similar to the HMAC conversion, existing algorithm names have been kept for compatibility. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'net/ipv6/esp6.c')
-rw-r--r--net/ipv6/esp6.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index a278d5e862fe..46a7e687948e 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -24,6 +24,7 @@
24 * This file is derived from net/ipv4/esp.c 24 * This file is derived from net/ipv4/esp.c
25 */ 25 */
26 26
27#include <linux/err.h>
27#include <linux/module.h> 28#include <linux/module.h>
28#include <net/ip.h> 29#include <net/ip.h>
29#include <net/xfrm.h> 30#include <net/xfrm.h>
@@ -44,7 +45,8 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
44 int hdr_len; 45 int hdr_len;
45 struct ipv6hdr *top_iph; 46 struct ipv6hdr *top_iph;
46 struct ipv6_esp_hdr *esph; 47 struct ipv6_esp_hdr *esph;
47 struct crypto_tfm *tfm; 48 struct crypto_blkcipher *tfm;
49 struct blkcipher_desc desc;
48 struct esp_data *esp; 50 struct esp_data *esp;
49 struct sk_buff *trailer; 51 struct sk_buff *trailer;
50 int blksize; 52 int blksize;
@@ -67,7 +69,9 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
67 69
68 alen = esp->auth.icv_trunc_len; 70 alen = esp->auth.icv_trunc_len;
69 tfm = esp->conf.tfm; 71 tfm = esp->conf.tfm;
70 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4); 72 desc.tfm = tfm;
73 desc.flags = 0;
74 blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
71 clen = ALIGN(clen + 2, blksize); 75 clen = ALIGN(clen + 2, blksize);
72 if (esp->conf.padlen) 76 if (esp->conf.padlen)
73 clen = ALIGN(clen, esp->conf.padlen); 77 clen = ALIGN(clen, esp->conf.padlen);
@@ -96,7 +100,7 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
96 xfrm_aevent_doreplay(x); 100 xfrm_aevent_doreplay(x);
97 101
98 if (esp->conf.ivlen) 102 if (esp->conf.ivlen)
99 crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 103 crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
100 104
101 do { 105 do {
102 struct scatterlist *sg = &esp->sgbuf[0]; 106 struct scatterlist *sg = &esp->sgbuf[0];
@@ -107,14 +111,17 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
107 goto error; 111 goto error;
108 } 112 }
109 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); 113 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
110 crypto_cipher_encrypt(tfm, sg, sg, clen); 114 err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
111 if (unlikely(sg != &esp->sgbuf[0])) 115 if (unlikely(sg != &esp->sgbuf[0]))
112 kfree(sg); 116 kfree(sg);
113 } while (0); 117 } while (0);
114 118
119 if (unlikely(err))
120 goto error;
121
115 if (esp->conf.ivlen) { 122 if (esp->conf.ivlen) {
116 memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 123 memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
117 crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 124 crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
118 } 125 }
119 126
120 if (esp->auth.icv_full_len) { 127 if (esp->auth.icv_full_len) {
@@ -123,8 +130,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
123 pskb_put(skb, trailer, alen); 130 pskb_put(skb, trailer, alen);
124 } 131 }
125 132
126 err = 0;
127
128error: 133error:
129 return err; 134 return err;
130} 135}
@@ -134,8 +139,10 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
134 struct ipv6hdr *iph; 139 struct ipv6hdr *iph;
135 struct ipv6_esp_hdr *esph; 140 struct ipv6_esp_hdr *esph;
136 struct esp_data *esp = x->data; 141 struct esp_data *esp = x->data;
142 struct crypto_blkcipher *tfm = esp->conf.tfm;
143 struct blkcipher_desc desc = { .tfm = tfm };
137 struct sk_buff *trailer; 144 struct sk_buff *trailer;
138 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 145 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
139 int alen = esp->auth.icv_trunc_len; 146 int alen = esp->auth.icv_trunc_len;
140 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen; 147 int elen = skb->len - sizeof(struct ipv6_esp_hdr) - esp->conf.ivlen - alen;
141 148
@@ -182,7 +189,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
182 189
183 /* Get ivec. This can be wrong, check against another impls. */ 190 /* Get ivec. This can be wrong, check against another impls. */
184 if (esp->conf.ivlen) 191 if (esp->conf.ivlen)
185 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); 192 crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
186 193
187 { 194 {
188 u8 nexthdr[2]; 195 u8 nexthdr[2];
@@ -197,9 +204,11 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
197 } 204 }
198 } 205 }
199 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen); 206 skb_to_sgvec(skb, sg, sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen, elen);
200 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); 207 ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
201 if (unlikely(sg != &esp->sgbuf[0])) 208 if (unlikely(sg != &esp->sgbuf[0]))
202 kfree(sg); 209 kfree(sg);
210 if (unlikely(ret))
211 goto out;
203 212
204 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) 213 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
205 BUG(); 214 BUG();
@@ -225,7 +234,7 @@ out:
225static u32 esp6_get_max_size(struct xfrm_state *x, int mtu) 234static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
226{ 235{
227 struct esp_data *esp = x->data; 236 struct esp_data *esp = x->data;
228 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 237 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
229 238
230 if (x->props.mode) { 239 if (x->props.mode) {
231 mtu = ALIGN(mtu + 2, blksize); 240 mtu = ALIGN(mtu + 2, blksize);
@@ -266,7 +275,7 @@ static void esp6_destroy(struct xfrm_state *x)
266 if (!esp) 275 if (!esp)
267 return; 276 return;
268 277
269 crypto_free_tfm(esp->conf.tfm); 278 crypto_free_blkcipher(esp->conf.tfm);
270 esp->conf.tfm = NULL; 279 esp->conf.tfm = NULL;
271 kfree(esp->conf.ivec); 280 kfree(esp->conf.ivec);
272 esp->conf.ivec = NULL; 281 esp->conf.ivec = NULL;
@@ -280,6 +289,7 @@ static void esp6_destroy(struct xfrm_state *x)
280static int esp6_init_state(struct xfrm_state *x) 289static int esp6_init_state(struct xfrm_state *x)
281{ 290{
282 struct esp_data *esp = NULL; 291 struct esp_data *esp = NULL;
292 struct crypto_blkcipher *tfm;
283 293
284 /* null auth and encryption can have zero length keys */ 294 /* null auth and encryption can have zero length keys */
285 if (x->aalg) { 295 if (x->aalg) {
@@ -327,13 +337,11 @@ static int esp6_init_state(struct xfrm_state *x)
327 } 337 }
328 esp->conf.key = x->ealg->alg_key; 338 esp->conf.key = x->ealg->alg_key;
329 esp->conf.key_len = (x->ealg->alg_key_len+7)/8; 339 esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
330 if (x->props.ealgo == SADB_EALG_NULL) 340 tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
331 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); 341 if (IS_ERR(tfm))
332 else
333 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
334 if (esp->conf.tfm == NULL)
335 goto error; 342 goto error;
336 esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); 343 esp->conf.tfm = tfm;
344 esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
337 esp->conf.padlen = 0; 345 esp->conf.padlen = 0;
338 if (esp->conf.ivlen) { 346 if (esp->conf.ivlen) {
339 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 347 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
@@ -341,7 +349,7 @@ static int esp6_init_state(struct xfrm_state *x)
341 goto error; 349 goto error;
342 get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 350 get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
343 } 351 }
344 if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) 352 if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len))
345 goto error; 353 goto error;
346 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; 354 x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen;
347 if (x->props.mode) 355 if (x->props.mode)