summaryrefslogtreecommitdiff
path: root/cipher
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2014-12-21 17:36:59 +0200
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2014-12-23 12:51:36 +0200
commit11b8d2d449a7bc664b4371ae14c57caa6704d272 (patch)
tree1d222fffafb2169d8061fd215357a637c901cad2 /cipher
parentc964321c8a1328e89d636d899a45d68802f5ac9f (diff)
downloadlibgcrypt-11b8d2d449a7bc664b4371ae14c57caa6704d272.tar.gz
chacha20: allow setting counter for stream random access
* cipher/chacha20.c (CHACHA20_CTR_SIZE): New. (chacha20_ivsetup): Add setup for full counter. (chacha20_setiv): Allow ivlen == CHACHA20_CTR_SIZE. -- Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher')
-rw-r--r--cipher/chacha20.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/cipher/chacha20.c b/cipher/chacha20.c
index c1847aa5..2eaeffde 100644
--- a/cipher/chacha20.c
+++ b/cipher/chacha20.c
@@ -45,6 +45,7 @@
#define CHACHA20_BLOCK_SIZE 64 /* Bytes. */
#define CHACHA20_MIN_IV_SIZE 8 /* Bytes. */
#define CHACHA20_MAX_IV_SIZE 12 /* Bytes. */
+#define CHACHA20_CTR_SIZE 16 /* Bytes. */
#define CHACHA20_INPUT_LENGTH (CHACHA20_BLOCK_SIZE / 4)
/* USE_SSE2 indicates whether to compile with Intel SSE2 code. */
@@ -312,22 +313,30 @@ chacha20_keysetup (CHACHA20_context_t * ctx, const byte * key,
static void
chacha20_ivsetup (CHACHA20_context_t * ctx, const byte * iv, size_t ivlen)
{
- ctx->input[12] = 0;
-
- if (ivlen == CHACHA20_MAX_IV_SIZE)
+ if (ivlen == CHACHA20_CTR_SIZE)
+ {
+ ctx->input[12] = buf_get_le32 (iv + 0);
+ ctx->input[13] = buf_get_le32 (iv + 4);
+ ctx->input[14] = buf_get_le32 (iv + 8);
+ ctx->input[15] = buf_get_le32 (iv + 12);
+ }
+ else if (ivlen == CHACHA20_MAX_IV_SIZE)
{
+ ctx->input[12] = 0;
ctx->input[13] = buf_get_le32 (iv + 0);
ctx->input[14] = buf_get_le32 (iv + 4);
ctx->input[15] = buf_get_le32 (iv + 8);
}
else if (ivlen == CHACHA20_MIN_IV_SIZE)
{
+ ctx->input[12] = 0;
ctx->input[13] = 0;
ctx->input[14] = buf_get_le32 (iv + 0);
ctx->input[15] = buf_get_le32 (iv + 4);
}
else
{
+ ctx->input[12] = 0;
ctx->input[13] = 0;
ctx->input[14] = 0;
ctx->input[15] = 0;
@@ -402,10 +411,12 @@ chacha20_setiv (void *context, const byte * iv, size_t ivlen)
CHACHA20_context_t *ctx = (CHACHA20_context_t *) context;
/* draft-nir-cfrg-chacha20-poly1305-02 defines 96-bit and 64-bit nonce. */
- if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE)
+ if (iv && ivlen != CHACHA20_MAX_IV_SIZE && ivlen != CHACHA20_MIN_IV_SIZE
+ && ivlen != CHACHA20_CTR_SIZE)
log_info ("WARNING: chacha20_setiv: bad ivlen=%u\n", (u32) ivlen);
- if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE))
+ if (iv && (ivlen == CHACHA20_MAX_IV_SIZE || ivlen == CHACHA20_MIN_IV_SIZE
+ || ivlen == CHACHA20_CTR_SIZE))
chacha20_ivsetup (ctx, iv, ivlen);
else
chacha20_ivsetup (ctx, NULL, 0);