Maybe it's time to specify some nettle-meta.h types for stream ciphers
and algorithms for authenticated encryption.
Currently we have nettle_hash, which I don't think needs any changes,
and nettle_cipher, where I'm considering the following changes:
1. Drop the length argument from nettle_set_key_func.
2. Make the context argument of nettle_crypt_func const.
3. Previous point implies that we can no longer have struct
nettle_cipher nettle_arcfour128. nettle_cipher will then be limited
to block ciphers only.
Then there are some minor variations. Maybe nettle_crypt_func should be
left unmodified, and we should have a new type, say nettle_cipher_func,
for block ciphers with a const context.
What should the right abstraction look like for stream ciphers?
Currently, arcfour, salsa20, and (soon) chacha. Consider
struct nettle_stream_cipher
{
const char *name;
unsigned context_size;
unsigned key_size;
unsigned nonce_size;
nettle_set_key_func *set_key;
nettle_set_key_func *set_nonce;
nettle_crypt_func *crypt;
};
Here, nettle_crypt_func should be the current definition without const.
This assumes encryption and decryption are identical, which is the case
for out current stream cipher list (and anything else xoring a stream to
the plaintext). For arcfour, set_nonce would be NULL. Not sure how
useful that really is to applications, ciphers with a nonce might not be
used interchangably with a cipher that has no nonce.
So lacking features in that definition are
* Support for stream ciphers with different processing for encryption
and decryption.
* Support for the random-access possibilities in salsa20 and chacha.
* Support for algorithms with arbitrary nonce size.
Also, internal block size is not visible. To use salsa20 with this
interface, one would need a one-block buffer, and new logic to handle
partial blocks.
For applications of stream ciphers, as well as ctr mode, is it important
to be able to process a message byte by byte? Or is it sufficient to do
like the current ctr and salsa20 code, to require that if a message is
processed using several calls to the crypt function, all but the last
must be an integral number of blocks? If we keep that requirement, we'd
have to add a block_size field to struct nettle_stream_cipher.
Next, AEAD (authenticated encryption with associated data). Currently
implemented algorithms are GCM and EAX. For internal use,
nettle-internal.h currently defines
/* Tentative interface for "authenticated encryption with associated
data" algorithms. Should be moved to nettle-meta.h when stable. */
struct nettle_aead
{
const char *name;
size_t context_size;
/* Block size of the input, and the size of the output digest */
size_t block_size;
/* Suggested key size; other sizes are sometimes possible. */
size_t key_size;
nettle_set_key_func *set_key;
nettle_set_key_func *set_iv;
nettle_hash_update_func *update;
nettle_crypt_func *encrypt;
nettle_crypt_func *decrypt;
nettle_hash_digest_func *digest;
};
Like for stream ciphers, nettle_crypt_func is the variant without const;
the context *is* modified as the message is processed.
Limitations:
* Assumes identical key setup for encrypt and decrypt, which is true for
GCM and AEX (both based on CTR mode for the encryption). Do we need
separate set_encrypt_key and set_decrypt_key functions?
* Assumes block size and digest size are identical. They might not be.
* set_iv should be renamed to set_nonce. Can the nonce be restricted to
fixed size here? Both gcm and eax are specified for arbitrary nonce
size. We may need two nettle_set_* function typedefs, one without
length argument (used for set_key in all these abstractions), and one
with a length argument, used for arbitrary size nonces, as well as any
interfaces supporting variable key size.
One might use the same abstraction for constructions with no associated
data (say, aes128-ctr-hmac-sha256) by setting update to NULL, or for
schemes with no authentication at all, like aes 128-ctr, by also setting
digest to NULL. Or for methods to provide authentication but no
encryption, like hmac-sha256 or poly1305. But I doubt that's very
useful.
Regards,
/Niels
--
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.