summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-02-01 20:53:35 +0100
committerNiels Möller <nisse@lysator.liu.se>2018-02-01 20:53:35 +0100
commit4ff20685e5c640427bce89f8e2154a9bcd8503e8 (patch)
tree7e7482cbdbcdc0d73c7039cdfbd8585ffa3bf20f
parent3919ca296ed152801514ac18663b0aff27a3a9db (diff)
downloadnettle-4ff20685e5c640427bce89f8e2154a9bcd8503e8.tar.gz
gcm: use ctr_crypt16() for improved performance
-rw-r--r--ChangeLog6
-rw-r--r--gcm.c48
2 files changed, 21 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 4697be51..5643343a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-02-01 Nikos Mavrogiannopoulos <nmav@redhat.com>
+
+ * gcm.c (gcm_fill): New function, for use with _ctr_crypt16.
+ (gcm_encrypt, gcm_decrypt): Use _ctr_crypt16. 50% speedup of
+ gcm_aes128, benchmarked on x86_64 with aesni instructions.
+
2018-02-01 Niels Möller <nisse@lysator.liu.se>
Based on a patch contributed by Nikos Mavrogiannopoulos.
diff --git a/gcm.c b/gcm.c
index 0a2102f1..14a6181b 100644
--- a/gcm.c
+++ b/gcm.c
@@ -6,8 +6,9 @@
See also the gcm paper at
http://www.cryptobarn.com/papers/gcm-spec.pdf.
- Copyright (C) 2011, 2013 Niels Möller
Copyright (C) 2011 Katholieke Universiteit Leuven
+ Copyright (C) 2011, 2013, 2018 Niels Möller
+ Copyright (C) 2018 Red Hat, Inc.
Contributed by Nikos Mavrogiannopoulos
@@ -51,6 +52,7 @@
#include "memxor.h"
#include "nettle-internal.h"
#include "macros.h"
+#include "ctr-internal.h"
#define GHASH_POLYNOMIAL 0xE1UL
@@ -434,41 +436,21 @@ gcm_update(struct gcm_ctx *ctx, const struct gcm_key *key,
ctx->auth_size += length;
}
+static nettle_fill16_func gcm_fill;
static void
-gcm_crypt(struct gcm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
- size_t length, uint8_t *dst, const uint8_t *src)
+gcm_fill(uint8_t *ctr, size_t blocks, union nettle_block16 *buffer)
{
- uint8_t buffer[GCM_BLOCK_SIZE];
+ uint32_t c;
- if (src != dst)
- {
- for (; length >= GCM_BLOCK_SIZE;
- (length -= GCM_BLOCK_SIZE,
- src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE))
- {
- f (cipher, GCM_BLOCK_SIZE, dst, ctx->ctr.b);
- memxor (dst, src, GCM_BLOCK_SIZE);
- INC32 (ctx->ctr);
- }
- }
- else
- {
- for (; length >= GCM_BLOCK_SIZE;
- (length -= GCM_BLOCK_SIZE,
- src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE))
- {
- f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b);
- memxor (dst, buffer, GCM_BLOCK_SIZE);
- INC32 (ctx->ctr);
- }
- }
- if (length > 0)
+ c = READ_UINT32(ctr + GCM_BLOCK_SIZE - 4);
+
+ for (; blocks-- > 0; buffer++, c++)
{
- /* A final partial block */
- f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b);
- memxor3 (dst, src, buffer, length);
- INC32 (ctx->ctr);
+ memcpy(buffer->b, ctr, GCM_BLOCK_SIZE - 4);
+ WRITE_UINT32(buffer->b + GCM_BLOCK_SIZE - 4, c);
}
+
+ WRITE_UINT32(ctr + GCM_BLOCK_SIZE - 4, c);
}
void
@@ -478,7 +460,7 @@ gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key,
{
assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
- gcm_crypt(ctx, cipher, f, length, dst, src);
+ _ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src);
gcm_hash(key, &ctx->x, length, dst);
ctx->data_size += length;
@@ -492,7 +474,7 @@ gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
gcm_hash(key, &ctx->x, length, src);
- gcm_crypt(ctx, cipher, f, length, dst, src);
+ _ctr_crypt16(cipher, f, gcm_fill, ctx->ctr.b, length, dst, src);
ctx->data_size += length;
}