Hello! > Applied, thanks. > > Another fix for wrongly formatted ICV for ESP will follow > tonight after test for interoperability with freebsd. So, this piece is by Maxim. Bert, beware, it is required to talk to another stacks but breaks communication with linuxes before this patch. For log: authentication signature for MD5/SHA was not truncated to conform RFC. Side note: well, my fault, but damn common sense requires not to break nice good MD5 digest to some absolutely unmotivated length. Alexey ===== net/ipv4/esp.c 1.4 vs edited ===== --- 1.4/net/ipv4/esp.c Fri Nov 8 11:34:37 2002 +++ edited/net/ipv4/esp.c Wed Nov 13 03:00:52 2002 @@ -190,11 +190,10 @@ struct crypto_tfm *tfm = esp->auth.tfm; char *digest = esp->auth.work_digest; - memset(auth_data, 0, esp->auth.authlen); crypto_hmac_init(tfm, esp->auth.key, &esp->auth.key_len); skb_digest_walk(skb, tfm, offset, len); crypto_hmac_final(tfm, esp->auth.key, &esp->auth.key_len, digest); - memcpy(auth_data, digest, crypto_tfm_alg_digestsize(tfm)); + memcpy(auth_data, digest, esp->auth.authlen); } /* Check that skb data bits are writable. If they are not, copy data @@ -463,16 +462,16 @@ /* If integrity check is required, do this. */ if (esp->auth.authlen) { - int icvsize = crypto_tfm_alg_digestsize(esp->auth.tfm); - u8 sum[icvsize]; - u8 sum1[icvsize]; + u8 sum[esp->auth.authlen]; + u8 sum1[esp->auth.authlen]; esp->auth.digest(esp, skb, 0, skb->len-esp->auth.authlen, sum); - if (skb_copy_bits(skb, skb->len-esp->auth.authlen, sum1, icvsize)) + if (skb_copy_bits(skb, skb->len-esp->auth.authlen, sum1, + esp->auth.authlen)) BUG(); - if (unlikely(memcmp(sum, sum1, icvsize))) { + if (unlikely(memcmp(sum, sum1, esp->auth.authlen))) { x->stats.integrity_failed++; goto out; } @@ -605,14 +604,20 @@ memset(esp, 0, sizeof(*esp)); if (x->aalg) { + int digestsize; + esp->auth.key = x->aalg->alg_key; esp->auth.key_len = (x->aalg->alg_key_len+7)/8; esp->auth.tfm = crypto_alloc_tfm(x->aalg->alg_name, 0); if (esp->auth.tfm == NULL) goto error; esp->auth.digest = esp_hmac_digest; - esp->auth.authlen = crypto_tfm_alg_digestsize(esp->auth.tfm); - esp->auth.work_digest = kmalloc(esp->auth.authlen, GFP_KERNEL); + digestsize = crypto_tfm_alg_digestsize(esp->auth.tfm); + /* XXX RFC2403 and RFC 2404 truncate auth to 96 bit */ + esp->auth.authlen = 12; + if (esp->auth.authlen > digestsize) /* XXX */ + BUG(); + esp->auth.work_digest = kmalloc(digestsize, GFP_KERNEL); if (!esp->auth.work_digest) goto error; }