mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-10-26 10:57:38 +08:00
Pull crypto library updates from Eric Biggers: - Migrate the x86 and riscv optimized implementations of various AES modes (ECB, CBC, CBC-CTS, CTR, XCTR, XTS) into lib/crypto/. This makes the library APIs be properly accelerated on these architectures, while still accelerating crypto_skcipher as well. It removes a lot of redundant glue code, since the crypto API boilerplate no longer needs to be duplicated for these architectures. It also fixes the longstanding issue where optimizations for these AES modes were disabled by default on these architectures. - Optimize AES-XTS on SPARC64 using the SPARC crypto opcodes - Move the SipHash code into lib/crypto/ - Update the ChaCha and Poly1305 functions to take size_t lengths, resolving issues where lengths over INT_MAX were mishandled - Make frame pointer unwinding work properly in some of the x86 assembly functions, by following the standard %rbp convention - Add helper functions for zeroizing structs - Make a few documentation improvements * tag 'libcrypto-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux: (49 commits) lib/crypto: md5: remove unused header lib/crypto: mips/chacha: Handle lengths of 2 GiB or more lib/crypto: arm/chacha: Handle lengths of 2 GiB or more in scalar code lib/crypto: chacha: Use size_t length lib/crypto: poly1305: Use size_t length lib/crypto: x86/sha512: Follow the normal %rbp convention lib/crypto: x86/sha256: Follow the normal %rbp convention lib/crypto: x86/sha1: Follow the normal %rbp convention lib/crypto: chacha20poly1305: zeroize state in __chacha20poly1305_decrypt lib/crypto: sparc/aes-xts: Add optimization using the AES opcodes lib: Move SipHash into lib/crypto/ lib/crypto: x86/aes-ctr: Remove some unreachable code crypto: x86/aesni-intel - Add transitional selections crypto: aes - Boost priority of encryption modes further lib/crypto: x86/aes: Set RNDKEY in aes_cbc_encrypt_aesni() lib/crypto: riscv/aes-xts: Migrate optimized code into library lib/crypto: riscv/aes-ctr: Migrate optimized code into library lib/crypto: riscv/aes-cbc: Migrate optimized code into library lib/crypto: riscv/aes-ecb: Migrate optimized code into library lib/crypto: riscv/aes: Pass key struct to assembly code ...
101 lines
2.4 KiB
C
101 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Poly1305 authenticator algorithm, RFC7539
|
|
*
|
|
* Copyright (C) 2015 Martin Willi
|
|
*
|
|
* Based on public domain code by Andrew Moon and Daniel J. Bernstein.
|
|
*/
|
|
|
|
#include <crypto/internal/poly1305.h>
|
|
#include <linux/export.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/string.h>
|
|
#include <linux/unaligned.h>
|
|
|
|
#ifdef CONFIG_CRYPTO_LIB_POLY1305_ARCH
|
|
#include "poly1305.h" /* $(SRCARCH)/poly1305.h */
|
|
#else
|
|
#define poly1305_block_init poly1305_block_init_generic
|
|
#define poly1305_blocks poly1305_blocks_generic
|
|
#define poly1305_emit poly1305_emit_generic
|
|
#endif
|
|
|
|
void poly1305_init(struct poly1305_desc_ctx *desc,
|
|
const u8 key[POLY1305_KEY_SIZE])
|
|
{
|
|
desc->s[0] = get_unaligned_le32(key + 16);
|
|
desc->s[1] = get_unaligned_le32(key + 20);
|
|
desc->s[2] = get_unaligned_le32(key + 24);
|
|
desc->s[3] = get_unaligned_le32(key + 28);
|
|
desc->buflen = 0;
|
|
poly1305_block_init(&desc->state, key);
|
|
}
|
|
EXPORT_SYMBOL(poly1305_init);
|
|
|
|
void poly1305_update(struct poly1305_desc_ctx *desc, const u8 *src,
|
|
size_t nbytes)
|
|
{
|
|
if (nbytes >= POLY1305_BLOCK_SIZE - desc->buflen) {
|
|
size_t bulk_len;
|
|
|
|
if (desc->buflen) {
|
|
size_t l = POLY1305_BLOCK_SIZE - desc->buflen;
|
|
|
|
memcpy(&desc->buf[desc->buflen], src, l);
|
|
src += l;
|
|
nbytes -= l;
|
|
|
|
poly1305_blocks(&desc->state, desc->buf,
|
|
POLY1305_BLOCK_SIZE, 1);
|
|
desc->buflen = 0;
|
|
}
|
|
|
|
bulk_len = round_down(nbytes, POLY1305_BLOCK_SIZE);
|
|
nbytes %= POLY1305_BLOCK_SIZE;
|
|
|
|
if (bulk_len) {
|
|
poly1305_blocks(&desc->state, src, bulk_len, 1);
|
|
src += bulk_len;
|
|
}
|
|
}
|
|
if (nbytes) {
|
|
memcpy(&desc->buf[desc->buflen], src, nbytes);
|
|
desc->buflen += nbytes;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(poly1305_update);
|
|
|
|
void poly1305_final(struct poly1305_desc_ctx *desc, u8 *dst)
|
|
{
|
|
if (unlikely(desc->buflen)) {
|
|
desc->buf[desc->buflen++] = 1;
|
|
memset(desc->buf + desc->buflen, 0,
|
|
POLY1305_BLOCK_SIZE - desc->buflen);
|
|
poly1305_blocks(&desc->state, desc->buf, POLY1305_BLOCK_SIZE,
|
|
0);
|
|
}
|
|
|
|
poly1305_emit(&desc->state.h, dst, desc->s);
|
|
memzero_explicit(desc, sizeof(*desc));
|
|
}
|
|
EXPORT_SYMBOL(poly1305_final);
|
|
|
|
#ifdef poly1305_mod_init_arch
|
|
static int __init poly1305_mod_init(void)
|
|
{
|
|
poly1305_mod_init_arch();
|
|
return 0;
|
|
}
|
|
subsys_initcall(poly1305_mod_init);
|
|
|
|
static void __exit poly1305_mod_exit(void)
|
|
{
|
|
}
|
|
module_exit(poly1305_mod_exit);
|
|
#endif
|
|
|
|
MODULE_LICENSE("GPL");
|
|
MODULE_DESCRIPTION("Poly1305 authenticator algorithm, RFC7539");
|