// calc_tag fills |tag| with the authentication tag for the given inputs. static void calc_tag(uint8_t tag[POLY1305_TAG_LEN], const uint8_t *key, const uint8_t nonce[12], const uint8_t *ad, size_t ad_len, const uint8_t *ciphertext, size_t ciphertext_len, const uint8_t *ciphertext_extra, size_t ciphertext_extra_len) { alignas(16) uint8_t poly1305_key[32]; OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key)); CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), key, nonce, 0); static const uint8_t padding[16] = { 0 }; // Padding is all zeros. poly1305_state ctx; CRYPTO_poly1305_init(&ctx, poly1305_key); CRYPTO_poly1305_update(&ctx, ad, ad_len); if (ad_len % 16 != 0) { CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16)); } CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len); CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len); const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len; if (ciphertext_total % 16 != 0) { CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ciphertext_total % 16)); } poly1305_update_length(&ctx, ad_len); poly1305_update_length(&ctx, ciphertext_total); CRYPTO_poly1305_finish(&ctx, tag); }
static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad, size_t ad_len, const uint8_t *ciphertext, size_t ciphertext_len) { CRYPTO_poly1305_update(ctx, ad, ad_len); poly1305_update_length(ctx, ad_len); CRYPTO_poly1305_update(ctx, ciphertext, ciphertext_len); poly1305_update_length(ctx, ciphertext_len); }
static void poly1305_update(poly1305_state *ctx, const uint8_t *ad, size_t ad_len, const uint8_t *ciphertext, size_t ciphertext_len) { poly1305_update_padded_16(ctx, ad, ad_len); poly1305_update_padded_16(ctx, ciphertext, ciphertext_len); poly1305_update_length(ctx, ad_len); poly1305_update_length(ctx, ciphertext_len); }