diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-04-03 16:19:44 +0200 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2017-04-04 03:44:35 +0200 |
commit | 9917f5821ce8e99d64731f9df891a6879d9f88f1 (patch) | |
tree | 076e0335d229e3d5e4bb932c1802a77de3483ad1 /src/crypto | |
parent | locking: always use _bh (diff) | |
download | wireguard-monolithic-historical-9917f5821ce8e99d64731f9df891a6879d9f88f1.tar.xz wireguard-monolithic-historical-9917f5821ce8e99d64731f9df891a6879d9f88f1.zip |
chacha20poly1305: check return values of sgops
Diffstat (limited to 'src/crypto')
-rw-r--r-- | src/crypto/chacha20poly1305.c | 24 | ||||
-rw-r--r-- | src/crypto/chacha20poly1305.h | 2 |
2 files changed, 17 insertions, 9 deletions
diff --git a/src/crypto/chacha20poly1305.c b/src/crypto/chacha20poly1305.c index 9cc1305..d0fbe1c 100644 --- a/src/crypto/chacha20poly1305.c +++ b/src/crypto/chacha20poly1305.c @@ -607,13 +607,14 @@ void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, chacha20poly1305_deinit_simd(have_simd); } -void chacha20poly1305_encrypt_sg(struct scatterlist *dst, struct scatterlist *src, const size_t src_len, +bool chacha20poly1305_encrypt_sg(struct scatterlist *dst, struct scatterlist *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, const u8 key[CHACHA20POLY1305_KEYLEN], bool have_simd) { struct poly1305_ctx poly1305_state; struct chacha20_ctx chacha20_state; + int ret = 0; struct blkcipher_walk walk; u8 block0[CHACHA20_BLOCK_SIZE] = { 0 }; u8 mac[POLY1305_MAC_SIZE]; @@ -631,19 +632,21 @@ void chacha20poly1305_encrypt_sg(struct scatterlist *dst, struct scatterlist *sr if (likely(src_len)) { blkcipher_walk_init(&walk, dst, src, src_len); - blkcipher_walk_virt_block(&chacha20_desc, &walk, CHACHA20_BLOCK_SIZE); + ret = blkcipher_walk_virt_block(&chacha20_desc, &walk, CHACHA20_BLOCK_SIZE); while (walk.nbytes >= CHACHA20_BLOCK_SIZE) { size_t chunk_len = rounddown(walk.nbytes, CHACHA20_BLOCK_SIZE); chacha20_crypt(&chacha20_state, walk.dst.virt.addr, walk.src.virt.addr, chunk_len, have_simd); poly1305_update(&poly1305_state, walk.dst.virt.addr, chunk_len, have_simd); - blkcipher_walk_done(&chacha20_desc, &walk, walk.nbytes % CHACHA20_BLOCK_SIZE); + ret = blkcipher_walk_done(&chacha20_desc, &walk, walk.nbytes % CHACHA20_BLOCK_SIZE); } if (walk.nbytes) { chacha20_crypt(&chacha20_state, walk.dst.virt.addr, walk.src.virt.addr, walk.nbytes, have_simd); poly1305_update(&poly1305_state, walk.dst.virt.addr, walk.nbytes, have_simd); - blkcipher_walk_done(&chacha20_desc, &walk, 0); + ret = blkcipher_walk_done(&chacha20_desc, &walk, 0); } } + if (unlikely(ret)) + goto err; poly1305_update(&poly1305_state, pad0, (0x10 - src_len) & 0xf, have_simd); @@ -655,9 +658,11 @@ void chacha20poly1305_encrypt_sg(struct scatterlist *dst, struct scatterlist *sr poly1305_finish(&poly1305_state, mac); scatterwalk_map_and_copy(mac, dst, src_len, sizeof(mac), 1); +err: memzero_explicit(&poly1305_state, sizeof(poly1305_state)); memzero_explicit(&chacha20_state, sizeof(chacha20_state)); memzero_explicit(mac, sizeof(mac)); + return !ret; } bool chacha20poly1305_decrypt(u8 *dst, const u8 *src, const size_t src_len, @@ -719,7 +724,7 @@ bool chacha20poly1305_decrypt_sg(struct scatterlist *dst, struct scatterlist *sr struct poly1305_ctx poly1305_state; struct chacha20_ctx chacha20_state; struct blkcipher_walk walk; - int ret; + int ret = 0; u8 block0[CHACHA20_BLOCK_SIZE] = { 0 }; u8 read_mac[POLY1305_MAC_SIZE], computed_mac[POLY1305_MAC_SIZE]; size_t dst_len; @@ -744,19 +749,21 @@ bool chacha20poly1305_decrypt_sg(struct scatterlist *dst, struct scatterlist *sr dst_len = src_len - POLY1305_MAC_SIZE; if (likely(dst_len)) { blkcipher_walk_init(&walk, dst, src, dst_len); - blkcipher_walk_virt_block(&chacha20_desc, &walk, CHACHA20_BLOCK_SIZE); + ret = blkcipher_walk_virt_block(&chacha20_desc, &walk, CHACHA20_BLOCK_SIZE); while (walk.nbytes >= CHACHA20_BLOCK_SIZE) { size_t chunk_len = rounddown(walk.nbytes, CHACHA20_BLOCK_SIZE); poly1305_update(&poly1305_state, walk.src.virt.addr, chunk_len, have_simd); chacha20_crypt(&chacha20_state, walk.dst.virt.addr, walk.src.virt.addr, chunk_len, have_simd); - blkcipher_walk_done(&chacha20_desc, &walk, walk.nbytes % CHACHA20_BLOCK_SIZE); + ret = blkcipher_walk_done(&chacha20_desc, &walk, walk.nbytes % CHACHA20_BLOCK_SIZE); } if (walk.nbytes) { poly1305_update(&poly1305_state, walk.src.virt.addr, walk.nbytes, have_simd); chacha20_crypt(&chacha20_state, walk.dst.virt.addr, walk.src.virt.addr, walk.nbytes, have_simd); - blkcipher_walk_done(&chacha20_desc, &walk, 0); + ret = blkcipher_walk_done(&chacha20_desc, &walk, 0); } } + if (unlikely(ret)) + goto err; poly1305_update(&poly1305_state, pad0, (0x10 - dst_len) & 0xf, have_simd); @@ -771,6 +778,7 @@ bool chacha20poly1305_decrypt_sg(struct scatterlist *dst, struct scatterlist *sr scatterwalk_map_and_copy(read_mac, src, dst_len, POLY1305_MAC_SIZE, 0); ret = crypto_memneq(read_mac, computed_mac, POLY1305_MAC_SIZE); +err: memzero_explicit(read_mac, POLY1305_MAC_SIZE); memzero_explicit(computed_mac, POLY1305_MAC_SIZE); memzero_explicit(&chacha20_state, sizeof(chacha20_state)); diff --git a/src/crypto/chacha20poly1305.h b/src/crypto/chacha20poly1305.h index 76b76d2..b881c82 100644 --- a/src/crypto/chacha20poly1305.h +++ b/src/crypto/chacha20poly1305.h @@ -19,7 +19,7 @@ void chacha20poly1305_encrypt(u8 *dst, const u8 *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, const u8 key[CHACHA20POLY1305_KEYLEN]); -void chacha20poly1305_encrypt_sg(struct scatterlist *dst, struct scatterlist *src, const size_t src_len, +bool __must_check chacha20poly1305_encrypt_sg(struct scatterlist *dst, struct scatterlist *src, const size_t src_len, const u8 *ad, const size_t ad_len, const u64 nonce, const u8 key[CHACHA20POLY1305_KEYLEN], bool have_simd); |