예제 #1
0
// 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);
}