summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/chacha/chacha.c
diff options
context:
space:
mode:
authorjsing <>2014-06-24 18:12:09 +0000
committerjsing <>2014-06-24 18:12:09 +0000
commit125ab32227935a33d4c3ef80e58ed8f9d7cfbe8d (patch)
tree77b512bc366b09aa3f9194007a50fa04d944872c /src/lib/libcrypto/chacha/chacha.c
parent6769d1991fea1c3627ae6df2bf0232cba30798a8 (diff)
downloadopenbsd-125ab32227935a33d4c3ef80e58ed8f9d7cfbe8d.tar.gz
openbsd-125ab32227935a33d4c3ef80e58ed8f9d7cfbe8d.tar.bz2
openbsd-125ab32227935a33d4c3ef80e58ed8f9d7cfbe8d.zip
If a chacha operation does not consume all of the generated key stream,
ensure that we save it and consume it on subsequent writes. Otherwise we end up discarding part of the key stream and instead generate a new block at the start of the next write. This was only an issue for callers that did multiple writes that are not multiples of 64 bytes - in particular, the ChaCha20Poly1305 usage does not hit this problem since it performs encryption in a single-shot. For the same reason, this is also a non-issue when openssl(1) is used to encrypt with ChaCha. Issue identified by insane coder; reported to bugs@ by Joseph M. Schwartz. ok beck@
Diffstat (limited to 'src/lib/libcrypto/chacha/chacha.c')
-rw-r--r--src/lib/libcrypto/chacha/chacha.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/src/lib/libcrypto/chacha/chacha.c b/src/lib/libcrypto/chacha/chacha.c
index a12c824fe6..141b3e99f6 100644
--- a/src/lib/libcrypto/chacha/chacha.c
+++ b/src/lib/libcrypto/chacha/chacha.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: chacha.c,v 1.4 2014/06/12 15:49:28 deraadt Exp $ */ 1/* $OpenBSD: chacha.c,v 1.5 2014/06/24 18:12:09 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -22,6 +22,7 @@ void
22ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, uint32_t keybits) 22ChaCha_set_key(ChaCha_ctx *ctx, const unsigned char *key, uint32_t keybits)
23{ 23{
24 chacha_keysetup((chacha_ctx *)ctx, key, keybits); 24 chacha_keysetup((chacha_ctx *)ctx, key, keybits);
25 ctx->unused = 0;
25} 26}
26 27
27void 28void
@@ -29,11 +30,25 @@ ChaCha_set_iv(ChaCha_ctx *ctx, const unsigned char *iv,
29 const unsigned char *counter) 30 const unsigned char *counter)
30{ 31{
31 chacha_ivsetup((chacha_ctx *)ctx, iv, counter); 32 chacha_ivsetup((chacha_ctx *)ctx, iv, counter);
33 ctx->unused = 0;
32} 34}
33 35
34void 36void
35ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, size_t len) 37ChaCha(ChaCha_ctx *ctx, unsigned char *out, const unsigned char *in, size_t len)
36{ 38{
39 unsigned char *k;
40 int i, l;
41
42 /* Consume remaining keystream, if any exists. */
43 if (ctx->unused > 0) {
44 k = ctx->ks + 64 - ctx->unused;
45 l = (len > ctx->unused) ? ctx->unused : len;
46 for (i = 0; i < l; i++)
47 *(out++) = *(in++) ^ *(k++);
48 ctx->unused -= l;
49 len -= l;
50 }
51
37 chacha_encrypt_bytes((chacha_ctx *)ctx, in, out, (uint32_t)len); 52 chacha_encrypt_bytes((chacha_ctx *)ctx, in, out, (uint32_t)len);
38} 53}
39 54