]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Add shared helper functions for ocb_encrypt and ocb_decrypt.
authorNiels Möller <nisse@lysator.liu.se>
Wed, 25 Jan 2023 13:07:12 +0000 (14:07 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Mon, 6 Feb 2023 19:23:08 +0000 (20:23 +0100)
ChangeLog
ocb.c

index 54aa427889092ef2d25ae8d6b80485858582dba3..04b1da4d4a028268b255cdcd22542eb9641d7891 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
 
 2023-01-25  Niels Möller  <nisse@lysator.liu.se>
 
+       * ocb.c (ocb_crypt_n, ocb_checksum_n): New functions, processing
+       complete blocks.
+       (ocb_encrypt, ocb_decrypt): Use new functions.
+
        * testsuite/ocb-test.c (test_main): Add tests with larger messages.
 
        * examples/nettle-benchmark.c (main): Benchmark ocb_aes128.
diff --git a/ocb.c b/ocb.c
index c2b524cd61d8d76f00ec7f8ecec062f1361327f0..aab6b6b22a69b2832cd1b0cf44b5a632f8533c92 100644 (file)
--- a/ocb.c
+++ b/ocb.c
@@ -159,36 +159,55 @@ ocb_update (struct ocb_ctx *ctx, const struct ocb_key *key,
     }
 }
 
-void
-ocb_encrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
+/* Process n complete blocks (encrypt or decrypt, checksum left to caller). */
+static void
+ocb_crypt_n (struct ocb_ctx *ctx, const struct ocb_key *key,
             const void *cipher, nettle_cipher_func *f,
-            size_t length, uint8_t *dst, const uint8_t *src)
+            size_t n, uint8_t *dst, const uint8_t *src)
 {
-  if (ctx->message_count == 0)
-    ctx->offset = ctx->initial;
-
-  for (; length >= OCB_BLOCK_SIZE;
-       length -= OCB_BLOCK_SIZE, src += OCB_BLOCK_SIZE, dst += OCB_BLOCK_SIZE)
+  for (; n > 0; n--, src += OCB_BLOCK_SIZE, dst += OCB_BLOCK_SIZE)
     {
       union nettle_block16 block;
-      memxor (ctx->checksum.b, src, OCB_BLOCK_SIZE);
       update_offset (key, &ctx->offset, ++ctx->message_count);
 
       memxor3 (block.b, ctx->offset.b, src, OCB_BLOCK_SIZE);
       f (cipher, OCB_BLOCK_SIZE, block.b, block.b);
-
       memxor3 (dst, ctx->offset.b, block.b, OCB_BLOCK_SIZE);
     }
+}
+
+/* Checksum of n complete blocks. */
+static void
+ocb_checksum_n (union nettle_block16 *checksum,
+               size_t n, const uint8_t *src)
+{
+  for (; n > 0; n--, src += OCB_BLOCK_SIZE)
+    memxor (checksum->b, src, OCB_BLOCK_SIZE);
+}
+
+void
+ocb_encrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
+            const void *cipher, nettle_cipher_func *f,
+            size_t length, uint8_t *dst, const uint8_t *src)
+{
+  size_t n = length / OCB_BLOCK_SIZE;
+
+  if (ctx->message_count == 0)
+    ctx->offset = ctx->initial;
 
+  ocb_checksum_n (&ctx->checksum, n, src);
+  ocb_crypt_n (ctx, key, cipher, f, n, dst, src);
+
+  length &= 15;
   if (length > 0)
     {
       union nettle_block16 block;
-      pad_block (&block, length, src);
+      pad_block (&block, length, src + n*OCB_BLOCK_SIZE);
       block16_xor (&ctx->checksum, &block);
 
       block16_xor (&ctx->offset, &key->L[0]);
       f (cipher, OCB_BLOCK_SIZE, block.b, ctx->offset.b);
-      memxor3 (dst, block.b, src, length);
+      memxor3 (dst + n*OCB_BLOCK_SIZE, block.b, src, length);
       ctx->message_count++;
     }
 }
@@ -199,26 +218,21 @@ ocb_decrypt (struct ocb_ctx *ctx, const struct ocb_key *key,
             const void *decrypt_ctx, nettle_cipher_func *decrypt,
             size_t length, uint8_t *dst, const uint8_t *src)
 {
+  size_t n = length / OCB_BLOCK_SIZE;
+
   if (ctx->message_count == 0)
     ctx->offset = ctx->initial;
 
-  for (; length >= OCB_BLOCK_SIZE;
-       length -= OCB_BLOCK_SIZE, src += OCB_BLOCK_SIZE, dst += OCB_BLOCK_SIZE)
-    {
-      union nettle_block16 block;
-      update_offset (key, &ctx->offset, ++ctx->message_count);
-
-      memxor3 (block.b, ctx->offset.b, src, OCB_BLOCK_SIZE);
-      decrypt (decrypt_ctx, OCB_BLOCK_SIZE, block.b, block.b);
-
-      memxor3 (dst, ctx->offset.b, block.b, OCB_BLOCK_SIZE);
-      memxor (ctx->checksum.b, dst, OCB_BLOCK_SIZE);
-    }
+  ocb_crypt_n (ctx, key, decrypt_ctx, decrypt, n, dst, src);
+  ocb_checksum_n (&ctx->checksum, n, dst);
 
+  length &= 15;
   if (length > 0)
     {
       union nettle_block16 block;
 
+      src += n*OCB_BLOCK_SIZE; dst += n*OCB_BLOCK_SIZE;
+
       block16_xor (&ctx->offset, &key->L[0]);
       encrypt (encrypt_ctx, OCB_BLOCK_SIZE, block.b, ctx->offset.b);
       memxor3 (dst, block.b, src, length);