X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fchacha-poly1305%2Fchacha-poly1305.c;h=2711abb29eb04455ac38a77f0c9a14b3cb66b5a7;hb=fa05f996c5500c056a36c1d43e33a407f876643c;hp=bd5cb2c40cf325d853d0d9f334148ad15af11f2a;hpb=03aafb2c9ea38c9baf9bc0672001ffe38c91c47d;p=meshlink diff --git a/src/chacha-poly1305/chacha-poly1305.c b/src/chacha-poly1305/chacha-poly1305.c index bd5cb2c4..2711abb2 100644 --- a/src/chacha-poly1305/chacha-poly1305.c +++ b/src/chacha-poly1305/chacha-poly1305.c @@ -1,6 +1,5 @@ #include "../system.h" -#include "../cipher.h" #include "../xalloc.h" #include "chacha.h" @@ -25,7 +24,7 @@ void chacha_poly1305_exit(chacha_poly1305_ctx_t *ctx) bool chacha_poly1305_set_key(chacha_poly1305_ctx_t *ctx, const void *key) { chacha_keysetup(&ctx->main_ctx, key, 256); - chacha_keysetup(&ctx->header_ctx, key + 32, 256); + chacha_keysetup(&ctx->header_ctx, (uint8_t *)key + 32, 256); return true; } @@ -61,7 +60,7 @@ bool chacha_poly1305_encrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v chacha_ivsetup(&ctx->main_ctx, seqbuf, one); chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); - poly1305_auth(outdata + inlen, outdata, inlen, poly_key); + poly1305_auth((uint8_t *)outdata + inlen, outdata, inlen, poly_key); if (outlen) *outlen = inlen + POLY1305_TAGLEN; @@ -88,7 +87,62 @@ bool chacha_poly1305_decrypt(chacha_poly1305_ctx_t *ctx, uint64_t seqnr, const v /* Check tag before anything else */ inlen -= POLY1305_TAGLEN; - const uint8_t *tag = indata + inlen; + const uint8_t *tag = (const uint8_t *)indata + inlen; + + poly1305_auth(expected_tag, indata, inlen, poly_key); + if (memcmp(expected_tag, tag, POLY1305_TAGLEN)) + return false; + + chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); + + if (outlen) + *outlen = inlen; + + return true; +} + +bool chacha_poly1305_encrypt_iv96(chacha_poly1305_ctx_t *ctx, const uint8_t *seqbuf, const void *indata, size_t inlen, void *outdata, size_t *outlen) { + const uint8_t one[4] = { 1, 0, 0, 0 }; /* NB little-endian */ + uint8_t poly_key[POLY1305_KEYLEN]; + + /* + * Run ChaCha20 once to generate the Poly1305 key. The IV is the + * packet sequence number. + */ + memset(poly_key, 0, sizeof(poly_key)); + chacha_ivsetup_96(&ctx->main_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); + + /* Set Chacha's block counter to 1 */ + chacha_ivsetup_96(&ctx->main_ctx, seqbuf, one); + + chacha_encrypt_bytes(&ctx->main_ctx, indata, outdata, inlen); + poly1305_auth((uint8_t *)outdata + inlen, outdata, inlen, poly_key); + + if (outlen) + *outlen = inlen + POLY1305_TAGLEN; + + return true; +} + +bool chacha_poly1305_decrypt_iv96(chacha_poly1305_ctx_t *ctx, const uint8_t *seqbuf, const void *indata, size_t inlen, void *outdata, size_t *outlen) { + const uint8_t one[4] = { 1, 0, 0, 0 }; /* NB little-endian */ + uint8_t expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; + + /* + * Run ChaCha20 once to generate the Poly1305 key. The IV is the + * packet sequence number. + */ + memset(poly_key, 0, sizeof(poly_key)); + chacha_ivsetup_96(&ctx->main_ctx, seqbuf, NULL); + chacha_encrypt_bytes(&ctx->main_ctx, poly_key, poly_key, sizeof(poly_key)); + + /* Set Chacha's block counter to 1 */ + chacha_ivsetup_96(&ctx->main_ctx, seqbuf, one); + + /* Check tag before anything else */ + inlen -= POLY1305_TAGLEN; + const uint8_t *tag = (const uint8_t *)indata + inlen; poly1305_auth(expected_tag, indata, inlen, poly_key); if (memcmp(expected_tag, tag, POLY1305_TAGLEN))