ni...@lysator.liu.se (Niels Möller) writes:

> Or use struct nettle_buffer for the destination operand, possibly in
> combination with some macro/function to query the needed space.

I have now tried this approach. For those have haven't used
nettle_buffer, it's struct with a data pointer, allocation size, and
current size. It can be setup to either use a fix buffer provided by the
application, or it can grow as needed, using realloc, xrealloc, or any
custom realloc function provided by the application.

A totally untested implementation in the aead-api branch. There actually
two interfaces, defined in aead.h.

First question is whether or not this is useful. If it is useful, maybe
the interfaces need tweaking. A first test (besides regular test cases)
would be to rewrite examples/rsa-encrypt.c and examples/rsa-decrypt.c to
use some aead mechanism for the bulk encryption, rather than aes-cbc +
hmac-sha1.

First, an interface for processing complete messages. These use the same
context as the lower-level algorithm. More or less the same as I have
sketched on this list previously.

-----8<---------

/* Interface for processing a complete message at a time. Application
   must allocate the context and call the set_key function before
   using this interface. */
size_t
aead_encrypt_msg_size (const struct nettle_aead *aead, size_t 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);

size_t
aead_decrypt_msg_size (const struct nettle_aead *aead, size_t 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);

-----8<---------

Second interface is for streaming operation, hiding the block size.
Here, the context is the context of the underlying aead algorithm, but
with a small extra buffer added at the end (aead->block_size for
encryption, and aead->block_size + aead->digest_size for decryption).

-----8<---------

/* Streaming interface, including buffering. Uses a context struct
   corresponding to the aead algorithm, with additional buffers added
   at the end. Hence, the context can be passed to algorithm-specific
   functions. Applications should call set_key and set_nonce before
   using these functions. */

#define aead_update(aead, ctx, size, data) \
  ((aead)->update((ctx), (size), (data)))

size_t
aead_encrypt_ctx_size (const struct nettle_aead *aead);

void
aead_encrypt_init (const struct nettle_aead *aead,
                   void *ctx, const uint8_t *nonce);

/* Attempts to grow the destination buffer as needed. Returns the
   amount of plaintext that could be processed. */
size_t
aead_encrypt (const struct nettle_aead *aead,
              void *ctx, struct nettle_buffer *buffer,
              size_t size, const uint8_t *plaintext);

/* Maximum output size for aead_encrypt_final. */
size_t
aead_encrypt_final_size (const struct nettle_aead *aead);

/* Returns 1 on success, 0 if buffer was too small and growing it
   failed. On failure, some output may still be generated, and the
   function can be called again with more output space. */
int
aead_encrypt_final (const struct nettle_aead *aead,
                    void *ctx, struct nettle_buffer *buffer);

size_t
aead_decrypt_ctx_size (const struct nettle_aead *aead);

void
aead_decrypt_init (const struct nettle_aead *aead,
                   void *ctx, const uint8_t *nonce);

/* Attempts to grow the destination buffer as needed. Returns the
   amount of plaintext that could be processed. */
size_t
aead_decrypt (const struct nettle_aead *aead,
              void *ctx, struct nettle_buffer *dst,
              size_t size, const uint8_t *gibberish);

/* Maximum output size for aead_decrypt_final. */
size_t
aead_decrypt_final_size (const struct nettle_aead *aead);

/* Returns 1 on success, 0 if buffer is too small or authentication
   failed. FIXME: Distinguish between failure cases? */
int
aead_decrypt_final (const struct nettle_aead *aead,
                    void *ctx, struct nettle_buffer *dst);

-----8<---------

In particular the decrypt function is quite messy, which makes me think
that it's a good idea to implement this at one place, on a level between
the application and the implementation of each specific aead mechanism.

Regards,
/Niels


-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.
_______________________________________________
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to