X-Git-Url: https://tinc-vpn.org/git/browse?a=blobdiff_plain;f=src%2Fchacha-poly1305%2Fpoly1305.c;h=b25435a71522741513b3b35ff62363307b16c9c2;hb=e994222a4370621a9ac69c13ed23531c1eaa6809;hp=0c90564cb0bba833886742713033b1fd2f43e560;hpb=63df2139835bb532125562c73ec3efbc437a3634;p=tinc diff --git a/src/chacha-poly1305/poly1305.c b/src/chacha-poly1305/poly1305.c index 0c90564c..b25435a7 100644 --- a/src/chacha-poly1305/poly1305.c +++ b/src/chacha-poly1305/poly1305.c @@ -5,6 +5,20 @@ public domain #include "poly1305.h" +/* use memcpy() to copy blocks of memory (typically faster) */ +#define USE_MEMCPY 1 +/* use unaligned little-endian load/store (can be faster) */ +#define USE_UNALIGNED 0 + +struct poly1305_context { + uint32_t r[5]; + uint32_t h[5]; + uint32_t pad[4]; + size_t leftover; + unsigned char buffer[POLY1305_BLOCK_SIZE]; + unsigned char final; +}; + #if (USE_UNALIGNED == 1) #define U8TO32(p) \ (*((uint32_t *)(p))) @@ -33,7 +47,7 @@ U32TO8(unsigned char *p, uint32_t v) { } #endif -void +static void poly1305_init(struct poly1305_context *st, const unsigned char key[32]) { /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ st->r[0] = (U8TO32(&key[ 0])) & 0x3ffffff; @@ -131,7 +145,7 @@ poly1305_blocks(struct poly1305_context *st, const unsigned char *m, size_t byte st->h[4] = h4; } -void +static void poly1305_finish(struct poly1305_context *st, unsigned char mac[16]) { uint32_t h0, h1, h2, h3, h4, c; uint32_t g0, g1, g2, g3, g4; @@ -241,8 +255,7 @@ poly1305_finish(struct poly1305_context *st, unsigned char mac[16]) { st->pad[3] = 0; } - -void +static void poly1305_update(struct poly1305_context *st, const unsigned char *m, size_t bytes) { size_t i; @@ -293,10 +306,37 @@ poly1305_update(struct poly1305_context *st, const unsigned char *m, size_t byte } } +/** + * Poly1305 tag generation. This concatenates a string according to the rules + * outlined in RFC 7539 and calculates the tag. + * + * \param key 32 byte secret one-time key for poly1305 + * \param ct ciphertext + * \param ct_len ciphertext length in bytes + * \param tag pointer to 16 bytes for tag storage + */ void -poly1305_auth(unsigned char mac[16], const unsigned char *m, size_t bytes, const unsigned char key[32]) { +poly1305_get_tag(const unsigned char key[32], const void *ct, int ct_len, unsigned char tag[16]) { struct poly1305_context ctx; + unsigned left_over; + uint64_t len; + unsigned char pad[16]; + poly1305_init(&ctx, key); - poly1305_update(&ctx, m, bytes); - poly1305_finish(&ctx, mac); + memset(&pad, 0, sizeof(pad)); + + /* payload and padding */ + poly1305_update(&ctx, ct, ct_len); + left_over = ct_len % 16; + + if(left_over) { + poly1305_update(&ctx, pad, 16 - left_over); + } + + /* lengths */ + len = 0; + poly1305_update(&ctx, (unsigned char *)&len, 8); + len = ct_len; + poly1305_update(&ctx, (unsigned char *)&len, 8); + poly1305_finish(&ctx, tag); }