Tim Kosse tim.kosse@filezilla-project.org writes:
I'm trying to implement chacha20-poly1305 as used by SSH (https://datatracker.ietf.org/doc/html/draft-ietf-sshm-chacha20-poly1305-04), which differs from RFC 8439's ChaCha-Poly1035 as implemented by Nettle.
I agree Nettle should support some way of doing this, thanks for looking into that. Not sure what API should look like, though. It's rather different from other mac:s, since one can't set a key once and authenticate multiple messages.
One option could be to instead promote some of the low-level functions.
If we promote _nettle_poly1305_set_key, _nettle_poly1305_update, and _nettle_poly1305_digest, then what's missing is a utility for the digest-time padding of a partial block. We would need something like either
poly1305_digest (struct poly1305_ctx *ctx, union nettle_block16 *s, uint8_t *buffer, unsigned index);
or current _nettle_poly1305_digest and something like
poly1305_pad (struct poly1305_ctx *ctx, uint8_t *buffer, unsigned index);
I think it's desirable that the new poly1305 functions are defined in such a way that current poly1305_aes and chacha_poly1305 api:s could build on top of it (even if that might be unfeasible at the moment since refactoring the corresponding context structs might break the abi).
Another option is to add an implementation of the specific openssh construction, if we don't foresee any need for additional variants building on the poly1305 primitive.
Some more detailed comments below:
struct poly1305_mac_ctx { struct poly1305_ctx pctx; union nettle_block16 s; uint8_t block[POLY1305_BLOCK_SIZE]; unsigned index; };
Having s in this struct implies some impedance mismatch if we try to use it in the implementation of poly1305_aes (there, s is aes_k(nonce), and the nonce is kept in the context struct to support autoincrement). I think I'd prefer passing s as an argument at digest time.
/* After calling this function, context must be re-keyed before calling poly1305_update/poly1305_digest again. */ void poly1305_digest(struct poly1305_mac_ctx* ctx, uint8_t* digest)
The requirement for rekeying after each use stands out, if we try to otherwise stick to nettle's conventions for MAC functions.
Regards, /Niels