diff options
author | Niels Möller <nisse@lysator.liu.se> | 2014-02-14 15:31:21 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2014-02-14 15:31:21 +0100 |
commit | d76caf61011c5fbe553ea0f024d9f43edc6f14de (patch) | |
tree | b2526a25afb9d1d4c5cbee00c07abdddc8e1430c | |
parent | c6ce389e5fa32c848c06e96bff81c55d626f9118 (diff) | |
download | nettle-d76caf61011c5fbe553ea0f024d9f43edc6f14de.tar.gz |
First sketch of aead convenience functions.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | Makefile.in | 6 | ||||
-rw-r--r-- | aead-decrypt-msg.c | 73 | ||||
-rw-r--r-- | aead-decrypt.c | 180 | ||||
-rw-r--r-- | aead-encrypt-msg.c | 53 | ||||
-rw-r--r-- | aead-encrypt.c | 167 |
6 files changed, 487 insertions, 2 deletions
@@ -1,3 +1,13 @@ +2014-02-14 Niels Möller <nisse@lysator.liu.se> + + * aead.h: New file. + * aead-encrypt.c: New file. + * aead-decrypt.c: New file. + * aead-encrypt-msg.c: New file. + * aead-decrypt-msg.c: New file. + * Makefile.in (nettle_SOURCES): Added new source files. + (HEADERS): Added aead.h. + 2014-02-13 Niels Möller <nisse@lysator.liu.se> * Makefile.in (nettle_SOURCES): Added eax-aes128.c diff --git a/Makefile.in b/Makefile.in index 18090053..10ae274b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -62,7 +62,9 @@ dvi installcheck uninstallcheck: all-here: $(TARGETS) $(DOCTARGETS) -nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \ +nettle_SOURCES = aead-decrypt.c aead-decrypt-msg.c \ + aead-encrypt.c aead-encrypt-msg.c \ + aes-decrypt-internal.c aes-decrypt.c \ aes-encrypt-internal.c aes-encrypt.c aes-encrypt-table.c \ aes-invert-internal.c aes-set-key-internal.c \ aes-set-encrypt-key.c aes-set-decrypt-key.c \ @@ -164,7 +166,7 @@ hogweed_SOURCES = sexp.c sexp-format.c \ ecc-ecdsa-sign.c ecdsa-sign.c \ ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c -HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \ +HEADERS = aead.h aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \ base16.h base64.h buffer.h camellia.h cast128.h \ cbc.h chacha.h chacha-poly1305.h ctr.h \ des.h des-compat.h dsa.h eax.h ecc-curve.h ecc.h ecdsa.h \ diff --git a/aead-decrypt-msg.c b/aead-decrypt-msg.c new file mode 100644 index 00000000..026aaeff --- /dev/null +++ b/aead-decrypt-msg.c @@ -0,0 +1,73 @@ +/* aead-decrypt-msg.c + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <string.h> + +#include "aead.h" + +#include "nettle-internal.h" +#include "nettle-meta.h" + +size_t +aead_decrypt_msg_size(const struct nettle_aead *aead, size_t size) +{ + if (size < aead->digest_size) + /* Invalid message */ + return 0; + else + return size - aead->digest_size; +} + +int +aead_decrypt_msg (const struct nettle_aead *aead, + void *ctx, const uint8_t *nonce, + size_t ad_size, const uint8_t *ad, + size_t gibberish_size, + uint8_t *plaintext, const uint8_t *gibberish) +{ + TMP_DECL (digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + size_t plaintext_size; + + TMP_ALLOC (digest, aead->digest_size); + plaintext_size = gibberish_size - aead->digest_size; + + /* Allow NULL nonce, for the case that the caller already has done + that. E.g., if the application uses a nonce size different from + aead->nonce_size. */ + if (nonce) + aead->set_nonce (ctx, nonce); + + if (gibberish_size < aead->digest_size) + /* Invalid message */ + return 0; + + aead->update (ctx, ad_size, ad); + aead->decrypt (ctx, plaintext_size, plaintext, gibberish); + aead->digest (ctx, aead->digest_size, digest); + return memcmp (gibberish + plaintext_size, + digest, aead->digest_size) == 0; +} diff --git a/aead-decrypt.c b/aead-decrypt.c new file mode 100644 index 00000000..a024d7c2 --- /dev/null +++ b/aead-decrypt.c @@ -0,0 +1,180 @@ +/* aead-decrypt.c + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "aead.h" + +#include "buffer.h" +#include "nettle-internal.h" +#include "nettle-meta.h" + +#define GET_BUF(aead, ctx) \ + ((uint8_t *)((char *) (ctx) + (aead)->context_size)) + +/* Needs a buffer of digest_size + block_size - 1 bytes. Let this be + followed by an uint8_t buffer index; using a small type avoids + alignment issues. */ + +size_t +aead_decrypt_ctx_size (const struct nettle_aead *aead) +{ + return aead->context_size + aead->block_size + aead->digest_size; +} + +void +aead_decrypt_init (const struct nettle_aead *aead, + void *ctx, const uint8_t *nonce) +{ + /* The case of unbuffered underlying method not supported. Niether + is block sizes larger than 256 bytes. */ + assert (aead->block_size > 0); + assert (aead->block_size <= 256); + + /* Allow NULL nonce, for the case that the caller already has done + that. E.g., if the application uses a nonce size different from + aead->nonce_size. */ + if (nonce) + aead->set_nonce (ctx, nonce); + + /* Initialize buffer index. */ + GET_BUF (aead, ctx)[aead->block_size + aead->digest_size - 1] = 0; +} + +size_t +aead_decrypt (const struct nettle_aead *aead, + void *ctx, struct nettle_buffer *buffer, + size_t size, const uint8_t *gibberish) +{ + uint8_t *buf; + uint8_t *dst; + uint8_t left_over; + size_t done; + + buf = GET_BUF (aead, ctx); + left_over = buf[aead->block_size + aead->digest_size-1]; + assert (left_over < aead->block_size + aead->digest_size); + + done = 0; + /* First try to process buffered data, one block at a time. */ + while (left_over > 0 + && left_over + size >= aead->block_size + aead->digest_size) + { + dst = nettle_buffer_space (buffer, aead->block_size); + if (!dst) + return done; + + if (left_over < aead->block_size) + { + unsigned part = aead->block_size - left_over; + + memcpy (buf + left_over, gibberish, part); + aead->decrypt (ctx, aead->block_size, dst, buf); + done += part; + size -= part; + + left_over = 0; + } + else + { + aead->decrypt (ctx, aead->block_size, dst, buf); + left_over -= aead->block_size; + memmove (buf, buf + aead->block_size, left_over); + } + } + + if (left_over + size < aead->block_size + aead->digest_size) + { + /* Buffer new data */ + assert (left_over + size < aead->block_size + aead->digest_size); + memcpy (buf + left_over, gibberish, size); + buf[aead->block_size + aead->digest_size-1] = left_over + size; + return done + size; + } + assert (left_over == 0); + assert (size >= aead->digest_size); + + size -= aead->digest_size; + left_over = size % aead->block_size; + size -= left_over; + + dst = nettle_buffer_space (buffer, size); + if (!dst) + { + /* Process as many blocks as possible, without growing the + buffer. */ + size_t avail = (buffer->alloc - buffer->size); + avail -= (avail % aead->block_size); + assert (avail < size); + size = avail; + left_over = 0; + dst = nettle_buffer_space (buffer, size); + assert (dst != NULL); + } + aead->encrypt (ctx, size, dst, gibberish); + done += size; + + /* Buffer left over + potential digest */ + left_over += aead->digest_size; + memcpy (buf, gibberish + size, left_over); + buf[aead->block_size + aead->digest_size - 1] = left_over; + + done += left_over; + return done; +} + +size_t +aead_decrypt_final_size (const struct nettle_aead *aead) +{ + return aead->block_size - 1; +} + +int +aead_decrypt_final (const struct nettle_aead *aead, + void *ctx, struct nettle_buffer *buffer) +{ + TMP_DECL (digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE); + const uint8_t *buf = GET_BUF (aead, ctx); + uint8_t *dst; + unsigned left_over = buf[aead->block_size - 1]; + assert (left_over < aead->block_size + aead->digest_size); + + if (left_over < aead->digest_size) + /* Too short */ + return 0; + left_over -= aead->digest_size; + dst = nettle_buffer_space (buffer, left_over); + if (!dst) + return 0; + + aead->encrypt (ctx, left_over, dst, buf); + + TMP_ALLOC (digest, aead->digest_size); + aead->digest (ctx, aead->digest_size, digest); + return memcmp (buf + left_over, digest, aead->digest_size) == 0; +} diff --git a/aead-encrypt-msg.c b/aead-encrypt-msg.c new file mode 100644 index 00000000..450548f4 --- /dev/null +++ b/aead-encrypt-msg.c @@ -0,0 +1,53 @@ +/* aead-encrypt-msg.c + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "aead.h" + +#include "nettle-meta.h" + +size_t +aead_encrypt_msg_size(const struct nettle_aead *aead, size_t size) +{ + return size + aead->digest_size; +} + +void +aead_encrypt_msg (const struct nettle_aead *aead, + void *ctx, const uint8_t *nonce, + size_t ad_size, const uint8_t *ad, + size_t plaintext_size, + uint8_t *gibberish, const uint8_t *plaintext) +{ + /* Allow NULL nonce, for the case that the caller already has done + that. E.g., if the application uses a nonce size different from + aead->nonce_size. */ + if (nonce) + aead->set_nonce (ctx, nonce); + aead->update (ctx, ad_size, ad); + aead->encrypt (ctx, plaintext_size, gibberish, plaintext); + aead->digest (ctx, aead->digest_size, gibberish + plaintext_size); +} diff --git a/aead-encrypt.c b/aead-encrypt.c new file mode 100644 index 00000000..1eaaa98e --- /dev/null +++ b/aead-encrypt.c @@ -0,0 +1,167 @@ +/* aead-encrypt.c + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <string.h> + +#include "aead.h" + +#include "nettle-meta.h" +#include "buffer.h" + +/* Needs a buffer of block_size - 1 bytes. Let this be followed by an + uint8_t buffer index; using a small type avoids alignment + issues. */ +#define GET_BUF(aead, ctx) \ + ((uint8_t *)((char *) (ctx) + (aead)->context_size)) + +size_t +aead_encrypt_ctx_size (const struct nettle_aead *aead) +{ + return aead->context_size + aead->block_size; +} + +void +aead_encrypt_init (const struct nettle_aead *aead, + void *ctx, const uint8_t *nonce) +{ + /* The case of unbuffered underlying method not supported. Niether + is block sizes larger than 256 bytes. */ + assert (aead->block_size > 0); + assert (aead->block_size <= 256); + + /* Allow NULL nonce, for the case that the caller already has done + that. E.g., if the application uses a nonce size different from + aead->nonce_size. */ + if (nonce) + aead->set_nonce (ctx, nonce); + + /* Initialize buffer index. */ + GET_BUF (aead, ctx)[aead->block_size-1] = 0; +} + +size_t +aead_encrypt (const struct nettle_aead *aead, + void *ctx, struct nettle_buffer *buffer, + size_t size, const uint8_t *plaintext) +{ + uint8_t *buf; + uint8_t *dst; + uint8_t left_over; + size_t done; + + buf = GET_BUF (aead, ctx); + left_over = buf[aead->block_size-1]; + assert (left_over < aead->block_size); + + if (left_over > 0) + { + /* Try to fill buffer */ + if (size >= aead->block_size - left_over) + { + dst = nettle_buffer_space (buffer, aead->block_size); + if (!dst) + /* Would could copy some more data into our buffer, but we + really can't make any progress until the caller + provides a larger output buffer. */ + return 0; + + done = aead->block_size - left_over; + memcpy (buf + left_over, plaintext, done); + aead->encrypt (ctx, aead->block_size, dst, buf); + size -= done; + plaintext += done; + } + else + { + memcpy (buf + left_over, plaintext, size); + left_over += size; + assert (left_over < aead->block_size); + buf[aead->block_size-1] = left_over; + return size; + } + } + else + done = 0; + + left_over = size % aead->block_size; + + dst = nettle_buffer_space (buffer, size - left_over); + if (dst) + { + /* Buffer rest of input. */ + size -= left_over; + memcpy (buf, plaintext + size, left_over); + done += left_over; + } + else + { + /* Process as many blocks as possible, without growing the buffer. */ + size_t avail = (buffer->alloc - buffer->size); + avail -= (avail % aead->block_size); + assert (avail < size); + size = avail; + left_over = 0; + dst = nettle_buffer_space (buffer, size); + assert (dst != NULL); + } + aead->encrypt (ctx, size, dst, plaintext); + done += size; + + buf[aead->block_size-1] = left_over; + + return done; +} + +size_t +aead_encrypt_final_size (const struct nettle_aead *aead) +{ + return aead->digest_size + aead->block_size - 1; +} + +int +aead_encrypt_final (const struct nettle_aead *aead, + void *ctx, struct nettle_buffer *buffer) +{ + uint8_t *buf = GET_BUF (aead, ctx); + uint8_t *dst; + uint8_t left_over = buf[aead->block_size - 1]; + assert (left_over < aead->block_size); + if (left_over) + { + dst = nettle_buffer_space (buffer, left_over); + if (!dst) + return 0; + aead->encrypt (ctx, left_over, dst, buf); + buf[aead->block_size - 1] = 0; + } + dst = nettle_buffer_space (buffer, aead->digest_size); + if (!dst) + return 0; + aead->digest (ctx, aead->digest_size, dst); + return 1; +} |