cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

poly1305.c (2118B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Poly1305 authenticator algorithm, RFC7539
      4 *
      5 * Copyright (C) 2015 Martin Willi
      6 *
      7 * Based on public domain code by Andrew Moon and Daniel J. Bernstein.
      8 */
      9
     10#include <crypto/internal/poly1305.h>
     11#include <linux/kernel.h>
     12#include <linux/module.h>
     13#include <asm/unaligned.h>
     14
     15void poly1305_init_generic(struct poly1305_desc_ctx *desc,
     16			   const u8 key[POLY1305_KEY_SIZE])
     17{
     18	poly1305_core_setkey(&desc->core_r, key);
     19	desc->s[0] = get_unaligned_le32(key + 16);
     20	desc->s[1] = get_unaligned_le32(key + 20);
     21	desc->s[2] = get_unaligned_le32(key + 24);
     22	desc->s[3] = get_unaligned_le32(key + 28);
     23	poly1305_core_init(&desc->h);
     24	desc->buflen = 0;
     25	desc->sset = true;
     26	desc->rset = 2;
     27}
     28EXPORT_SYMBOL_GPL(poly1305_init_generic);
     29
     30void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src,
     31			     unsigned int nbytes)
     32{
     33	unsigned int bytes;
     34
     35	if (unlikely(desc->buflen)) {
     36		bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen);
     37		memcpy(desc->buf + desc->buflen, src, bytes);
     38		src += bytes;
     39		nbytes -= bytes;
     40		desc->buflen += bytes;
     41
     42		if (desc->buflen == POLY1305_BLOCK_SIZE) {
     43			poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf,
     44					     1, 1);
     45			desc->buflen = 0;
     46		}
     47	}
     48
     49	if (likely(nbytes >= POLY1305_BLOCK_SIZE)) {
     50		poly1305_core_blocks(&desc->h, &desc->core_r, src,
     51				     nbytes / POLY1305_BLOCK_SIZE, 1);
     52		src += nbytes - (nbytes % POLY1305_BLOCK_SIZE);
     53		nbytes %= POLY1305_BLOCK_SIZE;
     54	}
     55
     56	if (unlikely(nbytes)) {
     57		desc->buflen = nbytes;
     58		memcpy(desc->buf, src, nbytes);
     59	}
     60}
     61EXPORT_SYMBOL_GPL(poly1305_update_generic);
     62
     63void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst)
     64{
     65	if (unlikely(desc->buflen)) {
     66		desc->buf[desc->buflen++] = 1;
     67		memset(desc->buf + desc->buflen, 0,
     68		       POLY1305_BLOCK_SIZE - desc->buflen);
     69		poly1305_core_blocks(&desc->h, &desc->core_r, desc->buf, 1, 0);
     70	}
     71
     72	poly1305_core_emit(&desc->h, desc->s, dst);
     73	*desc = (struct poly1305_desc_ctx){};
     74}
     75EXPORT_SYMBOL_GPL(poly1305_final_generic);
     76
     77MODULE_LICENSE("GPL");
     78MODULE_AUTHOR("Martin Willi <martin@strongswan.org>");