Nikos Mavrogiannopoulos nmav@gnutls.org writes:
On 02/06/2011 12:08 AM, Niels Möller wrote:
void gcm_set_key(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f);
I don't like the name of the function name. It doesn't reveal anything about its purpose. There is no key to set there. I'd suggest the original gcm_init.
I see your point, and I think I'll change the name. If we introduce a gcm_aes wrapper, that will have a _set_key method.
Moreover by not allowing the setting the blocksize as option any extension on that code to work with 64-bit ciphers, will require an abi break, or a new gcm64 mode... (what if 256-bit ciphers are added in the future?)
I don't think it's useful to be that general here. Variants with different block sizes will likely need a different context struct anyway.
I could rename gcm to gcm128 in the interface if that's clearer.
As I already mentioned I prefer having the cipher and f, to context to avoid supplying on individual calls. There is no advantage (that I can see) on having on each function parameters, and it just delegates the storage of those two pointers, to caller's structures instead. It's no big deal but it is inconvenience.
I haven't yet made up my mind on this, but let me explain the reason for having these pointers as function arguments.
The idea is that context structs in nettle should be non-magic with no pointers, so that it can be copied or relocated in memory at will. Say we implement gcm_aes as
struct gcm_aes_ctx { struct gcm_ctx gcm; struct aes_ctx aes; };
void gcm_aes_encrypt(struct gcm_aes_ctx *ctx, unsigned length, uint8_t *dst, const uint8_t *src) { gcm_encrypt(&ctx->gcm, &ctx->aes, (nettle_crypt_func) aes_encrypt, length, dst, src); }
Then the context struct is still non-magic. We can call gcm_aes_set_key, and then create multiple copies of gcm_aes_ctx (using plain memcpy) which are independent. If we add some pointers to struct gcm_ctx (which *does* increase the storage size of gcm_aes_ctx, although that's maybe not a big deal), plain copying will leave pointers pointing to other objects, and we'll have to introduce a function gcm_aes_copy.
And if you think copying here is the wrong thing (since we waste memory with multiple identical copies of an aes_ctx representing the key), then I think one should also split gcm_ctx into a key-dependent part (which should be shared rather than copied, in particular if we go for larger key-dependent tables) and a message-dependent part (which also shouldn't be copied, instead multiple instances should be independently initialized).
We can compare with the hmac code; there's no context struct for the general construction, but hmac_sha1_ctx and other's defined using the HMAC_CTX macro put both key-the dependent parts (.inner, .outer) and the message dependent part (.state) in a single struct.
When thinking about it, maybe the right thing is to redesign the general gcm-code to use a separate struct for the hash subkey, passed as argument to the functions needing it.
Regards, /Niels