mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge git://github.com/herbertx/crypto
* git://github.com/herbertx/crypto: (48 commits) crypto: user - Depend on NET instead of selecting it crypto: user - Add dependency on NET crypto: talitos - handle descriptor not found in error path crypto: user - Initialise match in crypto_alg_match crypto: testmgr - add twofish tests crypto: testmgr - add blowfish test-vectors crypto: Make hifn_795x build depend on !ARCH_DMA_ADDR_T_64BIT crypto: twofish-x86_64-3way - fix ctr blocksize to 1 crypto: blowfish-x86_64 - fix ctr blocksize to 1 crypto: whirlpool - count rounds from 0 crypto: Add userspace report for compress type algorithms crypto: Add userspace report for cipher type algorithms crypto: Add userspace report for rng type algorithms crypto: Add userspace report for pcompress type algorithms crypto: Add userspace report for nivaead type algorithms crypto: Add userspace report for aead type algorithms crypto: Add userspace report for givcipher type algorithms crypto: Add userspace report for ablkcipher type algorithms crypto: Add userspace report for blkcipher type algorithms crypto: Add userspace report for ahash type algorithms ...
This commit is contained in:
23
Documentation/devicetree/bindings/crypto/picochip-spacc.txt
Normal file
23
Documentation/devicetree/bindings/crypto/picochip-spacc.txt
Normal file
@@ -0,0 +1,23 @@
|
||||
Picochip picoXcell SPAcc (Security Protocol Accelerator) bindings
|
||||
|
||||
Picochip picoXcell devices contain crypto offload engines that may be used for
|
||||
IPSEC and femtocell layer 2 ciphering.
|
||||
|
||||
Required properties:
|
||||
- compatible : "picochip,spacc-ipsec" for the IPSEC offload engine
|
||||
"picochip,spacc-l2" for the femtocell layer 2 ciphering engine.
|
||||
- reg : Offset and length of the register set for this device
|
||||
- interrupt-parent : The interrupt controller that controls the SPAcc
|
||||
interrupt.
|
||||
- interrupts : The interrupt line from the SPAcc.
|
||||
- ref-clock : The input clock that drives the SPAcc.
|
||||
|
||||
Example SPAcc node:
|
||||
|
||||
spacc@10000 {
|
||||
compatible = "picochip,spacc-ipsec";
|
||||
reg = <0x100000 0x10000>;
|
||||
interrupt-parent = <&vic0>;
|
||||
interrupts = <24>;
|
||||
ref-clock = <&ipsec_clk>, "ref";
|
||||
};
|
||||
@@ -7,21 +7,33 @@ obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
|
||||
obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o
|
||||
obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o
|
||||
obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o
|
||||
obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o
|
||||
obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o
|
||||
obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o
|
||||
|
||||
aes-i586-y := aes-i586-asm_32.o aes_glue.o
|
||||
twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o
|
||||
salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o
|
||||
|
||||
aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o
|
||||
blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o
|
||||
twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
|
||||
twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o
|
||||
salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
|
||||
|
||||
aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o
|
||||
|
||||
ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
|
||||
|
||||
# enable AVX support only when $(AS) can actually assemble the instructions
|
||||
ifeq ($(call as-instr,vpxor %xmm0$(comma)%xmm1$(comma)%xmm2,yes,no),yes)
|
||||
AFLAGS_sha1_ssse3_asm.o += -DSHA1_ENABLE_AVX_SUPPORT
|
||||
CFLAGS_sha1_ssse3_glue.o += -DSHA1_ENABLE_AVX_SUPPORT
|
||||
endif
|
||||
sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <crypto/aes.h>
|
||||
#include <asm/aes.h>
|
||||
|
||||
asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
|
||||
asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);
|
||||
|
||||
390
arch/x86/crypto/blowfish-x86_64-asm_64.S
Normal file
390
arch/x86/crypto/blowfish-x86_64-asm_64.S
Normal file
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* Blowfish Cipher Algorithm (x86_64)
|
||||
*
|
||||
* Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
*/
|
||||
|
||||
.file "blowfish-x86_64-asm.S"
|
||||
.text
|
||||
|
||||
/* structure of crypto context */
|
||||
#define p 0
|
||||
#define s0 ((16 + 2) * 4)
|
||||
#define s1 ((16 + 2 + (1 * 256)) * 4)
|
||||
#define s2 ((16 + 2 + (2 * 256)) * 4)
|
||||
#define s3 ((16 + 2 + (3 * 256)) * 4)
|
||||
|
||||
/* register macros */
|
||||
#define CTX %rdi
|
||||
#define RIO %rsi
|
||||
|
||||
#define RX0 %rax
|
||||
#define RX1 %rbx
|
||||
#define RX2 %rcx
|
||||
#define RX3 %rdx
|
||||
|
||||
#define RX0d %eax
|
||||
#define RX1d %ebx
|
||||
#define RX2d %ecx
|
||||
#define RX3d %edx
|
||||
|
||||
#define RX0bl %al
|
||||
#define RX1bl %bl
|
||||
#define RX2bl %cl
|
||||
#define RX3bl %dl
|
||||
|
||||
#define RX0bh %ah
|
||||
#define RX1bh %bh
|
||||
#define RX2bh %ch
|
||||
#define RX3bh %dh
|
||||
|
||||
#define RT0 %rbp
|
||||
#define RT1 %rsi
|
||||
#define RT2 %r8
|
||||
#define RT3 %r9
|
||||
|
||||
#define RT0d %ebp
|
||||
#define RT1d %esi
|
||||
#define RT2d %r8d
|
||||
#define RT3d %r9d
|
||||
|
||||
#define RKEY %r10
|
||||
|
||||
/***********************************************************************
|
||||
* 1-way blowfish
|
||||
***********************************************************************/
|
||||
#define F() \
|
||||
rorq $16, RX0; \
|
||||
movzbl RX0bh, RT0d; \
|
||||
movzbl RX0bl, RT1d; \
|
||||
rolq $16, RX0; \
|
||||
movl s0(CTX,RT0,4), RT0d; \
|
||||
addl s1(CTX,RT1,4), RT0d; \
|
||||
movzbl RX0bh, RT1d; \
|
||||
movzbl RX0bl, RT2d; \
|
||||
rolq $32, RX0; \
|
||||
xorl s2(CTX,RT1,4), RT0d; \
|
||||
addl s3(CTX,RT2,4), RT0d; \
|
||||
xorq RT0, RX0;
|
||||
|
||||
#define add_roundkey_enc(n) \
|
||||
xorq p+4*(n)(CTX), RX0;
|
||||
|
||||
#define round_enc(n) \
|
||||
add_roundkey_enc(n); \
|
||||
\
|
||||
F(); \
|
||||
F();
|
||||
|
||||
#define add_roundkey_dec(n) \
|
||||
movq p+4*(n-1)(CTX), RT0; \
|
||||
rorq $32, RT0; \
|
||||
xorq RT0, RX0;
|
||||
|
||||
#define round_dec(n) \
|
||||
add_roundkey_dec(n); \
|
||||
\
|
||||
F(); \
|
||||
F(); \
|
||||
|
||||
#define read_block() \
|
||||
movq (RIO), RX0; \
|
||||
rorq $32, RX0; \
|
||||
bswapq RX0;
|
||||
|
||||
#define write_block() \
|
||||
bswapq RX0; \
|
||||
movq RX0, (RIO);
|
||||
|
||||
#define xor_block() \
|
||||
bswapq RX0; \
|
||||
xorq RX0, (RIO);
|
||||
|
||||
.align 8
|
||||
.global __blowfish_enc_blk
|
||||
.type __blowfish_enc_blk,@function;
|
||||
|
||||
__blowfish_enc_blk:
|
||||
/* input:
|
||||
* %rdi: ctx, CTX
|
||||
* %rsi: dst
|
||||
* %rdx: src
|
||||
* %rcx: bool, if true: xor output
|
||||
*/
|
||||
movq %rbp, %r11;
|
||||
|
||||
movq %rsi, %r10;
|
||||
movq %rdx, RIO;
|
||||
|
||||
read_block();
|
||||
|
||||
round_enc(0);
|
||||
round_enc(2);
|
||||
round_enc(4);
|
||||
round_enc(6);
|
||||
round_enc(8);
|
||||
round_enc(10);
|
||||
round_enc(12);
|
||||
round_enc(14);
|
||||
add_roundkey_enc(16);
|
||||
|
||||
movq %r11, %rbp;
|
||||
|
||||
movq %r10, RIO;
|
||||
test %cl, %cl;
|
||||
jnz __enc_xor;
|
||||
|
||||
write_block();
|
||||
ret;
|
||||
__enc_xor:
|
||||
xor_block();
|
||||
ret;
|
||||
|
||||
.align 8
|
||||
.global blowfish_dec_blk
|
||||
.type blowfish_dec_blk,@function;
|
||||
|
||||
blowfish_dec_blk:
|
||||
/* input:
|
||||
* %rdi: ctx, CTX
|
||||
* %rsi: dst
|
||||
* %rdx: src
|
||||
*/
|
||||
movq %rbp, %r11;
|
||||
|
||||
movq %rsi, %r10;
|
||||
movq %rdx, RIO;
|
||||
|
||||
read_block();
|
||||
|
||||
round_dec(17);
|
||||
round_dec(15);
|
||||
round_dec(13);
|
||||
round_dec(11);
|
||||
round_dec(9);
|
||||
round_dec(7);
|
||||
round_dec(5);
|
||||
round_dec(3);
|
||||
add_roundkey_dec(1);
|
||||
|
||||
movq %r10, RIO;
|
||||
write_block();
|
||||
|
||||
movq %r11, %rbp;
|
||||
|
||||
ret;
|
||||
|
||||
/**********************************************************************
|
||||
4-way blowfish, four blocks parallel
|
||||
**********************************************************************/
|
||||
|
||||
/* F() for 4-way. Slower when used alone/1-way, but faster when used
|
||||
* parallel/4-way (tested on AMD Phenom II & Intel Xeon E7330).
|
||||
*/
|
||||
#define F4(x) \
|
||||
movzbl x ## bh, RT1d; \
|
||||
movzbl x ## bl, RT3d; \
|
||||
rorq $16, x; \
|
||||
movzbl x ## bh, RT0d; \
|
||||
movzbl x ## bl, RT2d; \
|
||||
rorq $16, x; \
|
||||
movl s0(CTX,RT0,4), RT0d; \
|
||||
addl s1(CTX,RT2,4), RT0d; \
|
||||
xorl s2(CTX,RT1,4), RT0d; \
|
||||
addl s3(CTX,RT3,4), RT0d; \
|
||||
xorq RT0, x;
|
||||
|
||||
#define add_preloaded_roundkey4() \
|
||||
xorq RKEY, RX0; \
|
||||
xorq RKEY, RX1; \
|
||||
xorq RKEY, RX2; \
|
||||
xorq RKEY, RX3;
|
||||
|
||||
#define preload_roundkey_enc(n) \
|
||||
movq p+4*(n)(CTX), RKEY;
|
||||
|
||||
#define add_roundkey_enc4(n) \
|
||||
add_preloaded_roundkey4(); \
|
||||
preload_roundkey_enc(n + 2);
|
||||
|
||||
#define round_enc4(n) \
|
||||
add_roundkey_enc4(n); \
|
||||
\
|
||||
F4(RX0); \
|
||||
F4(RX1); \
|
||||
F4(RX2); \
|
||||
F4(RX3); \
|
||||
\
|
||||
F4(RX0); \
|
||||
F4(RX1); \
|
||||
F4(RX2); \
|
||||
F4(RX3);
|
||||
|
||||
#define preload_roundkey_dec(n) \
|
||||
movq p+4*((n)-1)(CTX), RKEY; \
|
||||
rorq $32, RKEY;
|
||||
|
||||
#define add_roundkey_dec4(n) \
|
||||
add_preloaded_roundkey4(); \
|
||||
preload_roundkey_dec(n - 2);
|
||||
|
||||
#define round_dec4(n) \
|
||||
add_roundkey_dec4(n); \
|
||||
\
|
||||
F4(RX0); \
|
||||
F4(RX1); \
|
||||
F4(RX2); \
|
||||
F4(RX3); \
|
||||
\
|
||||
F4(RX0); \
|
||||
F4(RX1); \
|
||||
F4(RX2); \
|
||||
F4(RX3);
|
||||
|
||||
#define read_block4() \
|
||||
movq (RIO), RX0; \
|
||||
rorq $32, RX0; \
|
||||
bswapq RX0; \
|
||||
\
|
||||
movq 8(RIO), RX1; \
|
||||
rorq $32, RX1; \
|
||||
bswapq RX1; \
|
||||
\
|
||||
movq 16(RIO), RX2; \
|
||||
rorq $32, RX2; \
|
||||
bswapq RX2; \
|
||||
\
|
||||
movq 24(RIO), RX3; \
|
||||
rorq $32, RX3; \
|
||||
bswapq RX3;
|
||||
|
||||
#define write_block4() \
|
||||
bswapq RX0; \
|
||||
movq RX0, (RIO); \
|
||||
\
|
||||
bswapq RX1; \
|
||||
movq RX1, 8(RIO); \
|
||||
\
|
||||
bswapq RX2; \
|
||||
movq RX2, 16(RIO); \
|
||||
\
|
||||
bswapq RX3; \
|
||||
movq RX3, 24(RIO);
|
||||
|
||||
#define xor_block4() \
|
||||
bswapq RX0; \
|
||||
xorq RX0, (RIO); \
|
||||
\
|
||||
bswapq RX1; \
|
||||
xorq RX1, 8(RIO); \
|
||||
\
|
||||
bswapq RX2; \
|
||||
xorq RX2, 16(RIO); \
|
||||
\
|
||||
bswapq RX3; \
|
||||
xorq RX3, 24(RIO);
|
||||
|
||||
.align 8
|
||||
.global __blowfish_enc_blk_4way
|
||||
.type __blowfish_enc_blk_4way,@function;
|
||||
|
||||
__blowfish_enc_blk_4way:
|
||||
/* input:
|
||||
* %rdi: ctx, CTX
|
||||
* %rsi: dst
|
||||
* %rdx: src
|
||||
* %rcx: bool, if true: xor output
|
||||
*/
|
||||
pushq %rbp;
|
||||
pushq %rbx;
|
||||
pushq %rcx;
|
||||
|
||||
preload_roundkey_enc(0);
|
||||
|
||||
movq %rsi, %r11;
|
||||
movq %rdx, RIO;
|
||||
|
||||
read_block4();
|
||||
|
||||
round_enc4(0);
|
||||
round_enc4(2);
|
||||
round_enc4(4);
|
||||
round_enc4(6);
|
||||
round_enc4(8);
|
||||
round_enc4(10);
|
||||
round_enc4(12);
|
||||
round_enc4(14);
|
||||
add_preloaded_roundkey4();
|
||||
|
||||
popq %rbp;
|
||||
movq %r11, RIO;
|
||||
|
||||
test %bpl, %bpl;
|
||||
jnz __enc_xor4;
|
||||
|
||||
write_block4();
|
||||
|
||||
popq %rbx;
|
||||
popq %rbp;
|
||||
ret;
|
||||
|
||||
__enc_xor4:
|
||||
xor_block4();
|
||||
|
||||
popq %rbx;
|
||||
popq %rbp;
|
||||
ret;
|
||||
|
||||
.align 8
|
||||
.global blowfish_dec_blk_4way
|
||||
.type blowfish_dec_blk_4way,@function;
|
||||
|
||||
blowfish_dec_blk_4way:
|
||||
/* input:
|
||||
* %rdi: ctx, CTX
|
||||
* %rsi: dst
|
||||
* %rdx: src
|
||||
*/
|
||||
pushq %rbp;
|
||||
pushq %rbx;
|
||||
preload_roundkey_dec(17);
|
||||
|
||||
movq %rsi, %r11;
|
||||
movq %rdx, RIO;
|
||||
|
||||
read_block4();
|
||||
|
||||
round_dec4(17);
|
||||
round_dec4(15);
|
||||
round_dec4(13);
|
||||
round_dec4(11);
|
||||
round_dec4(9);
|
||||
round_dec4(7);
|
||||
round_dec4(5);
|
||||
round_dec4(3);
|
||||
add_preloaded_roundkey4();
|
||||
|
||||
movq %r11, RIO;
|
||||
write_block4();
|
||||
|
||||
popq %rbx;
|
||||
popq %rbp;
|
||||
|
||||
ret;
|
||||
|
||||
492
arch/x86/crypto/blowfish_glue.c
Normal file
492
arch/x86/crypto/blowfish_glue.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
* Glue Code for assembler optimized version of Blowfish
|
||||
*
|
||||
* Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
*
|
||||
* CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
|
||||
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
* CTR part based on code (crypto/ctr.c) by:
|
||||
* (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <crypto/blowfish.h>
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/algapi.h>
|
||||
|
||||
/* regular block cipher functions */
|
||||
asmlinkage void __blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src,
|
||||
bool xor);
|
||||
asmlinkage void blowfish_dec_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src);
|
||||
|
||||
/* 4-way parallel cipher functions */
|
||||
asmlinkage void __blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
|
||||
const u8 *src, bool xor);
|
||||
asmlinkage void blowfish_dec_blk_4way(struct bf_ctx *ctx, u8 *dst,
|
||||
const u8 *src);
|
||||
|
||||
static inline void blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src)
|
||||
{
|
||||
__blowfish_enc_blk(ctx, dst, src, false);
|
||||
}
|
||||
|
||||
static inline void blowfish_enc_blk_xor(struct bf_ctx *ctx, u8 *dst,
|
||||
const u8 *src)
|
||||
{
|
||||
__blowfish_enc_blk(ctx, dst, src, true);
|
||||
}
|
||||
|
||||
static inline void blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst,
|
||||
const u8 *src)
|
||||
{
|
||||
__blowfish_enc_blk_4way(ctx, dst, src, false);
|
||||
}
|
||||
|
||||
static inline void blowfish_enc_blk_xor_4way(struct bf_ctx *ctx, u8 *dst,
|
||||
const u8 *src)
|
||||
{
|
||||
__blowfish_enc_blk_4way(ctx, dst, src, true);
|
||||
}
|
||||
|
||||
static void blowfish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
blowfish_enc_blk(crypto_tfm_ctx(tfm), dst, src);
|
||||
}
|
||||
|
||||
static void blowfish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
blowfish_dec_blk(crypto_tfm_ctx(tfm), dst, src);
|
||||
}
|
||||
|
||||
static struct crypto_alg bf_alg = {
|
||||
.cra_name = "blowfish",
|
||||
.cra_driver_name = "blowfish-asm",
|
||||
.cra_priority = 200,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||
.cra_blocksize = BF_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct bf_ctx),
|
||||
.cra_alignmask = 3,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(bf_alg.cra_list),
|
||||
.cra_u = {
|
||||
.cipher = {
|
||||
.cia_min_keysize = BF_MIN_KEY_SIZE,
|
||||
.cia_max_keysize = BF_MAX_KEY_SIZE,
|
||||
.cia_setkey = blowfish_setkey,
|
||||
.cia_encrypt = blowfish_encrypt,
|
||||
.cia_decrypt = blowfish_decrypt,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
|
||||
void (*fn)(struct bf_ctx *, u8 *, const u8 *),
|
||||
void (*fn_4way)(struct bf_ctx *, u8 *, const u8 *))
|
||||
{
|
||||
struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = BF_BLOCK_SIZE;
|
||||
unsigned int nbytes;
|
||||
int err;
|
||||
|
||||
err = blkcipher_walk_virt(desc, walk);
|
||||
|
||||
while ((nbytes = walk->nbytes)) {
|
||||
u8 *wsrc = walk->src.virt.addr;
|
||||
u8 *wdst = walk->dst.virt.addr;
|
||||
|
||||
/* Process four block batch */
|
||||
if (nbytes >= bsize * 4) {
|
||||
do {
|
||||
fn_4way(ctx, wdst, wsrc);
|
||||
|
||||
wsrc += bsize * 4;
|
||||
wdst += bsize * 4;
|
||||
nbytes -= bsize * 4;
|
||||
} while (nbytes >= bsize * 4);
|
||||
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Handle leftovers */
|
||||
do {
|
||||
fn(ctx, wdst, wsrc);
|
||||
|
||||
wsrc += bsize;
|
||||
wdst += bsize;
|
||||
nbytes -= bsize;
|
||||
} while (nbytes >= bsize);
|
||||
|
||||
done:
|
||||
err = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_crypt(desc, &walk, blowfish_enc_blk, blowfish_enc_blk_4way);
|
||||
}
|
||||
|
||||
static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_crypt(desc, &walk, blowfish_dec_blk, blowfish_dec_blk_4way);
|
||||
}
|
||||
|
||||
static struct crypto_alg blk_ecb_alg = {
|
||||
.cra_name = "ecb(blowfish)",
|
||||
.cra_driver_name = "ecb-blowfish-asm",
|
||||
.cra_priority = 300,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = BF_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct bf_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = BF_MIN_KEY_SIZE,
|
||||
.max_keysize = BF_MAX_KEY_SIZE,
|
||||
.setkey = blowfish_setkey,
|
||||
.encrypt = ecb_encrypt,
|
||||
.decrypt = ecb_decrypt,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = BF_BLOCK_SIZE;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
u64 *src = (u64 *)walk->src.virt.addr;
|
||||
u64 *dst = (u64 *)walk->dst.virt.addr;
|
||||
u64 *iv = (u64 *)walk->iv;
|
||||
|
||||
do {
|
||||
*dst = *src ^ *iv;
|
||||
blowfish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
|
||||
iv = dst;
|
||||
|
||||
src += 1;
|
||||
dst += 1;
|
||||
nbytes -= bsize;
|
||||
} while (nbytes >= bsize);
|
||||
|
||||
*(u64 *)walk->iv = *iv;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
nbytes = __cbc_encrypt(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = BF_BLOCK_SIZE;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
u64 *src = (u64 *)walk->src.virt.addr;
|
||||
u64 *dst = (u64 *)walk->dst.virt.addr;
|
||||
u64 ivs[4 - 1];
|
||||
u64 last_iv;
|
||||
|
||||
/* Start of the last block. */
|
||||
src += nbytes / bsize - 1;
|
||||
dst += nbytes / bsize - 1;
|
||||
|
||||
last_iv = *src;
|
||||
|
||||
/* Process four block batch */
|
||||
if (nbytes >= bsize * 4) {
|
||||
do {
|
||||
nbytes -= bsize * 4 - bsize;
|
||||
src -= 4 - 1;
|
||||
dst -= 4 - 1;
|
||||
|
||||
ivs[0] = src[0];
|
||||
ivs[1] = src[1];
|
||||
ivs[2] = src[2];
|
||||
|
||||
blowfish_dec_blk_4way(ctx, (u8 *)dst, (u8 *)src);
|
||||
|
||||
dst[1] ^= ivs[0];
|
||||
dst[2] ^= ivs[1];
|
||||
dst[3] ^= ivs[2];
|
||||
|
||||
nbytes -= bsize;
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
|
||||
*dst ^= *(src - 1);
|
||||
src -= 1;
|
||||
dst -= 1;
|
||||
} while (nbytes >= bsize * 4);
|
||||
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Handle leftovers */
|
||||
for (;;) {
|
||||
blowfish_dec_blk(ctx, (u8 *)dst, (u8 *)src);
|
||||
|
||||
nbytes -= bsize;
|
||||
if (nbytes < bsize)
|
||||
break;
|
||||
|
||||
*dst ^= *(src - 1);
|
||||
src -= 1;
|
||||
dst -= 1;
|
||||
}
|
||||
|
||||
done:
|
||||
*dst ^= *(u64 *)walk->iv;
|
||||
*(u64 *)walk->iv = last_iv;
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
nbytes = __cbc_decrypt(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg blk_cbc_alg = {
|
||||
.cra_name = "cbc(blowfish)",
|
||||
.cra_driver_name = "cbc-blowfish-asm",
|
||||
.cra_priority = 300,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = BF_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct bf_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = BF_MIN_KEY_SIZE,
|
||||
.max_keysize = BF_MAX_KEY_SIZE,
|
||||
.ivsize = BF_BLOCK_SIZE,
|
||||
.setkey = blowfish_setkey,
|
||||
.encrypt = cbc_encrypt,
|
||||
.decrypt = cbc_decrypt,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static void ctr_crypt_final(struct bf_ctx *ctx, struct blkcipher_walk *walk)
|
||||
{
|
||||
u8 *ctrblk = walk->iv;
|
||||
u8 keystream[BF_BLOCK_SIZE];
|
||||
u8 *src = walk->src.virt.addr;
|
||||
u8 *dst = walk->dst.virt.addr;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
|
||||
blowfish_enc_blk(ctx, keystream, ctrblk);
|
||||
crypto_xor(keystream, src, nbytes);
|
||||
memcpy(dst, keystream, nbytes);
|
||||
|
||||
crypto_inc(ctrblk, BF_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = BF_BLOCK_SIZE;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
u64 *src = (u64 *)walk->src.virt.addr;
|
||||
u64 *dst = (u64 *)walk->dst.virt.addr;
|
||||
u64 ctrblk = be64_to_cpu(*(__be64 *)walk->iv);
|
||||
__be64 ctrblocks[4];
|
||||
|
||||
/* Process four block batch */
|
||||
if (nbytes >= bsize * 4) {
|
||||
do {
|
||||
if (dst != src) {
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = src[3];
|
||||
}
|
||||
|
||||
/* create ctrblks for parallel encrypt */
|
||||
ctrblocks[0] = cpu_to_be64(ctrblk++);
|
||||
ctrblocks[1] = cpu_to_be64(ctrblk++);
|
||||
ctrblocks[2] = cpu_to_be64(ctrblk++);
|
||||
ctrblocks[3] = cpu_to_be64(ctrblk++);
|
||||
|
||||
blowfish_enc_blk_xor_4way(ctx, (u8 *)dst,
|
||||
(u8 *)ctrblocks);
|
||||
|
||||
src += 4;
|
||||
dst += 4;
|
||||
} while ((nbytes -= bsize * 4) >= bsize * 4);
|
||||
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Handle leftovers */
|
||||
do {
|
||||
if (dst != src)
|
||||
*dst = *src;
|
||||
|
||||
ctrblocks[0] = cpu_to_be64(ctrblk++);
|
||||
|
||||
blowfish_enc_blk_xor(ctx, (u8 *)dst, (u8 *)ctrblocks);
|
||||
|
||||
src += 1;
|
||||
dst += 1;
|
||||
} while ((nbytes -= bsize) >= bsize);
|
||||
|
||||
done:
|
||||
*(__be64 *)walk->iv = cpu_to_be64(ctrblk);
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt_block(desc, &walk, BF_BLOCK_SIZE);
|
||||
|
||||
while ((nbytes = walk.nbytes) >= BF_BLOCK_SIZE) {
|
||||
nbytes = __ctr_crypt(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
if (walk.nbytes) {
|
||||
ctr_crypt_final(crypto_blkcipher_ctx(desc->tfm), &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg blk_ctr_alg = {
|
||||
.cra_name = "ctr(blowfish)",
|
||||
.cra_driver_name = "ctr-blowfish-asm",
|
||||
.cra_priority = 300,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct bf_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = BF_MIN_KEY_SIZE,
|
||||
.max_keysize = BF_MAX_KEY_SIZE,
|
||||
.ivsize = BF_BLOCK_SIZE,
|
||||
.setkey = blowfish_setkey,
|
||||
.encrypt = ctr_crypt,
|
||||
.decrypt = ctr_crypt,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static int __init init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = crypto_register_alg(&bf_alg);
|
||||
if (err)
|
||||
goto bf_err;
|
||||
err = crypto_register_alg(&blk_ecb_alg);
|
||||
if (err)
|
||||
goto ecb_err;
|
||||
err = crypto_register_alg(&blk_cbc_alg);
|
||||
if (err)
|
||||
goto cbc_err;
|
||||
err = crypto_register_alg(&blk_ctr_alg);
|
||||
if (err)
|
||||
goto ctr_err;
|
||||
|
||||
return 0;
|
||||
|
||||
ctr_err:
|
||||
crypto_unregister_alg(&blk_cbc_alg);
|
||||
cbc_err:
|
||||
crypto_unregister_alg(&blk_ecb_alg);
|
||||
ecb_err:
|
||||
crypto_unregister_alg(&bf_alg);
|
||||
bf_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __exit fini(void)
|
||||
{
|
||||
crypto_unregister_alg(&blk_ctr_alg);
|
||||
crypto_unregister_alg(&blk_cbc_alg);
|
||||
crypto_unregister_alg(&blk_ecb_alg);
|
||||
crypto_unregister_alg(&bf_alg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Blowfish Cipher Algorithm, asm optimized");
|
||||
MODULE_ALIAS("blowfish");
|
||||
MODULE_ALIAS("blowfish-asm");
|
||||
558
arch/x86/crypto/sha1_ssse3_asm.S
Normal file
558
arch/x86/crypto/sha1_ssse3_asm.S
Normal file
File diff suppressed because it is too large
Load Diff
240
arch/x86/crypto/sha1_ssse3_glue.c
Normal file
240
arch/x86/crypto/sha1_ssse3_glue.c
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Cryptographic API.
|
||||
*
|
||||
* Glue code for the SHA1 Secure Hash Algorithm assembler implementation using
|
||||
* Supplemental SSE3 instructions.
|
||||
*
|
||||
* This file is based on sha1_generic.c
|
||||
*
|
||||
* Copyright (c) Alan Smithee.
|
||||
* Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk>
|
||||
* Copyright (c) Jean-Francois Dive <jef@linuxbe.org>
|
||||
* Copyright (c) Mathias Krause <minipli@googlemail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <crypto/internal/hash.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/cryptohash.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/sha.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <asm/i387.h>
|
||||
#include <asm/xcr.h>
|
||||
#include <asm/xsave.h>
|
||||
|
||||
|
||||
asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data,
|
||||
unsigned int rounds);
|
||||
#ifdef SHA1_ENABLE_AVX_SUPPORT
|
||||
asmlinkage void sha1_transform_avx(u32 *digest, const char *data,
|
||||
unsigned int rounds);
|
||||
#endif
|
||||
|
||||
static asmlinkage void (*sha1_transform_asm)(u32 *, const char *, unsigned int);
|
||||
|
||||
|
||||
static int sha1_ssse3_init(struct shash_desc *desc)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
*sctx = (struct sha1_state){
|
||||
.state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len, unsigned int partial)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int done = 0;
|
||||
|
||||
sctx->count += len;
|
||||
|
||||
if (partial) {
|
||||
done = SHA1_BLOCK_SIZE - partial;
|
||||
memcpy(sctx->buffer + partial, data, done);
|
||||
sha1_transform_asm(sctx->state, sctx->buffer, 1);
|
||||
}
|
||||
|
||||
if (len - done >= SHA1_BLOCK_SIZE) {
|
||||
const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE;
|
||||
|
||||
sha1_transform_asm(sctx->state, data + done, rounds);
|
||||
done += rounds * SHA1_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
memcpy(sctx->buffer, data + done, len - done);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int partial = sctx->count % SHA1_BLOCK_SIZE;
|
||||
int res;
|
||||
|
||||
/* Handle the fast case right here */
|
||||
if (partial + len < SHA1_BLOCK_SIZE) {
|
||||
sctx->count += len;
|
||||
memcpy(sctx->buffer + partial, data, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!irq_fpu_usable()) {
|
||||
res = crypto_sha1_update(desc, data, len);
|
||||
} else {
|
||||
kernel_fpu_begin();
|
||||
res = __sha1_ssse3_update(desc, data, len, partial);
|
||||
kernel_fpu_end();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/* Add padding and return the message digest. */
|
||||
static int sha1_ssse3_final(struct shash_desc *desc, u8 *out)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
unsigned int i, index, padlen;
|
||||
__be32 *dst = (__be32 *)out;
|
||||
__be64 bits;
|
||||
static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, };
|
||||
|
||||
bits = cpu_to_be64(sctx->count << 3);
|
||||
|
||||
/* Pad out to 56 mod 64 and append length */
|
||||
index = sctx->count % SHA1_BLOCK_SIZE;
|
||||
padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index);
|
||||
if (!irq_fpu_usable()) {
|
||||
crypto_sha1_update(desc, padding, padlen);
|
||||
crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits));
|
||||
} else {
|
||||
kernel_fpu_begin();
|
||||
/* We need to fill a whole block for __sha1_ssse3_update() */
|
||||
if (padlen <= 56) {
|
||||
sctx->count += padlen;
|
||||
memcpy(sctx->buffer + index, padding, padlen);
|
||||
} else {
|
||||
__sha1_ssse3_update(desc, padding, padlen, index);
|
||||
}
|
||||
__sha1_ssse3_update(desc, (const u8 *)&bits, sizeof(bits), 56);
|
||||
kernel_fpu_end();
|
||||
}
|
||||
|
||||
/* Store state in digest */
|
||||
for (i = 0; i < 5; i++)
|
||||
dst[i] = cpu_to_be32(sctx->state[i]);
|
||||
|
||||
/* Wipe context */
|
||||
memset(sctx, 0, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_ssse3_export(struct shash_desc *desc, void *out)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(out, sctx, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sha1_ssse3_import(struct shash_desc *desc, const void *in)
|
||||
{
|
||||
struct sha1_state *sctx = shash_desc_ctx(desc);
|
||||
|
||||
memcpy(sctx, in, sizeof(*sctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct shash_alg alg = {
|
||||
.digestsize = SHA1_DIGEST_SIZE,
|
||||
.init = sha1_ssse3_init,
|
||||
.update = sha1_ssse3_update,
|
||||
.final = sha1_ssse3_final,
|
||||
.export = sha1_ssse3_export,
|
||||
.import = sha1_ssse3_import,
|
||||
.descsize = sizeof(struct sha1_state),
|
||||
.statesize = sizeof(struct sha1_state),
|
||||
.base = {
|
||||
.cra_name = "sha1",
|
||||
.cra_driver_name= "sha1-ssse3",
|
||||
.cra_priority = 150,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_SHASH,
|
||||
.cra_blocksize = SHA1_BLOCK_SIZE,
|
||||
.cra_module = THIS_MODULE,
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SHA1_ENABLE_AVX_SUPPORT
|
||||
static bool __init avx_usable(void)
|
||||
{
|
||||
u64 xcr0;
|
||||
|
||||
if (!cpu_has_avx || !cpu_has_osxsave)
|
||||
return false;
|
||||
|
||||
xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK);
|
||||
if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) {
|
||||
pr_info("AVX detected but unusable.\n");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init sha1_ssse3_mod_init(void)
|
||||
{
|
||||
/* test for SSSE3 first */
|
||||
if (cpu_has_ssse3)
|
||||
sha1_transform_asm = sha1_transform_ssse3;
|
||||
|
||||
#ifdef SHA1_ENABLE_AVX_SUPPORT
|
||||
/* allow AVX to override SSSE3, it's a little faster */
|
||||
if (avx_usable())
|
||||
sha1_transform_asm = sha1_transform_avx;
|
||||
#endif
|
||||
|
||||
if (sha1_transform_asm) {
|
||||
pr_info("Using %s optimized SHA-1 implementation\n",
|
||||
sha1_transform_asm == sha1_transform_ssse3 ? "SSSE3"
|
||||
: "AVX");
|
||||
return crypto_register_shash(&alg);
|
||||
}
|
||||
pr_info("Neither AVX nor SSSE3 is available/usable.\n");
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static void __exit sha1_ssse3_mod_fini(void)
|
||||
{
|
||||
crypto_unregister_shash(&alg);
|
||||
}
|
||||
|
||||
module_init(sha1_ssse3_mod_init);
|
||||
module_exit(sha1_ssse3_mod_fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, Supplemental SSE3 accelerated");
|
||||
|
||||
MODULE_ALIAS("sha1");
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#define in_blk 12 /* input byte array address parameter*/
|
||||
#define out_blk 8 /* output byte array address parameter*/
|
||||
#define tfm 4 /* Twofish context structure */
|
||||
#define ctx 4 /* Twofish context structure */
|
||||
|
||||
#define a_offset 0
|
||||
#define b_offset 4
|
||||
@@ -229,8 +229,8 @@ twofish_enc_blk:
|
||||
push %esi
|
||||
push %edi
|
||||
|
||||
mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
|
||||
add $crypto_tfm_ctx_offset, %ebp /* ctx address */
|
||||
mov ctx + 16(%esp), %ebp /* abuse the base pointer: set new base
|
||||
* pointer to the ctx address */
|
||||
mov in_blk+16(%esp),%edi /* input address in edi */
|
||||
|
||||
mov (%edi), %eax
|
||||
@@ -285,8 +285,8 @@ twofish_dec_blk:
|
||||
push %edi
|
||||
|
||||
|
||||
mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
|
||||
add $crypto_tfm_ctx_offset, %ebp /* ctx address */
|
||||
mov ctx + 16(%esp), %ebp /* abuse the base pointer: set new base
|
||||
* pointer to the ctx address */
|
||||
mov in_blk+16(%esp),%edi /* input address in edi */
|
||||
|
||||
mov (%edi), %eax
|
||||
|
||||
316
arch/x86/crypto/twofish-x86_64-asm_64-3way.S
Normal file
316
arch/x86/crypto/twofish-x86_64-asm_64-3way.S
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Twofish Cipher 3-way parallel algorithm (x86_64)
|
||||
*
|
||||
* Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
*/
|
||||
|
||||
.file "twofish-x86_64-asm-3way.S"
|
||||
.text
|
||||
|
||||
/* structure of crypto context */
|
||||
#define s0 0
|
||||
#define s1 1024
|
||||
#define s2 2048
|
||||
#define s3 3072
|
||||
#define w 4096
|
||||
#define k 4128
|
||||
|
||||
/**********************************************************************
|
||||
3-way twofish
|
||||
**********************************************************************/
|
||||
#define CTX %rdi
|
||||
#define RIO %rdx
|
||||
|
||||
#define RAB0 %rax
|
||||
#define RAB1 %rbx
|
||||
#define RAB2 %rcx
|
||||
|
||||
#define RAB0d %eax
|
||||
#define RAB1d %ebx
|
||||
#define RAB2d %ecx
|
||||
|
||||
#define RAB0bh %ah
|
||||
#define RAB1bh %bh
|
||||
#define RAB2bh %ch
|
||||
|
||||
#define RAB0bl %al
|
||||
#define RAB1bl %bl
|
||||
#define RAB2bl %cl
|
||||
|
||||
#define RCD0 %r8
|
||||
#define RCD1 %r9
|
||||
#define RCD2 %r10
|
||||
|
||||
#define RCD0d %r8d
|
||||
#define RCD1d %r9d
|
||||
#define RCD2d %r10d
|
||||
|
||||
#define RX0 %rbp
|
||||
#define RX1 %r11
|
||||
#define RX2 %r12
|
||||
|
||||
#define RX0d %ebp
|
||||
#define RX1d %r11d
|
||||
#define RX2d %r12d
|
||||
|
||||
#define RY0 %r13
|
||||
#define RY1 %r14
|
||||
#define RY2 %r15
|
||||
|
||||
#define RY0d %r13d
|
||||
#define RY1d %r14d
|
||||
#define RY2d %r15d
|
||||
|
||||
#define RT0 %rdx
|
||||
#define RT1 %rsi
|
||||
|
||||
#define RT0d %edx
|
||||
#define RT1d %esi
|
||||
|
||||
#define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
|
||||
movzbl ab ## bl, tmp2 ## d; \
|
||||
movzbl ab ## bh, tmp1 ## d; \
|
||||
rorq $(rot), ab; \
|
||||
op1##l T0(CTX, tmp2, 4), dst ## d; \
|
||||
op2##l T1(CTX, tmp1, 4), dst ## d;
|
||||
|
||||
/*
|
||||
* Combined G1 & G2 function. Reordered with help of rotates to have moves
|
||||
* at begining.
|
||||
*/
|
||||
#define g1g2_3(ab, cd, Tx0, Tx1, Tx2, Tx3, Ty0, Ty1, Ty2, Ty3, x, y) \
|
||||
/* G1,1 && G2,1 */ \
|
||||
do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 0, ab ## 0, x ## 0); \
|
||||
do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 0, ab ## 0, y ## 0); \
|
||||
\
|
||||
do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 1, ab ## 1, x ## 1); \
|
||||
do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 1, ab ## 1, y ## 1); \
|
||||
\
|
||||
do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 2, ab ## 2, x ## 2); \
|
||||
do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 2, ab ## 2, y ## 2); \
|
||||
\
|
||||
/* G1,2 && G2,2 */ \
|
||||
do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
|
||||
do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
|
||||
xchgq cd ## 0, ab ## 0; \
|
||||
\
|
||||
do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
|
||||
do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
|
||||
xchgq cd ## 1, ab ## 1; \
|
||||
\
|
||||
do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
|
||||
do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
|
||||
xchgq cd ## 2, ab ## 2;
|
||||
|
||||
#define enc_round_end(ab, x, y, n) \
|
||||
addl y ## d, x ## d; \
|
||||
addl x ## d, y ## d; \
|
||||
addl k+4*(2*(n))(CTX), x ## d; \
|
||||
xorl ab ## d, x ## d; \
|
||||
addl k+4*(2*(n)+1)(CTX), y ## d; \
|
||||
shrq $32, ab; \
|
||||
roll $1, ab ## d; \
|
||||
xorl y ## d, ab ## d; \
|
||||
shlq $32, ab; \
|
||||
rorl $1, x ## d; \
|
||||
orq x, ab;
|
||||
|
||||
#define dec_round_end(ba, x, y, n) \
|
||||
addl y ## d, x ## d; \
|
||||
addl x ## d, y ## d; \
|
||||
addl k+4*(2*(n))(CTX), x ## d; \
|
||||
addl k+4*(2*(n)+1)(CTX), y ## d; \
|
||||
xorl ba ## d, y ## d; \
|
||||
shrq $32, ba; \
|
||||
roll $1, ba ## d; \
|
||||
xorl x ## d, ba ## d; \
|
||||
shlq $32, ba; \
|
||||
rorl $1, y ## d; \
|
||||
orq y, ba;
|
||||
|
||||
#define encrypt_round3(ab, cd, n) \
|
||||
g1g2_3(ab, cd, s0, s1, s2, s3, s0, s1, s2, s3, RX, RY); \
|
||||
\
|
||||
enc_round_end(ab ## 0, RX0, RY0, n); \
|
||||
enc_round_end(ab ## 1, RX1, RY1, n); \
|
||||
enc_round_end(ab ## 2, RX2, RY2, n);
|
||||
|
||||
#define decrypt_round3(ba, dc, n) \
|
||||
g1g2_3(ba, dc, s1, s2, s3, s0, s3, s0, s1, s2, RY, RX); \
|
||||
\
|
||||
dec_round_end(ba ## 0, RX0, RY0, n); \
|
||||
dec_round_end(ba ## 1, RX1, RY1, n); \
|
||||
dec_round_end(ba ## 2, RX2, RY2, n);
|
||||
|
||||
#define encrypt_cycle3(ab, cd, n) \
|
||||
encrypt_round3(ab, cd, n*2); \
|
||||
encrypt_round3(ab, cd, (n*2)+1);
|
||||
|
||||
#define decrypt_cycle3(ba, dc, n) \
|
||||
decrypt_round3(ba, dc, (n*2)+1); \
|
||||
decrypt_round3(ba, dc, (n*2));
|
||||
|
||||
#define inpack3(in, n, xy, m) \
|
||||
movq 4*(n)(in), xy ## 0; \
|
||||
xorq w+4*m(CTX), xy ## 0; \
|
||||
\
|
||||
movq 4*(4+(n))(in), xy ## 1; \
|
||||
xorq w+4*m(CTX), xy ## 1; \
|
||||
\
|
||||
movq 4*(8+(n))(in), xy ## 2; \
|
||||
xorq w+4*m(CTX), xy ## 2;
|
||||
|
||||
#define outunpack3(op, out, n, xy, m) \
|
||||
xorq w+4*m(CTX), xy ## 0; \
|
||||
op ## q xy ## 0, 4*(n)(out); \
|
||||
\
|
||||
xorq w+4*m(CTX), xy ## 1; \
|
||||
op ## q xy ## 1, 4*(4+(n))(out); \
|
||||
\
|
||||
xorq w+4*m(CTX), xy ## 2; \
|
||||
op ## q xy ## 2, 4*(8+(n))(out);
|
||||
|
||||
#define inpack_enc3() \
|
||||
inpack3(RIO, 0, RAB, 0); \
|
||||
inpack3(RIO, 2, RCD, 2);
|
||||
|
||||
#define outunpack_enc3(op) \
|
||||
outunpack3(op, RIO, 2, RAB, 6); \
|
||||
outunpack3(op, RIO, 0, RCD, 4);
|
||||
|
||||
#define inpack_dec3() \
|
||||
inpack3(RIO, 0, RAB, 4); \
|
||||
rorq $32, RAB0; \
|
||||
rorq $32, RAB1; \
|
||||
rorq $32, RAB2; \
|
||||
inpack3(RIO, 2, RCD, 6); \
|
||||
rorq $32, RCD0; \
|
||||
rorq $32, RCD1; \
|
||||
rorq $32, RCD2;
|
||||
|
||||
#define outunpack_dec3() \
|
||||
rorq $32, RCD0; \
|
||||
rorq $32, RCD1; \
|
||||
rorq $32, RCD2; \
|
||||
outunpack3(mov, RIO, 0, RCD, 0); \
|
||||
rorq $32, RAB0; \
|
||||
rorq $32, RAB1; \
|
||||
rorq $32, RAB2; \
|
||||
outunpack3(mov, RIO, 2, RAB, 2);
|
||||
|
||||
.align 8
|
||||
.global __twofish_enc_blk_3way
|
||||
.type __twofish_enc_blk_3way,@function;
|
||||
|
||||
__twofish_enc_blk_3way:
|
||||
/* input:
|
||||
* %rdi: ctx, CTX
|
||||
* %rsi: dst
|
||||
* %rdx: src, RIO
|
||||
* %rcx: bool, if true: xor output
|
||||
*/
|
||||
pushq %r15;
|
||||
pushq %r14;
|
||||
pushq %r13;
|
||||
pushq %r12;
|
||||
pushq %rbp;
|
||||
pushq %rbx;
|
||||
|
||||
pushq %rcx; /* bool xor */
|
||||
pushq %rsi; /* dst */
|
||||
|
||||
inpack_enc3();
|
||||
|
||||
encrypt_cycle3(RAB, RCD, 0);
|
||||
encrypt_cycle3(RAB, RCD, 1);
|
||||
encrypt_cycle3(RAB, RCD, 2);
|
||||
encrypt_cycle3(RAB, RCD, 3);
|
||||
encrypt_cycle3(RAB, RCD, 4);
|
||||
encrypt_cycle3(RAB, RCD, 5);
|
||||
encrypt_cycle3(RAB, RCD, 6);
|
||||
encrypt_cycle3(RAB, RCD, 7);
|
||||
|
||||
popq RIO; /* dst */
|
||||
popq %rbp; /* bool xor */
|
||||
|
||||
testb %bpl, %bpl;
|
||||
jnz __enc_xor3;
|
||||
|
||||
outunpack_enc3(mov);
|
||||
|
||||
popq %rbx;
|
||||
popq %rbp;
|
||||
popq %r12;
|
||||
popq %r13;
|
||||
popq %r14;
|
||||
popq %r15;
|
||||
ret;
|
||||
|
||||
__enc_xor3:
|
||||
outunpack_enc3(xor);
|
||||
|
||||
popq %rbx;
|
||||
popq %rbp;
|
||||
popq %r12;
|
||||
popq %r13;
|
||||
popq %r14;
|
||||
popq %r15;
|
||||
ret;
|
||||
|
||||
.global twofish_dec_blk_3way
|
||||
.type twofish_dec_blk_3way,@function;
|
||||
|
||||
twofish_dec_blk_3way:
|
||||
/* input:
|
||||
* %rdi: ctx, CTX
|
||||
* %rsi: dst
|
||||
* %rdx: src, RIO
|
||||
*/
|
||||
pushq %r15;
|
||||
pushq %r14;
|
||||
pushq %r13;
|
||||
pushq %r12;
|
||||
pushq %rbp;
|
||||
pushq %rbx;
|
||||
|
||||
pushq %rsi; /* dst */
|
||||
|
||||
inpack_dec3();
|
||||
|
||||
decrypt_cycle3(RAB, RCD, 7);
|
||||
decrypt_cycle3(RAB, RCD, 6);
|
||||
decrypt_cycle3(RAB, RCD, 5);
|
||||
decrypt_cycle3(RAB, RCD, 4);
|
||||
decrypt_cycle3(RAB, RCD, 3);
|
||||
decrypt_cycle3(RAB, RCD, 2);
|
||||
decrypt_cycle3(RAB, RCD, 1);
|
||||
decrypt_cycle3(RAB, RCD, 0);
|
||||
|
||||
popq RIO; /* dst */
|
||||
|
||||
outunpack_dec3();
|
||||
|
||||
popq %rbx;
|
||||
popq %rbp;
|
||||
popq %r12;
|
||||
popq %r13;
|
||||
popq %r14;
|
||||
popq %r15;
|
||||
ret;
|
||||
|
||||
@@ -221,10 +221,9 @@
|
||||
twofish_enc_blk:
|
||||
pushq R1
|
||||
|
||||
/* %rdi contains the crypto tfm address */
|
||||
/* %rdi contains the ctx address */
|
||||
/* %rsi contains the output address */
|
||||
/* %rdx contains the input address */
|
||||
add $crypto_tfm_ctx_offset, %rdi /* set ctx address */
|
||||
/* ctx address is moved to free one non-rex register
|
||||
as target for the 8bit high operations */
|
||||
mov %rdi, %r11
|
||||
@@ -274,10 +273,9 @@ twofish_enc_blk:
|
||||
twofish_dec_blk:
|
||||
pushq R1
|
||||
|
||||
/* %rdi contains the crypto tfm address */
|
||||
/* %rdi contains the ctx address */
|
||||
/* %rsi contains the output address */
|
||||
/* %rdx contains the input address */
|
||||
add $crypto_tfm_ctx_offset, %rdi /* set ctx address */
|
||||
/* ctx address is moved to free one non-rex register
|
||||
as target for the 8bit high operations */
|
||||
mov %rdi, %r11
|
||||
|
||||
@@ -44,17 +44,21 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
|
||||
asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
|
||||
asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src);
|
||||
EXPORT_SYMBOL_GPL(twofish_enc_blk);
|
||||
asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src);
|
||||
EXPORT_SYMBOL_GPL(twofish_dec_blk);
|
||||
|
||||
static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
twofish_enc_blk(tfm, dst, src);
|
||||
twofish_enc_blk(crypto_tfm_ctx(tfm), dst, src);
|
||||
}
|
||||
|
||||
static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||
{
|
||||
twofish_dec_blk(tfm, dst, src);
|
||||
twofish_dec_blk(crypto_tfm_ctx(tfm), dst, src);
|
||||
}
|
||||
|
||||
static struct crypto_alg alg = {
|
||||
|
||||
472
arch/x86/crypto/twofish_glue_3way.c
Normal file
472
arch/x86/crypto/twofish_glue_3way.c
Normal file
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
* Glue Code for 3-way parallel assembler optimized version of Twofish
|
||||
*
|
||||
* Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
|
||||
*
|
||||
* CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by:
|
||||
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
|
||||
* CTR part based on code (crypto/ctr.c) by:
|
||||
* (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/crypto.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <crypto/algapi.h>
|
||||
#include <crypto/twofish.h>
|
||||
#include <crypto/b128ops.h>
|
||||
|
||||
/* regular block cipher functions from twofish_x86_64 module */
|
||||
asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src);
|
||||
asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src);
|
||||
|
||||
/* 3-way parallel cipher functions */
|
||||
asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src, bool xor);
|
||||
asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src);
|
||||
|
||||
static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src)
|
||||
{
|
||||
__twofish_enc_blk_3way(ctx, dst, src, false);
|
||||
}
|
||||
|
||||
static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst,
|
||||
const u8 *src)
|
||||
{
|
||||
__twofish_enc_blk_3way(ctx, dst, src, true);
|
||||
}
|
||||
|
||||
static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk,
|
||||
void (*fn)(struct twofish_ctx *, u8 *, const u8 *),
|
||||
void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *))
|
||||
{
|
||||
struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = TF_BLOCK_SIZE;
|
||||
unsigned int nbytes;
|
||||
int err;
|
||||
|
||||
err = blkcipher_walk_virt(desc, walk);
|
||||
|
||||
while ((nbytes = walk->nbytes)) {
|
||||
u8 *wsrc = walk->src.virt.addr;
|
||||
u8 *wdst = walk->dst.virt.addr;
|
||||
|
||||
/* Process three block batch */
|
||||
if (nbytes >= bsize * 3) {
|
||||
do {
|
||||
fn_3way(ctx, wdst, wsrc);
|
||||
|
||||
wsrc += bsize * 3;
|
||||
wdst += bsize * 3;
|
||||
nbytes -= bsize * 3;
|
||||
} while (nbytes >= bsize * 3);
|
||||
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Handle leftovers */
|
||||
do {
|
||||
fn(ctx, wdst, wsrc);
|
||||
|
||||
wsrc += bsize;
|
||||
wdst += bsize;
|
||||
nbytes -= bsize;
|
||||
} while (nbytes >= bsize);
|
||||
|
||||
done:
|
||||
err = blkcipher_walk_done(desc, walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way);
|
||||
}
|
||||
|
||||
static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way);
|
||||
}
|
||||
|
||||
static struct crypto_alg blk_ecb_alg = {
|
||||
.cra_name = "ecb(twofish)",
|
||||
.cra_driver_name = "ecb-twofish-3way",
|
||||
.cra_priority = 300,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = TF_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct twofish_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = TF_MIN_KEY_SIZE,
|
||||
.max_keysize = TF_MAX_KEY_SIZE,
|
||||
.setkey = twofish_setkey,
|
||||
.encrypt = ecb_encrypt,
|
||||
.decrypt = ecb_decrypt,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static unsigned int __cbc_encrypt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = TF_BLOCK_SIZE;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
u128 *src = (u128 *)walk->src.virt.addr;
|
||||
u128 *dst = (u128 *)walk->dst.virt.addr;
|
||||
u128 *iv = (u128 *)walk->iv;
|
||||
|
||||
do {
|
||||
u128_xor(dst, src, iv);
|
||||
twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst);
|
||||
iv = dst;
|
||||
|
||||
src += 1;
|
||||
dst += 1;
|
||||
nbytes -= bsize;
|
||||
} while (nbytes >= bsize);
|
||||
|
||||
u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv);
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
nbytes = __cbc_encrypt(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static unsigned int __cbc_decrypt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = TF_BLOCK_SIZE;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
u128 *src = (u128 *)walk->src.virt.addr;
|
||||
u128 *dst = (u128 *)walk->dst.virt.addr;
|
||||
u128 ivs[3 - 1];
|
||||
u128 last_iv;
|
||||
|
||||
/* Start of the last block. */
|
||||
src += nbytes / bsize - 1;
|
||||
dst += nbytes / bsize - 1;
|
||||
|
||||
last_iv = *src;
|
||||
|
||||
/* Process three block batch */
|
||||
if (nbytes >= bsize * 3) {
|
||||
do {
|
||||
nbytes -= bsize * (3 - 1);
|
||||
src -= 3 - 1;
|
||||
dst -= 3 - 1;
|
||||
|
||||
ivs[0] = src[0];
|
||||
ivs[1] = src[1];
|
||||
|
||||
twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src);
|
||||
|
||||
u128_xor(dst + 1, dst + 1, ivs + 0);
|
||||
u128_xor(dst + 2, dst + 2, ivs + 1);
|
||||
|
||||
nbytes -= bsize;
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
|
||||
u128_xor(dst, dst, src - 1);
|
||||
src -= 1;
|
||||
dst -= 1;
|
||||
} while (nbytes >= bsize * 3);
|
||||
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Handle leftovers */
|
||||
for (;;) {
|
||||
twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src);
|
||||
|
||||
nbytes -= bsize;
|
||||
if (nbytes < bsize)
|
||||
break;
|
||||
|
||||
u128_xor(dst, dst, src - 1);
|
||||
src -= 1;
|
||||
dst -= 1;
|
||||
}
|
||||
|
||||
done:
|
||||
u128_xor(dst, dst, (u128 *)walk->iv);
|
||||
*(u128 *)walk->iv = last_iv;
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt(desc, &walk);
|
||||
|
||||
while ((nbytes = walk.nbytes)) {
|
||||
nbytes = __cbc_decrypt(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg blk_cbc_alg = {
|
||||
.cra_name = "cbc(twofish)",
|
||||
.cra_driver_name = "cbc-twofish-3way",
|
||||
.cra_priority = 300,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = TF_BLOCK_SIZE,
|
||||
.cra_ctxsize = sizeof(struct twofish_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = TF_MIN_KEY_SIZE,
|
||||
.max_keysize = TF_MAX_KEY_SIZE,
|
||||
.ivsize = TF_BLOCK_SIZE,
|
||||
.setkey = twofish_setkey,
|
||||
.encrypt = cbc_encrypt,
|
||||
.decrypt = cbc_decrypt,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static inline void u128_to_be128(be128 *dst, const u128 *src)
|
||||
{
|
||||
dst->a = cpu_to_be64(src->a);
|
||||
dst->b = cpu_to_be64(src->b);
|
||||
}
|
||||
|
||||
static inline void be128_to_u128(u128 *dst, const be128 *src)
|
||||
{
|
||||
dst->a = be64_to_cpu(src->a);
|
||||
dst->b = be64_to_cpu(src->b);
|
||||
}
|
||||
|
||||
static inline void u128_inc(u128 *i)
|
||||
{
|
||||
i->b++;
|
||||
if (!i->b)
|
||||
i->a++;
|
||||
}
|
||||
|
||||
static void ctr_crypt_final(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
u8 *ctrblk = walk->iv;
|
||||
u8 keystream[TF_BLOCK_SIZE];
|
||||
u8 *src = walk->src.virt.addr;
|
||||
u8 *dst = walk->dst.virt.addr;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
|
||||
twofish_enc_blk(ctx, keystream, ctrblk);
|
||||
crypto_xor(keystream, src, nbytes);
|
||||
memcpy(dst, keystream, nbytes);
|
||||
|
||||
crypto_inc(ctrblk, TF_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
static unsigned int __ctr_crypt(struct blkcipher_desc *desc,
|
||||
struct blkcipher_walk *walk)
|
||||
{
|
||||
struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
|
||||
unsigned int bsize = TF_BLOCK_SIZE;
|
||||
unsigned int nbytes = walk->nbytes;
|
||||
u128 *src = (u128 *)walk->src.virt.addr;
|
||||
u128 *dst = (u128 *)walk->dst.virt.addr;
|
||||
u128 ctrblk;
|
||||
be128 ctrblocks[3];
|
||||
|
||||
be128_to_u128(&ctrblk, (be128 *)walk->iv);
|
||||
|
||||
/* Process three block batch */
|
||||
if (nbytes >= bsize * 3) {
|
||||
do {
|
||||
if (dst != src) {
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
}
|
||||
|
||||
/* create ctrblks for parallel encrypt */
|
||||
u128_to_be128(&ctrblocks[0], &ctrblk);
|
||||
u128_inc(&ctrblk);
|
||||
u128_to_be128(&ctrblocks[1], &ctrblk);
|
||||
u128_inc(&ctrblk);
|
||||
u128_to_be128(&ctrblocks[2], &ctrblk);
|
||||
u128_inc(&ctrblk);
|
||||
|
||||
twofish_enc_blk_xor_3way(ctx, (u8 *)dst,
|
||||
(u8 *)ctrblocks);
|
||||
|
||||
src += 3;
|
||||
dst += 3;
|
||||
nbytes -= bsize * 3;
|
||||
} while (nbytes >= bsize * 3);
|
||||
|
||||
if (nbytes < bsize)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Handle leftovers */
|
||||
do {
|
||||
if (dst != src)
|
||||
*dst = *src;
|
||||
|
||||
u128_to_be128(&ctrblocks[0], &ctrblk);
|
||||
u128_inc(&ctrblk);
|
||||
|
||||
twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks);
|
||||
u128_xor(dst, dst, (u128 *)ctrblocks);
|
||||
|
||||
src += 1;
|
||||
dst += 1;
|
||||
nbytes -= bsize;
|
||||
} while (nbytes >= bsize);
|
||||
|
||||
done:
|
||||
u128_to_be128((be128 *)walk->iv, &ctrblk);
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
|
||||
struct scatterlist *src, unsigned int nbytes)
|
||||
{
|
||||
struct blkcipher_walk walk;
|
||||
int err;
|
||||
|
||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||
err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE);
|
||||
|
||||
while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) {
|
||||
nbytes = __ctr_crypt(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, nbytes);
|
||||
}
|
||||
|
||||
if (walk.nbytes) {
|
||||
ctr_crypt_final(desc, &walk);
|
||||
err = blkcipher_walk_done(desc, &walk, 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct crypto_alg blk_ctr_alg = {
|
||||
.cra_name = "ctr(twofish)",
|
||||
.cra_driver_name = "ctr-twofish-3way",
|
||||
.cra_priority = 300,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.cra_blocksize = 1,
|
||||
.cra_ctxsize = sizeof(struct twofish_ctx),
|
||||
.cra_alignmask = 0,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list),
|
||||
.cra_u = {
|
||||
.blkcipher = {
|
||||
.min_keysize = TF_MIN_KEY_SIZE,
|
||||
.max_keysize = TF_MAX_KEY_SIZE,
|
||||
.ivsize = TF_BLOCK_SIZE,
|
||||
.setkey = twofish_setkey,
|
||||
.encrypt = ctr_crypt,
|
||||
.decrypt = ctr_crypt,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
int __init init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = crypto_register_alg(&blk_ecb_alg);
|
||||
if (err)
|
||||
goto ecb_err;
|
||||
err = crypto_register_alg(&blk_cbc_alg);
|
||||
if (err)
|
||||
goto cbc_err;
|
||||
err = crypto_register_alg(&blk_ctr_alg);
|
||||
if (err)
|
||||
goto ctr_err;
|
||||
|
||||
return 0;
|
||||
|
||||
ctr_err:
|
||||
crypto_unregister_alg(&blk_cbc_alg);
|
||||
cbc_err:
|
||||
crypto_unregister_alg(&blk_ecb_alg);
|
||||
ecb_err:
|
||||
return err;
|
||||
}
|
||||
|
||||
void __exit fini(void)
|
||||
{
|
||||
crypto_unregister_alg(&blk_ctr_alg);
|
||||
crypto_unregister_alg(&blk_cbc_alg);
|
||||
crypto_unregister_alg(&blk_ecb_alg);
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
module_exit(fini);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized");
|
||||
MODULE_ALIAS("twofish");
|
||||
MODULE_ALIAS("twofish-asm");
|
||||
@@ -259,7 +259,9 @@ extern const char * const x86_power_flags[32];
|
||||
#define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM)
|
||||
#define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2)
|
||||
#define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3)
|
||||
#define cpu_has_ssse3 boot_cpu_has(X86_FEATURE_SSSE3)
|
||||
#define cpu_has_aes boot_cpu_has(X86_FEATURE_AES)
|
||||
#define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX)
|
||||
#define cpu_has_ht boot_cpu_has(X86_FEATURE_HT)
|
||||
#define cpu_has_mp boot_cpu_has(X86_FEATURE_MP)
|
||||
#define cpu_has_nx boot_cpu_has(X86_FEATURE_NX)
|
||||
@@ -287,6 +289,7 @@ extern const char * const x86_power_flags[32];
|
||||
#define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2)
|
||||
#define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC)
|
||||
#define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE)
|
||||
#define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE)
|
||||
#define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR)
|
||||
#define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ)
|
||||
#define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE)
|
||||
|
||||
@@ -100,6 +100,14 @@ config CRYPTO_MANAGER2
|
||||
select CRYPTO_BLKCIPHER2
|
||||
select CRYPTO_PCOMP2
|
||||
|
||||
config CRYPTO_USER
|
||||
tristate "Userspace cryptographic algorithm configuration"
|
||||
depends on NET
|
||||
select CRYPTO_MANAGER
|
||||
help
|
||||
Userapace configuration for cryptographic instantiations such as
|
||||
cbc(aes).
|
||||
|
||||
config CRYPTO_MANAGER_DISABLE_TESTS
|
||||
bool "Disable run-time self tests"
|
||||
default y
|
||||
@@ -407,6 +415,16 @@ config CRYPTO_SHA1
|
||||
help
|
||||
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
|
||||
|
||||
config CRYPTO_SHA1_SSSE3
|
||||
tristate "SHA1 digest algorithm (SSSE3/AVX)"
|
||||
depends on X86 && 64BIT
|
||||
select CRYPTO_SHA1
|
||||
select CRYPTO_HASH
|
||||
help
|
||||
SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented
|
||||
using Supplemental SSE3 (SSSE3) instructions or Advanced Vector
|
||||
Extensions (AVX), when available.
|
||||
|
||||
config CRYPTO_SHA256
|
||||
tristate "SHA224 and SHA256 digest algorithm"
|
||||
select CRYPTO_HASH
|
||||
@@ -590,6 +608,7 @@ config CRYPTO_ARC4
|
||||
config CRYPTO_BLOWFISH
|
||||
tristate "Blowfish cipher algorithm"
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_BLOWFISH_COMMON
|
||||
help
|
||||
Blowfish cipher algorithm, by Bruce Schneier.
|
||||
|
||||
@@ -600,6 +619,30 @@ config CRYPTO_BLOWFISH
|
||||
See also:
|
||||
<http://www.schneier.com/blowfish.html>
|
||||
|
||||
config CRYPTO_BLOWFISH_COMMON
|
||||
tristate
|
||||
help
|
||||
Common parts of the Blowfish cipher algorithm shared by the
|
||||
generic c and the assembler implementations.
|
||||
|
||||
See also:
|
||||
<http://www.schneier.com/blowfish.html>
|
||||
|
||||
config CRYPTO_BLOWFISH_X86_64
|
||||
tristate "Blowfish cipher algorithm (x86_64)"
|
||||
depends on (X86 || UML_X86) && 64BIT
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_BLOWFISH_COMMON
|
||||
help
|
||||
Blowfish cipher algorithm (x86_64), by Bruce Schneier.
|
||||
|
||||
This is a variable key length cipher which can use keys from 32
|
||||
bits to 448 bits in length. It's fast, simple and specifically
|
||||
designed for use on "large microprocessors".
|
||||
|
||||
See also:
|
||||
<http://www.schneier.com/blowfish.html>
|
||||
|
||||
config CRYPTO_CAMELLIA
|
||||
tristate "Camellia cipher algorithms"
|
||||
depends on CRYPTO
|
||||
@@ -793,6 +836,26 @@ config CRYPTO_TWOFISH_X86_64
|
||||
See also:
|
||||
<http://www.schneier.com/twofish.html>
|
||||
|
||||
config CRYPTO_TWOFISH_X86_64_3WAY
|
||||
tristate "Twofish cipher algorithm (x86_64, 3-way parallel)"
|
||||
depends on (X86 || UML_X86) && 64BIT
|
||||
select CRYPTO_ALGAPI
|
||||
select CRYPTO_TWOFISH_COMMON
|
||||
select CRYPTO_TWOFISH_X86_64
|
||||
help
|
||||
Twofish cipher algorithm (x86_64, 3-way parallel).
|
||||
|
||||
Twofish was submitted as an AES (Advanced Encryption Standard)
|
||||
candidate cipher by researchers at CounterPane Systems. It is a
|
||||
16 round block cipher supporting key sizes of 128, 192, and 256
|
||||
bits.
|
||||
|
||||
This module provides Twofish cipher algorithm that processes three
|
||||
blocks parallel, utilizing resources of out-of-order CPUs better.
|
||||
|
||||
See also:
|
||||
<http://www.schneier.com/twofish.html>
|
||||
|
||||
comment "Compression"
|
||||
|
||||
config CRYPTO_DEFLATE
|
||||
|
||||
@@ -31,6 +31,7 @@ obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
|
||||
cryptomgr-y := algboss.o testmgr.o
|
||||
|
||||
obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
|
||||
obj-$(CONFIG_CRYPTO_USER) += crypto_user.o
|
||||
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
|
||||
obj-$(CONFIG_CRYPTO_VMAC) += vmac.o
|
||||
obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
|
||||
@@ -60,7 +61,8 @@ obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
|
||||
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
|
||||
obj-$(CONFIG_CRYPTO_DES) += des_generic.o
|
||||
obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
|
||||
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
|
||||
obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish_generic.o
|
||||
obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
|
||||
obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
|
||||
obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include <crypto/scatterwalk.h>
|
||||
|
||||
@@ -381,6 +383,28 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_blkcipher rblkcipher;
|
||||
|
||||
snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher");
|
||||
snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
|
||||
alg->cra_ablkcipher.geniv ?: "<default>");
|
||||
|
||||
rblkcipher.blocksize = alg->cra_blocksize;
|
||||
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
|
||||
rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
|
||||
rblkcipher.ivsize = alg->cra_ablkcipher.ivsize;
|
||||
|
||||
NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
|
||||
sizeof(struct crypto_report_blkcipher), &rblkcipher);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__attribute__ ((unused));
|
||||
static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
@@ -403,6 +427,7 @@ const struct crypto_type crypto_ablkcipher_type = {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_ablkcipher_show,
|
||||
#endif
|
||||
.report = crypto_ablkcipher_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
|
||||
|
||||
@@ -432,6 +457,28 @@ static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_blkcipher rblkcipher;
|
||||
|
||||
snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher");
|
||||
snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
|
||||
alg->cra_ablkcipher.geniv ?: "<built-in>");
|
||||
|
||||
rblkcipher.blocksize = alg->cra_blocksize;
|
||||
rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize;
|
||||
rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize;
|
||||
rblkcipher.ivsize = alg->cra_ablkcipher.ivsize;
|
||||
|
||||
NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
|
||||
sizeof(struct crypto_report_blkcipher), &rblkcipher);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__attribute__ ((unused));
|
||||
static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
@@ -454,6 +501,7 @@ const struct crypto_type crypto_givcipher_type = {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_givcipher_show,
|
||||
#endif
|
||||
.report = crypto_givcipher_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_givcipher_type);
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -109,6 +111,28 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_aead raead;
|
||||
struct aead_alg *aead = &alg->cra_aead;
|
||||
|
||||
snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead");
|
||||
snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s",
|
||||
aead->geniv ?: "<built-in>");
|
||||
|
||||
raead.blocksize = alg->cra_blocksize;
|
||||
raead.maxauthsize = aead->maxauthsize;
|
||||
raead.ivsize = aead->ivsize;
|
||||
|
||||
NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD,
|
||||
sizeof(struct crypto_report_aead), &raead);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__attribute__ ((unused));
|
||||
static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
@@ -130,6 +154,7 @@ const struct crypto_type crypto_aead_type = {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_aead_show,
|
||||
#endif
|
||||
.report = crypto_aead_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_aead_type);
|
||||
|
||||
@@ -165,6 +190,28 @@ static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_aead raead;
|
||||
struct aead_alg *aead = &alg->cra_aead;
|
||||
|
||||
snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead");
|
||||
snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv);
|
||||
|
||||
raead.blocksize = alg->cra_blocksize;
|
||||
raead.maxauthsize = aead->maxauthsize;
|
||||
raead.ivsize = aead->ivsize;
|
||||
|
||||
NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD,
|
||||
sizeof(struct crypto_report_aead), &raead);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
|
||||
static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__attribute__ ((unused));
|
||||
static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
@@ -186,6 +233,7 @@ const struct crypto_type crypto_nivaead_type = {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_nivaead_show,
|
||||
#endif
|
||||
.report = crypto_nivaead_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_nivaead_type);
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -397,6 +399,24 @@ static unsigned int crypto_ahash_extsize(struct crypto_alg *alg)
|
||||
return sizeof(struct crypto_shash *);
|
||||
}
|
||||
|
||||
static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_hash rhash;
|
||||
|
||||
snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash");
|
||||
|
||||
rhash.blocksize = alg->cra_blocksize;
|
||||
rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize;
|
||||
|
||||
NLA_PUT(skb, CRYPTOCFGA_REPORT_HASH,
|
||||
sizeof(struct crypto_report_hash), &rhash);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__attribute__ ((unused));
|
||||
static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
@@ -415,6 +435,7 @@ const struct crypto_type crypto_ahash_type = {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_ahash_show,
|
||||
#endif
|
||||
.report = crypto_ahash_report,
|
||||
.maskclear = ~CRYPTO_ALG_TYPE_MASK,
|
||||
.maskset = CRYPTO_ALG_TYPE_AHASH_MASK,
|
||||
.type = CRYPTO_ALG_TYPE_AHASH,
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
static void crypto_remove_final(struct list_head *list);
|
||||
|
||||
static LIST_HEAD(crypto_template_list);
|
||||
|
||||
void crypto_larval_error(const char *name, u32 type, u32 mask)
|
||||
@@ -129,9 +127,8 @@ static void crypto_remove_spawn(struct crypto_spawn *spawn,
|
||||
BUG_ON(!list_empty(&inst->alg.cra_users));
|
||||
}
|
||||
|
||||
static void crypto_remove_spawns(struct crypto_alg *alg,
|
||||
struct list_head *list,
|
||||
struct crypto_alg *nalg)
|
||||
void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
|
||||
struct crypto_alg *nalg)
|
||||
{
|
||||
u32 new_type = (nalg ?: alg)->cra_flags;
|
||||
struct crypto_spawn *spawn, *n;
|
||||
@@ -177,6 +174,7 @@ static void crypto_remove_spawns(struct crypto_alg *alg,
|
||||
crypto_remove_spawn(spawn, list);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_remove_spawns);
|
||||
|
||||
static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
|
||||
{
|
||||
@@ -321,7 +319,7 @@ unlock:
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_alg_tested);
|
||||
|
||||
static void crypto_remove_final(struct list_head *list)
|
||||
void crypto_remove_final(struct list_head *list)
|
||||
{
|
||||
struct crypto_alg *alg;
|
||||
struct crypto_alg *n;
|
||||
@@ -331,6 +329,7 @@ static void crypto_remove_final(struct list_head *list)
|
||||
crypto_alg_put(alg);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_remove_final);
|
||||
|
||||
static void crypto_wait_for_test(struct crypto_larval *larval)
|
||||
{
|
||||
@@ -493,6 +492,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
|
||||
goto err;
|
||||
|
||||
inst->alg.cra_module = tmpl->module;
|
||||
inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE;
|
||||
|
||||
down_write(&crypto_alg_sem);
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/cryptouser.h>
|
||||
#include <net/netlink.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -492,6 +494,28 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
|
||||
return crypto_init_blkcipher_ops_async(tfm);
|
||||
}
|
||||
|
||||
static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg)
|
||||
{
|
||||
struct crypto_report_blkcipher rblkcipher;
|
||||
|
||||
snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher");
|
||||
snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s",
|
||||
alg->cra_blkcipher.geniv ?: "<default>");
|
||||
|
||||
rblkcipher.blocksize = alg->cra_blocksize;
|
||||
rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize;
|
||||
rblkcipher.max_keysize = alg->cra_blkcipher.max_keysize;
|
||||
rblkcipher.ivsize = alg->cra_blkcipher.ivsize;
|
||||
|
||||
NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER,
|
||||
sizeof(struct crypto_report_blkcipher), &rblkcipher);
|
||||
|
||||
return 0;
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
__attribute__ ((unused));
|
||||
static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg)
|
||||
@@ -511,6 +535,7 @@ const struct crypto_type crypto_blkcipher_type = {
|
||||
#ifdef CONFIG_PROC_FS
|
||||
.show = crypto_blkcipher_show,
|
||||
#endif
|
||||
.report = crypto_blkcipher_report,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(crypto_blkcipher_type);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user