diff options
author | Niels Möller <nisse@lysator.liu.se> | 2021-09-18 10:00:02 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2023-02-06 20:20:01 +0100 |
commit | c05ab7d805a2b45fd00979c18145c95fca47ecdb (patch) | |
tree | f33bfd27e2eb459fea49c2668cbc5c5f4d7b50c1 | |
parent | eb48e209db6fb6d6ce0005de88ba362b6fcbe933 (diff) | |
download | nettle-c05ab7d805a2b45fd00979c18145c95fca47ecdb.tar.gz |
Implement OCB mode
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | Makefile.in | 3 | ||||
-rw-r--r-- | nettle-meta.h | 1 | ||||
-rw-r--r-- | ocb-aes128-meta.c | 110 | ||||
-rw-r--r-- | ocb.c | 256 | ||||
-rw-r--r-- | ocb.h | 106 | ||||
-rw-r--r-- | testsuite/Makefile.in | 2 | ||||
-rw-r--r-- | testsuite/ocb-test.c | 147 |
8 files changed, 637 insertions, 2 deletions
@@ -714,6 +714,20 @@ * nettle.texinfo: Delete explicit node pointers in nettle.texinfo Instead, rely on makeinfo's automatic pointer creation. (Cipher functions): Split into nodes, with proper menu. +2021-09-18 Niels Möller <nisse@lysator.liu.se> + + Implement OCB mode. RFC 7253. + * ocb.c (ocb_set_key, ocb_set_nonce, ocb_update, ocb_encrypt) + (ocb_decrypt, ocb_digest): New file and functions. + * ocb.h: Corresponding header file. + * ocb-aes128-meta.c (nettle_ocb_aes128): New aead struct. + * Makefile.in (nettle_SOURCES): Add new source files. + (HEADERS): Add ocb.h. + * testsuite/ocb-test.c: New tests. + * testsuite/Makefile.in (TS_NETTLE_SOURCES): Add ocb-test.c + + * testsuite/testutils.c (test_aead): Check plaintext/ciphertext + before checking digest. 2021-09-14 Niels Möller <nisse@lysator.liu.se> diff --git a/Makefile.in b/Makefile.in index cd4993e8..4f4242e0 100644 --- a/Makefile.in +++ b/Makefile.in @@ -134,6 +134,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c aes-decrypt-table.c \ nettle-lookup-hash.c \ nettle-meta-aeads.c nettle-meta-armors.c \ nettle-meta-ciphers.c nettle-meta-hashes.c nettle-meta-macs.c \ + ocb.c ocb-aes128-meta.c \ pbkdf2.c pbkdf2-hmac-gosthash94.c pbkdf2-hmac-sha1.c \ pbkdf2-hmac-sha256.c pbkdf2-hmac-sha384.c pbkdf2-hmac-sha512.c \ poly1305-aes.c poly1305-internal.c poly1305-update.c \ @@ -238,7 +239,7 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h balloon.h \ md5.h md5-compat.h \ memops.h memxor.h \ nettle-meta.h nettle-types.h \ - pbkdf2.h \ + ocb.h pbkdf2.h \ pgp.h pkcs1.h pss.h pss-mgf1.h realloc.h ripemd160.h rsa.h \ salsa20.h sexp.h serpent.h \ sha.h sha1.h sha2.h sha3.h sm3.h sm4.h streebog.h twofish.h \ diff --git a/nettle-meta.h b/nettle-meta.h index 19dc96c5..2b548d7a 100644 --- a/nettle-meta.h +++ b/nettle-meta.h @@ -203,6 +203,7 @@ extern const struct nettle_aead nettle_gcm_camellia256; extern const struct nettle_aead nettle_gcm_sm4; extern const struct nettle_aead nettle_eax_aes128; extern const struct nettle_aead nettle_chacha_poly1305; +extern const struct nettle_aead nettle_ocb_aes128; /* With 128-bit tag */ struct nettle_armor { diff --git a/ocb-aes128-meta.c b/ocb-aes128-meta.c new file mode 100644 index 00000000..efd94a9c --- /dev/null +++ b/ocb-aes128-meta.c @@ -0,0 +1,110 @@ +/* ocb-aes128-meta.c + + Copyright (C) 2021 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aes.h" +#include "ocb.h" +#include "nettle-meta.h" + +#define OCB_IV_SIZE 12 + +struct ocb_aes128_ctx +{ + struct ocb_key key; + struct ocb_ctx ocb; + struct aes128_ctx encrypt; + struct aes128_ctx decrypt; +}; + +static void +ocb_aes128_set_key (struct ocb_aes128_ctx *ctx, const uint8_t *key) +{ + aes128_set_encrypt_key (&ctx->encrypt, key); + aes128_set_decrypt_key (&ctx->decrypt, key); + ocb_set_key (&ctx->key, &ctx->encrypt, (nettle_cipher_func *) aes128_encrypt); +} + +static void +ocb_aes128_set_nonce (struct ocb_aes128_ctx *ctx, + const uint8_t *iv) +{ + ocb_set_nonce (&ctx->ocb, &ctx->encrypt, (nettle_cipher_func *) aes128_encrypt, + OCB_DIGEST_SIZE, OCB_IV_SIZE, iv); +} + +static void +ocb_aes128_update (struct ocb_aes128_ctx *ctx, + size_t length, const uint8_t *data) +{ + ocb_update (&ctx->ocb, &ctx->key, &ctx->encrypt, (nettle_cipher_func *) aes128_encrypt, + length, data); +} + +static void +ocb_aes128_encrypt(struct ocb_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ocb_encrypt (&ctx->ocb, &ctx->key, &ctx->encrypt, (nettle_cipher_func *) aes128_encrypt, + length, dst, src); +} + +static void +ocb_aes128_decrypt(struct ocb_aes128_ctx *ctx, + size_t length, uint8_t *dst, const uint8_t *src) +{ + ocb_decrypt (&ctx->ocb, &ctx->key, &ctx->encrypt, (nettle_cipher_func *) aes128_encrypt, + &ctx->decrypt, (nettle_cipher_func *) aes128_decrypt, + length, dst, src); +} + +static void +ocb_aes128_digest(struct ocb_aes128_ctx *ctx, size_t length, uint8_t *digest) +{ + ocb_digest (&ctx->ocb, &ctx->key, &ctx->encrypt, (nettle_cipher_func *) aes128_encrypt, + length, digest); +} + +const struct nettle_aead +nettle_ocb_aes128 = + { "ocb_aes128", sizeof(struct ocb_aes128_ctx), + OCB_BLOCK_SIZE, AES128_KEY_SIZE, + OCB_IV_SIZE, OCB_DIGEST_SIZE, + (nettle_set_key_func *) ocb_aes128_set_key, + (nettle_set_key_func *) ocb_aes128_set_key, + (nettle_set_key_func *) ocb_aes128_set_nonce, + (nettle_hash_update_func *) ocb_aes128_update, + (nettle_crypt_func *) ocb_aes128_encrypt, + (nettle_crypt_func *) ocb_aes128_decrypt, + (nettle_hash_digest_func *) ocb_aes128_digest + }; @@ -0,0 +1,256 @@ +/* ocb.c + + OCB AEAD mode, RFC 7253 + + Copyright (C) 2021 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <string.h> + +#include "ocb.h" +#include "block-internal.h" + +/* Returns 64 bits from the concatenation (u0, u1), starting from bit offset. */ +static inline uint64_t +extract(uint64_t u0, uint64_t u1, unsigned offset) +{ + if (offset == 0) + return u0; +#if WORDS_BIGENDIAN + return (u0 << offset) | (u1 >> (64 - offset)); +#else + uint64_t t; + u0 = __builtin_bswap64(u0); + u1 = __builtin_bswap64(u1); + t = (u0 << offset) | (u1 >> (64 - offset)); + return __builtin_bswap64(t); +#endif +} + +void +ocb_set_key (struct ocb_key *key, const void *cipher, nettle_cipher_func *f) +{ + static const union nettle_block16 zero_block; + f (cipher, OCB_BLOCK_SIZE, key->L[0].b, zero_block.b); + block16_mulx_be (&key->L[1], &key->L[0]); + block16_mulx_be (&key->L[2], &key->L[1]); +} + +static void +update_offset(const struct ocb_key *key, + union nettle_block16 *offset, size_t i) +{ + unsigned ntz = __builtin_ctzll(i); + if (ntz > 0) + { + union nettle_block16 diff; + block16_mulx_be (&diff, &key->L[2]); + while (--ntz > 0) + block16_mulx_be (&diff, &diff); + + block16_xor (offset, &diff); + } + else + block16_xor (offset, &key->L[2]); +} + +static void +pad_block (union nettle_block16 *block, size_t length, const uint8_t *data) +{ + memcpy (block->b, data, length); + block->b[length] = 0x80; + memset (block->b + length + 1, 0, OCB_BLOCK_SIZE - 1 - length); +} + +void +ocb_set_nonce (struct ocb_ctx *ctx, + const void *cipher, nettle_cipher_func *f, + size_t tag_length, + size_t nonce_length, const uint8_t *nonce) +{ + union nettle_block16 top; + uint64_t stretch; + + unsigned bottom; + assert (nonce_length < 16); + assert (tag_length > 0); + assert (tag_length <= 16); + + /* Bit size, or zero for tag_length == 16 */ + top.b[0] = (tag_length & 15) << 4; + memset (top.b + 1, 0, 15 - nonce_length); + top.b[15 - nonce_length] |= 1; + memcpy (top.b + 16 - nonce_length, nonce, nonce_length); + bottom = top.b[15] & 0x3f; + top.b[15] &= 0xc0; + + f (cipher, OCB_BLOCK_SIZE, top.b, top.b); + + stretch = top.u64[0]; +#if WORDS_BIGENDIAN + stretch ^= (top.u64[0] << 8) | (top.u64[1] >> 56); +#else + stretch ^= (top.u64[0] >> 8) | (top.u64[1] << 56); +#endif + + ctx->initial.u64[0] = extract(top.u64[0], top.u64[1], bottom); + ctx->initial.u64[1] = extract(top.u64[1], stretch, bottom); + ctx->sum.u64[0] = ctx->sum.u64[1] = 0; + ctx->checksum.u64[0] = ctx->checksum.u64[1] = 0; + + ctx->data_count = ctx->message_count = 0; +} + +void +ocb_update (struct ocb_ctx *ctx, const struct ocb_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *data) +{ + if (data == 0) + return; + + assert (ctx->message_count == 0); + + if (ctx->data_count == 0) + ctx->offset.u64[0] = ctx->offset.u64[1] = 0; + + for (; length >= OCB_BLOCK_SIZE; + length -= OCB_BLOCK_SIZE, data += OCB_BLOCK_SIZE) + { + union nettle_block16 block; + update_offset (key, &ctx->offset, ++ctx->data_count); + memxor3 (block.b, ctx->offset.b, data, OCB_BLOCK_SIZE); + f (cipher, OCB_BLOCK_SIZE, block.b, block.b); + block16_xor (&ctx->sum, &block); + } + if (length > 0) + { + union nettle_block16 block; + pad_block (&block, length, data); + block16_xor (&ctx->offset, &key->L[0]); + block16_xor (&block, &ctx->offset); + + f (cipher, OCB_BLOCK_SIZE, block.b, block.b); + block16_xor (&ctx->sum, &block); + } +} + +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) +{ + if (length == 0) + return; + + 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; + 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); + } + + if (length > 0) + { + union nettle_block16 block; + pad_block (&block, length, src); + 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); + ctx->message_count++; + } +} + +void +ocb_decrypt (struct ocb_ctx *ctx, const struct ocb_key *key, + const void *encrypt_ctx, nettle_cipher_func *encrypt, + const void *decrypt_ctx, nettle_cipher_func *decrypt, + size_t length, uint8_t *dst, const uint8_t *src) +{ + if (length == 0) + return; + + 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); + } + + if (length > 0) + { + union nettle_block16 block; + + block16_xor (&ctx->offset, &key->L[0]); + encrypt (encrypt_ctx, OCB_BLOCK_SIZE, block.b, ctx->offset.b); + memxor3 (dst, block.b, src, length); + + pad_block (&block, length, dst); + block16_xor (&ctx->checksum, &block); + ctx->message_count++; + } +} + +void +ocb_digest (struct ocb_ctx *ctx, const struct ocb_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest) +{ + union nettle_block16 block; + assert (length <= OCB_DIGEST_SIZE); + block16_xor3 (&block, &key->L[1], + (ctx->message_count > 0) ? &ctx->offset : &ctx->initial); + block16_xor (&block, &ctx->checksum); + f (cipher, OCB_BLOCK_SIZE, block.b, block.b); + memxor3 (digest, block.b, ctx->sum.b, length); +} @@ -0,0 +1,106 @@ +/* ocb.h + + OCB AEAD mode, RFC 7253 + + Copyright (C) 2021 Niels Möller + + This file is part of GNU Nettle. + + GNU Nettle is free software: you can redistribute it and/or + modify it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + + or + + * the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your + option) any later version. + + or both in parallel, as here. + + GNU Nettle is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received copies of the GNU General Public License and + the GNU Lesser General Public License along with this program. If + not, see http://www.gnu.org/licenses/. +*/ + +#ifndef NETTLE_OCB_H_INCLUDED +#define NETTLE_OCB_H_INCLUDED + +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Name mangling */ +#define ocb_set_key nettle_ocb_set_key +#define ocb_set_nonce nettle_ocb_set_nonce +#define ocb_update nettle_ocb_update +#define ocb_encrypt nettle_ocb_encrypt +#define ocb_decrypt nettle_ocb_decrypt +#define ocb_digest nettle_ocb_digest + +#define OCB_BLOCK_SIZE 16 +#define OCB_DIGEST_SIZE 16 + +struct ocb_key { + /* L_*, L_$ and L_0 */ + union nettle_block16 L[3]; +}; + +struct ocb_ctx { + /* Initial offset, Offset_0 in the spec. */ + union nettle_block16 initial; + /* Offset, updated per block. */ + union nettle_block16 offset; + /* Authentication for the associated data */ + union nettle_block16 sum; + /* Authentication for the message */ + union nettle_block16 checksum; + /* Count of processed blocks. */ + size_t data_count; + size_t message_count; +}; + +void +ocb_set_key (struct ocb_key *key, const void *cipher, nettle_cipher_func *f); + +void +ocb_set_nonce (struct ocb_ctx *ctx, + const void *cipher, nettle_cipher_func *f, + size_t tag_length, size_t nonce_length, const uint8_t *nonce); + +void +ocb_update (struct ocb_ctx *ctx, const struct ocb_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, const uint8_t *data); + +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); + +void +ocb_decrypt (struct ocb_ctx *ctx, const struct ocb_key *key, + const void *encrypt_ctx, nettle_cipher_func *encrypt, + const void *decrypt_ctx, nettle_cipher_func *decrypt, + size_t length, uint8_t *dst, const uint8_t *src); + +void +ocb_digest (struct ocb_ctx *ctx, const struct ocb_key *key, + const void *cipher, nettle_cipher_func *f, + size_t length, uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* NETTLE_OCB_H_INCLUDED */ diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 025ab72d..be0cb965 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -28,7 +28,7 @@ TS_NETTLE_SOURCES = aes-test.c aes-keywrap-test.c arcfour-test.c arctwo-test.c \ serpent-test.c twofish-test.c version-test.c \ knuth-lfib-test.c \ cbc-test.c cfb-test.c ctr-test.c gcm-test.c eax-test.c ccm-test.c \ - cmac-test.c siv-test.c siv-gcm-test.c \ + cmac-test.c ocb-test.c siv-test.c siv-gcm-test.c \ poly1305-test.c chacha-poly1305-test.c \ hmac-test.c umac-test.c \ meta-hash-test.c meta-cipher-test.c\ diff --git a/testsuite/ocb-test.c b/testsuite/ocb-test.c new file mode 100644 index 00000000..abeea714 --- /dev/null +++ b/testsuite/ocb-test.c @@ -0,0 +1,147 @@ +#include "testutils.h" +#include "nettle-internal.h" + +void +test_main(void) +{ + /* From RFC 7253 */ + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX(""), /* auth data */ + SHEX(""), /* plaintext */ + SHEX(""), /* ciphertext */ + SHEX("BBAA99887766554433221100"), /* nonce */ + SHEX("785407BFFFC8AD9EDCC5520AC9111EE6")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("0001020304050607"), /* auth data */ + SHEX("0001020304050607"), /* plaintext */ + SHEX("6820B3657B6F615A"), /* ciphertext */ + SHEX("BBAA99887766554433221101"), /* nonce */ + SHEX("5725BDA0D3B4EB3A257C9AF1F8F03009")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("0001020304050607"), /* auth data */ + SHEX(""), /* plaintext */ + SHEX(""), /* ciphertext */ + SHEX("BBAA99887766554433221102"), /* nonce */ + SHEX("81017F8203F081277152FADE694A0A00")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX(""), /* auth data */ + SHEX("0001020304050607"), /* plaintext */ + SHEX("45DD69F8F5AAE724"), /* ciphertext */ + SHEX("BBAA99887766554433221103"), /* nonce */ + SHEX("14054CD1F35D82760B2CD00D2F99BFA9")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F"), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F"), /* plaintext */ + SHEX("571D535B60B277188BE5147170A9A22C"), /* ciphertext */ + SHEX("BBAA99887766554433221104"), /* nonce */ + SHEX("3AD7A4FF3835B8C5701C1CCEC8FC3358")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F"), /* auth data */ + SHEX(""), /* plaintext */ + SHEX(""), /* ciphertext */ + SHEX("BBAA99887766554433221105"), /* nonce */ + SHEX("8CF761B6902EF764462AD86498CA6B97")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX(""), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F"), /* plaintext */ + SHEX("5CE88EC2E0692706A915C00AEB8B2396"), /* ciphertext */ + SHEX("BBAA99887766554433221106"), /* nonce */ + SHEX("F40E1C743F52436BDF06D8FA1ECA343D")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617"), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617"), /* plaintext */ + SHEX("1CA2207308C87C010756104D8840CE1952F09673A448A122"), /* ciphertext */ + SHEX("BBAA99887766554433221107"), /* nonce */ + SHEX("C92C62241051F57356D7F3C90BB0E07F")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617"), /* auth data */ + SHEX(""), /* plaintext */ + SHEX(""), /* ciphertext */ + SHEX("BBAA99887766554433221108"), /* nonce */ + SHEX("6DC225A071FC1B9F7C69F93B0F1E10DE")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX(""), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617"), /* plaintext */ + SHEX("221BD0DE7FA6FE993ECCD769460A0AF2D6CDED0C395B1C3C"), /* ciphertext */ + SHEX("BBAA99887766554433221109"), /* nonce */ + SHEX("E725F32494B9F914D85C0B1EB38357FF")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F"), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F"), /* plaintext */ + SHEX("BD6F6C496201C69296C11EFD138A467ABD3C707924B964DE" + "AFFC40319AF5A485"), /* ciphertext */ + SHEX("BBAA9988776655443322110A"), /* nonce */ + SHEX("40FBBA186C5553C68AD9F592A79A4240")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F"), /* auth data */ + SHEX(""), /* plaintext */ + SHEX(""), /* ciphertext */ + SHEX("BBAA9988776655443322110B"), /* nonce */ + SHEX("FE80690BEE8A485D11F32965BC9D2A32")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX(""), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F"), /* plaintext */ + SHEX("2942BFC773BDA23CABC6ACFD9BFD5835BD300F0973792EF4" + "6040C53F1432BCDF"), /* ciphertext */ + SHEX("BBAA9988776655443322110C"), /* nonce */ + SHEX("B5E1DDE3BC18A5F840B52E653444D5DF")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627"), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627"), /* plaintext */ + SHEX("D5CA91748410C1751FF8A2F618255B68A0A12E093FF45460" + "6E59F9C1D0DDC54B65E8628E568BAD7A"), /* ciphertext */ + SHEX("BBAA9988776655443322110D"), /* nonce */ + SHEX("ED07BA06A4A69483A7035490C5769E60")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627"), /* auth data */ + SHEX(""), /* plaintext */ + SHEX(""), /* ciphertext */ + SHEX("BBAA9988776655443322110E"), /* nonce */ + SHEX("C5CD9D1850C141E358649994EE701B68")); /* tag */ + + test_aead(&nettle_ocb_aes128, NULL, + SHEX("000102030405060708090A0B0C0D0E0F"), /* key */ + SHEX(""), /* auth data */ + SHEX("000102030405060708090A0B0C0D0E0F1011121314151617" + "18191A1B1C1D1E1F2021222324252627"), /* plaintext */ + SHEX("4412923493C57D5DE0D700F753CCE0D1D2D95060122E9F15" + "A5DDBFC5787E50B5CC55EE507BCB084E"), /* ciphertext */ + SHEX("BBAA9988776655443322110F"), /* nonce */ + SHEX("479AD363AC366B95 A98CA5F3000B1479")); /* tag */ +} |