aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/esp4.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/ipv4/esp4.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/ipv4/esp4.c')
-rw-r--r--net/ipv4/esp4.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index fc2f8ce441de..7c63ae494742 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -1,3 +1,4 @@
1#include <linux/err.h>
1#include <linux/module.h> 2#include <linux/module.h>
2#include <net/ip.h> 3#include <net/ip.h>
3#include <net/xfrm.h> 4#include <net/xfrm.h>
@@ -16,7 +17,8 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
16 int err; 17 int err;
17 struct iphdr *top_iph; 18 struct iphdr *top_iph;
18 struct ip_esp_hdr *esph; 19 struct ip_esp_hdr *esph;
19 struct crypto_tfm *tfm; 20 struct crypto_blkcipher *tfm;
21 struct blkcipher_desc desc;
20 struct esp_data *esp; 22 struct esp_data *esp;
21 struct sk_buff *trailer; 23 struct sk_buff *trailer;
22 int blksize; 24 int blksize;
@@ -36,7 +38,9 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
36 esp = x->data; 38 esp = x->data;
37 alen = esp->auth.icv_trunc_len; 39 alen = esp->auth.icv_trunc_len;
38 tfm = esp->conf.tfm; 40 tfm = esp->conf.tfm;
39 blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4); 41 desc.tfm = tfm;
42 desc.flags = 0;
43 blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
40 clen = ALIGN(clen + 2, blksize); 44 clen = ALIGN(clen + 2, blksize);
41 if (esp->conf.padlen) 45 if (esp->conf.padlen)
42 clen = ALIGN(clen, esp->conf.padlen); 46 clen = ALIGN(clen, esp->conf.padlen);
@@ -92,7 +96,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
92 xfrm_aevent_doreplay(x); 96 xfrm_aevent_doreplay(x);
93 97
94 if (esp->conf.ivlen) 98 if (esp->conf.ivlen)
95 crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 99 crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
96 100
97 do { 101 do {
98 struct scatterlist *sg = &esp->sgbuf[0]; 102 struct scatterlist *sg = &esp->sgbuf[0];
@@ -103,14 +107,17 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
103 goto error; 107 goto error;
104 } 108 }
105 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen); 109 skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
106 crypto_cipher_encrypt(tfm, sg, sg, clen); 110 err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
107 if (unlikely(sg != &esp->sgbuf[0])) 111 if (unlikely(sg != &esp->sgbuf[0]))
108 kfree(sg); 112 kfree(sg);
109 } while (0); 113 } while (0);
110 114
115 if (unlikely(err))
116 goto error;
117
111 if (esp->conf.ivlen) { 118 if (esp->conf.ivlen) {
112 memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 119 memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen);
113 crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm)); 120 crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen);
114 } 121 }
115 122
116 if (esp->auth.icv_full_len) { 123 if (esp->auth.icv_full_len) {
@@ -121,8 +128,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
121 128
122 ip_send_check(top_iph); 129 ip_send_check(top_iph);
123 130
124 err = 0;
125
126error: 131error:
127 return err; 132 return err;
128} 133}
@@ -137,8 +142,10 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
137 struct iphdr *iph; 142 struct iphdr *iph;
138 struct ip_esp_hdr *esph; 143 struct ip_esp_hdr *esph;
139 struct esp_data *esp = x->data; 144 struct esp_data *esp = x->data;
145 struct crypto_blkcipher *tfm = esp->conf.tfm;
146 struct blkcipher_desc desc = { .tfm = tfm };
140 struct sk_buff *trailer; 147 struct sk_buff *trailer;
141 int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 148 int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4);
142 int alen = esp->auth.icv_trunc_len; 149 int alen = esp->auth.icv_trunc_len;
143 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen; 150 int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;
144 int nfrags; 151 int nfrags;
@@ -146,6 +153,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
146 u8 nexthdr[2]; 153 u8 nexthdr[2];
147 struct scatterlist *sg; 154 struct scatterlist *sg;
148 int padlen; 155 int padlen;
156 int err;
149 157
150 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr))) 158 if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))
151 goto out; 159 goto out;
@@ -178,7 +186,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
178 186
179 /* Get ivec. This can be wrong, check against another impls. */ 187 /* Get ivec. This can be wrong, check against another impls. */
180 if (esp->conf.ivlen) 188 if (esp->conf.ivlen)
181 crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); 189 crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen);
182 190
183 sg = &esp->sgbuf[0]; 191 sg = &esp->sgbuf[0];
184 192
@@ -188,9 +196,11 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
188 goto out; 196 goto out;
189 } 197 }
190 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen); 198 skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);
191 crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen); 199 err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
192 if (unlikely(sg != &esp->sgbuf[0])) 200 if (unlikely(sg != &esp->sgbuf[0]))
193 kfree(sg); 201 kfree(sg);
202 if (unlikely(err))
203 return err;
194 204
195 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) 205 if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))
196 BUG(); 206 BUG();
@@ -254,7 +264,7 @@ out:
254static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) 264static u32 esp4_get_max_size(struct xfrm_state *x, int mtu)
255{ 265{
256 struct esp_data *esp = x->data; 266 struct esp_data *esp = x->data;
257 u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); 267 u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4);
258 268
259 if (x->props.mode) { 269 if (x->props.mode) {
260 mtu = ALIGN(mtu + 2, blksize); 270 mtu = ALIGN(mtu + 2, blksize);
@@ -293,7 +303,7 @@ static void esp_destroy(struct xfrm_state *x)
293 if (!esp) 303 if (!esp)
294 return; 304 return;
295 305
296 crypto_free_tfm(esp->conf.tfm); 306 crypto_free_blkcipher(esp->conf.tfm);
297 esp->conf.tfm = NULL; 307 esp->conf.tfm = NULL;
298 kfree(esp->conf.ivec); 308 kfree(esp->conf.ivec);
299 esp->conf.ivec = NULL; 309 esp->conf.ivec = NULL;
@@ -307,6 +317,7 @@ static void esp_destroy(struct xfrm_state *x)
307static int esp_init_state(struct xfrm_state *x) 317static int esp_init_state(struct xfrm_state *x)
308{ 318{
309 struct esp_data *esp = NULL; 319 struct esp_data *esp = NULL;
320 struct crypto_blkcipher *tfm;
310 321
311 /* null auth and encryption can have zero length keys */ 322 /* null auth and encryption can have zero length keys */
312 if (x->aalg) { 323 if (x->aalg) {
@@ -351,13 +362,11 @@ static int esp_init_state(struct xfrm_state *x)
351 } 362 }
352 esp->conf.key = x->ealg->alg_key; 363 esp->conf.key = x->ealg->alg_key;
353 esp->conf.key_len = (x->ealg->alg_key_len+7)/8; 364 esp->conf.key_len = (x->ealg->alg_key_len+7)/8;
354 if (x->props.ealgo == SADB_EALG_NULL) 365 tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC);
355 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_ECB); 366 if (IS_ERR(tfm))
356 else
357 esp->conf.tfm = crypto_alloc_tfm(x->ealg->alg_name, CRYPTO_TFM_MODE_CBC);
358 if (esp->conf.tfm == NULL)
359 goto error; 367 goto error;
360 esp->conf.ivlen = crypto_tfm_alg_ivsize(esp->conf.tfm); 368 esp->conf.tfm = tfm;
369 esp->conf.ivlen = crypto_blkcipher_ivsize(tfm);
361 esp->conf.padlen = 0; 370 esp->conf.padlen = 0;
362 if (esp->conf.ivlen) { 371 if (esp->conf.ivlen) {
363 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 372 esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL);
@@ -365,7 +374,7 @@ static int esp_init_state(struct xfrm_state *x)
365 goto error; 374 goto error;
366 get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 375 get_random_bytes(esp->conf.ivec, esp->conf.ivlen);
367 } 376 }
368 if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) 377 if (crypto_blkcipher_setkey(tfm, esp->conf.key, esp->conf.key_len))
369 goto error; 378 goto error;
370 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; 379 x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen;
371 if (x->props.mode) 380 if (x->props.mode)