Message ID | 20171211201517.46407-1-ebiggers3@gmail.com (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Herbert Xu |
Headers | show |
On Mon, Dec 11, 2017 at 12:15:17PM -0800, Eric Biggers wrote: > From: Eric Biggers <ebiggers@google.com> > > If the rfc7539 template was instantiated with a hash algorithm with > digest size larger than 16 bytes (POLY1305_DIGEST_SIZE), then the digest > overran the 'tag' buffer in 'struct chachapoly_req_ctx', corrupting the > subsequent memory, including 'cryptlen'. This caused a crash during > crypto_skcipher_decrypt(). > > Fix it by, when instantiating the template, requiring that the > underlying hash algorithm has the digest size expected for Poly1305. > > Reproducer: > > #include <linux/if_alg.h> > #include <sys/socket.h> > #include <unistd.h> > > int main() > { > int algfd, reqfd; > struct sockaddr_alg addr = { > .salg_type = "aead", > .salg_name = "rfc7539(chacha20,sha256)", > }; > unsigned char buf[32] = { 0 }; > > algfd = socket(AF_ALG, SOCK_SEQPACKET, 0); > bind(algfd, (void *)&addr, sizeof(addr)); > setsockopt(algfd, SOL_ALG, ALG_SET_KEY, buf, sizeof(buf)); > reqfd = accept(algfd, 0, 0); > write(reqfd, buf, 16); > read(reqfd, buf, 16); > } > > Reported-by: syzbot <syzkaller@googlegroups.com> > Fixes: 71ebc4d1b27d ("crypto: chacha20poly1305 - Add a ChaCha20-Poly1305 AEAD construction, RFC7539") > Cc: <stable@vger.kernel.org> # v4.2+ > Signed-off-by: Eric Biggers <ebiggers@google.com> Patch applied. Thanks.
diff --git a/crypto/chacha20poly1305.c b/crypto/chacha20poly1305.c index db1bc3147bc4..600afa99941f 100644 --- a/crypto/chacha20poly1305.c +++ b/crypto/chacha20poly1305.c @@ -610,6 +610,11 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, algt->mask)); if (IS_ERR(poly)) return PTR_ERR(poly); + poly_hash = __crypto_hash_alg_common(poly); + + err = -EINVAL; + if (poly_hash->digestsize != POLY1305_DIGEST_SIZE) + goto out_put_poly; err = -ENOMEM; inst = kzalloc(sizeof(*inst) + sizeof(*ctx), GFP_KERNEL); @@ -618,7 +623,6 @@ static int chachapoly_create(struct crypto_template *tmpl, struct rtattr **tb, ctx = aead_instance_ctx(inst); ctx->saltlen = CHACHAPOLY_IV_SIZE - ivsize; - poly_hash = __crypto_hash_alg_common(poly); err = crypto_init_ahash_spawn(&ctx->poly, poly_hash, aead_crypto_instance(inst)); if (err)