Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[IPSEC]: Use crypto_aead and authenc in ESP

This patch converts ESP to use the crypto_aead interface and in particular
the authenc algorithm. This lays the foundations for future support of
combined mode algorithms.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Herbert Xu and committed by
David S. Miller
38320c70 bf164cc0

+598 -429
+7 -45
include/net/esp.h
··· 1 1 #ifndef _NET_ESP_H 2 2 #define _NET_ESP_H 3 3 4 - #include <linux/crypto.h> 5 - #include <net/xfrm.h> 6 - #include <linux/scatterlist.h> 4 + #include <linux/skbuff.h> 7 5 8 - #define ESP_NUM_FAST_SG 4 6 + struct crypto_aead; 9 7 10 - struct esp_data 11 - { 12 - struct scatterlist sgbuf[ESP_NUM_FAST_SG]; 8 + struct esp_data { 9 + /* 0..255 */ 10 + int padlen; 13 11 14 - /* Confidentiality */ 15 - struct { 16 - int padlen; /* 0..255 */ 17 - /* ivlen is offset from enc_data, where encrypted data start. 18 - * It is logically different of crypto_tfm_alg_ivsize(tfm). 19 - * We assume that it is either zero (no ivec), or 20 - * >= crypto_tfm_alg_ivsize(tfm). */ 21 - int ivlen; 22 - int ivinitted; 23 - u8 *ivec; /* ivec buffer */ 24 - struct crypto_blkcipher *tfm; /* crypto handle */ 25 - } conf; 26 - 27 - /* Integrity. It is active when icv_full_len != 0 */ 28 - struct { 29 - u8 *work_icv; 30 - int icv_full_len; 31 - int icv_trunc_len; 32 - struct crypto_hash *tfm; 33 - } auth; 12 + /* Confidentiality & Integrity */ 13 + struct crypto_aead *aead; 34 14 }; 35 15 36 16 extern void *pskb_put(struct sk_buff *skb, struct sk_buff *tail, int len); 37 - 38 - static inline int esp_mac_digest(struct esp_data *esp, struct sk_buff *skb, 39 - int offset, int len) 40 - { 41 - struct hash_desc desc; 42 - int err; 43 - 44 - desc.tfm = esp->auth.tfm; 45 - desc.flags = 0; 46 - 47 - err = crypto_hash_init(&desc); 48 - if (unlikely(err)) 49 - return err; 50 - err = skb_icv_walk(skb, &desc, offset, len, crypto_hash_update); 51 - if (unlikely(err)) 52 - return err; 53 - return crypto_hash_final(&desc, esp->auth.work_icv); 54 - } 55 17 56 18 struct ip_esp_hdr; 57 19
+1
net/ipv4/Kconfig
··· 343 343 tristate "IP: ESP transformation" 344 344 select XFRM 345 345 select CRYPTO 346 + select CRYPTO_AEAD 346 347 select CRYPTO_HMAC 347 348 select CRYPTO_MD5 348 349 select CRYPTO_CBC
+301 -194
net/ipv4/esp4.c
··· 1 + #include <crypto/aead.h> 2 + #include <crypto/authenc.h> 1 3 #include <linux/err.h> 2 4 #include <linux/module.h> 3 5 #include <net/ip.h> 4 6 #include <net/xfrm.h> 5 7 #include <net/esp.h> 6 8 #include <linux/scatterlist.h> 7 - #include <linux/crypto.h> 8 9 #include <linux/kernel.h> 9 10 #include <linux/pfkeyv2.h> 10 - #include <linux/random.h> 11 + #include <linux/rtnetlink.h> 12 + #include <linux/slab.h> 11 13 #include <linux/spinlock.h> 12 14 #include <linux/in6.h> 13 15 #include <net/icmp.h> 14 16 #include <net/protocol.h> 15 17 #include <net/udp.h> 16 18 19 + struct esp_skb_cb { 20 + struct xfrm_skb_cb xfrm; 21 + void *tmp; 22 + }; 23 + 24 + #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) 25 + 26 + /* 27 + * Allocate an AEAD request structure with extra space for SG and IV. 28 + * 29 + * For alignment considerations the IV is placed at the front, followed 30 + * by the request and finally the SG list. 31 + * 32 + * TODO: Use spare space in skb for this where possible. 33 + */ 34 + static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags) 35 + { 36 + unsigned int len; 37 + 38 + len = crypto_aead_ivsize(aead); 39 + if (len) { 40 + len += crypto_aead_alignmask(aead) & 41 + ~(crypto_tfm_ctx_alignment() - 1); 42 + len = ALIGN(len, crypto_tfm_ctx_alignment()); 43 + } 44 + 45 + len += sizeof(struct aead_givcrypt_request) + crypto_aead_reqsize(aead); 46 + len = ALIGN(len, __alignof__(struct scatterlist)); 47 + 48 + len += sizeof(struct scatterlist) * nfrags; 49 + 50 + return kmalloc(len, GFP_ATOMIC); 51 + } 52 + 53 + static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp) 54 + { 55 + return crypto_aead_ivsize(aead) ? 56 + PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : tmp; 57 + } 58 + 59 + static inline struct aead_givcrypt_request *esp_tmp_givreq( 60 + struct crypto_aead *aead, u8 *iv) 61 + { 62 + struct aead_givcrypt_request *req; 63 + 64 + req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead), 65 + crypto_tfm_ctx_alignment()); 66 + aead_givcrypt_set_tfm(req, aead); 67 + return req; 68 + } 69 + 70 + static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) 71 + { 72 + struct aead_request *req; 73 + 74 + req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead), 75 + crypto_tfm_ctx_alignment()); 76 + aead_request_set_tfm(req, aead); 77 + return req; 78 + } 79 + 80 + static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead, 81 + struct aead_request *req) 82 + { 83 + return (void *)ALIGN((unsigned long)(req + 1) + 84 + crypto_aead_reqsize(aead), 85 + __alignof__(struct scatterlist)); 86 + } 87 + 88 + static inline struct scatterlist *esp_givreq_sg( 89 + struct crypto_aead *aead, struct aead_givcrypt_request *req) 90 + { 91 + return (void *)ALIGN((unsigned long)(req + 1) + 92 + crypto_aead_reqsize(aead), 93 + __alignof__(struct scatterlist)); 94 + } 95 + 96 + static void esp_output_done(struct crypto_async_request *base, int err) 97 + { 98 + struct sk_buff *skb = base->data; 99 + 100 + kfree(ESP_SKB_CB(skb)->tmp); 101 + xfrm_output_resume(skb, err); 102 + } 103 + 17 104 static int esp_output(struct xfrm_state *x, struct sk_buff *skb) 18 105 { 19 106 int err; 20 107 struct ip_esp_hdr *esph; 21 - struct crypto_blkcipher *tfm; 22 - struct blkcipher_desc desc; 108 + struct crypto_aead *aead; 109 + struct aead_givcrypt_request *req; 110 + struct scatterlist *sg; 111 + struct scatterlist *asg; 23 112 struct esp_data *esp; 24 113 struct sk_buff *trailer; 114 + void *tmp; 115 + u8 *iv; 25 116 u8 *tail; 26 117 int blksize; 27 118 int clen; ··· 127 36 clen = skb->len; 128 37 129 38 esp = x->data; 130 - alen = esp->auth.icv_trunc_len; 131 - tfm = esp->conf.tfm; 132 - desc.tfm = tfm; 133 - desc.flags = 0; 134 - blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); 135 - clen = ALIGN(clen + 2, blksize); 136 - if (esp->conf.padlen) 137 - clen = ALIGN(clen, esp->conf.padlen); 39 + aead = esp->aead; 40 + alen = crypto_aead_authsize(aead); 138 41 139 - if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) 42 + blksize = ALIGN(crypto_aead_blocksize(aead), 4); 43 + clen = ALIGN(clen + 2, blksize); 44 + if (esp->padlen) 45 + clen = ALIGN(clen, esp->padlen); 46 + 47 + if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0) 140 48 goto error; 49 + nfrags = err; 50 + 51 + tmp = esp_alloc_tmp(aead, nfrags + 1); 52 + if (!tmp) 53 + goto error; 54 + 55 + iv = esp_tmp_iv(aead, tmp); 56 + req = esp_tmp_givreq(aead, iv); 57 + asg = esp_givreq_sg(aead, req); 58 + sg = asg + 1; 141 59 142 60 /* Fill padding... */ 143 61 tail = skb_tail_pointer(trailer); ··· 156 56 tail[i] = i + 1; 157 57 } while (0); 158 58 tail[clen - skb->len - 2] = (clen - skb->len) - 2; 159 - pskb_put(skb, trailer, clen - skb->len); 59 + tail[clen - skb->len - 1] = *skb_mac_header(skb); 60 + pskb_put(skb, trailer, clen - skb->len + alen); 160 61 161 62 skb_push(skb, -skb_network_offset(skb)); 162 63 esph = ip_esp_hdr(skb); 163 - *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); 164 64 *skb_mac_header(skb) = IPPROTO_ESP; 165 - 166 - spin_lock_bh(&x->lock); 167 65 168 66 /* this is non-NULL only with UDP Encapsulation */ 169 67 if (x->encap) { 170 68 struct xfrm_encap_tmpl *encap = x->encap; 171 69 struct udphdr *uh; 172 70 __be32 *udpdata32; 71 + unsigned int sport, dport; 72 + int encap_type; 73 + 74 + spin_lock_bh(&x->lock); 75 + sport = encap->encap_sport; 76 + dport = encap->encap_dport; 77 + encap_type = encap->encap_type; 78 + spin_unlock_bh(&x->lock); 173 79 174 80 uh = (struct udphdr *)esph; 175 - uh->source = encap->encap_sport; 176 - uh->dest = encap->encap_dport; 177 - uh->len = htons(skb->len + alen - skb_transport_offset(skb)); 81 + uh->source = sport; 82 + uh->dest = dport; 83 + uh->len = htons(skb->len - skb_transport_offset(skb)); 178 84 uh->check = 0; 179 85 180 - switch (encap->encap_type) { 86 + switch (encap_type) { 181 87 default: 182 88 case UDP_ENCAP_ESPINUDP: 183 89 esph = (struct ip_esp_hdr *)(uh + 1); ··· 201 95 esph->spi = x->id.spi; 202 96 esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); 203 97 204 - if (esp->conf.ivlen) { 205 - if (unlikely(!esp->conf.ivinitted)) { 206 - get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 207 - esp->conf.ivinitted = 1; 208 - } 209 - crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen); 210 - } 98 + sg_init_table(sg, nfrags); 99 + skb_to_sgvec(skb, sg, 100 + esph->enc_data + crypto_aead_ivsize(aead) - skb->data, 101 + clen + alen); 102 + sg_init_one(asg, esph, sizeof(*esph)); 211 103 212 - do { 213 - struct scatterlist *sg = &esp->sgbuf[0]; 104 + aead_givcrypt_set_callback(req, 0, esp_output_done, skb); 105 + aead_givcrypt_set_crypt(req, sg, sg, clen, iv); 106 + aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); 107 + aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq); 214 108 215 - if (unlikely(nfrags > ESP_NUM_FAST_SG)) { 216 - sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); 217 - if (!sg) 218 - goto unlock; 219 - } 220 - sg_init_table(sg, nfrags); 221 - skb_to_sgvec(skb, sg, 222 - esph->enc_data + 223 - esp->conf.ivlen - 224 - skb->data, clen); 225 - err = crypto_blkcipher_encrypt(&desc, sg, sg, clen); 226 - if (unlikely(sg != &esp->sgbuf[0])) 227 - kfree(sg); 228 - } while (0); 109 + ESP_SKB_CB(skb)->tmp = tmp; 110 + err = crypto_aead_givencrypt(req); 111 + if (err == -EINPROGRESS) 112 + goto error; 229 113 230 - if (unlikely(err)) 231 - goto unlock; 114 + if (err == -EBUSY) 115 + err = NET_XMIT_DROP; 232 116 233 - if (esp->conf.ivlen) { 234 - memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen); 235 - crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen); 236 - } 237 - 238 - if (esp->auth.icv_full_len) { 239 - err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data, 240 - sizeof(*esph) + esp->conf.ivlen + clen); 241 - memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen); 242 - } 243 - 244 - unlock: 245 - spin_unlock_bh(&x->lock); 117 + kfree(tmp); 246 118 247 119 error: 248 120 return err; 249 121 } 250 122 251 - /* 252 - * Note: detecting truncated vs. non-truncated authentication data is very 253 - * expensive, so we only support truncated data, which is the recommended 254 - * and common case. 255 - */ 256 - static int esp_input(struct xfrm_state *x, struct sk_buff *skb) 123 + static int esp_input_done2(struct sk_buff *skb, int err) 257 124 { 258 125 struct iphdr *iph; 259 - struct ip_esp_hdr *esph; 126 + struct xfrm_state *x = xfrm_input_state(skb); 260 127 struct esp_data *esp = x->data; 261 - struct crypto_blkcipher *tfm = esp->conf.tfm; 262 - struct blkcipher_desc desc = { .tfm = tfm }; 263 - struct sk_buff *trailer; 264 - int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); 265 - int alen = esp->auth.icv_trunc_len; 266 - int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen; 267 - int nfrags; 128 + struct crypto_aead *aead = esp->aead; 129 + int alen = crypto_aead_authsize(aead); 130 + int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); 131 + int elen = skb->len - hlen; 268 132 int ihl; 269 133 u8 nexthdr[2]; 270 - struct scatterlist *sg; 271 134 int padlen; 272 - int err = -EINVAL; 273 135 274 - if (!pskb_may_pull(skb, sizeof(*esph))) 275 - goto out; 276 - 277 - if (elen <= 0 || (elen & (blksize-1))) 278 - goto out; 279 - 280 - if ((err = skb_cow_data(skb, 0, &trailer)) < 0) 281 - goto out; 282 - nfrags = err; 283 - 284 - skb->ip_summed = CHECKSUM_NONE; 285 - 286 - spin_lock(&x->lock); 287 - 288 - /* If integrity check is required, do this. */ 289 - if (esp->auth.icv_full_len) { 290 - u8 sum[alen]; 291 - 292 - err = esp_mac_digest(esp, skb, 0, skb->len - alen); 293 - if (err) 294 - goto unlock; 295 - 296 - if (skb_copy_bits(skb, skb->len - alen, sum, alen)) 297 - BUG(); 298 - 299 - if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { 300 - err = -EBADMSG; 301 - goto unlock; 302 - } 303 - } 304 - 305 - esph = (struct ip_esp_hdr *)skb->data; 306 - 307 - /* Get ivec. This can be wrong, check against another impls. */ 308 - if (esp->conf.ivlen) 309 - crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen); 310 - 311 - sg = &esp->sgbuf[0]; 312 - 313 - if (unlikely(nfrags > ESP_NUM_FAST_SG)) { 314 - err = -ENOMEM; 315 - sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); 316 - if (!sg) 317 - goto unlock; 318 - } 319 - sg_init_table(sg, nfrags); 320 - skb_to_sgvec(skb, sg, 321 - sizeof(*esph) + esp->conf.ivlen, 322 - elen); 323 - err = crypto_blkcipher_decrypt(&desc, sg, sg, elen); 324 - if (unlikely(sg != &esp->sgbuf[0])) 325 - kfree(sg); 326 - 327 - unlock: 328 - spin_unlock(&x->lock); 136 + kfree(ESP_SKB_CB(skb)->tmp); 329 137 330 138 if (unlikely(err)) 331 139 goto out; ··· 249 229 250 230 err = -EINVAL; 251 231 padlen = nexthdr[0]; 252 - if (padlen+2 >= elen) 232 + if (padlen + 2 + alen >= elen) 253 233 goto out; 254 234 255 235 /* ... check padding bits here. Silly. :-) */ 256 - 257 - /* RFC4303: Drop dummy packets without any error */ 258 - if (nexthdr[1] == IPPROTO_NONE) 259 - goto out; 260 236 261 237 iph = ip_hdr(skb); 262 238 ihl = iph->ihl * 4; ··· 295 279 } 296 280 297 281 pskb_trim(skb, skb->len - alen - padlen - 2); 298 - __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen); 282 + __skb_pull(skb, hlen); 299 283 skb_set_transport_header(skb, -ihl); 300 284 301 - return nexthdr[1]; 285 + err = nexthdr[1]; 286 + 287 + /* RFC4303: Drop dummy packets without any error */ 288 + if (err == IPPROTO_NONE) 289 + err = -EINVAL; 290 + 291 + out: 292 + return err; 293 + } 294 + 295 + static void esp_input_done(struct crypto_async_request *base, int err) 296 + { 297 + struct sk_buff *skb = base->data; 298 + 299 + xfrm_input_resume(skb, esp_input_done2(skb, err)); 300 + } 301 + 302 + /* 303 + * Note: detecting truncated vs. non-truncated authentication data is very 304 + * expensive, so we only support truncated data, which is the recommended 305 + * and common case. 306 + */ 307 + static int esp_input(struct xfrm_state *x, struct sk_buff *skb) 308 + { 309 + struct ip_esp_hdr *esph; 310 + struct esp_data *esp = x->data; 311 + struct crypto_aead *aead = esp->aead; 312 + struct aead_request *req; 313 + struct sk_buff *trailer; 314 + int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead); 315 + int nfrags; 316 + void *tmp; 317 + u8 *iv; 318 + struct scatterlist *sg; 319 + struct scatterlist *asg; 320 + int err = -EINVAL; 321 + 322 + if (!pskb_may_pull(skb, sizeof(*esph))) 323 + goto out; 324 + 325 + if (elen <= 0) 326 + goto out; 327 + 328 + if ((err = skb_cow_data(skb, 0, &trailer)) < 0) 329 + goto out; 330 + nfrags = err; 331 + 332 + err = -ENOMEM; 333 + tmp = esp_alloc_tmp(aead, nfrags + 1); 334 + if (!tmp) 335 + goto out; 336 + 337 + ESP_SKB_CB(skb)->tmp = tmp; 338 + iv = esp_tmp_iv(aead, tmp); 339 + req = esp_tmp_req(aead, iv); 340 + asg = esp_req_sg(aead, req); 341 + sg = asg + 1; 342 + 343 + skb->ip_summed = CHECKSUM_NONE; 344 + 345 + esph = (struct ip_esp_hdr *)skb->data; 346 + 347 + /* Get ivec. This can be wrong, check against another impls. */ 348 + iv = esph->enc_data; 349 + 350 + sg_init_table(sg, nfrags); 351 + skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen); 352 + sg_init_one(asg, esph, sizeof(*esph)); 353 + 354 + aead_request_set_callback(req, 0, esp_input_done, skb); 355 + aead_request_set_crypt(req, sg, sg, elen, iv); 356 + aead_request_set_assoc(req, asg, sizeof(*esph)); 357 + 358 + err = crypto_aead_decrypt(req); 359 + if (err == -EINPROGRESS) 360 + goto out; 361 + 362 + err = esp_input_done2(skb, err); 302 363 303 364 out: 304 365 return err; ··· 384 291 static u32 esp4_get_mtu(struct xfrm_state *x, int mtu) 385 292 { 386 293 struct esp_data *esp = x->data; 387 - u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); 388 - u32 align = max_t(u32, blksize, esp->conf.padlen); 294 + u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); 295 + u32 align = max_t(u32, blksize, esp->padlen); 389 296 u32 rem; 390 297 391 - mtu -= x->props.header_len + esp->auth.icv_trunc_len; 298 + mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); 392 299 rem = mtu & (align - 1); 393 300 mtu &= ~(align - 1); 394 301 ··· 435 342 if (!esp) 436 343 return; 437 344 438 - crypto_free_blkcipher(esp->conf.tfm); 439 - esp->conf.tfm = NULL; 440 - kfree(esp->conf.ivec); 441 - esp->conf.ivec = NULL; 442 - crypto_free_hash(esp->auth.tfm); 443 - esp->auth.tfm = NULL; 444 - kfree(esp->auth.work_icv); 445 - esp->auth.work_icv = NULL; 345 + crypto_free_aead(esp->aead); 446 346 kfree(esp); 447 347 } 448 348 449 349 static int esp_init_state(struct xfrm_state *x) 450 350 { 451 351 struct esp_data *esp = NULL; 452 - struct crypto_blkcipher *tfm; 352 + struct crypto_aead *aead; 353 + struct crypto_authenc_key_param *param; 354 + struct rtattr *rta; 355 + char *key; 356 + char *p; 357 + char authenc_name[CRYPTO_MAX_ALG_NAME]; 453 358 u32 align; 359 + unsigned int keylen; 360 + int err; 454 361 455 362 if (x->ealg == NULL) 456 - goto error; 363 + return -EINVAL; 364 + 365 + if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)", 366 + x->aalg ? x->aalg->alg_name : "digest_null", 367 + x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME) 368 + return -ENAMETOOLONG; 457 369 458 370 esp = kzalloc(sizeof(*esp), GFP_KERNEL); 459 371 if (esp == NULL) 460 372 return -ENOMEM; 461 373 374 + x->data = esp; 375 + 376 + aead = crypto_alloc_aead(authenc_name, 0, 0); 377 + err = PTR_ERR(aead); 378 + if (IS_ERR(aead)) 379 + goto error; 380 + 381 + esp->aead = aead; 382 + 383 + keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) + 384 + (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param)); 385 + err = -ENOMEM; 386 + key = kmalloc(keylen, GFP_KERNEL); 387 + if (!key) 388 + goto error; 389 + 390 + p = key; 391 + rta = (void *)p; 392 + rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM; 393 + rta->rta_len = RTA_LENGTH(sizeof(*param)); 394 + param = RTA_DATA(rta); 395 + p += RTA_SPACE(sizeof(*param)); 396 + 462 397 if (x->aalg) { 463 398 struct xfrm_algo_desc *aalg_desc; 464 - struct crypto_hash *hash; 465 399 466 - hash = crypto_alloc_hash(x->aalg->alg_name, 0, 467 - CRYPTO_ALG_ASYNC); 468 - if (IS_ERR(hash)) 469 - goto error; 470 - 471 - esp->auth.tfm = hash; 472 - if (crypto_hash_setkey(hash, x->aalg->alg_key, 473 - (x->aalg->alg_key_len + 7) / 8)) 474 - goto error; 400 + memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8); 401 + p += (x->aalg->alg_key_len + 7) / 8; 475 402 476 403 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 477 404 BUG_ON(!aalg_desc); 478 405 406 + err = -EINVAL; 479 407 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 480 - crypto_hash_digestsize(hash)) { 408 + crypto_aead_authsize(aead)) { 481 409 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", 482 410 x->aalg->alg_name, 483 - crypto_hash_digestsize(hash), 411 + crypto_aead_authsize(aead), 484 412 aalg_desc->uinfo.auth.icv_fullbits/8); 485 - goto error; 413 + goto free_key; 486 414 } 487 415 488 - esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 489 - esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; 490 - 491 - esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL); 492 - if (!esp->auth.work_icv) 493 - goto error; 416 + err = crypto_aead_setauthsize( 417 + aead, aalg_desc->uinfo.auth.icv_truncbits / 8); 418 + if (err) 419 + goto free_key; 494 420 } 495 421 496 - tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC); 497 - if (IS_ERR(tfm)) 422 + esp->padlen = 0; 423 + 424 + param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8); 425 + memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8); 426 + 427 + err = crypto_aead_setkey(aead, key, keylen); 428 + 429 + free_key: 430 + kfree(key); 431 + 432 + if (err) 498 433 goto error; 499 - esp->conf.tfm = tfm; 500 - esp->conf.ivlen = crypto_blkcipher_ivsize(tfm); 501 - esp->conf.padlen = 0; 502 - if (esp->conf.ivlen) { 503 - esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 504 - if (unlikely(esp->conf.ivec == NULL)) 505 - goto error; 506 - esp->conf.ivinitted = 0; 507 - } 508 - if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key, 509 - (x->ealg->alg_key_len + 7) / 8)) 510 - goto error; 511 - x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; 434 + 435 + x->props.header_len = sizeof(struct ip_esp_hdr) + 436 + crypto_aead_ivsize(aead); 512 437 if (x->props.mode == XFRM_MODE_TUNNEL) 513 438 x->props.header_len += sizeof(struct iphdr); 514 439 else if (x->props.mode == XFRM_MODE_BEET) ··· 545 434 break; 546 435 } 547 436 } 548 - x->data = esp; 549 - align = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); 550 - if (esp->conf.padlen) 551 - align = max_t(u32, align, esp->conf.padlen); 552 - x->props.trailer_len = align + 1 + esp->auth.icv_trunc_len; 553 - return 0; 437 + 438 + align = ALIGN(crypto_aead_blocksize(aead), 4); 439 + if (esp->padlen) 440 + align = max_t(u32, align, esp->padlen); 441 + x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead); 554 442 555 443 error: 556 - x->data = esp; 557 - esp_destroy(x); 558 - x->data = NULL; 559 - return -EINVAL; 444 + return err; 560 445 } 561 446 562 447 static struct xfrm_type esp_type =
+1
net/ipv6/Kconfig
··· 85 85 depends on IPV6 86 86 select XFRM 87 87 select CRYPTO 88 + select CRYPTO_AEAD 88 89 select CRYPTO_HMAC 89 90 select CRYPTO_MD5 90 91 select CRYPTO_CBC
+288 -190
net/ipv6/esp6.c
··· 24 24 * This file is derived from net/ipv4/esp.c 25 25 */ 26 26 27 + #include <crypto/aead.h> 28 + #include <crypto/authenc.h> 27 29 #include <linux/err.h> 28 30 #include <linux/module.h> 29 31 #include <net/ip.h> 30 32 #include <net/xfrm.h> 31 33 #include <net/esp.h> 32 34 #include <linux/scatterlist.h> 33 - #include <linux/crypto.h> 34 35 #include <linux/kernel.h> 35 36 #include <linux/pfkeyv2.h> 36 37 #include <linux/random.h> 38 + #include <linux/slab.h> 37 39 #include <linux/spinlock.h> 38 40 #include <net/icmp.h> 39 41 #include <net/ipv6.h> 40 42 #include <net/protocol.h> 41 43 #include <linux/icmpv6.h> 42 44 45 + struct esp_skb_cb { 46 + struct xfrm_skb_cb xfrm; 47 + void *tmp; 48 + }; 49 + 50 + #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0])) 51 + 52 + /* 53 + * Allocate an AEAD request structure with extra space for SG and IV. 54 + * 55 + * For alignment considerations the IV is placed at the front, followed 56 + * by the request and finally the SG list. 57 + * 58 + * TODO: Use spare space in skb for this where possible. 59 + */ 60 + static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags) 61 + { 62 + unsigned int len; 63 + 64 + len = crypto_aead_ivsize(aead); 65 + if (len) { 66 + len += crypto_aead_alignmask(aead) & 67 + ~(crypto_tfm_ctx_alignment() - 1); 68 + len = ALIGN(len, crypto_tfm_ctx_alignment()); 69 + } 70 + 71 + len += sizeof(struct aead_givcrypt_request) + crypto_aead_reqsize(aead); 72 + len = ALIGN(len, __alignof__(struct scatterlist)); 73 + 74 + len += sizeof(struct scatterlist) * nfrags; 75 + 76 + return kmalloc(len, GFP_ATOMIC); 77 + } 78 + 79 + static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp) 80 + { 81 + return crypto_aead_ivsize(aead) ? 82 + PTR_ALIGN((u8 *)tmp, crypto_aead_alignmask(aead) + 1) : tmp; 83 + } 84 + 85 + static inline struct aead_givcrypt_request *esp_tmp_givreq( 86 + struct crypto_aead *aead, u8 *iv) 87 + { 88 + struct aead_givcrypt_request *req; 89 + 90 + req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead), 91 + crypto_tfm_ctx_alignment()); 92 + aead_givcrypt_set_tfm(req, aead); 93 + return req; 94 + } 95 + 96 + static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv) 97 + { 98 + struct aead_request *req; 99 + 100 + req = (void *)PTR_ALIGN(iv + crypto_aead_ivsize(aead), 101 + crypto_tfm_ctx_alignment()); 102 + aead_request_set_tfm(req, aead); 103 + return req; 104 + } 105 + 106 + static inline struct scatterlist *esp_req_sg(struct crypto_aead *aead, 107 + struct aead_request *req) 108 + { 109 + return (void *)ALIGN((unsigned long)(req + 1) + 110 + crypto_aead_reqsize(aead), 111 + __alignof__(struct scatterlist)); 112 + } 113 + 114 + static inline struct scatterlist *esp_givreq_sg( 115 + struct crypto_aead *aead, struct aead_givcrypt_request *req) 116 + { 117 + return (void *)ALIGN((unsigned long)(req + 1) + 118 + crypto_aead_reqsize(aead), 119 + __alignof__(struct scatterlist)); 120 + } 121 + 122 + static void esp_output_done(struct crypto_async_request *base, int err) 123 + { 124 + struct sk_buff *skb = base->data; 125 + 126 + kfree(ESP_SKB_CB(skb)->tmp); 127 + xfrm_output_resume(skb, err); 128 + } 129 + 43 130 static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) 44 131 { 45 132 int err; 46 133 struct ip_esp_hdr *esph; 47 - struct crypto_blkcipher *tfm; 48 - struct blkcipher_desc desc; 134 + struct crypto_aead *aead; 135 + struct aead_givcrypt_request *req; 136 + struct scatterlist *sg; 137 + struct scatterlist *asg; 49 138 struct sk_buff *trailer; 139 + void *tmp; 50 140 int blksize; 51 141 int clen; 52 142 int alen; 53 143 int nfrags; 144 + u8 *iv; 54 145 u8 *tail; 55 146 struct esp_data *esp = x->data; 56 147 ··· 151 60 /* Round to block size */ 152 61 clen = skb->len; 153 62 154 - alen = esp->auth.icv_trunc_len; 155 - tfm = esp->conf.tfm; 156 - desc.tfm = tfm; 157 - desc.flags = 0; 158 - blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); 159 - clen = ALIGN(clen + 2, blksize); 160 - if (esp->conf.padlen) 161 - clen = ALIGN(clen, esp->conf.padlen); 63 + aead = esp->aead; 64 + alen = crypto_aead_authsize(aead); 162 65 163 - if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0) { 66 + blksize = ALIGN(crypto_aead_blocksize(aead), 4); 67 + clen = ALIGN(clen + 2, blksize); 68 + if (esp->padlen) 69 + clen = ALIGN(clen, esp->padlen); 70 + 71 + if ((err = skb_cow_data(skb, clen - skb->len + alen, &trailer)) < 0) 164 72 goto error; 165 - } 73 + nfrags = err; 74 + 75 + tmp = esp_alloc_tmp(aead, nfrags + 1); 76 + if (!tmp) 77 + goto error; 78 + 79 + iv = esp_tmp_iv(aead, tmp); 80 + req = esp_tmp_givreq(aead, iv); 81 + asg = esp_givreq_sg(aead, req); 82 + sg = asg + 1; 166 83 167 84 /* Fill padding... */ 168 85 tail = skb_tail_pointer(trailer); ··· 180 81 tail[i] = i + 1; 181 82 } while (0); 182 83 tail[clen-skb->len - 2] = (clen - skb->len) - 2; 183 - pskb_put(skb, trailer, clen - skb->len); 84 + tail[clen - skb->len - 1] = *skb_mac_header(skb); 85 + pskb_put(skb, trailer, clen - skb->len + alen); 184 86 185 87 skb_push(skb, -skb_network_offset(skb)); 186 88 esph = ip_esp_hdr(skb); 187 - *(skb_tail_pointer(trailer) - 1) = *skb_mac_header(skb); 188 89 *skb_mac_header(skb) = IPPROTO_ESP; 189 90 190 91 esph->spi = x->id.spi; 191 92 esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq); 192 93 193 - spin_lock_bh(&x->lock); 94 + sg_init_table(sg, nfrags); 95 + skb_to_sgvec(skb, sg, 96 + esph->enc_data + crypto_aead_ivsize(aead) - skb->data, 97 + clen + alen); 98 + sg_init_one(asg, esph, sizeof(*esph)); 194 99 195 - if (esp->conf.ivlen) { 196 - if (unlikely(!esp->conf.ivinitted)) { 197 - get_random_bytes(esp->conf.ivec, esp->conf.ivlen); 198 - esp->conf.ivinitted = 1; 199 - } 200 - crypto_blkcipher_set_iv(tfm, esp->conf.ivec, esp->conf.ivlen); 201 - } 100 + aead_givcrypt_set_callback(req, 0, esp_output_done, skb); 101 + aead_givcrypt_set_crypt(req, sg, sg, clen, iv); 102 + aead_givcrypt_set_assoc(req, asg, sizeof(*esph)); 103 + aead_givcrypt_set_giv(req, esph->enc_data, XFRM_SKB_CB(skb)->seq); 202 104 203 - do { 204 - struct scatterlist *sg = &esp->sgbuf[0]; 105 + ESP_SKB_CB(skb)->tmp = tmp; 106 + err = crypto_aead_givencrypt(req); 107 + if (err == -EINPROGRESS) 108 + goto error; 205 109 206 - if (unlikely(nfrags > ESP_NUM_FAST_SG)) { 207 - sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); 208 - if (!sg) 209 - goto unlock; 210 - } 211 - sg_init_table(sg, nfrags); 212 - skb_to_sgvec(skb, sg, 213 - esph->enc_data + 214 - esp->conf.ivlen - 215 - skb->data, clen); 216 - err = crypto_blkcipher_encrypt(&desc, sg, sg, clen); 217 - if (unlikely(sg != &esp->sgbuf[0])) 218 - kfree(sg); 219 - } while (0); 110 + if (err == -EBUSY) 111 + err = NET_XMIT_DROP; 220 112 221 - if (unlikely(err)) 222 - goto unlock; 223 - 224 - if (esp->conf.ivlen) { 225 - memcpy(esph->enc_data, esp->conf.ivec, esp->conf.ivlen); 226 - crypto_blkcipher_get_iv(tfm, esp->conf.ivec, esp->conf.ivlen); 227 - } 228 - 229 - if (esp->auth.icv_full_len) { 230 - err = esp_mac_digest(esp, skb, (u8 *)esph - skb->data, 231 - sizeof(*esph) + esp->conf.ivlen + clen); 232 - memcpy(pskb_put(skb, trailer, alen), esp->auth.work_icv, alen); 233 - } 234 - 235 - unlock: 236 - spin_unlock_bh(&x->lock); 113 + kfree(tmp); 237 114 238 115 error: 239 116 return err; 240 117 } 241 118 119 + static int esp_input_done2(struct sk_buff *skb, int err) 120 + { 121 + struct xfrm_state *x = xfrm_input_state(skb); 122 + struct esp_data *esp = x->data; 123 + struct crypto_aead *aead = esp->aead; 124 + int alen = crypto_aead_authsize(aead); 125 + int hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); 126 + int elen = skb->len - hlen; 127 + int hdr_len = skb_network_header_len(skb); 128 + int padlen; 129 + u8 nexthdr[2]; 130 + 131 + kfree(ESP_SKB_CB(skb)->tmp); 132 + 133 + if (unlikely(err)) 134 + goto out; 135 + 136 + if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) 137 + BUG(); 138 + 139 + err = -EINVAL; 140 + padlen = nexthdr[0]; 141 + if (padlen + 2 + alen >= elen) { 142 + LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage " 143 + "padlen=%d, elen=%d\n", padlen + 2, elen - alen); 144 + goto out; 145 + } 146 + 147 + /* ... check padding bits here. Silly. :-) */ 148 + 149 + pskb_trim(skb, skb->len - alen - padlen - 2); 150 + __skb_pull(skb, hlen); 151 + skb_set_transport_header(skb, -hdr_len); 152 + 153 + err = nexthdr[1]; 154 + 155 + /* RFC4303: Drop dummy packets without any error */ 156 + if (err == IPPROTO_NONE) 157 + err = -EINVAL; 158 + 159 + out: 160 + return err; 161 + } 162 + 163 + static void esp_input_done(struct crypto_async_request *base, int err) 164 + { 165 + struct sk_buff *skb = base->data; 166 + 167 + xfrm_input_resume(skb, esp_input_done2(skb, err)); 168 + } 169 + 242 170 static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) 243 171 { 244 - struct ipv6hdr *iph; 245 172 struct ip_esp_hdr *esph; 246 173 struct esp_data *esp = x->data; 247 - struct crypto_blkcipher *tfm = esp->conf.tfm; 248 - struct blkcipher_desc desc = { .tfm = tfm }; 174 + struct crypto_aead *aead = esp->aead; 175 + struct aead_request *req; 249 176 struct sk_buff *trailer; 250 - int blksize = ALIGN(crypto_blkcipher_blocksize(tfm), 4); 251 - int alen = esp->auth.icv_trunc_len; 252 - int elen = skb->len - sizeof(*esph) - esp->conf.ivlen - alen; 253 - int hdr_len = skb_network_header_len(skb); 177 + int elen = skb->len - sizeof(*esph) - crypto_aead_ivsize(aead); 254 178 int nfrags; 255 179 int ret = 0; 180 + void *tmp; 181 + u8 *iv; 182 + struct scatterlist *sg; 183 + struct scatterlist *asg; 256 184 257 185 if (!pskb_may_pull(skb, sizeof(*esph))) { 258 186 ret = -EINVAL; 259 187 goto out; 260 188 } 261 189 262 - if (elen <= 0 || (elen & (blksize-1))) { 190 + if (elen <= 0) { 263 191 ret = -EINVAL; 264 192 goto out; 265 193 } ··· 296 170 goto out; 297 171 } 298 172 299 - skb->ip_summed = CHECKSUM_NONE; 300 - 301 - spin_lock(&x->lock); 302 - 303 - /* If integrity check is required, do this. */ 304 - if (esp->auth.icv_full_len) { 305 - u8 sum[alen]; 306 - 307 - ret = esp_mac_digest(esp, skb, 0, skb->len - alen); 308 - if (ret) 309 - goto unlock; 310 - 311 - if (skb_copy_bits(skb, skb->len - alen, sum, alen)) 312 - BUG(); 313 - 314 - if (unlikely(memcmp(esp->auth.work_icv, sum, alen))) { 315 - ret = -EBADMSG; 316 - goto unlock; 317 - } 318 - } 319 - 320 - esph = (struct ip_esp_hdr *)skb->data; 321 - iph = ipv6_hdr(skb); 322 - 323 - /* Get ivec. This can be wrong, check against another impls. */ 324 - if (esp->conf.ivlen) 325 - crypto_blkcipher_set_iv(tfm, esph->enc_data, esp->conf.ivlen); 326 - 327 - { 328 - struct scatterlist *sg = &esp->sgbuf[0]; 329 - 330 - if (unlikely(nfrags > ESP_NUM_FAST_SG)) { 331 - sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); 332 - if (!sg) { 333 - ret = -ENOMEM; 334 - goto unlock; 335 - } 336 - } 337 - sg_init_table(sg, nfrags); 338 - skb_to_sgvec(skb, sg, 339 - sizeof(*esph) + esp->conf.ivlen, 340 - elen); 341 - ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen); 342 - if (unlikely(sg != &esp->sgbuf[0])) 343 - kfree(sg); 344 - } 345 - 346 - unlock: 347 - spin_unlock(&x->lock); 348 - 349 - if (unlikely(ret)) 173 + ret = -ENOMEM; 174 + tmp = esp_alloc_tmp(aead, nfrags + 1); 175 + if (!tmp) 350 176 goto out; 351 177 352 - { 353 - u8 nexthdr[2]; 354 - u8 padlen; 178 + ESP_SKB_CB(skb)->tmp = tmp; 179 + iv = esp_tmp_iv(aead, tmp); 180 + req = esp_tmp_req(aead, iv); 181 + asg = esp_req_sg(aead, req); 182 + sg = asg + 1; 355 183 356 - if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) 357 - BUG(); 184 + skb->ip_summed = CHECKSUM_NONE; 358 185 359 - padlen = nexthdr[0]; 360 - if (padlen+2 >= elen) { 361 - LIMIT_NETDEBUG(KERN_WARNING "ipsec esp packet is garbage padlen=%d, elen=%d\n", padlen+2, elen); 362 - ret = -EINVAL; 363 - goto out; 364 - } 365 - /* ... check padding bits here. Silly. :-) */ 186 + esph = (struct ip_esp_hdr *)skb->data; 366 187 367 - /* RFC4303: Drop dummy packets without any error */ 368 - if (nexthdr[1] == IPPROTO_NONE) { 369 - ret = -EINVAL; 370 - goto out; 371 - } 188 + /* Get ivec. This can be wrong, check against another impls. */ 189 + iv = esph->enc_data; 372 190 373 - pskb_trim(skb, skb->len - alen - padlen - 2); 374 - ret = nexthdr[1]; 375 - } 191 + sg_init_table(sg, nfrags); 192 + skb_to_sgvec(skb, sg, sizeof(*esph) + crypto_aead_ivsize(aead), elen); 193 + sg_init_one(asg, esph, sizeof(*esph)); 376 194 377 - __skb_pull(skb, sizeof(*esph) + esp->conf.ivlen); 378 - skb_set_transport_header(skb, -hdr_len); 195 + aead_request_set_callback(req, 0, esp_input_done, skb); 196 + aead_request_set_crypt(req, sg, sg, elen, iv); 197 + aead_request_set_assoc(req, asg, sizeof(*esph)); 198 + 199 + ret = crypto_aead_decrypt(req); 200 + if (ret == -EINPROGRESS) 201 + goto out; 202 + 203 + ret = esp_input_done2(skb, ret); 204 + 379 205 out: 380 206 return ret; 381 207 } ··· 335 257 static u32 esp6_get_mtu(struct xfrm_state *x, int mtu) 336 258 { 337 259 struct esp_data *esp = x->data; 338 - u32 blksize = ALIGN(crypto_blkcipher_blocksize(esp->conf.tfm), 4); 339 - u32 align = max_t(u32, blksize, esp->conf.padlen); 260 + u32 blksize = ALIGN(crypto_aead_blocksize(esp->aead), 4); 261 + u32 align = max_t(u32, blksize, esp->padlen); 340 262 u32 rem; 341 263 342 - mtu -= x->props.header_len + esp->auth.icv_trunc_len; 264 + mtu -= x->props.header_len + crypto_aead_authsize(esp->aead); 343 265 rem = mtu & (align - 1); 344 266 mtu &= ~(align - 1); 345 267 ··· 378 300 if (!esp) 379 301 return; 380 302 381 - crypto_free_blkcipher(esp->conf.tfm); 382 - esp->conf.tfm = NULL; 383 - kfree(esp->conf.ivec); 384 - esp->conf.ivec = NULL; 385 - crypto_free_hash(esp->auth.tfm); 386 - esp->auth.tfm = NULL; 387 - kfree(esp->auth.work_icv); 388 - esp->auth.work_icv = NULL; 303 + crypto_free_aead(esp->aead); 389 304 kfree(esp); 390 305 } 391 306 392 307 static int esp6_init_state(struct xfrm_state *x) 393 308 { 394 309 struct esp_data *esp = NULL; 395 - struct crypto_blkcipher *tfm; 310 + struct crypto_aead *aead; 311 + struct crypto_authenc_key_param *param; 312 + struct rtattr *rta; 313 + char *key; 314 + char *p; 315 + char authenc_name[CRYPTO_MAX_ALG_NAME]; 316 + u32 align; 317 + unsigned int keylen; 318 + int err; 396 319 397 320 if (x->ealg == NULL) 398 - goto error; 321 + return -EINVAL; 399 322 400 323 if (x->encap) 401 - goto error; 324 + return -EINVAL; 325 + 326 + if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME, "authenc(%s,%s)", 327 + x->aalg ? x->aalg->alg_name : "digest_null", 328 + x->ealg->alg_name) >= CRYPTO_MAX_ALG_NAME) 329 + return -ENAMETOOLONG; 402 330 403 331 esp = kzalloc(sizeof(*esp), GFP_KERNEL); 404 332 if (esp == NULL) 405 333 return -ENOMEM; 406 334 335 + x->data = esp; 336 + 337 + aead = crypto_alloc_aead(authenc_name, 0, 0); 338 + err = PTR_ERR(aead); 339 + if (IS_ERR(aead)) 340 + goto error; 341 + 342 + esp->aead = aead; 343 + 344 + keylen = (x->aalg ? (x->aalg->alg_key_len + 7) / 8 : 0) + 345 + (x->ealg->alg_key_len + 7) / 8 + RTA_SPACE(sizeof(*param)); 346 + err = -ENOMEM; 347 + key = kmalloc(keylen, GFP_KERNEL); 348 + if (!key) 349 + goto error; 350 + 351 + p = key; 352 + rta = (void *)p; 353 + rta->rta_type = CRYPTO_AUTHENC_KEYA_PARAM; 354 + rta->rta_len = RTA_LENGTH(sizeof(*param)); 355 + param = RTA_DATA(rta); 356 + p += RTA_SPACE(sizeof(*param)); 357 + 407 358 if (x->aalg) { 408 359 struct xfrm_algo_desc *aalg_desc; 409 - struct crypto_hash *hash; 410 360 411 - hash = crypto_alloc_hash(x->aalg->alg_name, 0, 412 - CRYPTO_ALG_ASYNC); 413 - if (IS_ERR(hash)) 414 - goto error; 415 - 416 - esp->auth.tfm = hash; 417 - if (crypto_hash_setkey(hash, x->aalg->alg_key, 418 - (x->aalg->alg_key_len + 7) / 8)) 419 - goto error; 361 + memcpy(p, x->aalg->alg_key, (x->aalg->alg_key_len + 7) / 8); 362 + p += (x->aalg->alg_key_len + 7) / 8; 420 363 421 364 aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0); 422 365 BUG_ON(!aalg_desc); 423 366 367 + err = -EINVAL; 424 368 if (aalg_desc->uinfo.auth.icv_fullbits/8 != 425 - crypto_hash_digestsize(hash)) { 369 + crypto_aead_authsize(aead)) { 426 370 NETDEBUG(KERN_INFO "ESP: %s digestsize %u != %hu\n", 427 371 x->aalg->alg_name, 428 - crypto_hash_digestsize(hash), 372 + crypto_aead_authsize(aead), 429 373 aalg_desc->uinfo.auth.icv_fullbits/8); 430 - goto error; 374 + goto free_key; 431 375 } 432 376 433 - esp->auth.icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8; 434 - esp->auth.icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8; 377 + err = crypto_aead_setauthsize( 378 + aead, aalg_desc->uinfo.auth.icv_truncbits / 8); 379 + if (err) 380 + goto free_key; 381 + } 435 382 436 - esp->auth.work_icv = kmalloc(esp->auth.icv_full_len, GFP_KERNEL); 437 - if (!esp->auth.work_icv) 438 - goto error; 439 - } 440 - tfm = crypto_alloc_blkcipher(x->ealg->alg_name, 0, CRYPTO_ALG_ASYNC); 441 - if (IS_ERR(tfm)) 383 + esp->padlen = 0; 384 + 385 + param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8); 386 + memcpy(p, x->ealg->alg_key, (x->ealg->alg_key_len + 7) / 8); 387 + 388 + err = crypto_aead_setkey(aead, key, keylen); 389 + 390 + free_key: 391 + kfree(key); 392 + 393 + if (err) 442 394 goto error; 443 - esp->conf.tfm = tfm; 444 - esp->conf.ivlen = crypto_blkcipher_ivsize(tfm); 445 - esp->conf.padlen = 0; 446 - if (esp->conf.ivlen) { 447 - esp->conf.ivec = kmalloc(esp->conf.ivlen, GFP_KERNEL); 448 - if (unlikely(esp->conf.ivec == NULL)) 449 - goto error; 450 - esp->conf.ivinitted = 0; 451 - } 452 - if (crypto_blkcipher_setkey(tfm, x->ealg->alg_key, 453 - (x->ealg->alg_key_len + 7) / 8)) 454 - goto error; 455 - x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; 395 + 396 + x->props.header_len = sizeof(struct ip_esp_hdr) + 397 + crypto_aead_ivsize(aead); 456 398 switch (x->props.mode) { 457 399 case XFRM_MODE_BEET: 458 400 case XFRM_MODE_TRANSPORT: ··· 483 385 default: 484 386 goto error; 485 387 } 486 - x->data = esp; 487 - return 0; 388 + 389 + align = ALIGN(crypto_aead_blocksize(aead), 4); 390 + if (esp->padlen) 391 + align = max_t(u32, align, esp->padlen); 392 + x->props.trailer_len = align + 1 + crypto_aead_authsize(esp->aead); 488 393 489 394 error: 490 - x->data = esp; 491 - esp6_destroy(x); 492 - x->data = NULL; 493 - return -EINVAL; 395 + return err; 494 396 } 495 397 496 398 static struct xfrm_type esp6_type =