diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 12:24:41 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-01 12:24:41 -0400 |
| commit | dc47d3810cdcb4f32bfa31d50f26af97aced0638 (patch) | |
| tree | f1574adeaae857d935ad9c2e08a19727e54ef14a | |
| parent | f6d90b4f9ce018bff429d6e01ee672de712b8641 (diff) | |
| parent | 5db017aa2809c49ca0a43b0f3ed1267e6be60883 (diff) | |
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
...
45 files changed, 4049 insertions, 208 deletions
diff --git a/Documentation/devicetree/bindings/crypto/picochip-spacc.txt b/Documentation/devicetree/bindings/crypto/picochip-spacc.txt new file mode 100644 index 000000000000..d8609ece1f4c --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/picochip-spacc.txt | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | Picochip picoXcell SPAcc (Security Protocol Accelerator) bindings | ||
| 2 | |||
| 3 | Picochip picoXcell devices contain crypto offload engines that may be used for | ||
| 4 | IPSEC and femtocell layer 2 ciphering. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible : "picochip,spacc-ipsec" for the IPSEC offload engine | ||
| 8 | "picochip,spacc-l2" for the femtocell layer 2 ciphering engine. | ||
| 9 | - reg : Offset and length of the register set for this device | ||
| 10 | - interrupt-parent : The interrupt controller that controls the SPAcc | ||
| 11 | interrupt. | ||
| 12 | - interrupts : The interrupt line from the SPAcc. | ||
| 13 | - ref-clock : The input clock that drives the SPAcc. | ||
| 14 | |||
| 15 | Example SPAcc node: | ||
| 16 | |||
| 17 | spacc@10000 { | ||
| 18 | compatible = "picochip,spacc-ipsec"; | ||
| 19 | reg = <0x100000 0x10000>; | ||
| 20 | interrupt-parent = <&vic0>; | ||
| 21 | interrupts = <24>; | ||
| 22 | ref-clock = <&ipsec_clk>, "ref"; | ||
| 23 | }; | ||
diff --git a/arch/x86/crypto/Makefile b/arch/x86/crypto/Makefile index c04f1b7a9139..3537d4b91f74 100644 --- a/arch/x86/crypto/Makefile +++ b/arch/x86/crypto/Makefile | |||
| @@ -7,21 +7,33 @@ obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o | |||
| 7 | obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o | 7 | obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o |
| 8 | 8 | ||
| 9 | obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o | 9 | obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o |
| 10 | obj-$(CONFIG_CRYPTO_BLOWFISH_X86_64) += blowfish-x86_64.o | ||
| 10 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o | 11 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64) += twofish-x86_64.o |
| 12 | obj-$(CONFIG_CRYPTO_TWOFISH_X86_64_3WAY) += twofish-x86_64-3way.o | ||
| 11 | obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o | 13 | obj-$(CONFIG_CRYPTO_SALSA20_X86_64) += salsa20-x86_64.o |
| 12 | obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o | 14 | obj-$(CONFIG_CRYPTO_AES_NI_INTEL) += aesni-intel.o |
| 13 | obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o | 15 | obj-$(CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL) += ghash-clmulni-intel.o |
| 14 | 16 | ||
| 15 | obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o | 17 | obj-$(CONFIG_CRYPTO_CRC32C_INTEL) += crc32c-intel.o |
| 18 | obj-$(CONFIG_CRYPTO_SHA1_SSSE3) += sha1-ssse3.o | ||
| 16 | 19 | ||
| 17 | aes-i586-y := aes-i586-asm_32.o aes_glue.o | 20 | aes-i586-y := aes-i586-asm_32.o aes_glue.o |
| 18 | twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o | 21 | twofish-i586-y := twofish-i586-asm_32.o twofish_glue.o |
| 19 | salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o | 22 | salsa20-i586-y := salsa20-i586-asm_32.o salsa20_glue.o |
| 20 | 23 | ||
| 21 | aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o | 24 | aes-x86_64-y := aes-x86_64-asm_64.o aes_glue.o |
| 25 | blowfish-x86_64-y := blowfish-x86_64-asm_64.o blowfish_glue.o | ||
| 22 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o | 26 | twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o |
| 27 | twofish-x86_64-3way-y := twofish-x86_64-asm_64-3way.o twofish_glue_3way.o | ||
| 23 | salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o | 28 | salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o |
| 24 | 29 | ||
| 25 | aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o | 30 | aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o |
| 26 | 31 | ||
| 27 | ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o | 32 | ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o |
| 33 | |||
| 34 | # enable AVX support only when $(AS) can actually assemble the instructions | ||
| 35 | ifeq ($(call as-instr,vpxor %xmm0$(comma)%xmm1$(comma)%xmm2,yes,no),yes) | ||
| 36 | AFLAGS_sha1_ssse3_asm.o += -DSHA1_ENABLE_AVX_SUPPORT | ||
| 37 | CFLAGS_sha1_ssse3_glue.o += -DSHA1_ENABLE_AVX_SUPPORT | ||
| 38 | endif | ||
| 39 | sha1-ssse3-y := sha1_ssse3_asm.o sha1_ssse3_glue.o | ||
diff --git a/arch/x86/crypto/aes_glue.c b/arch/x86/crypto/aes_glue.c index 49ae9fe32b22..b0b6950cc8c8 100644 --- a/arch/x86/crypto/aes_glue.c +++ b/arch/x86/crypto/aes_glue.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | #include <crypto/aes.h> | 6 | #include <crypto/aes.h> |
| 7 | #include <asm/aes.h> | ||
| 7 | 8 | ||
| 8 | asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); | 9 | asmlinkage void aes_enc_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); |
| 9 | asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); | 10 | asmlinkage void aes_dec_blk(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); |
diff --git a/arch/x86/crypto/blowfish-x86_64-asm_64.S b/arch/x86/crypto/blowfish-x86_64-asm_64.S new file mode 100644 index 000000000000..391d245dc086 --- /dev/null +++ b/arch/x86/crypto/blowfish-x86_64-asm_64.S | |||
| @@ -0,0 +1,390 @@ | |||
| 1 | /* | ||
| 2 | * Blowfish Cipher Algorithm (x86_64) | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 19 | * USA | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | .file "blowfish-x86_64-asm.S" | ||
| 24 | .text | ||
| 25 | |||
| 26 | /* structure of crypto context */ | ||
| 27 | #define p 0 | ||
| 28 | #define s0 ((16 + 2) * 4) | ||
| 29 | #define s1 ((16 + 2 + (1 * 256)) * 4) | ||
| 30 | #define s2 ((16 + 2 + (2 * 256)) * 4) | ||
| 31 | #define s3 ((16 + 2 + (3 * 256)) * 4) | ||
| 32 | |||
| 33 | /* register macros */ | ||
| 34 | #define CTX %rdi | ||
| 35 | #define RIO %rsi | ||
| 36 | |||
| 37 | #define RX0 %rax | ||
| 38 | #define RX1 %rbx | ||
| 39 | #define RX2 %rcx | ||
| 40 | #define RX3 %rdx | ||
| 41 | |||
| 42 | #define RX0d %eax | ||
| 43 | #define RX1d %ebx | ||
| 44 | #define RX2d %ecx | ||
| 45 | #define RX3d %edx | ||
| 46 | |||
| 47 | #define RX0bl %al | ||
| 48 | #define RX1bl %bl | ||
| 49 | #define RX2bl %cl | ||
| 50 | #define RX3bl %dl | ||
| 51 | |||
| 52 | #define RX0bh %ah | ||
| 53 | #define RX1bh %bh | ||
| 54 | #define RX2bh %ch | ||
| 55 | #define RX3bh %dh | ||
| 56 | |||
| 57 | #define RT0 %rbp | ||
| 58 | #define RT1 %rsi | ||
| 59 | #define RT2 %r8 | ||
| 60 | #define RT3 %r9 | ||
| 61 | |||
| 62 | #define RT0d %ebp | ||
| 63 | #define RT1d %esi | ||
| 64 | #define RT2d %r8d | ||
| 65 | #define RT3d %r9d | ||
| 66 | |||
| 67 | #define RKEY %r10 | ||
| 68 | |||
| 69 | /*********************************************************************** | ||
| 70 | * 1-way blowfish | ||
| 71 | ***********************************************************************/ | ||
| 72 | #define F() \ | ||
| 73 | rorq $16, RX0; \ | ||
| 74 | movzbl RX0bh, RT0d; \ | ||
| 75 | movzbl RX0bl, RT1d; \ | ||
| 76 | rolq $16, RX0; \ | ||
| 77 | movl s0(CTX,RT0,4), RT0d; \ | ||
| 78 | addl s1(CTX,RT1,4), RT0d; \ | ||
| 79 | movzbl RX0bh, RT1d; \ | ||
| 80 | movzbl RX0bl, RT2d; \ | ||
| 81 | rolq $32, RX0; \ | ||
| 82 | xorl s2(CTX,RT1,4), RT0d; \ | ||
| 83 | addl s3(CTX,RT2,4), RT0d; \ | ||
| 84 | xorq RT0, RX0; | ||
| 85 | |||
| 86 | #define add_roundkey_enc(n) \ | ||
| 87 | xorq p+4*(n)(CTX), RX0; | ||
| 88 | |||
| 89 | #define round_enc(n) \ | ||
| 90 | add_roundkey_enc(n); \ | ||
| 91 | \ | ||
| 92 | F(); \ | ||
| 93 | F(); | ||
| 94 | |||
| 95 | #define add_roundkey_dec(n) \ | ||
| 96 | movq p+4*(n-1)(CTX), RT0; \ | ||
| 97 | rorq $32, RT0; \ | ||
| 98 | xorq RT0, RX0; | ||
| 99 | |||
| 100 | #define round_dec(n) \ | ||
| 101 | add_roundkey_dec(n); \ | ||
| 102 | \ | ||
| 103 | F(); \ | ||
| 104 | F(); \ | ||
| 105 | |||
| 106 | #define read_block() \ | ||
| 107 | movq (RIO), RX0; \ | ||
| 108 | rorq $32, RX0; \ | ||
| 109 | bswapq RX0; | ||
| 110 | |||
| 111 | #define write_block() \ | ||
| 112 | bswapq RX0; \ | ||
| 113 | movq RX0, (RIO); | ||
| 114 | |||
| 115 | #define xor_block() \ | ||
| 116 | bswapq RX0; \ | ||
| 117 | xorq RX0, (RIO); | ||
| 118 | |||
| 119 | .align 8 | ||
| 120 | .global __blowfish_enc_blk | ||
| 121 | .type __blowfish_enc_blk,@function; | ||
| 122 | |||
| 123 | __blowfish_enc_blk: | ||
| 124 | /* input: | ||
| 125 | * %rdi: ctx, CTX | ||
| 126 | * %rsi: dst | ||
| 127 | * %rdx: src | ||
| 128 | * %rcx: bool, if true: xor output | ||
| 129 | */ | ||
| 130 | movq %rbp, %r11; | ||
| 131 | |||
| 132 | movq %rsi, %r10; | ||
| 133 | movq %rdx, RIO; | ||
| 134 | |||
| 135 | read_block(); | ||
| 136 | |||
| 137 | round_enc(0); | ||
| 138 | round_enc(2); | ||
| 139 | round_enc(4); | ||
| 140 | round_enc(6); | ||
| 141 | round_enc(8); | ||
| 142 | round_enc(10); | ||
| 143 | round_enc(12); | ||
| 144 | round_enc(14); | ||
| 145 | add_roundkey_enc(16); | ||
| 146 | |||
| 147 | movq %r11, %rbp; | ||
| 148 | |||
| 149 | movq %r10, RIO; | ||
| 150 | test %cl, %cl; | ||
| 151 | jnz __enc_xor; | ||
| 152 | |||
| 153 | write_block(); | ||
| 154 | ret; | ||
| 155 | __enc_xor: | ||
| 156 | xor_block(); | ||
| 157 | ret; | ||
| 158 | |||
| 159 | .align 8 | ||
| 160 | .global blowfish_dec_blk | ||
| 161 | .type blowfish_dec_blk,@function; | ||
| 162 | |||
| 163 | blowfish_dec_blk: | ||
| 164 | /* input: | ||
| 165 | * %rdi: ctx, CTX | ||
| 166 | * %rsi: dst | ||
| 167 | * %rdx: src | ||
| 168 | */ | ||
| 169 | movq %rbp, %r11; | ||
| 170 | |||
| 171 | movq %rsi, %r10; | ||
| 172 | movq %rdx, RIO; | ||
| 173 | |||
| 174 | read_block(); | ||
| 175 | |||
| 176 | round_dec(17); | ||
| 177 | round_dec(15); | ||
| 178 | round_dec(13); | ||
| 179 | round_dec(11); | ||
| 180 | round_dec(9); | ||
| 181 | round_dec(7); | ||
| 182 | round_dec(5); | ||
| 183 | round_dec(3); | ||
| 184 | add_roundkey_dec(1); | ||
| 185 | |||
| 186 | movq %r10, RIO; | ||
| 187 | write_block(); | ||
| 188 | |||
| 189 | movq %r11, %rbp; | ||
| 190 | |||
| 191 | ret; | ||
| 192 | |||
| 193 | /********************************************************************** | ||
| 194 | 4-way blowfish, four blocks parallel | ||
| 195 | **********************************************************************/ | ||
| 196 | |||
| 197 | /* F() for 4-way. Slower when used alone/1-way, but faster when used | ||
| 198 | * parallel/4-way (tested on AMD Phenom II & Intel Xeon E7330). | ||
| 199 | */ | ||
| 200 | #define F4(x) \ | ||
| 201 | movzbl x ## bh, RT1d; \ | ||
| 202 | movzbl x ## bl, RT3d; \ | ||
| 203 | rorq $16, x; \ | ||
| 204 | movzbl x ## bh, RT0d; \ | ||
| 205 | movzbl x ## bl, RT2d; \ | ||
| 206 | rorq $16, x; \ | ||
| 207 | movl s0(CTX,RT0,4), RT0d; \ | ||
| 208 | addl s1(CTX,RT2,4), RT0d; \ | ||
| 209 | xorl s2(CTX,RT1,4), RT0d; \ | ||
| 210 | addl s3(CTX,RT3,4), RT0d; \ | ||
| 211 | xorq RT0, x; | ||
| 212 | |||
| 213 | #define add_preloaded_roundkey4() \ | ||
| 214 | xorq RKEY, RX0; \ | ||
| 215 | xorq RKEY, RX1; \ | ||
| 216 | xorq RKEY, RX2; \ | ||
| 217 | xorq RKEY, RX3; | ||
| 218 | |||
| 219 | #define preload_roundkey_enc(n) \ | ||
| 220 | movq p+4*(n)(CTX), RKEY; | ||
| 221 | |||
| 222 | #define add_roundkey_enc4(n) \ | ||
| 223 | add_preloaded_roundkey4(); \ | ||
| 224 | preload_roundkey_enc(n + 2); | ||
| 225 | |||
| 226 | #define round_enc4(n) \ | ||
| 227 | add_roundkey_enc4(n); \ | ||
| 228 | \ | ||
| 229 | F4(RX0); \ | ||
| 230 | F4(RX1); \ | ||
| 231 | F4(RX2); \ | ||
| 232 | F4(RX3); \ | ||
| 233 | \ | ||
| 234 | F4(RX0); \ | ||
| 235 | F4(RX1); \ | ||
| 236 | F4(RX2); \ | ||
| 237 | F4(RX3); | ||
| 238 | |||
| 239 | #define preload_roundkey_dec(n) \ | ||
| 240 | movq p+4*((n)-1)(CTX), RKEY; \ | ||
| 241 | rorq $32, RKEY; | ||
| 242 | |||
| 243 | #define add_roundkey_dec4(n) \ | ||
| 244 | add_preloaded_roundkey4(); \ | ||
| 245 | preload_roundkey_dec(n - 2); | ||
| 246 | |||
| 247 | #define round_dec4(n) \ | ||
| 248 | add_roundkey_dec4(n); \ | ||
| 249 | \ | ||
| 250 | F4(RX0); \ | ||
| 251 | F4(RX1); \ | ||
| 252 | F4(RX2); \ | ||
| 253 | F4(RX3); \ | ||
| 254 | \ | ||
| 255 | F4(RX0); \ | ||
| 256 | F4(RX1); \ | ||
| 257 | F4(RX2); \ | ||
| 258 | F4(RX3); | ||
| 259 | |||
| 260 | #define read_block4() \ | ||
| 261 | movq (RIO), RX0; \ | ||
| 262 | rorq $32, RX0; \ | ||
| 263 | bswapq RX0; \ | ||
| 264 | \ | ||
| 265 | movq 8(RIO), RX1; \ | ||
| 266 | rorq $32, RX1; \ | ||
| 267 | bswapq RX1; \ | ||
| 268 | \ | ||
| 269 | movq 16(RIO), RX2; \ | ||
| 270 | rorq $32, RX2; \ | ||
| 271 | bswapq RX2; \ | ||
| 272 | \ | ||
| 273 | movq 24(RIO), RX3; \ | ||
| 274 | rorq $32, RX3; \ | ||
| 275 | bswapq RX3; | ||
| 276 | |||
| 277 | #define write_block4() \ | ||
| 278 | bswapq RX0; \ | ||
| 279 | movq RX0, (RIO); \ | ||
| 280 | \ | ||
| 281 | bswapq RX1; \ | ||
| 282 | movq RX1, 8(RIO); \ | ||
| 283 | \ | ||
| 284 | bswapq RX2; \ | ||
| 285 | movq RX2, 16(RIO); \ | ||
| 286 | \ | ||
| 287 | bswapq RX3; \ | ||
| 288 | movq RX3, 24(RIO); | ||
| 289 | |||
| 290 | #define xor_block4() \ | ||
| 291 | bswapq RX0; \ | ||
| 292 | xorq RX0, (RIO); \ | ||
| 293 | \ | ||
| 294 | bswapq RX1; \ | ||
| 295 | xorq RX1, 8(RIO); \ | ||
| 296 | \ | ||
| 297 | bswapq RX2; \ | ||
| 298 | xorq RX2, 16(RIO); \ | ||
| 299 | \ | ||
| 300 | bswapq RX3; \ | ||
| 301 | xorq RX3, 24(RIO); | ||
| 302 | |||
| 303 | .align 8 | ||
| 304 | .global __blowfish_enc_blk_4way | ||
| 305 | .type __blowfish_enc_blk_4way,@function; | ||
| 306 | |||
| 307 | __blowfish_enc_blk_4way: | ||
| 308 | /* input: | ||
| 309 | * %rdi: ctx, CTX | ||
| 310 | * %rsi: dst | ||
| 311 | * %rdx: src | ||
| 312 | * %rcx: bool, if true: xor output | ||
| 313 | */ | ||
| 314 | pushq %rbp; | ||
| 315 | pushq %rbx; | ||
| 316 | pushq %rcx; | ||
| 317 | |||
| 318 | preload_roundkey_enc(0); | ||
| 319 | |||
| 320 | movq %rsi, %r11; | ||
| 321 | movq %rdx, RIO; | ||
| 322 | |||
| 323 | read_block4(); | ||
| 324 | |||
| 325 | round_enc4(0); | ||
| 326 | round_enc4(2); | ||
| 327 | round_enc4(4); | ||
| 328 | round_enc4(6); | ||
| 329 | round_enc4(8); | ||
| 330 | round_enc4(10); | ||
| 331 | round_enc4(12); | ||
| 332 | round_enc4(14); | ||
| 333 | add_preloaded_roundkey4(); | ||
| 334 | |||
| 335 | popq %rbp; | ||
| 336 | movq %r11, RIO; | ||
| 337 | |||
| 338 | test %bpl, %bpl; | ||
| 339 | jnz __enc_xor4; | ||
| 340 | |||
| 341 | write_block4(); | ||
| 342 | |||
| 343 | popq %rbx; | ||
| 344 | popq %rbp; | ||
| 345 | ret; | ||
| 346 | |||
| 347 | __enc_xor4: | ||
| 348 | xor_block4(); | ||
| 349 | |||
| 350 | popq %rbx; | ||
| 351 | popq %rbp; | ||
| 352 | ret; | ||
| 353 | |||
| 354 | .align 8 | ||
| 355 | .global blowfish_dec_blk_4way | ||
| 356 | .type blowfish_dec_blk_4way,@function; | ||
| 357 | |||
| 358 | blowfish_dec_blk_4way: | ||
| 359 | /* input: | ||
| 360 | * %rdi: ctx, CTX | ||
| 361 | * %rsi: dst | ||
| 362 | * %rdx: src | ||
| 363 | */ | ||
| 364 | pushq %rbp; | ||
| 365 | pushq %rbx; | ||
| 366 | preload_roundkey_dec(17); | ||
| 367 | |||
| 368 | movq %rsi, %r11; | ||
| 369 | movq %rdx, RIO; | ||
| 370 | |||
| 371 | read_block4(); | ||
| 372 | |||
| 373 | round_dec4(17); | ||
| 374 | round_dec4(15); | ||
| 375 | round_dec4(13); | ||
| 376 | round_dec4(11); | ||
| 377 | round_dec4(9); | ||
| 378 | round_dec4(7); | ||
| 379 | round_dec4(5); | ||
| 380 | round_dec4(3); | ||
| 381 | add_preloaded_roundkey4(); | ||
| 382 | |||
| 383 | movq %r11, RIO; | ||
| 384 | write_block4(); | ||
| 385 | |||
| 386 | popq %rbx; | ||
| 387 | popq %rbp; | ||
| 388 | |||
| 389 | ret; | ||
| 390 | |||
diff --git a/arch/x86/crypto/blowfish_glue.c b/arch/x86/crypto/blowfish_glue.c new file mode 100644 index 000000000000..b05aa163d55a --- /dev/null +++ b/arch/x86/crypto/blowfish_glue.c | |||
| @@ -0,0 +1,492 @@ | |||
| 1 | /* | ||
| 2 | * Glue Code for assembler optimized version of Blowfish | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 5 | * | ||
| 6 | * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: | ||
| 7 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 8 | * CTR part based on code (crypto/ctr.c) by: | ||
| 9 | * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 24 | * USA | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <crypto/blowfish.h> | ||
| 29 | #include <linux/crypto.h> | ||
| 30 | #include <linux/init.h> | ||
| 31 | #include <linux/module.h> | ||
| 32 | #include <linux/types.h> | ||
| 33 | #include <crypto/algapi.h> | ||
| 34 | |||
| 35 | /* regular block cipher functions */ | ||
| 36 | asmlinkage void __blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src, | ||
| 37 | bool xor); | ||
| 38 | asmlinkage void blowfish_dec_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src); | ||
| 39 | |||
| 40 | /* 4-way parallel cipher functions */ | ||
| 41 | asmlinkage void __blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst, | ||
| 42 | const u8 *src, bool xor); | ||
| 43 | asmlinkage void blowfish_dec_blk_4way(struct bf_ctx *ctx, u8 *dst, | ||
| 44 | const u8 *src); | ||
| 45 | |||
| 46 | static inline void blowfish_enc_blk(struct bf_ctx *ctx, u8 *dst, const u8 *src) | ||
| 47 | { | ||
| 48 | __blowfish_enc_blk(ctx, dst, src, false); | ||
| 49 | } | ||
| 50 | |||
| 51 | static inline void blowfish_enc_blk_xor(struct bf_ctx *ctx, u8 *dst, | ||
| 52 | const u8 *src) | ||
| 53 | { | ||
| 54 | __blowfish_enc_blk(ctx, dst, src, true); | ||
| 55 | } | ||
| 56 | |||
| 57 | static inline void blowfish_enc_blk_4way(struct bf_ctx *ctx, u8 *dst, | ||
| 58 | const u8 *src) | ||
| 59 | { | ||
| 60 | __blowfish_enc_blk_4way(ctx, dst, src, false); | ||
| 61 | } | ||
| 62 | |||
| 63 | static inline void blowfish_enc_blk_xor_4way(struct bf_ctx *ctx, u8 *dst, | ||
| 64 | const u8 *src) | ||
| 65 | { | ||
| 66 | __blowfish_enc_blk_4way(ctx, dst, src, true); | ||
| 67 | } | ||
| 68 | |||
| 69 | static void blowfish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
| 70 | { | ||
| 71 | blowfish_enc_blk(crypto_tfm_ctx(tfm), dst, src); | ||
| 72 | } | ||
| 73 | |||
| 74 | static void blowfish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
| 75 | { | ||
| 76 | blowfish_dec_blk(crypto_tfm_ctx(tfm), dst, src); | ||
| 77 | } | ||
| 78 | |||
| 79 | static struct crypto_alg bf_alg = { | ||
| 80 | .cra_name = "blowfish", | ||
| 81 | .cra_driver_name = "blowfish-asm", | ||
| 82 | .cra_priority = 200, | ||
| 83 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
| 84 | .cra_blocksize = BF_BLOCK_SIZE, | ||
| 85 | .cra_ctxsize = sizeof(struct bf_ctx), | ||
| 86 | .cra_alignmask = 3, | ||
| 87 | .cra_module = THIS_MODULE, | ||
| 88 | .cra_list = LIST_HEAD_INIT(bf_alg.cra_list), | ||
| 89 | .cra_u = { | ||
| 90 | .cipher = { | ||
| 91 | .cia_min_keysize = BF_MIN_KEY_SIZE, | ||
| 92 | .cia_max_keysize = BF_MAX_KEY_SIZE, | ||
| 93 | .cia_setkey = blowfish_setkey, | ||
| 94 | .cia_encrypt = blowfish_encrypt, | ||
| 95 | .cia_decrypt = blowfish_decrypt, | ||
| 96 | } | ||
| 97 | } | ||
| 98 | }; | ||
| 99 | |||
| 100 | static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, | ||
| 101 | void (*fn)(struct bf_ctx *, u8 *, const u8 *), | ||
| 102 | void (*fn_4way)(struct bf_ctx *, u8 *, const u8 *)) | ||
| 103 | { | ||
| 104 | struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 105 | unsigned int bsize = BF_BLOCK_SIZE; | ||
| 106 | unsigned int nbytes; | ||
| 107 | int err; | ||
| 108 | |||
| 109 | err = blkcipher_walk_virt(desc, walk); | ||
| 110 | |||
| 111 | while ((nbytes = walk->nbytes)) { | ||
| 112 | u8 *wsrc = walk->src.virt.addr; | ||
| 113 | u8 *wdst = walk->dst.virt.addr; | ||
| 114 | |||
| 115 | /* Process four block batch */ | ||
| 116 | if (nbytes >= bsize * 4) { | ||
| 117 | do { | ||
| 118 | fn_4way(ctx, wdst, wsrc); | ||
| 119 | |||
| 120 | wsrc += bsize * 4; | ||
| 121 | wdst += bsize * 4; | ||
| 122 | nbytes -= bsize * 4; | ||
| 123 | } while (nbytes >= bsize * 4); | ||
| 124 | |||
| 125 | if (nbytes < bsize) | ||
| 126 | goto done; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* Handle leftovers */ | ||
| 130 | do { | ||
| 131 | fn(ctx, wdst, wsrc); | ||
| 132 | |||
| 133 | wsrc += bsize; | ||
| 134 | wdst += bsize; | ||
| 135 | nbytes -= bsize; | ||
| 136 | } while (nbytes >= bsize); | ||
| 137 | |||
| 138 | done: | ||
| 139 | err = blkcipher_walk_done(desc, walk, nbytes); | ||
| 140 | } | ||
| 141 | |||
| 142 | return err; | ||
| 143 | } | ||
| 144 | |||
| 145 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 146 | struct scatterlist *src, unsigned int nbytes) | ||
| 147 | { | ||
| 148 | struct blkcipher_walk walk; | ||
| 149 | |||
| 150 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 151 | return ecb_crypt(desc, &walk, blowfish_enc_blk, blowfish_enc_blk_4way); | ||
| 152 | } | ||
| 153 | |||
| 154 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 155 | struct scatterlist *src, unsigned int nbytes) | ||
| 156 | { | ||
| 157 | struct blkcipher_walk walk; | ||
| 158 | |||
| 159 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 160 | return ecb_crypt(desc, &walk, blowfish_dec_blk, blowfish_dec_blk_4way); | ||
| 161 | } | ||
| 162 | |||
| 163 | static struct crypto_alg blk_ecb_alg = { | ||
| 164 | .cra_name = "ecb(blowfish)", | ||
| 165 | .cra_driver_name = "ecb-blowfish-asm", | ||
| 166 | .cra_priority = 300, | ||
| 167 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 168 | .cra_blocksize = BF_BLOCK_SIZE, | ||
| 169 | .cra_ctxsize = sizeof(struct bf_ctx), | ||
| 170 | .cra_alignmask = 0, | ||
| 171 | .cra_type = &crypto_blkcipher_type, | ||
| 172 | .cra_module = THIS_MODULE, | ||
| 173 | .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list), | ||
| 174 | .cra_u = { | ||
| 175 | .blkcipher = { | ||
| 176 | .min_keysize = BF_MIN_KEY_SIZE, | ||
| 177 | .max_keysize = BF_MAX_KEY_SIZE, | ||
| 178 | .setkey = blowfish_setkey, | ||
| 179 | .encrypt = ecb_encrypt, | ||
| 180 | .decrypt = ecb_decrypt, | ||
| 181 | }, | ||
| 182 | }, | ||
| 183 | }; | ||
| 184 | |||
| 185 | static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, | ||
| 186 | struct blkcipher_walk *walk) | ||
| 187 | { | ||
| 188 | struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 189 | unsigned int bsize = BF_BLOCK_SIZE; | ||
| 190 | unsigned int nbytes = walk->nbytes; | ||
| 191 | u64 *src = (u64 *)walk->src.virt.addr; | ||
| 192 | u64 *dst = (u64 *)walk->dst.virt.addr; | ||
| 193 | u64 *iv = (u64 *)walk->iv; | ||
| 194 | |||
| 195 | do { | ||
| 196 | *dst = *src ^ *iv; | ||
| 197 | blowfish_enc_blk(ctx, (u8 *)dst, (u8 *)dst); | ||
| 198 | iv = dst; | ||
| 199 | |||
| 200 | src += 1; | ||
| 201 | dst += 1; | ||
| 202 | nbytes -= bsize; | ||
| 203 | } while (nbytes >= bsize); | ||
| 204 | |||
| 205 | *(u64 *)walk->iv = *iv; | ||
| 206 | return nbytes; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 210 | struct scatterlist *src, unsigned int nbytes) | ||
| 211 | { | ||
| 212 | struct blkcipher_walk walk; | ||
| 213 | int err; | ||
| 214 | |||
| 215 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 216 | err = blkcipher_walk_virt(desc, &walk); | ||
| 217 | |||
| 218 | while ((nbytes = walk.nbytes)) { | ||
| 219 | nbytes = __cbc_encrypt(desc, &walk); | ||
| 220 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 221 | } | ||
| 222 | |||
| 223 | return err; | ||
| 224 | } | ||
| 225 | |||
| 226 | static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, | ||
| 227 | struct blkcipher_walk *walk) | ||
| 228 | { | ||
| 229 | struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 230 | unsigned int bsize = BF_BLOCK_SIZE; | ||
| 231 | unsigned int nbytes = walk->nbytes; | ||
| 232 | u64 *src = (u64 *)walk->src.virt.addr; | ||
| 233 | u64 *dst = (u64 *)walk->dst.virt.addr; | ||
| 234 | u64 ivs[4 - 1]; | ||
| 235 | u64 last_iv; | ||
| 236 | |||
| 237 | /* Start of the last block. */ | ||
| 238 | src += nbytes / bsize - 1; | ||
| 239 | dst += nbytes / bsize - 1; | ||
| 240 | |||
| 241 | last_iv = *src; | ||
| 242 | |||
| 243 | /* Process four block batch */ | ||
| 244 | if (nbytes >= bsize * 4) { | ||
| 245 | do { | ||
| 246 | nbytes -= bsize * 4 - bsize; | ||
| 247 | src -= 4 - 1; | ||
| 248 | dst -= 4 - 1; | ||
| 249 | |||
| 250 | ivs[0] = src[0]; | ||
| 251 | ivs[1] = src[1]; | ||
| 252 | ivs[2] = src[2]; | ||
| 253 | |||
| 254 | blowfish_dec_blk_4way(ctx, (u8 *)dst, (u8 *)src); | ||
| 255 | |||
| 256 | dst[1] ^= ivs[0]; | ||
| 257 | dst[2] ^= ivs[1]; | ||
| 258 | dst[3] ^= ivs[2]; | ||
| 259 | |||
| 260 | nbytes -= bsize; | ||
| 261 | if (nbytes < bsize) | ||
| 262 | goto done; | ||
| 263 | |||
| 264 | *dst ^= *(src - 1); | ||
| 265 | src -= 1; | ||
| 266 | dst -= 1; | ||
| 267 | } while (nbytes >= bsize * 4); | ||
| 268 | |||
| 269 | if (nbytes < bsize) | ||
| 270 | goto done; | ||
| 271 | } | ||
| 272 | |||
| 273 | /* Handle leftovers */ | ||
| 274 | for (;;) { | ||
| 275 | blowfish_dec_blk(ctx, (u8 *)dst, (u8 *)src); | ||
| 276 | |||
| 277 | nbytes -= bsize; | ||
| 278 | if (nbytes < bsize) | ||
| 279 | break; | ||
| 280 | |||
| 281 | *dst ^= *(src - 1); | ||
| 282 | src -= 1; | ||
| 283 | dst -= 1; | ||
| 284 | } | ||
| 285 | |||
| 286 | done: | ||
| 287 | *dst ^= *(u64 *)walk->iv; | ||
| 288 | *(u64 *)walk->iv = last_iv; | ||
| 289 | |||
| 290 | return nbytes; | ||
| 291 | } | ||
| 292 | |||
| 293 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 294 | struct scatterlist *src, unsigned int nbytes) | ||
| 295 | { | ||
| 296 | struct blkcipher_walk walk; | ||
| 297 | int err; | ||
| 298 | |||
| 299 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 300 | err = blkcipher_walk_virt(desc, &walk); | ||
| 301 | |||
| 302 | while ((nbytes = walk.nbytes)) { | ||
| 303 | nbytes = __cbc_decrypt(desc, &walk); | ||
| 304 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 305 | } | ||
| 306 | |||
| 307 | return err; | ||
| 308 | } | ||
| 309 | |||
| 310 | static struct crypto_alg blk_cbc_alg = { | ||
| 311 | .cra_name = "cbc(blowfish)", | ||
| 312 | .cra_driver_name = "cbc-blowfish-asm", | ||
| 313 | .cra_priority = 300, | ||
| 314 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 315 | .cra_blocksize = BF_BLOCK_SIZE, | ||
| 316 | .cra_ctxsize = sizeof(struct bf_ctx), | ||
| 317 | .cra_alignmask = 0, | ||
| 318 | .cra_type = &crypto_blkcipher_type, | ||
| 319 | .cra_module = THIS_MODULE, | ||
| 320 | .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list), | ||
| 321 | .cra_u = { | ||
| 322 | .blkcipher = { | ||
| 323 | .min_keysize = BF_MIN_KEY_SIZE, | ||
| 324 | .max_keysize = BF_MAX_KEY_SIZE, | ||
| 325 | .ivsize = BF_BLOCK_SIZE, | ||
| 326 | .setkey = blowfish_setkey, | ||
| 327 | .encrypt = cbc_encrypt, | ||
| 328 | .decrypt = cbc_decrypt, | ||
| 329 | }, | ||
| 330 | }, | ||
| 331 | }; | ||
| 332 | |||
| 333 | static void ctr_crypt_final(struct bf_ctx *ctx, struct blkcipher_walk *walk) | ||
| 334 | { | ||
| 335 | u8 *ctrblk = walk->iv; | ||
| 336 | u8 keystream[BF_BLOCK_SIZE]; | ||
| 337 | u8 *src = walk->src.virt.addr; | ||
| 338 | u8 *dst = walk->dst.virt.addr; | ||
| 339 | unsigned int nbytes = walk->nbytes; | ||
| 340 | |||
| 341 | blowfish_enc_blk(ctx, keystream, ctrblk); | ||
| 342 | crypto_xor(keystream, src, nbytes); | ||
| 343 | memcpy(dst, keystream, nbytes); | ||
| 344 | |||
| 345 | crypto_inc(ctrblk, BF_BLOCK_SIZE); | ||
| 346 | } | ||
| 347 | |||
| 348 | static unsigned int __ctr_crypt(struct blkcipher_desc *desc, | ||
| 349 | struct blkcipher_walk *walk) | ||
| 350 | { | ||
| 351 | struct bf_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 352 | unsigned int bsize = BF_BLOCK_SIZE; | ||
| 353 | unsigned int nbytes = walk->nbytes; | ||
| 354 | u64 *src = (u64 *)walk->src.virt.addr; | ||
| 355 | u64 *dst = (u64 *)walk->dst.virt.addr; | ||
| 356 | u64 ctrblk = be64_to_cpu(*(__be64 *)walk->iv); | ||
| 357 | __be64 ctrblocks[4]; | ||
| 358 | |||
| 359 | /* Process four block batch */ | ||
| 360 | if (nbytes >= bsize * 4) { | ||
| 361 | do { | ||
| 362 | if (dst != src) { | ||
| 363 | dst[0] = src[0]; | ||
| 364 | dst[1] = src[1]; | ||
| 365 | dst[2] = src[2]; | ||
| 366 | dst[3] = src[3]; | ||
| 367 | } | ||
| 368 | |||
| 369 | /* create ctrblks for parallel encrypt */ | ||
| 370 | ctrblocks[0] = cpu_to_be64(ctrblk++); | ||
| 371 | ctrblocks[1] = cpu_to_be64(ctrblk++); | ||
| 372 | ctrblocks[2] = cpu_to_be64(ctrblk++); | ||
| 373 | ctrblocks[3] = cpu_to_be64(ctrblk++); | ||
| 374 | |||
| 375 | blowfish_enc_blk_xor_4way(ctx, (u8 *)dst, | ||
| 376 | (u8 *)ctrblocks); | ||
| 377 | |||
| 378 | src += 4; | ||
| 379 | dst += 4; | ||
| 380 | } while ((nbytes -= bsize * 4) >= bsize * 4); | ||
| 381 | |||
| 382 | if (nbytes < bsize) | ||
| 383 | goto done; | ||
| 384 | } | ||
| 385 | |||
| 386 | /* Handle leftovers */ | ||
| 387 | do { | ||
| 388 | if (dst != src) | ||
| 389 | *dst = *src; | ||
| 390 | |||
| 391 | ctrblocks[0] = cpu_to_be64(ctrblk++); | ||
| 392 | |||
| 393 | blowfish_enc_blk_xor(ctx, (u8 *)dst, (u8 *)ctrblocks); | ||
| 394 | |||
| 395 | src += 1; | ||
| 396 | dst += 1; | ||
| 397 | } while ((nbytes -= bsize) >= bsize); | ||
| 398 | |||
| 399 | done: | ||
| 400 | *(__be64 *)walk->iv = cpu_to_be64(ctrblk); | ||
| 401 | return nbytes; | ||
| 402 | } | ||
| 403 | |||
| 404 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 405 | struct scatterlist *src, unsigned int nbytes) | ||
| 406 | { | ||
| 407 | struct blkcipher_walk walk; | ||
| 408 | int err; | ||
| 409 | |||
| 410 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 411 | err = blkcipher_walk_virt_block(desc, &walk, BF_BLOCK_SIZE); | ||
| 412 | |||
| 413 | while ((nbytes = walk.nbytes) >= BF_BLOCK_SIZE) { | ||
| 414 | nbytes = __ctr_crypt(desc, &walk); | ||
| 415 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 416 | } | ||
| 417 | |||
| 418 | if (walk.nbytes) { | ||
| 419 | ctr_crypt_final(crypto_blkcipher_ctx(desc->tfm), &walk); | ||
| 420 | err = blkcipher_walk_done(desc, &walk, 0); | ||
| 421 | } | ||
| 422 | |||
| 423 | return err; | ||
| 424 | } | ||
| 425 | |||
| 426 | static struct crypto_alg blk_ctr_alg = { | ||
| 427 | .cra_name = "ctr(blowfish)", | ||
| 428 | .cra_driver_name = "ctr-blowfish-asm", | ||
| 429 | .cra_priority = 300, | ||
| 430 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 431 | .cra_blocksize = 1, | ||
| 432 | .cra_ctxsize = sizeof(struct bf_ctx), | ||
| 433 | .cra_alignmask = 0, | ||
| 434 | .cra_type = &crypto_blkcipher_type, | ||
| 435 | .cra_module = THIS_MODULE, | ||
| 436 | .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list), | ||
| 437 | .cra_u = { | ||
| 438 | .blkcipher = { | ||
| 439 | .min_keysize = BF_MIN_KEY_SIZE, | ||
| 440 | .max_keysize = BF_MAX_KEY_SIZE, | ||
| 441 | .ivsize = BF_BLOCK_SIZE, | ||
| 442 | .setkey = blowfish_setkey, | ||
| 443 | .encrypt = ctr_crypt, | ||
| 444 | .decrypt = ctr_crypt, | ||
| 445 | }, | ||
| 446 | }, | ||
| 447 | }; | ||
| 448 | |||
| 449 | static int __init init(void) | ||
| 450 | { | ||
| 451 | int err; | ||
| 452 | |||
| 453 | err = crypto_register_alg(&bf_alg); | ||
| 454 | if (err) | ||
| 455 | goto bf_err; | ||
| 456 | err = crypto_register_alg(&blk_ecb_alg); | ||
| 457 | if (err) | ||
| 458 | goto ecb_err; | ||
| 459 | err = crypto_register_alg(&blk_cbc_alg); | ||
| 460 | if (err) | ||
| 461 | goto cbc_err; | ||
| 462 | err = crypto_register_alg(&blk_ctr_alg); | ||
| 463 | if (err) | ||
| 464 | goto ctr_err; | ||
| 465 | |||
| 466 | return 0; | ||
| 467 | |||
| 468 | ctr_err: | ||
| 469 | crypto_unregister_alg(&blk_cbc_alg); | ||
| 470 | cbc_err: | ||
| 471 | crypto_unregister_alg(&blk_ecb_alg); | ||
| 472 | ecb_err: | ||
| 473 | crypto_unregister_alg(&bf_alg); | ||
| 474 | bf_err: | ||
| 475 | return err; | ||
| 476 | } | ||
| 477 | |||
| 478 | static void __exit fini(void) | ||
| 479 | { | ||
| 480 | crypto_unregister_alg(&blk_ctr_alg); | ||
| 481 | crypto_unregister_alg(&blk_cbc_alg); | ||
| 482 | crypto_unregister_alg(&blk_ecb_alg); | ||
| 483 | crypto_unregister_alg(&bf_alg); | ||
| 484 | } | ||
| 485 | |||
| 486 | module_init(init); | ||
| 487 | module_exit(fini); | ||
| 488 | |||
| 489 | MODULE_LICENSE("GPL"); | ||
| 490 | MODULE_DESCRIPTION("Blowfish Cipher Algorithm, asm optimized"); | ||
| 491 | MODULE_ALIAS("blowfish"); | ||
| 492 | MODULE_ALIAS("blowfish-asm"); | ||
diff --git a/arch/x86/crypto/sha1_ssse3_asm.S b/arch/x86/crypto/sha1_ssse3_asm.S new file mode 100644 index 000000000000..b2c2f57d70e8 --- /dev/null +++ b/arch/x86/crypto/sha1_ssse3_asm.S | |||
| @@ -0,0 +1,558 @@ | |||
| 1 | /* | ||
| 2 | * This is a SIMD SHA-1 implementation. It requires the Intel(R) Supplemental | ||
| 3 | * SSE3 instruction set extensions introduced in Intel Core Microarchitecture | ||
| 4 | * processors. CPUs supporting Intel(R) AVX extensions will get an additional | ||
| 5 | * boost. | ||
| 6 | * | ||
| 7 | * This work was inspired by the vectorized implementation of Dean Gaudet. | ||
| 8 | * Additional information on it can be found at: | ||
| 9 | * http://www.arctic.org/~dean/crypto/sha1.html | ||
| 10 | * | ||
| 11 | * It was improved upon with more efficient vectorization of the message | ||
| 12 | * scheduling. This implementation has also been optimized for all current and | ||
| 13 | * several future generations of Intel CPUs. | ||
| 14 | * | ||
| 15 | * See this article for more information about the implementation details: | ||
| 16 | * http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/ | ||
| 17 | * | ||
| 18 | * Copyright (C) 2010, Intel Corp. | ||
| 19 | * Authors: Maxim Locktyukhin <maxim.locktyukhin@intel.com> | ||
| 20 | * Ronen Zohar <ronen.zohar@intel.com> | ||
| 21 | * | ||
| 22 | * Converted to AT&T syntax and adapted for inclusion in the Linux kernel: | ||
| 23 | * Author: Mathias Krause <minipli@googlemail.com> | ||
| 24 | * | ||
| 25 | * This program is free software; you can redistribute it and/or modify | ||
| 26 | * it under the terms of the GNU General Public License as published by | ||
| 27 | * the Free Software Foundation; either version 2 of the License, or | ||
| 28 | * (at your option) any later version. | ||
| 29 | */ | ||
| 30 | |||
| 31 | #define CTX %rdi // arg1 | ||
| 32 | #define BUF %rsi // arg2 | ||
| 33 | #define CNT %rdx // arg3 | ||
| 34 | |||
| 35 | #define REG_A %ecx | ||
| 36 | #define REG_B %esi | ||
| 37 | #define REG_C %edi | ||
| 38 | #define REG_D %ebp | ||
| 39 | #define REG_E %edx | ||
| 40 | |||
| 41 | #define REG_T1 %eax | ||
| 42 | #define REG_T2 %ebx | ||
| 43 | |||
| 44 | #define K_BASE %r8 | ||
| 45 | #define HASH_PTR %r9 | ||
| 46 | #define BUFFER_PTR %r10 | ||
| 47 | #define BUFFER_END %r11 | ||
| 48 | |||
| 49 | #define W_TMP1 %xmm0 | ||
| 50 | #define W_TMP2 %xmm9 | ||
| 51 | |||
| 52 | #define W0 %xmm1 | ||
| 53 | #define W4 %xmm2 | ||
| 54 | #define W8 %xmm3 | ||
| 55 | #define W12 %xmm4 | ||
| 56 | #define W16 %xmm5 | ||
| 57 | #define W20 %xmm6 | ||
| 58 | #define W24 %xmm7 | ||
| 59 | #define W28 %xmm8 | ||
| 60 | |||
| 61 | #define XMM_SHUFB_BSWAP %xmm10 | ||
| 62 | |||
| 63 | /* we keep window of 64 w[i]+K pre-calculated values in a circular buffer */ | ||
| 64 | #define WK(t) (((t) & 15) * 4)(%rsp) | ||
| 65 | #define W_PRECALC_AHEAD 16 | ||
| 66 | |||
| 67 | /* | ||
| 68 | * This macro implements the SHA-1 function's body for single 64-byte block | ||
| 69 | * param: function's name | ||
| 70 | */ | ||
| 71 | .macro SHA1_VECTOR_ASM name | ||
| 72 | .global \name | ||
| 73 | .type \name, @function | ||
| 74 | .align 32 | ||
| 75 | \name: | ||
| 76 | push %rbx | ||
| 77 | push %rbp | ||
| 78 | push %r12 | ||
| 79 | |||
| 80 | mov %rsp, %r12 | ||
| 81 | sub $64, %rsp # allocate workspace | ||
| 82 | and $~15, %rsp # align stack | ||
| 83 | |||
| 84 | mov CTX, HASH_PTR | ||
| 85 | mov BUF, BUFFER_PTR | ||
| 86 | |||
| 87 | shl $6, CNT # multiply by 64 | ||
| 88 | add BUF, CNT | ||
| 89 | mov CNT, BUFFER_END | ||
| 90 | |||
| 91 | lea K_XMM_AR(%rip), K_BASE | ||
| 92 | xmm_mov BSWAP_SHUFB_CTL(%rip), XMM_SHUFB_BSWAP | ||
| 93 | |||
| 94 | SHA1_PIPELINED_MAIN_BODY | ||
| 95 | |||
| 96 | # cleanup workspace | ||
| 97 | mov $8, %ecx | ||
| 98 | mov %rsp, %rdi | ||
| 99 | xor %rax, %rax | ||
| 100 | rep stosq | ||
| 101 | |||
| 102 | mov %r12, %rsp # deallocate workspace | ||
| 103 | |||
| 104 | pop %r12 | ||
| 105 | pop %rbp | ||
| 106 | pop %rbx | ||
| 107 | ret | ||
| 108 | |||
| 109 | .size \name, .-\name | ||
| 110 | .endm | ||
| 111 | |||
| 112 | /* | ||
| 113 | * This macro implements 80 rounds of SHA-1 for one 64-byte block | ||
| 114 | */ | ||
| 115 | .macro SHA1_PIPELINED_MAIN_BODY | ||
| 116 | INIT_REGALLOC | ||
| 117 | |||
| 118 | mov (HASH_PTR), A | ||
| 119 | mov 4(HASH_PTR), B | ||
| 120 | mov 8(HASH_PTR), C | ||
| 121 | mov 12(HASH_PTR), D | ||
| 122 | mov 16(HASH_PTR), E | ||
| 123 | |||
| 124 | .set i, 0 | ||
| 125 | .rept W_PRECALC_AHEAD | ||
| 126 | W_PRECALC i | ||
| 127 | .set i, (i+1) | ||
| 128 | .endr | ||
| 129 | |||
| 130 | .align 4 | ||
| 131 | 1: | ||
| 132 | RR F1,A,B,C,D,E,0 | ||
| 133 | RR F1,D,E,A,B,C,2 | ||
| 134 | RR F1,B,C,D,E,A,4 | ||
| 135 | RR F1,E,A,B,C,D,6 | ||
| 136 | RR F1,C,D,E,A,B,8 | ||
| 137 | |||
| 138 | RR F1,A,B,C,D,E,10 | ||
| 139 | RR F1,D,E,A,B,C,12 | ||
| 140 | RR F1,B,C,D,E,A,14 | ||
| 141 | RR F1,E,A,B,C,D,16 | ||
| 142 | RR F1,C,D,E,A,B,18 | ||
| 143 | |||
| 144 | RR F2,A,B,C,D,E,20 | ||
| 145 | RR F2,D,E,A,B,C,22 | ||
| 146 | RR F2,B,C,D,E,A,24 | ||
| 147 | RR F2,E,A,B,C,D,26 | ||
| 148 | RR F2,C,D,E,A,B,28 | ||
| 149 | |||
| 150 | RR F2,A,B,C,D,E,30 | ||
| 151 | RR F2,D,E,A,B,C,32 | ||
| 152 | RR F2,B,C,D,E,A,34 | ||
| 153 | RR F2,E,A,B,C,D,36 | ||
| 154 | RR F2,C,D,E,A,B,38 | ||
| 155 | |||
| 156 | RR F3,A,B,C,D,E,40 | ||
| 157 | RR F3,D,E,A,B,C,42 | ||
| 158 | RR F3,B,C,D,E,A,44 | ||
| 159 | RR F3,E,A,B,C,D,46 | ||
| 160 | RR F3,C,D,E,A,B,48 | ||
| 161 | |||
| 162 | RR F3,A,B,C,D,E,50 | ||
| 163 | RR F3,D,E,A,B,C,52 | ||
| 164 | RR F3,B,C,D,E,A,54 | ||
| 165 | RR F3,E,A,B,C,D,56 | ||
| 166 | RR F3,C,D,E,A,B,58 | ||
| 167 | |||
| 168 | add $64, BUFFER_PTR # move to the next 64-byte block | ||
| 169 | cmp BUFFER_END, BUFFER_PTR # if the current is the last one use | ||
| 170 | cmovae K_BASE, BUFFER_PTR # dummy source to avoid buffer overrun | ||
| 171 | |||
| 172 | RR F4,A,B,C,D,E,60 | ||
| 173 | RR F4,D,E,A,B,C,62 | ||
| 174 | RR F4,B,C,D,E,A,64 | ||
| 175 | RR F4,E,A,B,C,D,66 | ||
| 176 | RR F4,C,D,E,A,B,68 | ||
| 177 | |||
| 178 | RR F4,A,B,C,D,E,70 | ||
| 179 | RR F4,D,E,A,B,C,72 | ||
| 180 | RR F4,B,C,D,E,A,74 | ||
| 181 | RR F4,E,A,B,C,D,76 | ||
| 182 | RR F4,C,D,E,A,B,78 | ||
| 183 | |||
| 184 | UPDATE_HASH (HASH_PTR), A | ||
| 185 | UPDATE_HASH 4(HASH_PTR), B | ||
| 186 | UPDATE_HASH 8(HASH_PTR), C | ||
| 187 | UPDATE_HASH 12(HASH_PTR), D | ||
| 188 | UPDATE_HASH 16(HASH_PTR), E | ||
| 189 | |||
| 190 | RESTORE_RENAMED_REGS | ||
| 191 | cmp K_BASE, BUFFER_PTR # K_BASE means, we reached the end | ||
| 192 | jne 1b | ||
| 193 | .endm | ||
| 194 | |||
| 195 | .macro INIT_REGALLOC | ||
| 196 | .set A, REG_A | ||
| 197 | .set B, REG_B | ||
| 198 | .set C, REG_C | ||
| 199 | .set D, REG_D | ||
| 200 | .set E, REG_E | ||
| 201 | .set T1, REG_T1 | ||
| 202 | .set T2, REG_T2 | ||
| 203 | .endm | ||
| 204 | |||
| 205 | .macro RESTORE_RENAMED_REGS | ||
| 206 | # order is important (REG_C is where it should be) | ||
| 207 | mov B, REG_B | ||
| 208 | mov D, REG_D | ||
| 209 | mov A, REG_A | ||
| 210 | mov E, REG_E | ||
| 211 | .endm | ||
| 212 | |||
| 213 | .macro SWAP_REG_NAMES a, b | ||
| 214 | .set _T, \a | ||
| 215 | .set \a, \b | ||
| 216 | .set \b, _T | ||
| 217 | .endm | ||
| 218 | |||
| 219 | .macro F1 b, c, d | ||
| 220 | mov \c, T1 | ||
| 221 | SWAP_REG_NAMES \c, T1 | ||
| 222 | xor \d, T1 | ||
| 223 | and \b, T1 | ||
| 224 | xor \d, T1 | ||
| 225 | .endm | ||
| 226 | |||
| 227 | .macro F2 b, c, d | ||
| 228 | mov \d, T1 | ||
| 229 | SWAP_REG_NAMES \d, T1 | ||
| 230 | xor \c, T1 | ||
| 231 | xor \b, T1 | ||
| 232 | .endm | ||
| 233 | |||
| 234 | .macro F3 b, c ,d | ||
| 235 | mov \c, T1 | ||
| 236 | SWAP_REG_NAMES \c, T1 | ||
| 237 | mov \b, T2 | ||
| 238 | or \b, T1 | ||
| 239 | and \c, T2 | ||
| 240 | and \d, T1 | ||
| 241 | or T2, T1 | ||
| 242 | .endm | ||
| 243 | |||
| 244 | .macro F4 b, c, d | ||
| 245 | F2 \b, \c, \d | ||
| 246 | .endm | ||
| 247 | |||
| 248 | .macro UPDATE_HASH hash, val | ||
| 249 | add \hash, \val | ||
| 250 | mov \val, \hash | ||
| 251 | .endm | ||
| 252 | |||
| 253 | /* | ||
| 254 | * RR does two rounds of SHA-1 back to back with W[] pre-calc | ||
| 255 | * t1 = F(b, c, d); e += w(i) | ||
| 256 | * e += t1; b <<= 30; d += w(i+1); | ||
| 257 | * t1 = F(a, b, c); | ||
| 258 | * d += t1; a <<= 5; | ||
| 259 | * e += a; | ||
| 260 | * t1 = e; a >>= 7; | ||
| 261 | * t1 <<= 5; | ||
| 262 | * d += t1; | ||
| 263 | */ | ||
| 264 | .macro RR F, a, b, c, d, e, round | ||
| 265 | add WK(\round), \e | ||
| 266 | \F \b, \c, \d # t1 = F(b, c, d); | ||
| 267 | W_PRECALC (\round + W_PRECALC_AHEAD) | ||
| 268 | rol $30, \b | ||
| 269 | add T1, \e | ||
| 270 | add WK(\round + 1), \d | ||
| 271 | |||
| 272 | \F \a, \b, \c | ||
| 273 | W_PRECALC (\round + W_PRECALC_AHEAD + 1) | ||
| 274 | rol $5, \a | ||
| 275 | add \a, \e | ||
| 276 | add T1, \d | ||
| 277 | ror $7, \a # (a <<r 5) >>r 7) => a <<r 30) | ||
| 278 | |||
| 279 | mov \e, T1 | ||
| 280 | SWAP_REG_NAMES \e, T1 | ||
| 281 | |||
| 282 | rol $5, T1 | ||
| 283 | add T1, \d | ||
| 284 | |||
| 285 | # write: \a, \b | ||
| 286 | # rotate: \a<=\d, \b<=\e, \c<=\a, \d<=\b, \e<=\c | ||
| 287 | .endm | ||
| 288 | |||
| 289 | .macro W_PRECALC r | ||
| 290 | .set i, \r | ||
| 291 | |||
| 292 | .if (i < 20) | ||
| 293 | .set K_XMM, 0 | ||
| 294 | .elseif (i < 40) | ||
| 295 | .set K_XMM, 16 | ||
| 296 | .elseif (i < 60) | ||
| 297 | .set K_XMM, 32 | ||
| 298 | .elseif (i < 80) | ||
| 299 | .set K_XMM, 48 | ||
| 300 | .endif | ||
| 301 | |||
| 302 | .if ((i < 16) || ((i >= 80) && (i < (80 + W_PRECALC_AHEAD)))) | ||
| 303 | .set i, ((\r) % 80) # pre-compute for the next iteration | ||
| 304 | .if (i == 0) | ||
| 305 | W_PRECALC_RESET | ||
| 306 | .endif | ||
| 307 | W_PRECALC_00_15 | ||
| 308 | .elseif (i<32) | ||
| 309 | W_PRECALC_16_31 | ||
| 310 | .elseif (i < 80) // rounds 32-79 | ||
| 311 | W_PRECALC_32_79 | ||
| 312 | .endif | ||
| 313 | .endm | ||
| 314 | |||
| 315 | .macro W_PRECALC_RESET | ||
| 316 | .set W, W0 | ||
| 317 | .set W_minus_04, W4 | ||
| 318 | .set W_minus_08, W8 | ||
| 319 | .set W_minus_12, W12 | ||
| 320 | .set W_minus_16, W16 | ||
| 321 | .set W_minus_20, W20 | ||
| 322 | .set W_minus_24, W24 | ||
| 323 | .set W_minus_28, W28 | ||
| 324 | .set W_minus_32, W | ||
| 325 | .endm | ||
| 326 | |||
| 327 | .macro W_PRECALC_ROTATE | ||
| 328 | .set W_minus_32, W_minus_28 | ||
| 329 | .set W_minus_28, W_minus_24 | ||
| 330 | .set W_minus_24, W_minus_20 | ||
| 331 | .set W_minus_20, W_minus_16 | ||
| 332 | .set W_minus_16, W_minus_12 | ||
| 333 | .set W_minus_12, W_minus_08 | ||
| 334 | .set W_minus_08, W_minus_04 | ||
| 335 | .set W_minus_04, W | ||
| 336 | .set W, W_minus_32 | ||
| 337 | .endm | ||
| 338 | |||
| 339 | .macro W_PRECALC_SSSE3 | ||
| 340 | |||
| 341 | .macro W_PRECALC_00_15 | ||
| 342 | W_PRECALC_00_15_SSSE3 | ||
| 343 | .endm | ||
| 344 | .macro W_PRECALC_16_31 | ||
| 345 | W_PRECALC_16_31_SSSE3 | ||
| 346 | .endm | ||
| 347 | .macro W_PRECALC_32_79 | ||
| 348 | W_PRECALC_32_79_SSSE3 | ||
| 349 | .endm | ||
| 350 | |||
| 351 | /* message scheduling pre-compute for rounds 0-15 */ | ||
| 352 | .macro W_PRECALC_00_15_SSSE3 | ||
| 353 | .if ((i & 3) == 0) | ||
| 354 | movdqu (i*4)(BUFFER_PTR), W_TMP1 | ||
| 355 | .elseif ((i & 3) == 1) | ||
| 356 | pshufb XMM_SHUFB_BSWAP, W_TMP1 | ||
| 357 | movdqa W_TMP1, W | ||
| 358 | .elseif ((i & 3) == 2) | ||
| 359 | paddd (K_BASE), W_TMP1 | ||
| 360 | .elseif ((i & 3) == 3) | ||
| 361 | movdqa W_TMP1, WK(i&~3) | ||
| 362 | W_PRECALC_ROTATE | ||
| 363 | .endif | ||
| 364 | .endm | ||
| 365 | |||
| 366 | /* message scheduling pre-compute for rounds 16-31 | ||
| 367 | * | ||
| 368 | * - calculating last 32 w[i] values in 8 XMM registers | ||
| 369 | * - pre-calculate K+w[i] values and store to mem, for later load by ALU add | ||
| 370 | * instruction | ||
| 371 | * | ||
| 372 | * some "heavy-lifting" vectorization for rounds 16-31 due to w[i]->w[i-3] | ||
| 373 | * dependency, but improves for 32-79 | ||
| 374 | */ | ||
| 375 | .macro W_PRECALC_16_31_SSSE3 | ||
| 376 | # blended scheduling of vector and scalar instruction streams, one 4-wide | ||
| 377 | # vector iteration / 4 scalar rounds | ||
| 378 | .if ((i & 3) == 0) | ||
| 379 | movdqa W_minus_12, W | ||
| 380 | palignr $8, W_minus_16, W # w[i-14] | ||
| 381 | movdqa W_minus_04, W_TMP1 | ||
| 382 | psrldq $4, W_TMP1 # w[i-3] | ||
| 383 | pxor W_minus_08, W | ||
| 384 | .elseif ((i & 3) == 1) | ||
| 385 | pxor W_minus_16, W_TMP1 | ||
| 386 | pxor W_TMP1, W | ||
| 387 | movdqa W, W_TMP2 | ||
| 388 | movdqa W, W_TMP1 | ||
| 389 | pslldq $12, W_TMP2 | ||
| 390 | .elseif ((i & 3) == 2) | ||
| 391 | psrld $31, W | ||
| 392 | pslld $1, W_TMP1 | ||
| 393 | por W, W_TMP1 | ||
| 394 | movdqa W_TMP2, W | ||
| 395 | psrld $30, W_TMP2 | ||
| 396 | pslld $2, W | ||
| 397 | .elseif ((i & 3) == 3) | ||
| 398 | pxor W, W_TMP1 | ||
| 399 | pxor W_TMP2, W_TMP1 | ||
| 400 | movdqa W_TMP1, W | ||
| 401 | paddd K_XMM(K_BASE), W_TMP1 | ||
| 402 | movdqa W_TMP1, WK(i&~3) | ||
| 403 | W_PRECALC_ROTATE | ||
| 404 | .endif | ||
| 405 | .endm | ||
| 406 | |||
| 407 | /* message scheduling pre-compute for rounds 32-79 | ||
| 408 | * | ||
| 409 | * in SHA-1 specification: w[i] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) rol 1 | ||
| 410 | * instead we do equal: w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]) rol 2 | ||
| 411 | * allows more efficient vectorization since w[i]=>w[i-3] dependency is broken | ||
| 412 | */ | ||
| 413 | .macro W_PRECALC_32_79_SSSE3 | ||
| 414 | .if ((i & 3) == 0) | ||
| 415 | movdqa W_minus_04, W_TMP1 | ||
| 416 | pxor W_minus_28, W # W is W_minus_32 before xor | ||
| 417 | palignr $8, W_minus_08, W_TMP1 | ||
| 418 | .elseif ((i & 3) == 1) | ||
| 419 | pxor W_minus_16, W | ||
| 420 | pxor W_TMP1, W | ||
| 421 | movdqa W, W_TMP1 | ||
| 422 | .elseif ((i & 3) == 2) | ||
| 423 | psrld $30, W | ||
| 424 | pslld $2, W_TMP1 | ||
| 425 | por W, W_TMP1 | ||
| 426 | .elseif ((i & 3) == 3) | ||
| 427 | movdqa W_TMP1, W | ||
| 428 | paddd K_XMM(K_BASE), W_TMP1 | ||
| 429 | movdqa W_TMP1, WK(i&~3) | ||
| 430 | W_PRECALC_ROTATE | ||
| 431 | .endif | ||
| 432 | .endm | ||
| 433 | |||
| 434 | .endm // W_PRECALC_SSSE3 | ||
| 435 | |||
| 436 | |||
| 437 | #define K1 0x5a827999 | ||
| 438 | #define K2 0x6ed9eba1 | ||
| 439 | #define K3 0x8f1bbcdc | ||
| 440 | #define K4 0xca62c1d6 | ||
| 441 | |||
| 442 | .section .rodata | ||
| 443 | .align 16 | ||
| 444 | |||
| 445 | K_XMM_AR: | ||
| 446 | .long K1, K1, K1, K1 | ||
| 447 | .long K2, K2, K2, K2 | ||
| 448 | .long K3, K3, K3, K3 | ||
| 449 | .long K4, K4, K4, K4 | ||
| 450 | |||
| 451 | BSWAP_SHUFB_CTL: | ||
| 452 | .long 0x00010203 | ||
| 453 | .long 0x04050607 | ||
| 454 | .long 0x08090a0b | ||
| 455 | .long 0x0c0d0e0f | ||
| 456 | |||
| 457 | |||
| 458 | .section .text | ||
| 459 | |||
| 460 | W_PRECALC_SSSE3 | ||
| 461 | .macro xmm_mov a, b | ||
| 462 | movdqu \a,\b | ||
| 463 | .endm | ||
| 464 | |||
| 465 | /* SSSE3 optimized implementation: | ||
| 466 | * extern "C" void sha1_transform_ssse3(u32 *digest, const char *data, u32 *ws, | ||
| 467 | * unsigned int rounds); | ||
| 468 | */ | ||
| 469 | SHA1_VECTOR_ASM sha1_transform_ssse3 | ||
| 470 | |||
| 471 | #ifdef SHA1_ENABLE_AVX_SUPPORT | ||
| 472 | |||
| 473 | .macro W_PRECALC_AVX | ||
| 474 | |||
| 475 | .purgem W_PRECALC_00_15 | ||
| 476 | .macro W_PRECALC_00_15 | ||
| 477 | W_PRECALC_00_15_AVX | ||
| 478 | .endm | ||
| 479 | .purgem W_PRECALC_16_31 | ||
| 480 | .macro W_PRECALC_16_31 | ||
| 481 | W_PRECALC_16_31_AVX | ||
| 482 | .endm | ||
| 483 | .purgem W_PRECALC_32_79 | ||
| 484 | .macro W_PRECALC_32_79 | ||
| 485 | W_PRECALC_32_79_AVX | ||
| 486 | .endm | ||
| 487 | |||
| 488 | .macro W_PRECALC_00_15_AVX | ||
| 489 | .if ((i & 3) == 0) | ||
| 490 | vmovdqu (i*4)(BUFFER_PTR), W_TMP1 | ||
| 491 | .elseif ((i & 3) == 1) | ||
| 492 | vpshufb XMM_SHUFB_BSWAP, W_TMP1, W | ||
| 493 | .elseif ((i & 3) == 2) | ||
| 494 | vpaddd (K_BASE), W, W_TMP1 | ||
| 495 | .elseif ((i & 3) == 3) | ||
| 496 | vmovdqa W_TMP1, WK(i&~3) | ||
| 497 | W_PRECALC_ROTATE | ||
| 498 | .endif | ||
| 499 | .endm | ||
| 500 | |||
| 501 | .macro W_PRECALC_16_31_AVX | ||
| 502 | .if ((i & 3) == 0) | ||
| 503 | vpalignr $8, W_minus_16, W_minus_12, W # w[i-14] | ||
| 504 | vpsrldq $4, W_minus_04, W_TMP1 # w[i-3] | ||
| 505 | vpxor W_minus_08, W, W | ||
| 506 | vpxor W_minus_16, W_TMP1, W_TMP1 | ||
| 507 | .elseif ((i & 3) == 1) | ||
| 508 | vpxor W_TMP1, W, W | ||
| 509 | vpslldq $12, W, W_TMP2 | ||
| 510 | vpslld $1, W, W_TMP1 | ||
| 511 | .elseif ((i & 3) == 2) | ||
| 512 | vpsrld $31, W, W | ||
| 513 | vpor W, W_TMP1, W_TMP1 | ||
| 514 | vpslld $2, W_TMP2, W | ||
| 515 | vpsrld $30, W_TMP2, W_TMP2 | ||
| 516 | .elseif ((i & 3) == 3) | ||
| 517 | vpxor W, W_TMP1, W_TMP1 | ||
| 518 | vpxor W_TMP2, W_TMP1, W | ||
| 519 | vpaddd K_XMM(K_BASE), W, W_TMP1 | ||
| 520 | vmovdqu W_TMP1, WK(i&~3) | ||
| 521 | W_PRECALC_ROTATE | ||
| 522 | .endif | ||
| 523 | .endm | ||
| 524 | |||
| 525 | .macro W_PRECALC_32_79_AVX | ||
| 526 | .if ((i & 3) == 0) | ||
| 527 | vpalignr $8, W_minus_08, W_minus_04, W_TMP1 | ||
| 528 | vpxor W_minus_28, W, W # W is W_minus_32 before xor | ||
| 529 | .elseif ((i & 3) == 1) | ||
| 530 | vpxor W_minus_16, W_TMP1, W_TMP1 | ||
| 531 | vpxor W_TMP1, W, W | ||
| 532 | .elseif ((i & 3) == 2) | ||
| 533 | vpslld $2, W, W_TMP1 | ||
| 534 | vpsrld $30, W, W | ||
| 535 | vpor W, W_TMP1, W | ||
| 536 | .elseif ((i & 3) == 3) | ||
| 537 | vpaddd K_XMM(K_BASE), W, W_TMP1 | ||
| 538 | vmovdqu W_TMP1, WK(i&~3) | ||
| 539 | W_PRECALC_ROTATE | ||
| 540 | .endif | ||
| 541 | .endm | ||
| 542 | |||
| 543 | .endm // W_PRECALC_AVX | ||
| 544 | |||
| 545 | W_PRECALC_AVX | ||
| 546 | .purgem xmm_mov | ||
| 547 | .macro xmm_mov a, b | ||
| 548 | vmovdqu \a,\b | ||
| 549 | .endm | ||
| 550 | |||
| 551 | |||
| 552 | /* AVX optimized implementation: | ||
| 553 | * extern "C" void sha1_transform_avx(u32 *digest, const char *data, u32 *ws, | ||
| 554 | * unsigned int rounds); | ||
| 555 | */ | ||
| 556 | SHA1_VECTOR_ASM sha1_transform_avx | ||
| 557 | |||
| 558 | #endif | ||
diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c new file mode 100644 index 000000000000..f916499d0abe --- /dev/null +++ b/arch/x86/crypto/sha1_ssse3_glue.c | |||
| @@ -0,0 +1,240 @@ | |||
| 1 | /* | ||
| 2 | * Cryptographic API. | ||
| 3 | * | ||
| 4 | * Glue code for the SHA1 Secure Hash Algorithm assembler implementation using | ||
| 5 | * Supplemental SSE3 instructions. | ||
| 6 | * | ||
| 7 | * This file is based on sha1_generic.c | ||
| 8 | * | ||
| 9 | * Copyright (c) Alan Smithee. | ||
| 10 | * Copyright (c) Andrew McDonald <andrew@mcdonald.org.uk> | ||
| 11 | * Copyright (c) Jean-Francois Dive <jef@linuxbe.org> | ||
| 12 | * Copyright (c) Mathias Krause <minipli@googlemail.com> | ||
| 13 | * | ||
| 14 | * This program is free software; you can redistribute it and/or modify it | ||
| 15 | * under the terms of the GNU General Public License as published by the Free | ||
| 16 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 17 | * any later version. | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 22 | |||
| 23 | #include <crypto/internal/hash.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/mm.h> | ||
| 27 | #include <linux/cryptohash.h> | ||
| 28 | #include <linux/types.h> | ||
| 29 | #include <crypto/sha.h> | ||
| 30 | #include <asm/byteorder.h> | ||
| 31 | #include <asm/i387.h> | ||
| 32 | #include <asm/xcr.h> | ||
| 33 | #include <asm/xsave.h> | ||
| 34 | |||
| 35 | |||
| 36 | asmlinkage void sha1_transform_ssse3(u32 *digest, const char *data, | ||
| 37 | unsigned int rounds); | ||
| 38 | #ifdef SHA1_ENABLE_AVX_SUPPORT | ||
| 39 | asmlinkage void sha1_transform_avx(u32 *digest, const char *data, | ||
| 40 | unsigned int rounds); | ||
| 41 | #endif | ||
| 42 | |||
| 43 | static asmlinkage void (*sha1_transform_asm)(u32 *, const char *, unsigned int); | ||
| 44 | |||
| 45 | |||
| 46 | static int sha1_ssse3_init(struct shash_desc *desc) | ||
| 47 | { | ||
| 48 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
| 49 | |||
| 50 | *sctx = (struct sha1_state){ | ||
| 51 | .state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 }, | ||
| 52 | }; | ||
| 53 | |||
| 54 | return 0; | ||
| 55 | } | ||
| 56 | |||
| 57 | static int __sha1_ssse3_update(struct shash_desc *desc, const u8 *data, | ||
| 58 | unsigned int len, unsigned int partial) | ||
| 59 | { | ||
| 60 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
| 61 | unsigned int done = 0; | ||
| 62 | |||
| 63 | sctx->count += len; | ||
| 64 | |||
| 65 | if (partial) { | ||
| 66 | done = SHA1_BLOCK_SIZE - partial; | ||
| 67 | memcpy(sctx->buffer + partial, data, done); | ||
| 68 | sha1_transform_asm(sctx->state, sctx->buffer, 1); | ||
| 69 | } | ||
| 70 | |||
| 71 | if (len - done >= SHA1_BLOCK_SIZE) { | ||
| 72 | const unsigned int rounds = (len - done) / SHA1_BLOCK_SIZE; | ||
| 73 | |||
| 74 | sha1_transform_asm(sctx->state, data + done, rounds); | ||
| 75 | done += rounds * SHA1_BLOCK_SIZE; | ||
| 76 | } | ||
| 77 | |||
| 78 | memcpy(sctx->buffer, data + done, len - done); | ||
| 79 | |||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | static int sha1_ssse3_update(struct shash_desc *desc, const u8 *data, | ||
| 84 | unsigned int len) | ||
| 85 | { | ||
| 86 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
| 87 | unsigned int partial = sctx->count % SHA1_BLOCK_SIZE; | ||
| 88 | int res; | ||
| 89 | |||
| 90 | /* Handle the fast case right here */ | ||
| 91 | if (partial + len < SHA1_BLOCK_SIZE) { | ||
| 92 | sctx->count += len; | ||
| 93 | memcpy(sctx->buffer + partial, data, len); | ||
| 94 | |||
| 95 | return 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | if (!irq_fpu_usable()) { | ||
| 99 | res = crypto_sha1_update(desc, data, len); | ||
| 100 | } else { | ||
| 101 | kernel_fpu_begin(); | ||
| 102 | res = __sha1_ssse3_update(desc, data, len, partial); | ||
| 103 | kernel_fpu_end(); | ||
| 104 | } | ||
| 105 | |||
| 106 | return res; | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | /* Add padding and return the message digest. */ | ||
| 111 | static int sha1_ssse3_final(struct shash_desc *desc, u8 *out) | ||
| 112 | { | ||
| 113 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
| 114 | unsigned int i, index, padlen; | ||
| 115 | __be32 *dst = (__be32 *)out; | ||
| 116 | __be64 bits; | ||
| 117 | static const u8 padding[SHA1_BLOCK_SIZE] = { 0x80, }; | ||
| 118 | |||
| 119 | bits = cpu_to_be64(sctx->count << 3); | ||
| 120 | |||
| 121 | /* Pad out to 56 mod 64 and append length */ | ||
| 122 | index = sctx->count % SHA1_BLOCK_SIZE; | ||
| 123 | padlen = (index < 56) ? (56 - index) : ((SHA1_BLOCK_SIZE+56) - index); | ||
| 124 | if (!irq_fpu_usable()) { | ||
| 125 | crypto_sha1_update(desc, padding, padlen); | ||
| 126 | crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits)); | ||
| 127 | } else { | ||
| 128 | kernel_fpu_begin(); | ||
| 129 | /* We need to fill a whole block for __sha1_ssse3_update() */ | ||
| 130 | if (padlen <= 56) { | ||
| 131 | sctx->count += padlen; | ||
| 132 | memcpy(sctx->buffer + index, padding, padlen); | ||
| 133 | } else { | ||
| 134 | __sha1_ssse3_update(desc, padding, padlen, index); | ||
| 135 | } | ||
| 136 | __sha1_ssse3_update(desc, (const u8 *)&bits, sizeof(bits), 56); | ||
| 137 | kernel_fpu_end(); | ||
| 138 | } | ||
| 139 | |||
| 140 | /* Store state in digest */ | ||
| 141 | for (i = 0; i < 5; i++) | ||
| 142 | dst[i] = cpu_to_be32(sctx->state[i]); | ||
| 143 | |||
| 144 | /* Wipe context */ | ||
| 145 | memset(sctx, 0, sizeof(*sctx)); | ||
| 146 | |||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | static int sha1_ssse3_export(struct shash_desc *desc, void *out) | ||
| 151 | { | ||
| 152 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
| 153 | |||
| 154 | memcpy(out, sctx, sizeof(*sctx)); | ||
| 155 | |||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int sha1_ssse3_import(struct shash_desc *desc, const void *in) | ||
| 160 | { | ||
| 161 | struct sha1_state *sctx = shash_desc_ctx(desc); | ||
| 162 | |||
| 163 | memcpy(sctx, in, sizeof(*sctx)); | ||
| 164 | |||
| 165 | return 0; | ||
| 166 | } | ||
| 167 | |||
| 168 | static struct shash_alg alg = { | ||
| 169 | .digestsize = SHA1_DIGEST_SIZE, | ||
| 170 | .init = sha1_ssse3_init, | ||
| 171 | .update = sha1_ssse3_update, | ||
| 172 | .final = sha1_ssse3_final, | ||
| 173 | .export = sha1_ssse3_export, | ||
| 174 | .import = sha1_ssse3_import, | ||
| 175 | .descsize = sizeof(struct sha1_state), | ||
| 176 | .statesize = sizeof(struct sha1_state), | ||
| 177 | .base = { | ||
| 178 | .cra_name = "sha1", | ||
| 179 | .cra_driver_name= "sha1-ssse3", | ||
| 180 | .cra_priority = 150, | ||
| 181 | .cra_flags = CRYPTO_ALG_TYPE_SHASH, | ||
| 182 | .cra_blocksize = SHA1_BLOCK_SIZE, | ||
| 183 | .cra_module = THIS_MODULE, | ||
| 184 | } | ||
| 185 | }; | ||
| 186 | |||
| 187 | #ifdef SHA1_ENABLE_AVX_SUPPORT | ||
| 188 | static bool __init avx_usable(void) | ||
| 189 | { | ||
| 190 | u64 xcr0; | ||
| 191 | |||
| 192 | if (!cpu_has_avx || !cpu_has_osxsave) | ||
| 193 | return false; | ||
| 194 | |||
| 195 | xcr0 = xgetbv(XCR_XFEATURE_ENABLED_MASK); | ||
| 196 | if ((xcr0 & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM)) { | ||
| 197 | pr_info("AVX detected but unusable.\n"); | ||
| 198 | |||
| 199 | return false; | ||
| 200 | } | ||
| 201 | |||
| 202 | return true; | ||
| 203 | } | ||
| 204 | #endif | ||
| 205 | |||
| 206 | static int __init sha1_ssse3_mod_init(void) | ||
| 207 | { | ||
| 208 | /* test for SSSE3 first */ | ||
| 209 | if (cpu_has_ssse3) | ||
| 210 | sha1_transform_asm = sha1_transform_ssse3; | ||
| 211 | |||
| 212 | #ifdef SHA1_ENABLE_AVX_SUPPORT | ||
| 213 | /* allow AVX to override SSSE3, it's a little faster */ | ||
| 214 | if (avx_usable()) | ||
| 215 | sha1_transform_asm = sha1_transform_avx; | ||
| 216 | #endif | ||
| 217 | |||
| 218 | if (sha1_transform_asm) { | ||
| 219 | pr_info("Using %s optimized SHA-1 implementation\n", | ||
| 220 | sha1_transform_asm == sha1_transform_ssse3 ? "SSSE3" | ||
| 221 | : "AVX"); | ||
| 222 | return crypto_register_shash(&alg); | ||
| 223 | } | ||
| 224 | pr_info("Neither AVX nor SSSE3 is available/usable.\n"); | ||
| 225 | |||
| 226 | return -ENODEV; | ||
| 227 | } | ||
| 228 | |||
| 229 | static void __exit sha1_ssse3_mod_fini(void) | ||
| 230 | { | ||
| 231 | crypto_unregister_shash(&alg); | ||
| 232 | } | ||
| 233 | |||
| 234 | module_init(sha1_ssse3_mod_init); | ||
| 235 | module_exit(sha1_ssse3_mod_fini); | ||
| 236 | |||
| 237 | MODULE_LICENSE("GPL"); | ||
| 238 | MODULE_DESCRIPTION("SHA1 Secure Hash Algorithm, Supplemental SSE3 accelerated"); | ||
| 239 | |||
| 240 | MODULE_ALIAS("sha1"); | ||
diff --git a/arch/x86/crypto/twofish-i586-asm_32.S b/arch/x86/crypto/twofish-i586-asm_32.S index 575331cb2a8a..658af4bb35c9 100644 --- a/arch/x86/crypto/twofish-i586-asm_32.S +++ b/arch/x86/crypto/twofish-i586-asm_32.S | |||
| @@ -26,7 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | #define in_blk 12 /* input byte array address parameter*/ | 27 | #define in_blk 12 /* input byte array address parameter*/ |
| 28 | #define out_blk 8 /* output byte array address parameter*/ | 28 | #define out_blk 8 /* output byte array address parameter*/ |
| 29 | #define tfm 4 /* Twofish context structure */ | 29 | #define ctx 4 /* Twofish context structure */ |
| 30 | 30 | ||
| 31 | #define a_offset 0 | 31 | #define a_offset 0 |
| 32 | #define b_offset 4 | 32 | #define b_offset 4 |
| @@ -229,8 +229,8 @@ twofish_enc_blk: | |||
| 229 | push %esi | 229 | push %esi |
| 230 | push %edi | 230 | push %edi |
| 231 | 231 | ||
| 232 | mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */ | 232 | mov ctx + 16(%esp), %ebp /* abuse the base pointer: set new base |
| 233 | add $crypto_tfm_ctx_offset, %ebp /* ctx address */ | 233 | * pointer to the ctx address */ |
| 234 | mov in_blk+16(%esp),%edi /* input address in edi */ | 234 | mov in_blk+16(%esp),%edi /* input address in edi */ |
| 235 | 235 | ||
| 236 | mov (%edi), %eax | 236 | mov (%edi), %eax |
| @@ -285,8 +285,8 @@ twofish_dec_blk: | |||
| 285 | push %edi | 285 | push %edi |
| 286 | 286 | ||
| 287 | 287 | ||
| 288 | mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */ | 288 | mov ctx + 16(%esp), %ebp /* abuse the base pointer: set new base |
| 289 | add $crypto_tfm_ctx_offset, %ebp /* ctx address */ | 289 | * pointer to the ctx address */ |
| 290 | mov in_blk+16(%esp),%edi /* input address in edi */ | 290 | mov in_blk+16(%esp),%edi /* input address in edi */ |
| 291 | 291 | ||
| 292 | mov (%edi), %eax | 292 | mov (%edi), %eax |
diff --git a/arch/x86/crypto/twofish-x86_64-asm_64-3way.S b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S new file mode 100644 index 000000000000..5b012a2c5119 --- /dev/null +++ b/arch/x86/crypto/twofish-x86_64-asm_64-3way.S | |||
| @@ -0,0 +1,316 @@ | |||
| 1 | /* | ||
| 2 | * Twofish Cipher 3-way parallel algorithm (x86_64) | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 19 | * USA | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | .file "twofish-x86_64-asm-3way.S" | ||
| 24 | .text | ||
| 25 | |||
| 26 | /* structure of crypto context */ | ||
| 27 | #define s0 0 | ||
| 28 | #define s1 1024 | ||
| 29 | #define s2 2048 | ||
| 30 | #define s3 3072 | ||
| 31 | #define w 4096 | ||
| 32 | #define k 4128 | ||
| 33 | |||
| 34 | /********************************************************************** | ||
| 35 | 3-way twofish | ||
| 36 | **********************************************************************/ | ||
| 37 | #define CTX %rdi | ||
| 38 | #define RIO %rdx | ||
| 39 | |||
| 40 | #define RAB0 %rax | ||
| 41 | #define RAB1 %rbx | ||
| 42 | #define RAB2 %rcx | ||
| 43 | |||
| 44 | #define RAB0d %eax | ||
| 45 | #define RAB1d %ebx | ||
| 46 | #define RAB2d %ecx | ||
| 47 | |||
| 48 | #define RAB0bh %ah | ||
| 49 | #define RAB1bh %bh | ||
| 50 | #define RAB2bh %ch | ||
| 51 | |||
| 52 | #define RAB0bl %al | ||
| 53 | #define RAB1bl %bl | ||
| 54 | #define RAB2bl %cl | ||
| 55 | |||
| 56 | #define RCD0 %r8 | ||
| 57 | #define RCD1 %r9 | ||
| 58 | #define RCD2 %r10 | ||
| 59 | |||
| 60 | #define RCD0d %r8d | ||
| 61 | #define RCD1d %r9d | ||
| 62 | #define RCD2d %r10d | ||
| 63 | |||
| 64 | #define RX0 %rbp | ||
| 65 | #define RX1 %r11 | ||
| 66 | #define RX2 %r12 | ||
| 67 | |||
| 68 | #define RX0d %ebp | ||
| 69 | #define RX1d %r11d | ||
| 70 | #define RX2d %r12d | ||
| 71 | |||
| 72 | #define RY0 %r13 | ||
| 73 | #define RY1 %r14 | ||
| 74 | #define RY2 %r15 | ||
| 75 | |||
| 76 | #define RY0d %r13d | ||
| 77 | #define RY1d %r14d | ||
| 78 | #define RY2d %r15d | ||
| 79 | |||
| 80 | #define RT0 %rdx | ||
| 81 | #define RT1 %rsi | ||
| 82 | |||
| 83 | #define RT0d %edx | ||
| 84 | #define RT1d %esi | ||
| 85 | |||
| 86 | #define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \ | ||
| 87 | movzbl ab ## bl, tmp2 ## d; \ | ||
| 88 | movzbl ab ## bh, tmp1 ## d; \ | ||
| 89 | rorq $(rot), ab; \ | ||
| 90 | op1##l T0(CTX, tmp2, 4), dst ## d; \ | ||
| 91 | op2##l T1(CTX, tmp1, 4), dst ## d; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * Combined G1 & G2 function. Reordered with help of rotates to have moves | ||
| 95 | * at begining. | ||
| 96 | */ | ||
| 97 | #define g1g2_3(ab, cd, Tx0, Tx1, Tx2, Tx3, Ty0, Ty1, Ty2, Ty3, x, y) \ | ||
| 98 | /* G1,1 && G2,1 */ \ | ||
| 99 | do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 0, ab ## 0, x ## 0); \ | ||
| 100 | do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 0, ab ## 0, y ## 0); \ | ||
| 101 | \ | ||
| 102 | do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 1, ab ## 1, x ## 1); \ | ||
| 103 | do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 1, ab ## 1, y ## 1); \ | ||
| 104 | \ | ||
| 105 | do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 2, ab ## 2, x ## 2); \ | ||
| 106 | do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 2, ab ## 2, y ## 2); \ | ||
| 107 | \ | ||
| 108 | /* G1,2 && G2,2 */ \ | ||
| 109 | do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \ | ||
| 110 | do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \ | ||
| 111 | xchgq cd ## 0, ab ## 0; \ | ||
| 112 | \ | ||
| 113 | do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \ | ||
| 114 | do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \ | ||
| 115 | xchgq cd ## 1, ab ## 1; \ | ||
| 116 | \ | ||
| 117 | do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \ | ||
| 118 | do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \ | ||
| 119 | xchgq cd ## 2, ab ## 2; | ||
| 120 | |||
| 121 | #define enc_round_end(ab, x, y, n) \ | ||
| 122 | addl y ## d, x ## d; \ | ||
| 123 | addl x ## d, y ## d; \ | ||
| 124 | addl k+4*(2*(n))(CTX), x ## d; \ | ||
| 125 | xorl ab ## d, x ## d; \ | ||
| 126 | addl k+4*(2*(n)+1)(CTX), y ## d; \ | ||
| 127 | shrq $32, ab; \ | ||
| 128 | roll $1, ab ## d; \ | ||
| 129 | xorl y ## d, ab ## d; \ | ||
| 130 | shlq $32, ab; \ | ||
| 131 | rorl $1, x ## d; \ | ||
| 132 | orq x, ab; | ||
| 133 | |||
| 134 | #define dec_round_end(ba, x, y, n) \ | ||
| 135 | addl y ## d, x ## d; \ | ||
| 136 | addl x ## d, y ## d; \ | ||
| 137 | addl k+4*(2*(n))(CTX), x ## d; \ | ||
| 138 | addl k+4*(2*(n)+1)(CTX), y ## d; \ | ||
| 139 | xorl ba ## d, y ## d; \ | ||
| 140 | shrq $32, ba; \ | ||
| 141 | roll $1, ba ## d; \ | ||
| 142 | xorl x ## d, ba ## d; \ | ||
| 143 | shlq $32, ba; \ | ||
| 144 | rorl $1, y ## d; \ | ||
| 145 | orq y, ba; | ||
| 146 | |||
| 147 | #define encrypt_round3(ab, cd, n) \ | ||
| 148 | g1g2_3(ab, cd, s0, s1, s2, s3, s0, s1, s2, s3, RX, RY); \ | ||
| 149 | \ | ||
| 150 | enc_round_end(ab ## 0, RX0, RY0, n); \ | ||
| 151 | enc_round_end(ab ## 1, RX1, RY1, n); \ | ||
| 152 | enc_round_end(ab ## 2, RX2, RY2, n); | ||
| 153 | |||
| 154 | #define decrypt_round3(ba, dc, n) \ | ||
| 155 | g1g2_3(ba, dc, s1, s2, s3, s0, s3, s0, s1, s2, RY, RX); \ | ||
| 156 | \ | ||
| 157 | dec_round_end(ba ## 0, RX0, RY0, n); \ | ||
| 158 | dec_round_end(ba ## 1, RX1, RY1, n); \ | ||
| 159 | dec_round_end(ba ## 2, RX2, RY2, n); | ||
| 160 | |||
| 161 | #define encrypt_cycle3(ab, cd, n) \ | ||
| 162 | encrypt_round3(ab, cd, n*2); \ | ||
| 163 | encrypt_round3(ab, cd, (n*2)+1); | ||
| 164 | |||
| 165 | #define decrypt_cycle3(ba, dc, n) \ | ||
| 166 | decrypt_round3(ba, dc, (n*2)+1); \ | ||
| 167 | decrypt_round3(ba, dc, (n*2)); | ||
| 168 | |||
| 169 | #define inpack3(in, n, xy, m) \ | ||
| 170 | movq 4*(n)(in), xy ## 0; \ | ||
| 171 | xorq w+4*m(CTX), xy ## 0; \ | ||
| 172 | \ | ||
| 173 | movq 4*(4+(n))(in), xy ## 1; \ | ||
| 174 | xorq w+4*m(CTX), xy ## 1; \ | ||
| 175 | \ | ||
| 176 | movq 4*(8+(n))(in), xy ## 2; \ | ||
| 177 | xorq w+4*m(CTX), xy ## 2; | ||
| 178 | |||
| 179 | #define outunpack3(op, out, n, xy, m) \ | ||
| 180 | xorq w+4*m(CTX), xy ## 0; \ | ||
| 181 | op ## q xy ## 0, 4*(n)(out); \ | ||
| 182 | \ | ||
| 183 | xorq w+4*m(CTX), xy ## 1; \ | ||
| 184 | op ## q xy ## 1, 4*(4+(n))(out); \ | ||
| 185 | \ | ||
| 186 | xorq w+4*m(CTX), xy ## 2; \ | ||
| 187 | op ## q xy ## 2, 4*(8+(n))(out); | ||
| 188 | |||
| 189 | #define inpack_enc3() \ | ||
| 190 | inpack3(RIO, 0, RAB, 0); \ | ||
| 191 | inpack3(RIO, 2, RCD, 2); | ||
| 192 | |||
| 193 | #define outunpack_enc3(op) \ | ||
| 194 | outunpack3(op, RIO, 2, RAB, 6); \ | ||
| 195 | outunpack3(op, RIO, 0, RCD, 4); | ||
| 196 | |||
| 197 | #define inpack_dec3() \ | ||
| 198 | inpack3(RIO, 0, RAB, 4); \ | ||
| 199 | rorq $32, RAB0; \ | ||
| 200 | rorq $32, RAB1; \ | ||
| 201 | rorq $32, RAB2; \ | ||
| 202 | inpack3(RIO, 2, RCD, 6); \ | ||
| 203 | rorq $32, RCD0; \ | ||
| 204 | rorq $32, RCD1; \ | ||
| 205 | rorq $32, RCD2; | ||
| 206 | |||
| 207 | #define outunpack_dec3() \ | ||
| 208 | rorq $32, RCD0; \ | ||
| 209 | rorq $32, RCD1; \ | ||
| 210 | rorq $32, RCD2; \ | ||
| 211 | outunpack3(mov, RIO, 0, RCD, 0); \ | ||
| 212 | rorq $32, RAB0; \ | ||
| 213 | rorq $32, RAB1; \ | ||
| 214 | rorq $32, RAB2; \ | ||
| 215 | outunpack3(mov, RIO, 2, RAB, 2); | ||
| 216 | |||
| 217 | .align 8 | ||
| 218 | .global __twofish_enc_blk_3way | ||
| 219 | .type __twofish_enc_blk_3way,@function; | ||
| 220 | |||
| 221 | __twofish_enc_blk_3way: | ||
| 222 | /* input: | ||
| 223 | * %rdi: ctx, CTX | ||
| 224 | * %rsi: dst | ||
| 225 | * %rdx: src, RIO | ||
| 226 | * %rcx: bool, if true: xor output | ||
| 227 | */ | ||
| 228 | pushq %r15; | ||
| 229 | pushq %r14; | ||
| 230 | pushq %r13; | ||
| 231 | pushq %r12; | ||
| 232 | pushq %rbp; | ||
| 233 | pushq %rbx; | ||
| 234 | |||
| 235 | pushq %rcx; /* bool xor */ | ||
| 236 | pushq %rsi; /* dst */ | ||
| 237 | |||
| 238 | inpack_enc3(); | ||
| 239 | |||
| 240 | encrypt_cycle3(RAB, RCD, 0); | ||
| 241 | encrypt_cycle3(RAB, RCD, 1); | ||
| 242 | encrypt_cycle3(RAB, RCD, 2); | ||
| 243 | encrypt_cycle3(RAB, RCD, 3); | ||
| 244 | encrypt_cycle3(RAB, RCD, 4); | ||
| 245 | encrypt_cycle3(RAB, RCD, 5); | ||
| 246 | encrypt_cycle3(RAB, RCD, 6); | ||
| 247 | encrypt_cycle3(RAB, RCD, 7); | ||
| 248 | |||
| 249 | popq RIO; /* dst */ | ||
| 250 | popq %rbp; /* bool xor */ | ||
| 251 | |||
| 252 | testb %bpl, %bpl; | ||
| 253 | jnz __enc_xor3; | ||
| 254 | |||
| 255 | outunpack_enc3(mov); | ||
| 256 | |||
| 257 | popq %rbx; | ||
| 258 | popq %rbp; | ||
| 259 | popq %r12; | ||
| 260 | popq %r13; | ||
| 261 | popq %r14; | ||
| 262 | popq %r15; | ||
| 263 | ret; | ||
| 264 | |||
| 265 | __enc_xor3: | ||
| 266 | outunpack_enc3(xor); | ||
| 267 | |||
| 268 | popq %rbx; | ||
| 269 | popq %rbp; | ||
| 270 | popq %r12; | ||
| 271 | popq %r13; | ||
| 272 | popq %r14; | ||
| 273 | popq %r15; | ||
| 274 | ret; | ||
| 275 | |||
| 276 | .global twofish_dec_blk_3way | ||
| 277 | .type twofish_dec_blk_3way,@function; | ||
| 278 | |||
| 279 | twofish_dec_blk_3way: | ||
| 280 | /* input: | ||
| 281 | * %rdi: ctx, CTX | ||
| 282 | * %rsi: dst | ||
| 283 | * %rdx: src, RIO | ||
| 284 | */ | ||
| 285 | pushq %r15; | ||
| 286 | pushq %r14; | ||
| 287 | pushq %r13; | ||
| 288 | pushq %r12; | ||
| 289 | pushq %rbp; | ||
| 290 | pushq %rbx; | ||
| 291 | |||
| 292 | pushq %rsi; /* dst */ | ||
| 293 | |||
| 294 | inpack_dec3(); | ||
| 295 | |||
| 296 | decrypt_cycle3(RAB, RCD, 7); | ||
| 297 | decrypt_cycle3(RAB, RCD, 6); | ||
| 298 | decrypt_cycle3(RAB, RCD, 5); | ||
| 299 | decrypt_cycle3(RAB, RCD, 4); | ||
| 300 | decrypt_cycle3(RAB, RCD, 3); | ||
| 301 | decrypt_cycle3(RAB, RCD, 2); | ||
| 302 | decrypt_cycle3(RAB, RCD, 1); | ||
| 303 | decrypt_cycle3(RAB, RCD, 0); | ||
| 304 | |||
| 305 | popq RIO; /* dst */ | ||
| 306 | |||
| 307 | outunpack_dec3(); | ||
| 308 | |||
| 309 | popq %rbx; | ||
| 310 | popq %rbp; | ||
| 311 | popq %r12; | ||
| 312 | popq %r13; | ||
| 313 | popq %r14; | ||
| 314 | popq %r15; | ||
| 315 | ret; | ||
| 316 | |||
diff --git a/arch/x86/crypto/twofish-x86_64-asm_64.S b/arch/x86/crypto/twofish-x86_64-asm_64.S index 573aa102542e..7bcf3fcc3668 100644 --- a/arch/x86/crypto/twofish-x86_64-asm_64.S +++ b/arch/x86/crypto/twofish-x86_64-asm_64.S | |||
| @@ -221,10 +221,9 @@ | |||
| 221 | twofish_enc_blk: | 221 | twofish_enc_blk: |
| 222 | pushq R1 | 222 | pushq R1 |
| 223 | 223 | ||
| 224 | /* %rdi contains the crypto tfm address */ | 224 | /* %rdi contains the ctx address */ |
| 225 | /* %rsi contains the output address */ | 225 | /* %rsi contains the output address */ |
| 226 | /* %rdx contains the input address */ | 226 | /* %rdx contains the input address */ |
| 227 | add $crypto_tfm_ctx_offset, %rdi /* set ctx address */ | ||
| 228 | /* ctx address is moved to free one non-rex register | 227 | /* ctx address is moved to free one non-rex register |
| 229 | as target for the 8bit high operations */ | 228 | as target for the 8bit high operations */ |
| 230 | mov %rdi, %r11 | 229 | mov %rdi, %r11 |
| @@ -274,10 +273,9 @@ twofish_enc_blk: | |||
| 274 | twofish_dec_blk: | 273 | twofish_dec_blk: |
| 275 | pushq R1 | 274 | pushq R1 |
| 276 | 275 | ||
| 277 | /* %rdi contains the crypto tfm address */ | 276 | /* %rdi contains the ctx address */ |
| 278 | /* %rsi contains the output address */ | 277 | /* %rsi contains the output address */ |
| 279 | /* %rdx contains the input address */ | 278 | /* %rdx contains the input address */ |
| 280 | add $crypto_tfm_ctx_offset, %rdi /* set ctx address */ | ||
| 281 | /* ctx address is moved to free one non-rex register | 279 | /* ctx address is moved to free one non-rex register |
| 282 | as target for the 8bit high operations */ | 280 | as target for the 8bit high operations */ |
| 283 | mov %rdi, %r11 | 281 | mov %rdi, %r11 |
diff --git a/arch/x86/crypto/twofish_glue.c b/arch/x86/crypto/twofish_glue.c index cefaf8b9aa18..dc6b3fb817fc 100644 --- a/arch/x86/crypto/twofish_glue.c +++ b/arch/x86/crypto/twofish_glue.c | |||
| @@ -44,17 +44,21 @@ | |||
| 44 | #include <linux/module.h> | 44 | #include <linux/module.h> |
| 45 | #include <linux/types.h> | 45 | #include <linux/types.h> |
| 46 | 46 | ||
| 47 | asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | 47 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, |
| 48 | asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src); | 48 | const u8 *src); |
| 49 | EXPORT_SYMBOL_GPL(twofish_enc_blk); | ||
| 50 | asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, | ||
| 51 | const u8 *src); | ||
| 52 | EXPORT_SYMBOL_GPL(twofish_dec_blk); | ||
| 49 | 53 | ||
| 50 | static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | 54 | static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) |
| 51 | { | 55 | { |
| 52 | twofish_enc_blk(tfm, dst, src); | 56 | twofish_enc_blk(crypto_tfm_ctx(tfm), dst, src); |
| 53 | } | 57 | } |
| 54 | 58 | ||
| 55 | static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | 59 | static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) |
| 56 | { | 60 | { |
| 57 | twofish_dec_blk(tfm, dst, src); | 61 | twofish_dec_blk(crypto_tfm_ctx(tfm), dst, src); |
| 58 | } | 62 | } |
| 59 | 63 | ||
| 60 | static struct crypto_alg alg = { | 64 | static struct crypto_alg alg = { |
diff --git a/arch/x86/crypto/twofish_glue_3way.c b/arch/x86/crypto/twofish_glue_3way.c new file mode 100644 index 000000000000..5ede9c444c3e --- /dev/null +++ b/arch/x86/crypto/twofish_glue_3way.c | |||
| @@ -0,0 +1,472 @@ | |||
| 1 | /* | ||
| 2 | * Glue Code for 3-way parallel assembler optimized version of Twofish | ||
| 3 | * | ||
| 4 | * Copyright (c) 2011 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | ||
| 5 | * | ||
| 6 | * CBC & ECB parts based on code (crypto/cbc.c,ecb.c) by: | ||
| 7 | * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au> | ||
| 8 | * CTR part based on code (crypto/ctr.c) by: | ||
| 9 | * (C) Copyright IBM Corp. 2007 - Joy Latten <latten@us.ibm.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation; either version 2 of the License, or | ||
| 14 | * (at your option) any later version. | ||
| 15 | * | ||
| 16 | * This program is distributed in the hope that it will be useful, | ||
| 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 19 | * GNU General Public License for more details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 | ||
| 24 | * USA | ||
| 25 | * | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include <linux/crypto.h> | ||
| 29 | #include <linux/init.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/types.h> | ||
| 32 | #include <crypto/algapi.h> | ||
| 33 | #include <crypto/twofish.h> | ||
| 34 | #include <crypto/b128ops.h> | ||
| 35 | |||
| 36 | /* regular block cipher functions from twofish_x86_64 module */ | ||
| 37 | asmlinkage void twofish_enc_blk(struct twofish_ctx *ctx, u8 *dst, | ||
| 38 | const u8 *src); | ||
| 39 | asmlinkage void twofish_dec_blk(struct twofish_ctx *ctx, u8 *dst, | ||
| 40 | const u8 *src); | ||
| 41 | |||
| 42 | /* 3-way parallel cipher functions */ | ||
| 43 | asmlinkage void __twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 44 | const u8 *src, bool xor); | ||
| 45 | asmlinkage void twofish_dec_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 46 | const u8 *src); | ||
| 47 | |||
| 48 | static inline void twofish_enc_blk_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 49 | const u8 *src) | ||
| 50 | { | ||
| 51 | __twofish_enc_blk_3way(ctx, dst, src, false); | ||
| 52 | } | ||
| 53 | |||
| 54 | static inline void twofish_enc_blk_xor_3way(struct twofish_ctx *ctx, u8 *dst, | ||
| 55 | const u8 *src) | ||
| 56 | { | ||
| 57 | __twofish_enc_blk_3way(ctx, dst, src, true); | ||
| 58 | } | ||
| 59 | |||
| 60 | static int ecb_crypt(struct blkcipher_desc *desc, struct blkcipher_walk *walk, | ||
| 61 | void (*fn)(struct twofish_ctx *, u8 *, const u8 *), | ||
| 62 | void (*fn_3way)(struct twofish_ctx *, u8 *, const u8 *)) | ||
| 63 | { | ||
| 64 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 65 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 66 | unsigned int nbytes; | ||
| 67 | int err; | ||
| 68 | |||
| 69 | err = blkcipher_walk_virt(desc, walk); | ||
| 70 | |||
| 71 | while ((nbytes = walk->nbytes)) { | ||
| 72 | u8 *wsrc = walk->src.virt.addr; | ||
| 73 | u8 *wdst = walk->dst.virt.addr; | ||
| 74 | |||
| 75 | /* Process three block batch */ | ||
| 76 | if (nbytes >= bsize * 3) { | ||
| 77 | do { | ||
| 78 | fn_3way(ctx, wdst, wsrc); | ||
| 79 | |||
| 80 | wsrc += bsize * 3; | ||
| 81 | wdst += bsize * 3; | ||
| 82 | nbytes -= bsize * 3; | ||
| 83 | } while (nbytes >= bsize * 3); | ||
| 84 | |||
| 85 | if (nbytes < bsize) | ||
| 86 | goto done; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* Handle leftovers */ | ||
| 90 | do { | ||
| 91 | fn(ctx, wdst, wsrc); | ||
| 92 | |||
| 93 | wsrc += bsize; | ||
| 94 | wdst += bsize; | ||
| 95 | nbytes -= bsize; | ||
| 96 | } while (nbytes >= bsize); | ||
| 97 | |||
| 98 | done: | ||
| 99 | err = blkcipher_walk_done(desc, walk, nbytes); | ||
| 100 | } | ||
| 101 | |||
| 102 | return err; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int ecb_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 106 | struct scatterlist *src, unsigned int nbytes) | ||
| 107 | { | ||
| 108 | struct blkcipher_walk walk; | ||
| 109 | |||
| 110 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 111 | return ecb_crypt(desc, &walk, twofish_enc_blk, twofish_enc_blk_3way); | ||
| 112 | } | ||
| 113 | |||
| 114 | static int ecb_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 115 | struct scatterlist *src, unsigned int nbytes) | ||
| 116 | { | ||
| 117 | struct blkcipher_walk walk; | ||
| 118 | |||
| 119 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 120 | return ecb_crypt(desc, &walk, twofish_dec_blk, twofish_dec_blk_3way); | ||
| 121 | } | ||
| 122 | |||
| 123 | static struct crypto_alg blk_ecb_alg = { | ||
| 124 | .cra_name = "ecb(twofish)", | ||
| 125 | .cra_driver_name = "ecb-twofish-3way", | ||
| 126 | .cra_priority = 300, | ||
| 127 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 128 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 129 | .cra_ctxsize = sizeof(struct twofish_ctx), | ||
| 130 | .cra_alignmask = 0, | ||
| 131 | .cra_type = &crypto_blkcipher_type, | ||
| 132 | .cra_module = THIS_MODULE, | ||
| 133 | .cra_list = LIST_HEAD_INIT(blk_ecb_alg.cra_list), | ||
| 134 | .cra_u = { | ||
| 135 | .blkcipher = { | ||
| 136 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 137 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 138 | .setkey = twofish_setkey, | ||
| 139 | .encrypt = ecb_encrypt, | ||
| 140 | .decrypt = ecb_decrypt, | ||
| 141 | }, | ||
| 142 | }, | ||
| 143 | }; | ||
| 144 | |||
| 145 | static unsigned int __cbc_encrypt(struct blkcipher_desc *desc, | ||
| 146 | struct blkcipher_walk *walk) | ||
| 147 | { | ||
| 148 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 149 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 150 | unsigned int nbytes = walk->nbytes; | ||
| 151 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 152 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 153 | u128 *iv = (u128 *)walk->iv; | ||
| 154 | |||
| 155 | do { | ||
| 156 | u128_xor(dst, src, iv); | ||
| 157 | twofish_enc_blk(ctx, (u8 *)dst, (u8 *)dst); | ||
| 158 | iv = dst; | ||
| 159 | |||
| 160 | src += 1; | ||
| 161 | dst += 1; | ||
| 162 | nbytes -= bsize; | ||
| 163 | } while (nbytes >= bsize); | ||
| 164 | |||
| 165 | u128_xor((u128 *)walk->iv, (u128 *)walk->iv, iv); | ||
| 166 | return nbytes; | ||
| 167 | } | ||
| 168 | |||
| 169 | static int cbc_encrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 170 | struct scatterlist *src, unsigned int nbytes) | ||
| 171 | { | ||
| 172 | struct blkcipher_walk walk; | ||
| 173 | int err; | ||
| 174 | |||
| 175 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 176 | err = blkcipher_walk_virt(desc, &walk); | ||
| 177 | |||
| 178 | while ((nbytes = walk.nbytes)) { | ||
| 179 | nbytes = __cbc_encrypt(desc, &walk); | ||
| 180 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 181 | } | ||
| 182 | |||
| 183 | return err; | ||
| 184 | } | ||
| 185 | |||
| 186 | static unsigned int __cbc_decrypt(struct blkcipher_desc *desc, | ||
| 187 | struct blkcipher_walk *walk) | ||
| 188 | { | ||
| 189 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 190 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 191 | unsigned int nbytes = walk->nbytes; | ||
| 192 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 193 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 194 | u128 ivs[3 - 1]; | ||
| 195 | u128 last_iv; | ||
| 196 | |||
| 197 | /* Start of the last block. */ | ||
| 198 | src += nbytes / bsize - 1; | ||
| 199 | dst += nbytes / bsize - 1; | ||
| 200 | |||
| 201 | last_iv = *src; | ||
| 202 | |||
| 203 | /* Process three block batch */ | ||
| 204 | if (nbytes >= bsize * 3) { | ||
| 205 | do { | ||
| 206 | nbytes -= bsize * (3 - 1); | ||
| 207 | src -= 3 - 1; | ||
| 208 | dst -= 3 - 1; | ||
| 209 | |||
| 210 | ivs[0] = src[0]; | ||
| 211 | ivs[1] = src[1]; | ||
| 212 | |||
| 213 | twofish_dec_blk_3way(ctx, (u8 *)dst, (u8 *)src); | ||
| 214 | |||
| 215 | u128_xor(dst + 1, dst + 1, ivs + 0); | ||
| 216 | u128_xor(dst + 2, dst + 2, ivs + 1); | ||
| 217 | |||
| 218 | nbytes -= bsize; | ||
| 219 | if (nbytes < bsize) | ||
| 220 | goto done; | ||
| 221 | |||
| 222 | u128_xor(dst, dst, src - 1); | ||
| 223 | src -= 1; | ||
| 224 | dst -= 1; | ||
| 225 | } while (nbytes >= bsize * 3); | ||
| 226 | |||
| 227 | if (nbytes < bsize) | ||
| 228 | goto done; | ||
| 229 | } | ||
| 230 | |||
| 231 | /* Handle leftovers */ | ||
| 232 | for (;;) { | ||
| 233 | twofish_dec_blk(ctx, (u8 *)dst, (u8 *)src); | ||
| 234 | |||
| 235 | nbytes -= bsize; | ||
| 236 | if (nbytes < bsize) | ||
| 237 | break; | ||
| 238 | |||
| 239 | u128_xor(dst, dst, src - 1); | ||
| 240 | src -= 1; | ||
| 241 | dst -= 1; | ||
| 242 | } | ||
| 243 | |||
| 244 | done: | ||
| 245 | u128_xor(dst, dst, (u128 *)walk->iv); | ||
| 246 | *(u128 *)walk->iv = last_iv; | ||
| 247 | |||
| 248 | return nbytes; | ||
| 249 | } | ||
| 250 | |||
| 251 | static int cbc_decrypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 252 | struct scatterlist *src, unsigned int nbytes) | ||
| 253 | { | ||
| 254 | struct blkcipher_walk walk; | ||
| 255 | int err; | ||
| 256 | |||
| 257 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 258 | err = blkcipher_walk_virt(desc, &walk); | ||
| 259 | |||
| 260 | while ((nbytes = walk.nbytes)) { | ||
| 261 | nbytes = __cbc_decrypt(desc, &walk); | ||
| 262 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 263 | } | ||
| 264 | |||
| 265 | return err; | ||
| 266 | } | ||
| 267 | |||
| 268 | static struct crypto_alg blk_cbc_alg = { | ||
| 269 | .cra_name = "cbc(twofish)", | ||
| 270 | .cra_driver_name = "cbc-twofish-3way", | ||
| 271 | .cra_priority = 300, | ||
| 272 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 273 | .cra_blocksize = TF_BLOCK_SIZE, | ||
| 274 | .cra_ctxsize = sizeof(struct twofish_ctx), | ||
| 275 | .cra_alignmask = 0, | ||
| 276 | .cra_type = &crypto_blkcipher_type, | ||
| 277 | .cra_module = THIS_MODULE, | ||
| 278 | .cra_list = LIST_HEAD_INIT(blk_cbc_alg.cra_list), | ||
| 279 | .cra_u = { | ||
| 280 | .blkcipher = { | ||
| 281 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 282 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 283 | .ivsize = TF_BLOCK_SIZE, | ||
| 284 | .setkey = twofish_setkey, | ||
| 285 | .encrypt = cbc_encrypt, | ||
| 286 | .decrypt = cbc_decrypt, | ||
| 287 | }, | ||
| 288 | }, | ||
| 289 | }; | ||
| 290 | |||
| 291 | static inline void u128_to_be128(be128 *dst, const u128 *src) | ||
| 292 | { | ||
| 293 | dst->a = cpu_to_be64(src->a); | ||
| 294 | dst->b = cpu_to_be64(src->b); | ||
| 295 | } | ||
| 296 | |||
| 297 | static inline void be128_to_u128(u128 *dst, const be128 *src) | ||
| 298 | { | ||
| 299 | dst->a = be64_to_cpu(src->a); | ||
| 300 | dst->b = be64_to_cpu(src->b); | ||
| 301 | } | ||
| 302 | |||
| 303 | static inline void u128_inc(u128 *i) | ||
| 304 | { | ||
| 305 | i->b++; | ||
| 306 | if (!i->b) | ||
| 307 | i->a++; | ||
| 308 | } | ||
| 309 | |||
| 310 | static void ctr_crypt_final(struct blkcipher_desc *desc, | ||
| 311 | struct blkcipher_walk *walk) | ||
| 312 | { | ||
| 313 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 314 | u8 *ctrblk = walk->iv; | ||
| 315 | u8 keystream[TF_BLOCK_SIZE]; | ||
| 316 | u8 *src = walk->src.virt.addr; | ||
| 317 | u8 *dst = walk->dst.virt.addr; | ||
| 318 | unsigned int nbytes = walk->nbytes; | ||
| 319 | |||
| 320 | twofish_enc_blk(ctx, keystream, ctrblk); | ||
| 321 | crypto_xor(keystream, src, nbytes); | ||
| 322 | memcpy(dst, keystream, nbytes); | ||
| 323 | |||
| 324 | crypto_inc(ctrblk, TF_BLOCK_SIZE); | ||
| 325 | } | ||
| 326 | |||
| 327 | static unsigned int __ctr_crypt(struct blkcipher_desc *desc, | ||
| 328 | struct blkcipher_walk *walk) | ||
| 329 | { | ||
| 330 | struct twofish_ctx *ctx = crypto_blkcipher_ctx(desc->tfm); | ||
| 331 | unsigned int bsize = TF_BLOCK_SIZE; | ||
| 332 | unsigned int nbytes = walk->nbytes; | ||
| 333 | u128 *src = (u128 *)walk->src.virt.addr; | ||
| 334 | u128 *dst = (u128 *)walk->dst.virt.addr; | ||
| 335 | u128 ctrblk; | ||
| 336 | be128 ctrblocks[3]; | ||
| 337 | |||
| 338 | be128_to_u128(&ctrblk, (be128 *)walk->iv); | ||
| 339 | |||
| 340 | /* Process three block batch */ | ||
| 341 | if (nbytes >= bsize * 3) { | ||
| 342 | do { | ||
| 343 | if (dst != src) { | ||
| 344 | dst[0] = src[0]; | ||
| 345 | dst[1] = src[1]; | ||
| 346 | dst[2] = src[2]; | ||
| 347 | } | ||
| 348 | |||
| 349 | /* create ctrblks for parallel encrypt */ | ||
| 350 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 351 | u128_inc(&ctrblk); | ||
| 352 | u128_to_be128(&ctrblocks[1], &ctrblk); | ||
| 353 | u128_inc(&ctrblk); | ||
| 354 | u128_to_be128(&ctrblocks[2], &ctrblk); | ||
| 355 | u128_inc(&ctrblk); | ||
| 356 | |||
| 357 | twofish_enc_blk_xor_3way(ctx, (u8 *)dst, | ||
| 358 | (u8 *)ctrblocks); | ||
| 359 | |||
| 360 | src += 3; | ||
| 361 | dst += 3; | ||
| 362 | nbytes -= bsize * 3; | ||
| 363 | } while (nbytes >= bsize * 3); | ||
| 364 | |||
| 365 | if (nbytes < bsize) | ||
| 366 | goto done; | ||
| 367 | } | ||
| 368 | |||
| 369 | /* Handle leftovers */ | ||
| 370 | do { | ||
| 371 | if (dst != src) | ||
| 372 | *dst = *src; | ||
| 373 | |||
| 374 | u128_to_be128(&ctrblocks[0], &ctrblk); | ||
| 375 | u128_inc(&ctrblk); | ||
| 376 | |||
| 377 | twofish_enc_blk(ctx, (u8 *)ctrblocks, (u8 *)ctrblocks); | ||
| 378 | u128_xor(dst, dst, (u128 *)ctrblocks); | ||
| 379 | |||
| 380 | src += 1; | ||
| 381 | dst += 1; | ||
| 382 | nbytes -= bsize; | ||
| 383 | } while (nbytes >= bsize); | ||
| 384 | |||
| 385 | done: | ||
| 386 | u128_to_be128((be128 *)walk->iv, &ctrblk); | ||
| 387 | return nbytes; | ||
| 388 | } | ||
| 389 | |||
| 390 | static int ctr_crypt(struct blkcipher_desc *desc, struct scatterlist *dst, | ||
| 391 | struct scatterlist *src, unsigned int nbytes) | ||
| 392 | { | ||
| 393 | struct blkcipher_walk walk; | ||
| 394 | int err; | ||
| 395 | |||
| 396 | blkcipher_walk_init(&walk, dst, src, nbytes); | ||
| 397 | err = blkcipher_walk_virt_block(desc, &walk, TF_BLOCK_SIZE); | ||
| 398 | |||
| 399 | while ((nbytes = walk.nbytes) >= TF_BLOCK_SIZE) { | ||
| 400 | nbytes = __ctr_crypt(desc, &walk); | ||
| 401 | err = blkcipher_walk_done(desc, &walk, nbytes); | ||
| 402 | } | ||
| 403 | |||
| 404 | if (walk.nbytes) { | ||
| 405 | ctr_crypt_final(desc, &walk); | ||
| 406 | err = blkcipher_walk_done(desc, &walk, 0); | ||
| 407 | } | ||
| 408 | |||
| 409 | return err; | ||
| 410 | } | ||
| 411 | |||
| 412 | static struct crypto_alg blk_ctr_alg = { | ||
| 413 | .cra_name = "ctr(twofish)", | ||
| 414 | .cra_driver_name = "ctr-twofish-3way", | ||
| 415 | .cra_priority = 300, | ||
| 416 | .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, | ||
| 417 | .cra_blocksize = 1, | ||
| 418 | .cra_ctxsize = sizeof(struct twofish_ctx), | ||
| 419 | .cra_alignmask = 0, | ||
| 420 | .cra_type = &crypto_blkcipher_type, | ||
| 421 | .cra_module = THIS_MODULE, | ||
| 422 | .cra_list = LIST_HEAD_INIT(blk_ctr_alg.cra_list), | ||
| 423 | .cra_u = { | ||
| 424 | .blkcipher = { | ||
| 425 | .min_keysize = TF_MIN_KEY_SIZE, | ||
| 426 | .max_keysize = TF_MAX_KEY_SIZE, | ||
| 427 | .ivsize = TF_BLOCK_SIZE, | ||
| 428 | .setkey = twofish_setkey, | ||
| 429 | .encrypt = ctr_crypt, | ||
| 430 | .decrypt = ctr_crypt, | ||
| 431 | }, | ||
| 432 | }, | ||
| 433 | }; | ||
| 434 | |||
| 435 | int __init init(void) | ||
| 436 | { | ||
| 437 | int err; | ||
| 438 | |||
| 439 | err = crypto_register_alg(&blk_ecb_alg); | ||
| 440 | if (err) | ||
| 441 | goto ecb_err; | ||
| 442 | err = crypto_register_alg(&blk_cbc_alg); | ||
| 443 | if (err) | ||
| 444 | goto cbc_err; | ||
| 445 | err = crypto_register_alg(&blk_ctr_alg); | ||
| 446 | if (err) | ||
| 447 | goto ctr_err; | ||
| 448 | |||
| 449 | return 0; | ||
| 450 | |||
| 451 | ctr_err: | ||
| 452 | crypto_unregister_alg(&blk_cbc_alg); | ||
| 453 | cbc_err: | ||
| 454 | crypto_unregister_alg(&blk_ecb_alg); | ||
| 455 | ecb_err: | ||
| 456 | return err; | ||
| 457 | } | ||
| 458 | |||
| 459 | void __exit fini(void) | ||
| 460 | { | ||
| 461 | crypto_unregister_alg(&blk_ctr_alg); | ||
| 462 | crypto_unregister_alg(&blk_cbc_alg); | ||
| 463 | crypto_unregister_alg(&blk_ecb_alg); | ||
| 464 | } | ||
| 465 | |||
| 466 | module_init(init); | ||
| 467 | module_exit(fini); | ||
| 468 | |||
| 469 | MODULE_LICENSE("GPL"); | ||
| 470 | MODULE_DESCRIPTION("Twofish Cipher Algorithm, 3-way parallel asm optimized"); | ||
| 471 | MODULE_ALIAS("twofish"); | ||
| 472 | MODULE_ALIAS("twofish-asm"); | ||
diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h index 2f84a433b6a0..f3444f700f36 100644 --- a/arch/x86/include/asm/cpufeature.h +++ b/arch/x86/include/asm/cpufeature.h | |||
| @@ -259,7 +259,9 @@ extern const char * const x86_power_flags[32]; | |||
| 259 | #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) | 259 | #define cpu_has_xmm boot_cpu_has(X86_FEATURE_XMM) |
| 260 | #define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) | 260 | #define cpu_has_xmm2 boot_cpu_has(X86_FEATURE_XMM2) |
| 261 | #define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) | 261 | #define cpu_has_xmm3 boot_cpu_has(X86_FEATURE_XMM3) |
| 262 | #define cpu_has_ssse3 boot_cpu_has(X86_FEATURE_SSSE3) | ||
| 262 | #define cpu_has_aes boot_cpu_has(X86_FEATURE_AES) | 263 | #define cpu_has_aes boot_cpu_has(X86_FEATURE_AES) |
| 264 | #define cpu_has_avx boot_cpu_has(X86_FEATURE_AVX) | ||
| 263 | #define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) | 265 | #define cpu_has_ht boot_cpu_has(X86_FEATURE_HT) |
| 264 | #define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) | 266 | #define cpu_has_mp boot_cpu_has(X86_FEATURE_MP) |
| 265 | #define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) | 267 | #define cpu_has_nx boot_cpu_has(X86_FEATURE_NX) |
| @@ -287,6 +289,7 @@ extern const char * const x86_power_flags[32]; | |||
| 287 | #define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) | 289 | #define cpu_has_xmm4_2 boot_cpu_has(X86_FEATURE_XMM4_2) |
| 288 | #define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) | 290 | #define cpu_has_x2apic boot_cpu_has(X86_FEATURE_X2APIC) |
| 289 | #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) | 291 | #define cpu_has_xsave boot_cpu_has(X86_FEATURE_XSAVE) |
| 292 | #define cpu_has_osxsave boot_cpu_has(X86_FEATURE_OSXSAVE) | ||
| 290 | #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) | 293 | #define cpu_has_hypervisor boot_cpu_has(X86_FEATURE_HYPERVISOR) |
| 291 | #define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) | 294 | #define cpu_has_pclmulqdq boot_cpu_has(X86_FEATURE_PCLMULQDQ) |
| 292 | #define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) | 295 | #define cpu_has_perfctr_core boot_cpu_has(X86_FEATURE_PERFCTR_CORE) |
diff --git a/crypto/Kconfig b/crypto/Kconfig index ae27b7534ea7..527a857d10b6 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig | |||
| @@ -100,6 +100,14 @@ config CRYPTO_MANAGER2 | |||
| 100 | select CRYPTO_BLKCIPHER2 | 100 | select CRYPTO_BLKCIPHER2 |
| 101 | select CRYPTO_PCOMP2 | 101 | select CRYPTO_PCOMP2 |
| 102 | 102 | ||
| 103 | config CRYPTO_USER | ||
| 104 | tristate "Userspace cryptographic algorithm configuration" | ||
| 105 | depends on NET | ||
| 106 | select CRYPTO_MANAGER | ||
| 107 | help | ||
| 108 | Userapace configuration for cryptographic instantiations such as | ||
| 109 | cbc(aes). | ||
| 110 | |||
| 103 | config CRYPTO_MANAGER_DISABLE_TESTS | 111 | config CRYPTO_MANAGER_DISABLE_TESTS |
| 104 | bool "Disable run-time self tests" | 112 | bool "Disable run-time self tests" |
| 105 | default y | 113 | default y |
| @@ -407,6 +415,16 @@ config CRYPTO_SHA1 | |||
| 407 | help | 415 | help |
| 408 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). | 416 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2). |
| 409 | 417 | ||
| 418 | config CRYPTO_SHA1_SSSE3 | ||
| 419 | tristate "SHA1 digest algorithm (SSSE3/AVX)" | ||
| 420 | depends on X86 && 64BIT | ||
| 421 | select CRYPTO_SHA1 | ||
| 422 | select CRYPTO_HASH | ||
| 423 | help | ||
| 424 | SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2) implemented | ||
| 425 | using Supplemental SSE3 (SSSE3) instructions or Advanced Vector | ||
| 426 | Extensions (AVX), when available. | ||
| 427 | |||
| 410 | config CRYPTO_SHA256 | 428 | config CRYPTO_SHA256 |
| 411 | tristate "SHA224 and SHA256 digest algorithm" | 429 | tristate "SHA224 and SHA256 digest algorithm" |
| 412 | select CRYPTO_HASH | 430 | select CRYPTO_HASH |
| @@ -590,6 +608,7 @@ config CRYPTO_ARC4 | |||
| 590 | config CRYPTO_BLOWFISH | 608 | config CRYPTO_BLOWFISH |
| 591 | tristate "Blowfish cipher algorithm" | 609 | tristate "Blowfish cipher algorithm" |
| 592 | select CRYPTO_ALGAPI | 610 | select CRYPTO_ALGAPI |
| 611 | select CRYPTO_BLOWFISH_COMMON | ||
| 593 | help | 612 | help |
| 594 | Blowfish cipher algorithm, by Bruce Schneier. | 613 | Blowfish cipher algorithm, by Bruce Schneier. |
| 595 | 614 | ||
| @@ -600,6 +619,30 @@ config CRYPTO_BLOWFISH | |||
| 600 | See also: | 619 | See also: |
| 601 | <http://www.schneier.com/blowfish.html> | 620 | <http://www.schneier.com/blowfish.html> |
| 602 | 621 | ||
| 622 | config CRYPTO_BLOWFISH_COMMON | ||
| 623 | tristate | ||
| 624 | help | ||
| 625 | Common parts of the Blowfish cipher algorithm shared by the | ||
| 626 | generic c and the assembler implementations. | ||
| 627 | |||
| 628 | See also: | ||
| 629 | <http://www.schneier.com/blowfish.html> | ||
| 630 | |||
| 631 | config CRYPTO_BLOWFISH_X86_64 | ||
| 632 | tristate "Blowfish cipher algorithm (x86_64)" | ||
| 633 | depends on (X86 || UML_X86) && 64BIT | ||
| 634 | select CRYPTO_ALGAPI | ||
| 635 | select CRYPTO_BLOWFISH_COMMON | ||
| 636 | help | ||
| 637 | Blowfish cipher algorithm (x86_64), by Bruce Schneier. | ||
| 638 | |||
| 639 | This is a variable key length cipher which can use keys from 32 | ||
| 640 | bits to 448 bits in length. It's fast, simple and specifically | ||
| 641 | designed for use on "large microprocessors". | ||
| 642 | |||
| 643 | See also: | ||
| 644 | <http://www.schneier.com/blowfish.html> | ||
| 645 | |||
| 603 | config CRYPTO_CAMELLIA | 646 | config CRYPTO_CAMELLIA |
| 604 | tristate "Camellia cipher algorithms" | 647 | tristate "Camellia cipher algorithms" |
| 605 | depends on CRYPTO | 648 | depends on CRYPTO |
| @@ -793,6 +836,26 @@ config CRYPTO_TWOFISH_X86_64 | |||
| 793 | See also: | 836 | See also: |
| 794 | <http://www.schneier.com/twofish.html> | 837 | <http://www.schneier.com/twofish.html> |
| 795 | 838 | ||
| 839 | config CRYPTO_TWOFISH_X86_64_3WAY | ||
| 840 | tristate "Twofish cipher algorithm (x86_64, 3-way parallel)" | ||
| 841 | depends on (X86 || UML_X86) && 64BIT | ||
| 842 | select CRYPTO_ALGAPI | ||
| 843 | select CRYPTO_TWOFISH_COMMON | ||
| 844 | select CRYPTO_TWOFISH_X86_64 | ||
| 845 | help | ||
| 846 | Twofish cipher algorithm (x86_64, 3-way parallel). | ||
| 847 | |||
| 848 | Twofish was submitted as an AES (Advanced Encryption Standard) | ||
| 849 | candidate cipher by researchers at CounterPane Systems. It is a | ||
| 850 | 16 round block cipher supporting key sizes of 128, 192, and 256 | ||
| 851 | bits. | ||
| 852 | |||
| 853 | This module provides Twofish cipher algorithm that processes three | ||
| 854 | blocks parallel, utilizing resources of out-of-order CPUs better. | ||
| 855 | |||
| 856 | See also: | ||
| 857 | <http://www.schneier.com/twofish.html> | ||
| 858 | |||
| 796 | comment "Compression" | 859 | comment "Compression" |
| 797 | 860 | ||
| 798 | config CRYPTO_DEFLATE | 861 | config CRYPTO_DEFLATE |
diff --git a/crypto/Makefile b/crypto/Makefile index ce5a813d3639..9e6eee2c05db 100644 --- a/crypto/Makefile +++ b/crypto/Makefile | |||
| @@ -31,6 +31,7 @@ obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o | |||
| 31 | cryptomgr-y := algboss.o testmgr.o | 31 | cryptomgr-y := algboss.o testmgr.o |
| 32 | 32 | ||
| 33 | obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o | 33 | obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o |
| 34 | obj-$(CONFIG_CRYPTO_USER) += crypto_user.o | ||
| 34 | obj-$(CONFIG_CRYPTO_HMAC) += hmac.o | 35 | obj-$(CONFIG_CRYPTO_HMAC) += hmac.o |
| 35 | obj-$(CONFIG_CRYPTO_VMAC) += vmac.o | 36 | obj-$(CONFIG_CRYPTO_VMAC) += vmac.o |
| 36 | obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o | 37 | obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o |
| @@ -60,7 +61,8 @@ obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o | |||
| 60 | obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o | 61 | obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o |
| 61 | obj-$(CONFIG_CRYPTO_DES) += des_generic.o | 62 | obj-$(CONFIG_CRYPTO_DES) += des_generic.o |
| 62 | obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o | 63 | obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o |
| 63 | obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o | 64 | obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish_generic.o |
| 65 | obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o | ||
| 64 | obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o | 66 | obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o |
| 65 | obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o | 67 | obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o |
| 66 | obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o | 68 | obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o |
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c index fdc67d38660b..a816f24f2d52 100644 --- a/crypto/ablkcipher.c +++ b/crypto/ablkcipher.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
| 24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
| 26 | #include <linux/cryptouser.h> | ||
| 27 | #include <net/netlink.h> | ||
| 26 | 28 | ||
| 27 | #include <crypto/scatterwalk.h> | 29 | #include <crypto/scatterwalk.h> |
| 28 | 30 | ||
| @@ -381,6 +383,28 @@ static int crypto_init_ablkcipher_ops(struct crypto_tfm *tfm, u32 type, | |||
| 381 | return 0; | 383 | return 0; |
| 382 | } | 384 | } |
| 383 | 385 | ||
| 386 | static int crypto_ablkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 387 | { | ||
| 388 | struct crypto_report_blkcipher rblkcipher; | ||
| 389 | |||
| 390 | snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "ablkcipher"); | ||
| 391 | snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s", | ||
| 392 | alg->cra_ablkcipher.geniv ?: "<default>"); | ||
| 393 | |||
| 394 | rblkcipher.blocksize = alg->cra_blocksize; | ||
| 395 | rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize; | ||
| 396 | rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize; | ||
| 397 | rblkcipher.ivsize = alg->cra_ablkcipher.ivsize; | ||
| 398 | |||
| 399 | NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER, | ||
| 400 | sizeof(struct crypto_report_blkcipher), &rblkcipher); | ||
| 401 | |||
| 402 | return 0; | ||
| 403 | |||
| 404 | nla_put_failure: | ||
| 405 | return -EMSGSIZE; | ||
| 406 | } | ||
| 407 | |||
| 384 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 408 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| 385 | __attribute__ ((unused)); | 409 | __attribute__ ((unused)); |
| 386 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 410 | static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -403,6 +427,7 @@ const struct crypto_type crypto_ablkcipher_type = { | |||
| 403 | #ifdef CONFIG_PROC_FS | 427 | #ifdef CONFIG_PROC_FS |
| 404 | .show = crypto_ablkcipher_show, | 428 | .show = crypto_ablkcipher_show, |
| 405 | #endif | 429 | #endif |
| 430 | .report = crypto_ablkcipher_report, | ||
| 406 | }; | 431 | }; |
| 407 | EXPORT_SYMBOL_GPL(crypto_ablkcipher_type); | 432 | EXPORT_SYMBOL_GPL(crypto_ablkcipher_type); |
| 408 | 433 | ||
| @@ -432,6 +457,28 @@ static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type, | |||
| 432 | return 0; | 457 | return 0; |
| 433 | } | 458 | } |
| 434 | 459 | ||
| 460 | static int crypto_givcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 461 | { | ||
| 462 | struct crypto_report_blkcipher rblkcipher; | ||
| 463 | |||
| 464 | snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "givcipher"); | ||
| 465 | snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s", | ||
| 466 | alg->cra_ablkcipher.geniv ?: "<built-in>"); | ||
| 467 | |||
| 468 | rblkcipher.blocksize = alg->cra_blocksize; | ||
| 469 | rblkcipher.min_keysize = alg->cra_ablkcipher.min_keysize; | ||
| 470 | rblkcipher.max_keysize = alg->cra_ablkcipher.max_keysize; | ||
| 471 | rblkcipher.ivsize = alg->cra_ablkcipher.ivsize; | ||
| 472 | |||
| 473 | NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER, | ||
| 474 | sizeof(struct crypto_report_blkcipher), &rblkcipher); | ||
| 475 | |||
| 476 | return 0; | ||
| 477 | |||
| 478 | nla_put_failure: | ||
| 479 | return -EMSGSIZE; | ||
| 480 | } | ||
| 481 | |||
| 435 | static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) | 482 | static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| 436 | __attribute__ ((unused)); | 483 | __attribute__ ((unused)); |
| 437 | static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) | 484 | static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -454,6 +501,7 @@ const struct crypto_type crypto_givcipher_type = { | |||
| 454 | #ifdef CONFIG_PROC_FS | 501 | #ifdef CONFIG_PROC_FS |
| 455 | .show = crypto_givcipher_show, | 502 | .show = crypto_givcipher_show, |
| 456 | #endif | 503 | #endif |
| 504 | .report = crypto_givcipher_report, | ||
| 457 | }; | 505 | }; |
| 458 | EXPORT_SYMBOL_GPL(crypto_givcipher_type); | 506 | EXPORT_SYMBOL_GPL(crypto_givcipher_type); |
| 459 | 507 | ||
diff --git a/crypto/aead.c b/crypto/aead.c index 6729e8ff68e7..701556ffaaef 100644 --- a/crypto/aead.c +++ b/crypto/aead.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
| 24 | #include <linux/cryptouser.h> | ||
| 25 | #include <net/netlink.h> | ||
| 24 | 26 | ||
| 25 | #include "internal.h" | 27 | #include "internal.h" |
| 26 | 28 | ||
| @@ -109,6 +111,28 @@ static int crypto_init_aead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 109 | return 0; | 111 | return 0; |
| 110 | } | 112 | } |
| 111 | 113 | ||
| 114 | static int crypto_aead_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 115 | { | ||
| 116 | struct crypto_report_aead raead; | ||
| 117 | struct aead_alg *aead = &alg->cra_aead; | ||
| 118 | |||
| 119 | snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "aead"); | ||
| 120 | snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", | ||
| 121 | aead->geniv ?: "<built-in>"); | ||
| 122 | |||
| 123 | raead.blocksize = alg->cra_blocksize; | ||
| 124 | raead.maxauthsize = aead->maxauthsize; | ||
| 125 | raead.ivsize = aead->ivsize; | ||
| 126 | |||
| 127 | NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD, | ||
| 128 | sizeof(struct crypto_report_aead), &raead); | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | |||
| 132 | nla_put_failure: | ||
| 133 | return -EMSGSIZE; | ||
| 134 | } | ||
| 135 | |||
| 112 | static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) | 136 | static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) |
| 113 | __attribute__ ((unused)); | 137 | __attribute__ ((unused)); |
| 114 | static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) | 138 | static void crypto_aead_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -130,6 +154,7 @@ const struct crypto_type crypto_aead_type = { | |||
| 130 | #ifdef CONFIG_PROC_FS | 154 | #ifdef CONFIG_PROC_FS |
| 131 | .show = crypto_aead_show, | 155 | .show = crypto_aead_show, |
| 132 | #endif | 156 | #endif |
| 157 | .report = crypto_aead_report, | ||
| 133 | }; | 158 | }; |
| 134 | EXPORT_SYMBOL_GPL(crypto_aead_type); | 159 | EXPORT_SYMBOL_GPL(crypto_aead_type); |
| 135 | 160 | ||
| @@ -165,6 +190,28 @@ static int crypto_init_nivaead_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 165 | return 0; | 190 | return 0; |
| 166 | } | 191 | } |
| 167 | 192 | ||
| 193 | static int crypto_nivaead_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 194 | { | ||
| 195 | struct crypto_report_aead raead; | ||
| 196 | struct aead_alg *aead = &alg->cra_aead; | ||
| 197 | |||
| 198 | snprintf(raead.type, CRYPTO_MAX_ALG_NAME, "%s", "nivaead"); | ||
| 199 | snprintf(raead.geniv, CRYPTO_MAX_ALG_NAME, "%s", aead->geniv); | ||
| 200 | |||
| 201 | raead.blocksize = alg->cra_blocksize; | ||
| 202 | raead.maxauthsize = aead->maxauthsize; | ||
| 203 | raead.ivsize = aead->ivsize; | ||
| 204 | |||
| 205 | NLA_PUT(skb, CRYPTOCFGA_REPORT_AEAD, | ||
| 206 | sizeof(struct crypto_report_aead), &raead); | ||
| 207 | |||
| 208 | return 0; | ||
| 209 | |||
| 210 | nla_put_failure: | ||
| 211 | return -EMSGSIZE; | ||
| 212 | } | ||
| 213 | |||
| 214 | |||
| 168 | static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) | 215 | static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) |
| 169 | __attribute__ ((unused)); | 216 | __attribute__ ((unused)); |
| 170 | static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) | 217 | static void crypto_nivaead_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -186,6 +233,7 @@ const struct crypto_type crypto_nivaead_type = { | |||
| 186 | #ifdef CONFIG_PROC_FS | 233 | #ifdef CONFIG_PROC_FS |
| 187 | .show = crypto_nivaead_show, | 234 | .show = crypto_nivaead_show, |
| 188 | #endif | 235 | #endif |
| 236 | .report = crypto_nivaead_report, | ||
| 189 | }; | 237 | }; |
| 190 | EXPORT_SYMBOL_GPL(crypto_nivaead_type); | 238 | EXPORT_SYMBOL_GPL(crypto_nivaead_type); |
| 191 | 239 | ||
diff --git a/crypto/ahash.c b/crypto/ahash.c index f669822a7a44..a3e6ef99394a 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
| 24 | #include <linux/cryptouser.h> | ||
| 25 | #include <net/netlink.h> | ||
| 24 | 26 | ||
| 25 | #include "internal.h" | 27 | #include "internal.h" |
| 26 | 28 | ||
| @@ -397,6 +399,24 @@ static unsigned int crypto_ahash_extsize(struct crypto_alg *alg) | |||
| 397 | return sizeof(struct crypto_shash *); | 399 | return sizeof(struct crypto_shash *); |
| 398 | } | 400 | } |
| 399 | 401 | ||
| 402 | static int crypto_ahash_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 403 | { | ||
| 404 | struct crypto_report_hash rhash; | ||
| 405 | |||
| 406 | snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "ahash"); | ||
| 407 | |||
| 408 | rhash.blocksize = alg->cra_blocksize; | ||
| 409 | rhash.digestsize = __crypto_hash_alg_common(alg)->digestsize; | ||
| 410 | |||
| 411 | NLA_PUT(skb, CRYPTOCFGA_REPORT_HASH, | ||
| 412 | sizeof(struct crypto_report_hash), &rhash); | ||
| 413 | |||
| 414 | return 0; | ||
| 415 | |||
| 416 | nla_put_failure: | ||
| 417 | return -EMSGSIZE; | ||
| 418 | } | ||
| 419 | |||
| 400 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) | 420 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) |
| 401 | __attribute__ ((unused)); | 421 | __attribute__ ((unused)); |
| 402 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) | 422 | static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -415,6 +435,7 @@ const struct crypto_type crypto_ahash_type = { | |||
| 415 | #ifdef CONFIG_PROC_FS | 435 | #ifdef CONFIG_PROC_FS |
| 416 | .show = crypto_ahash_show, | 436 | .show = crypto_ahash_show, |
| 417 | #endif | 437 | #endif |
| 438 | .report = crypto_ahash_report, | ||
| 418 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, | 439 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, |
| 419 | .maskset = CRYPTO_ALG_TYPE_AHASH_MASK, | 440 | .maskset = CRYPTO_ALG_TYPE_AHASH_MASK, |
| 420 | .type = CRYPTO_ALG_TYPE_AHASH, | 441 | .type = CRYPTO_ALG_TYPE_AHASH, |
diff --git a/crypto/algapi.c b/crypto/algapi.c index c3cf1a69a47a..54dd4e33b5d6 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c | |||
| @@ -22,8 +22,6 @@ | |||
| 22 | 22 | ||
| 23 | #include "internal.h" | 23 | #include "internal.h" |
| 24 | 24 | ||
| 25 | static void crypto_remove_final(struct list_head *list); | ||
| 26 | |||
| 27 | static LIST_HEAD(crypto_template_list); | 25 | static LIST_HEAD(crypto_template_list); |
| 28 | 26 | ||
| 29 | void crypto_larval_error(const char *name, u32 type, u32 mask) | 27 | void crypto_larval_error(const char *name, u32 type, u32 mask) |
| @@ -129,9 +127,8 @@ static void crypto_remove_spawn(struct crypto_spawn *spawn, | |||
| 129 | BUG_ON(!list_empty(&inst->alg.cra_users)); | 127 | BUG_ON(!list_empty(&inst->alg.cra_users)); |
| 130 | } | 128 | } |
| 131 | 129 | ||
| 132 | static void crypto_remove_spawns(struct crypto_alg *alg, | 130 | void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, |
| 133 | struct list_head *list, | 131 | struct crypto_alg *nalg) |
| 134 | struct crypto_alg *nalg) | ||
| 135 | { | 132 | { |
| 136 | u32 new_type = (nalg ?: alg)->cra_flags; | 133 | u32 new_type = (nalg ?: alg)->cra_flags; |
| 137 | struct crypto_spawn *spawn, *n; | 134 | struct crypto_spawn *spawn, *n; |
| @@ -177,6 +174,7 @@ static void crypto_remove_spawns(struct crypto_alg *alg, | |||
| 177 | crypto_remove_spawn(spawn, list); | 174 | crypto_remove_spawn(spawn, list); |
| 178 | } | 175 | } |
| 179 | } | 176 | } |
| 177 | EXPORT_SYMBOL_GPL(crypto_remove_spawns); | ||
| 180 | 178 | ||
| 181 | static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) | 179 | static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) |
| 182 | { | 180 | { |
| @@ -321,7 +319,7 @@ unlock: | |||
| 321 | } | 319 | } |
| 322 | EXPORT_SYMBOL_GPL(crypto_alg_tested); | 320 | EXPORT_SYMBOL_GPL(crypto_alg_tested); |
| 323 | 321 | ||
| 324 | static void crypto_remove_final(struct list_head *list) | 322 | void crypto_remove_final(struct list_head *list) |
| 325 | { | 323 | { |
| 326 | struct crypto_alg *alg; | 324 | struct crypto_alg *alg; |
| 327 | struct crypto_alg *n; | 325 | struct crypto_alg *n; |
| @@ -331,6 +329,7 @@ static void crypto_remove_final(struct list_head *list) | |||
| 331 | crypto_alg_put(alg); | 329 | crypto_alg_put(alg); |
| 332 | } | 330 | } |
| 333 | } | 331 | } |
| 332 | EXPORT_SYMBOL_GPL(crypto_remove_final); | ||
| 334 | 333 | ||
| 335 | static void crypto_wait_for_test(struct crypto_larval *larval) | 334 | static void crypto_wait_for_test(struct crypto_larval *larval) |
| 336 | { | 335 | { |
| @@ -493,6 +492,7 @@ int crypto_register_instance(struct crypto_template *tmpl, | |||
| 493 | goto err; | 492 | goto err; |
| 494 | 493 | ||
| 495 | inst->alg.cra_module = tmpl->module; | 494 | inst->alg.cra_module = tmpl->module; |
| 495 | inst->alg.cra_flags |= CRYPTO_ALG_INSTANCE; | ||
| 496 | 496 | ||
| 497 | down_write(&crypto_alg_sem); | 497 | down_write(&crypto_alg_sem); |
| 498 | 498 | ||
diff --git a/crypto/blkcipher.c b/crypto/blkcipher.c index 7a7219266e3c..2572d2600136 100644 --- a/crypto/blkcipher.c +++ b/crypto/blkcipher.c | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
| 27 | #include <linux/cryptouser.h> | ||
| 28 | #include <net/netlink.h> | ||
| 27 | 29 | ||
| 28 | #include "internal.h" | 30 | #include "internal.h" |
| 29 | 31 | ||
| @@ -492,6 +494,28 @@ static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 492 | return crypto_init_blkcipher_ops_async(tfm); | 494 | return crypto_init_blkcipher_ops_async(tfm); |
| 493 | } | 495 | } |
| 494 | 496 | ||
| 497 | static int crypto_blkcipher_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 498 | { | ||
| 499 | struct crypto_report_blkcipher rblkcipher; | ||
| 500 | |||
| 501 | snprintf(rblkcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "blkcipher"); | ||
| 502 | snprintf(rblkcipher.geniv, CRYPTO_MAX_ALG_NAME, "%s", | ||
| 503 | alg->cra_blkcipher.geniv ?: "<default>"); | ||
| 504 | |||
| 505 | rblkcipher.blocksize = alg->cra_blocksize; | ||
| 506 | rblkcipher.min_keysize = alg->cra_blkcipher.min_keysize; | ||
| 507 | rblkcipher.max_keysize = alg->cra_blkcipher.max_keysize; | ||
| 508 | rblkcipher.ivsize = alg->cra_blkcipher.ivsize; | ||
| 509 | |||
| 510 | NLA_PUT(skb, CRYPTOCFGA_REPORT_BLKCIPHER, | ||
| 511 | sizeof(struct crypto_report_blkcipher), &rblkcipher); | ||
| 512 | |||
| 513 | return 0; | ||
| 514 | |||
| 515 | nla_put_failure: | ||
| 516 | return -EMSGSIZE; | ||
| 517 | } | ||
| 518 | |||
| 495 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 519 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| 496 | __attribute__ ((unused)); | 520 | __attribute__ ((unused)); |
| 497 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) | 521 | static void crypto_blkcipher_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -511,6 +535,7 @@ const struct crypto_type crypto_blkcipher_type = { | |||
| 511 | #ifdef CONFIG_PROC_FS | 535 | #ifdef CONFIG_PROC_FS |
| 512 | .show = crypto_blkcipher_show, | 536 | .show = crypto_blkcipher_show, |
| 513 | #endif | 537 | #endif |
| 538 | .report = crypto_blkcipher_report, | ||
| 514 | }; | 539 | }; |
| 515 | EXPORT_SYMBOL_GPL(crypto_blkcipher_type); | 540 | EXPORT_SYMBOL_GPL(crypto_blkcipher_type); |
| 516 | 541 | ||
diff --git a/crypto/blowfish.c b/crypto/blowfish_common.c index a67d52ee0580..f636aab0209f 100644 --- a/crypto/blowfish.c +++ b/crypto/blowfish_common.c | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Cryptographic API. | 2 | * Cryptographic API. |
| 3 | * | 3 | * |
| 4 | * Common Blowfish algorithm parts shared between the c and assembler | ||
| 5 | * implementations. | ||
| 6 | * | ||
| 4 | * Blowfish Cipher Algorithm, by Bruce Schneier. | 7 | * Blowfish Cipher Algorithm, by Bruce Schneier. |
| 5 | * http://www.counterpane.com/blowfish.html | 8 | * http://www.counterpane.com/blowfish.html |
| 6 | * | 9 | * |
| @@ -22,15 +25,7 @@ | |||
| 22 | #include <asm/byteorder.h> | 25 | #include <asm/byteorder.h> |
| 23 | #include <linux/crypto.h> | 26 | #include <linux/crypto.h> |
| 24 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 25 | 28 | #include <crypto/blowfish.h> | |
| 26 | #define BF_BLOCK_SIZE 8 | ||
| 27 | #define BF_MIN_KEY_SIZE 4 | ||
| 28 | #define BF_MAX_KEY_SIZE 56 | ||
| 29 | |||
| 30 | struct bf_ctx { | ||
| 31 | u32 p[18]; | ||
| 32 | u32 s[1024]; | ||
| 33 | }; | ||
| 34 | 29 | ||
| 35 | static const u32 bf_pbox[16 + 2] = { | 30 | static const u32 bf_pbox[16 + 2] = { |
| 36 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, | 31 | 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, |
| @@ -309,9 +304,9 @@ static const u32 bf_sbox[256 * 4] = { | |||
| 309 | #define GET32_0(x) (((x) >> (24)) & (0xff)) | 304 | #define GET32_0(x) (((x) >> (24)) & (0xff)) |
| 310 | 305 | ||
| 311 | #define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \ | 306 | #define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \ |
| 312 | S[512 + GET32_2(x)]) + S[768 + GET32_3(x)]) | 307 | S[512 + GET32_2(x)]) + S[768 + GET32_3(x)]) |
| 313 | 308 | ||
| 314 | #define ROUND(a, b, n) b ^= P[n]; a ^= bf_F (b) | 309 | #define ROUND(a, b, n) ({ b ^= P[n]; a ^= bf_F(b); }) |
| 315 | 310 | ||
| 316 | /* | 311 | /* |
| 317 | * The blowfish encipher, processes 64-bit blocks. | 312 | * The blowfish encipher, processes 64-bit blocks. |
| @@ -348,57 +343,10 @@ static void encrypt_block(struct bf_ctx *bctx, u32 *dst, u32 *src) | |||
| 348 | dst[1] = yl; | 343 | dst[1] = yl; |
| 349 | } | 344 | } |
| 350 | 345 | ||
| 351 | static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
| 352 | { | ||
| 353 | const __be32 *in_blk = (const __be32 *)src; | ||
| 354 | __be32 *const out_blk = (__be32 *)dst; | ||
| 355 | u32 in32[2], out32[2]; | ||
| 356 | |||
| 357 | in32[0] = be32_to_cpu(in_blk[0]); | ||
| 358 | in32[1] = be32_to_cpu(in_blk[1]); | ||
| 359 | encrypt_block(crypto_tfm_ctx(tfm), out32, in32); | ||
| 360 | out_blk[0] = cpu_to_be32(out32[0]); | ||
| 361 | out_blk[1] = cpu_to_be32(out32[1]); | ||
| 362 | } | ||
| 363 | |||
| 364 | static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
| 365 | { | ||
| 366 | struct bf_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 367 | const __be32 *in_blk = (const __be32 *)src; | ||
| 368 | __be32 *const out_blk = (__be32 *)dst; | ||
| 369 | const u32 *P = ctx->p; | ||
| 370 | const u32 *S = ctx->s; | ||
| 371 | u32 yl = be32_to_cpu(in_blk[0]); | ||
| 372 | u32 yr = be32_to_cpu(in_blk[1]); | ||
| 373 | |||
| 374 | ROUND(yr, yl, 17); | ||
| 375 | ROUND(yl, yr, 16); | ||
| 376 | ROUND(yr, yl, 15); | ||
| 377 | ROUND(yl, yr, 14); | ||
| 378 | ROUND(yr, yl, 13); | ||
| 379 | ROUND(yl, yr, 12); | ||
| 380 | ROUND(yr, yl, 11); | ||
| 381 | ROUND(yl, yr, 10); | ||
| 382 | ROUND(yr, yl, 9); | ||
| 383 | ROUND(yl, yr, 8); | ||
| 384 | ROUND(yr, yl, 7); | ||
| 385 | ROUND(yl, yr, 6); | ||
| 386 | ROUND(yr, yl, 5); | ||
| 387 | ROUND(yl, yr, 4); | ||
| 388 | ROUND(yr, yl, 3); | ||
| 389 | ROUND(yl, yr, 2); | ||
| 390 | |||
| 391 | yl ^= P[1]; | ||
| 392 | yr ^= P[0]; | ||
| 393 | |||
| 394 | out_blk[0] = cpu_to_be32(yr); | ||
| 395 | out_blk[1] = cpu_to_be32(yl); | ||
| 396 | } | ||
| 397 | |||
| 398 | /* | 346 | /* |
| 399 | * Calculates the blowfish S and P boxes for encryption and decryption. | 347 | * Calculates the blowfish S and P boxes for encryption and decryption. |
| 400 | */ | 348 | */ |
| 401 | static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | 349 | int blowfish_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) |
| 402 | { | 350 | { |
| 403 | struct bf_ctx *ctx = crypto_tfm_ctx(tfm); | 351 | struct bf_ctx *ctx = crypto_tfm_ctx(tfm); |
| 404 | u32 *P = ctx->p; | 352 | u32 *P = ctx->p; |
| @@ -448,35 +396,7 @@ static int bf_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) | |||
| 448 | /* Bruce says not to bother with the weak key check. */ | 396 | /* Bruce says not to bother with the weak key check. */ |
| 449 | return 0; | 397 | return 0; |
| 450 | } | 398 | } |
| 451 | 399 | EXPORT_SYMBOL_GPL(blowfish_setkey); | |
| 452 | static struct crypto_alg alg = { | ||
| 453 | .cra_name = "blowfish", | ||
| 454 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
| 455 | .cra_blocksize = BF_BLOCK_SIZE, | ||
| 456 | .cra_ctxsize = sizeof(struct bf_ctx), | ||
| 457 | .cra_alignmask = 3, | ||
| 458 | .cra_module = THIS_MODULE, | ||
| 459 | .cra_list = LIST_HEAD_INIT(alg.cra_list), | ||
| 460 | .cra_u = { .cipher = { | ||
| 461 | .cia_min_keysize = BF_MIN_KEY_SIZE, | ||
| 462 | .cia_max_keysize = BF_MAX_KEY_SIZE, | ||
| 463 | .cia_setkey = bf_setkey, | ||
| 464 | .cia_encrypt = bf_encrypt, | ||
| 465 | .cia_decrypt = bf_decrypt } } | ||
| 466 | }; | ||
| 467 | |||
| 468 | static int __init blowfish_mod_init(void) | ||
| 469 | { | ||
| 470 | return crypto_register_alg(&alg); | ||
| 471 | } | ||
| 472 | |||
| 473 | static void __exit blowfish_mod_fini(void) | ||
| 474 | { | ||
| 475 | crypto_unregister_alg(&alg); | ||
| 476 | } | ||
| 477 | |||
| 478 | module_init(blowfish_mod_init); | ||
| 479 | module_exit(blowfish_mod_fini); | ||
| 480 | 400 | ||
| 481 | MODULE_LICENSE("GPL"); | 401 | MODULE_LICENSE("GPL"); |
| 482 | MODULE_DESCRIPTION("Blowfish Cipher Algorithm"); | 402 | MODULE_DESCRIPTION("Blowfish Cipher common functions"); |
diff --git a/crypto/blowfish_generic.c b/crypto/blowfish_generic.c new file mode 100644 index 000000000000..6f269b5cfa3b --- /dev/null +++ b/crypto/blowfish_generic.c | |||
| @@ -0,0 +1,142 @@ | |||
| 1 | /* | ||
| 2 | * Cryptographic API. | ||
| 3 | * | ||
| 4 | * Blowfish Cipher Algorithm, by Bruce Schneier. | ||
| 5 | * http://www.counterpane.com/blowfish.html | ||
| 6 | * | ||
| 7 | * Adapted from Kerneli implementation. | ||
| 8 | * | ||
| 9 | * Copyright (c) Herbert Valerio Riedel <hvr@hvrlab.org> | ||
| 10 | * Copyright (c) Kyle McMartin <kyle@debian.org> | ||
| 11 | * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify | ||
| 14 | * it under the terms of the GNU General Public License as published by | ||
| 15 | * the Free Software Foundation; either version 2 of the License, or | ||
| 16 | * (at your option) any later version. | ||
| 17 | * | ||
| 18 | */ | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/mm.h> | ||
| 22 | #include <asm/byteorder.h> | ||
| 23 | #include <linux/crypto.h> | ||
| 24 | #include <linux/types.h> | ||
| 25 | #include <crypto/blowfish.h> | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Round loop unrolling macros, S is a pointer to a S-Box array | ||
| 29 | * organized in 4 unsigned longs at a row. | ||
| 30 | */ | ||
| 31 | #define GET32_3(x) (((x) & 0xff)) | ||
| 32 | #define GET32_2(x) (((x) >> (8)) & (0xff)) | ||
| 33 | #define GET32_1(x) (((x) >> (16)) & (0xff)) | ||
| 34 | #define GET32_0(x) (((x) >> (24)) & (0xff)) | ||
| 35 | |||
| 36 | #define bf_F(x) (((S[GET32_0(x)] + S[256 + GET32_1(x)]) ^ \ | ||
| 37 | S[512 + GET32_2(x)]) + S[768 + GET32_3(x)]) | ||
| 38 | |||
| 39 | #define ROUND(a, b, n) ({ b ^= P[n]; a ^= bf_F(b); }) | ||
| 40 | |||
| 41 | static void bf_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
| 42 | { | ||
| 43 | struct bf_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 44 | const __be32 *in_blk = (const __be32 *)src; | ||
| 45 | __be32 *const out_blk = (__be32 *)dst; | ||
| 46 | const u32 *P = ctx->p; | ||
| 47 | const u32 *S = ctx->s; | ||
| 48 | u32 yl = be32_to_cpu(in_blk[0]); | ||
| 49 | u32 yr = be32_to_cpu(in_blk[1]); | ||
| 50 | |||
| 51 | ROUND(yr, yl, 0); | ||
| 52 | ROUND(yl, yr, 1); | ||
| 53 | ROUND(yr, yl, 2); | ||
| 54 | ROUND(yl, yr, 3); | ||
| 55 | ROUND(yr, yl, 4); | ||
| 56 | ROUND(yl, yr, 5); | ||
| 57 | ROUND(yr, yl, 6); | ||
| 58 | ROUND(yl, yr, 7); | ||
| 59 | ROUND(yr, yl, 8); | ||
| 60 | ROUND(yl, yr, 9); | ||
| 61 | ROUND(yr, yl, 10); | ||
| 62 | ROUND(yl, yr, 11); | ||
| 63 | ROUND(yr, yl, 12); | ||
| 64 | ROUND(yl, yr, 13); | ||
| 65 | ROUND(yr, yl, 14); | ||
| 66 | ROUND(yl, yr, 15); | ||
| 67 | |||
| 68 | yl ^= P[16]; | ||
| 69 | yr ^= P[17]; | ||
| 70 | |||
| 71 | out_blk[0] = cpu_to_be32(yr); | ||
| 72 | out_blk[1] = cpu_to_be32(yl); | ||
| 73 | } | ||
| 74 | |||
| 75 | static void bf_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src) | ||
| 76 | { | ||
| 77 | struct bf_ctx *ctx = crypto_tfm_ctx(tfm); | ||
| 78 | const __be32 *in_blk = (const __be32 *)src; | ||
| 79 | __be32 *const out_blk = (__be32 *)dst; | ||
| 80 | const u32 *P = ctx->p; | ||
| 81 | const u32 *S = ctx->s; | ||
| 82 | u32 yl = be32_to_cpu(in_blk[0]); | ||
| 83 | u32 yr = be32_to_cpu(in_blk[1]); | ||
| 84 | |||
| 85 | ROUND(yr, yl, 17); | ||
| 86 | ROUND(yl, yr, 16); | ||
| 87 | ROUND(yr, yl, 15); | ||
| 88 | ROUND(yl, yr, 14); | ||
| 89 | ROUND(yr, yl, 13); | ||
| 90 | ROUND(yl, yr, 12); | ||
| 91 | ROUND(yr, yl, 11); | ||
| 92 | ROUND(yl, yr, 10); | ||
| 93 | ROUND(yr, yl, 9); | ||
| 94 | ROUND(yl, yr, 8); | ||
| 95 | ROUND(yr, yl, 7); | ||
| 96 | ROUND(yl, yr, 6); | ||
| 97 | ROUND(yr, yl, 5); | ||
| 98 | ROUND(yl, yr, 4); | ||
| 99 | ROUND(yr, yl, 3); | ||
| 100 | ROUND(yl, yr, 2); | ||
| 101 | |||
| 102 | yl ^= P[1]; | ||
| 103 | yr ^= P[0]; | ||
| 104 | |||
| 105 | out_blk[0] = cpu_to_be32(yr); | ||
| 106 | out_blk[1] = cpu_to_be32(yl); | ||
| 107 | } | ||
| 108 | |||
| 109 | static struct crypto_alg alg = { | ||
| 110 | .cra_name = "blowfish", | ||
| 111 | .cra_driver_name = "blowfish-generic", | ||
| 112 | .cra_priority = 100, | ||
| 113 | .cra_flags = CRYPTO_ALG_TYPE_CIPHER, | ||
| 114 | .cra_blocksize = BF_BLOCK_SIZE, | ||
| 115 | .cra_ctxsize = sizeof(struct bf_ctx), | ||
| 116 | .cra_alignmask = 3, | ||
| 117 | .cra_module = THIS_MODULE, | ||
| 118 | .cra_list = LIST_HEAD_INIT(alg.cra_list), | ||
| 119 | .cra_u = { .cipher = { | ||
| 120 | .cia_min_keysize = BF_MIN_KEY_SIZE, | ||
| 121 | .cia_max_keysize = BF_MAX_KEY_SIZE, | ||
| 122 | .cia_setkey = blowfish_setkey, | ||
| 123 | .cia_encrypt = bf_encrypt, | ||
| 124 | .cia_decrypt = bf_decrypt } } | ||
| 125 | }; | ||
| 126 | |||
| 127 | static int __init blowfish_mod_init(void) | ||
| 128 | { | ||
| 129 | return crypto_register_alg(&alg); | ||
| 130 | } | ||
| 131 | |||
| 132 | static void __exit blowfish_mod_fini(void) | ||
| 133 | { | ||
| 134 | crypto_unregister_alg(&alg); | ||
| 135 | } | ||
| 136 | |||
| 137 | module_init(blowfish_mod_init); | ||
| 138 | module_exit(blowfish_mod_fini); | ||
| 139 | |||
| 140 | MODULE_LICENSE("GPL"); | ||
| 141 | MODULE_DESCRIPTION("Blowfish Cipher Algorithm"); | ||
| 142 | MODULE_ALIAS("blowfish"); | ||
diff --git a/crypto/cryptd.c b/crypto/cryptd.c index e46d21ae26bc..671d4d6d14df 100644 --- a/crypto/cryptd.c +++ b/crypto/cryptd.c | |||
| @@ -945,7 +945,7 @@ static void __exit cryptd_exit(void) | |||
| 945 | crypto_unregister_template(&cryptd_tmpl); | 945 | crypto_unregister_template(&cryptd_tmpl); |
| 946 | } | 946 | } |
| 947 | 947 | ||
| 948 | module_init(cryptd_init); | 948 | subsys_initcall(cryptd_init); |
| 949 | module_exit(cryptd_exit); | 949 | module_exit(cryptd_exit); |
| 950 | 950 | ||
| 951 | MODULE_LICENSE("GPL"); | 951 | MODULE_LICENSE("GPL"); |
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c new file mode 100644 index 000000000000..2abca780312d --- /dev/null +++ b/crypto/crypto_user.c | |||
| @@ -0,0 +1,438 @@ | |||
| 1 | /* | ||
| 2 | * Crypto user configuration API. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 secunet Security Networks AG | ||
| 5 | * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms and conditions of the GNU General Public License, | ||
| 9 | * version 2, as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 14 | * more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along with | ||
| 17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/module.h> | ||
| 22 | #include <linux/crypto.h> | ||
| 23 | #include <linux/cryptouser.h> | ||
| 24 | #include <net/netlink.h> | ||
| 25 | #include <linux/security.h> | ||
| 26 | #include <net/net_namespace.h> | ||
| 27 | #include "internal.h" | ||
| 28 | |||
| 29 | DEFINE_MUTEX(crypto_cfg_mutex); | ||
| 30 | |||
| 31 | /* The crypto netlink socket */ | ||
| 32 | static struct sock *crypto_nlsk; | ||
| 33 | |||
| 34 | struct crypto_dump_info { | ||
| 35 | struct sk_buff *in_skb; | ||
| 36 | struct sk_buff *out_skb; | ||
| 37 | u32 nlmsg_seq; | ||
| 38 | u16 nlmsg_flags; | ||
| 39 | }; | ||
| 40 | |||
| 41 | static struct crypto_alg *crypto_alg_match(struct crypto_user_alg *p, int exact) | ||
| 42 | { | ||
| 43 | struct crypto_alg *q, *alg = NULL; | ||
| 44 | |||
| 45 | down_read(&crypto_alg_sem); | ||
| 46 | |||
| 47 | if (list_empty(&crypto_alg_list)) | ||
| 48 | return NULL; | ||
| 49 | |||
| 50 | list_for_each_entry(q, &crypto_alg_list, cra_list) { | ||
| 51 | int match = 0; | ||
| 52 | |||
| 53 | if ((q->cra_flags ^ p->cru_type) & p->cru_mask) | ||
| 54 | continue; | ||
| 55 | |||
| 56 | if (strlen(p->cru_driver_name)) | ||
| 57 | match = !strcmp(q->cra_driver_name, | ||
| 58 | p->cru_driver_name); | ||
| 59 | else if (!exact) | ||
| 60 | match = !strcmp(q->cra_name, p->cru_name); | ||
| 61 | |||
| 62 | if (match) { | ||
| 63 | alg = q; | ||
| 64 | break; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | |||
| 68 | up_read(&crypto_alg_sem); | ||
| 69 | |||
| 70 | return alg; | ||
| 71 | } | ||
| 72 | |||
| 73 | static int crypto_report_cipher(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 74 | { | ||
| 75 | struct crypto_report_cipher rcipher; | ||
| 76 | |||
| 77 | snprintf(rcipher.type, CRYPTO_MAX_ALG_NAME, "%s", "cipher"); | ||
| 78 | |||
| 79 | rcipher.blocksize = alg->cra_blocksize; | ||
| 80 | rcipher.min_keysize = alg->cra_cipher.cia_min_keysize; | ||
| 81 | rcipher.max_keysize = alg->cra_cipher.cia_max_keysize; | ||
| 82 | |||
| 83 | NLA_PUT(skb, CRYPTOCFGA_REPORT_CIPHER, | ||
| 84 | sizeof(struct crypto_report_cipher), &rcipher); | ||
| 85 | |||
| 86 | return 0; | ||
| 87 | |||
| 88 | nla_put_failure: | ||
| 89 | return -EMSGSIZE; | ||
| 90 | } | ||
| 91 | |||
| 92 | static int crypto_report_comp(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 93 | { | ||
| 94 | struct crypto_report_comp rcomp; | ||
| 95 | |||
| 96 | snprintf(rcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "compression"); | ||
| 97 | |||
| 98 | NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS, | ||
| 99 | sizeof(struct crypto_report_comp), &rcomp); | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | |||
| 103 | nla_put_failure: | ||
| 104 | return -EMSGSIZE; | ||
| 105 | } | ||
| 106 | |||
| 107 | static int crypto_report_one(struct crypto_alg *alg, | ||
| 108 | struct crypto_user_alg *ualg, struct sk_buff *skb) | ||
| 109 | { | ||
| 110 | memcpy(&ualg->cru_name, &alg->cra_name, sizeof(ualg->cru_name)); | ||
| 111 | memcpy(&ualg->cru_driver_name, &alg->cra_driver_name, | ||
| 112 | sizeof(ualg->cru_driver_name)); | ||
| 113 | memcpy(&ualg->cru_module_name, module_name(alg->cra_module), | ||
| 114 | CRYPTO_MAX_ALG_NAME); | ||
| 115 | |||
| 116 | ualg->cru_flags = alg->cra_flags; | ||
| 117 | ualg->cru_refcnt = atomic_read(&alg->cra_refcnt); | ||
| 118 | |||
| 119 | NLA_PUT_U32(skb, CRYPTOCFGA_PRIORITY_VAL, alg->cra_priority); | ||
| 120 | |||
| 121 | if (alg->cra_flags & CRYPTO_ALG_LARVAL) { | ||
| 122 | struct crypto_report_larval rl; | ||
| 123 | |||
| 124 | snprintf(rl.type, CRYPTO_MAX_ALG_NAME, "%s", "larval"); | ||
| 125 | |||
| 126 | NLA_PUT(skb, CRYPTOCFGA_REPORT_LARVAL, | ||
| 127 | sizeof(struct crypto_report_larval), &rl); | ||
| 128 | |||
| 129 | goto out; | ||
| 130 | } | ||
| 131 | |||
| 132 | if (alg->cra_type && alg->cra_type->report) { | ||
| 133 | if (alg->cra_type->report(skb, alg)) | ||
| 134 | goto nla_put_failure; | ||
| 135 | |||
| 136 | goto out; | ||
| 137 | } | ||
| 138 | |||
| 139 | switch (alg->cra_flags & (CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_LARVAL)) { | ||
| 140 | case CRYPTO_ALG_TYPE_CIPHER: | ||
| 141 | if (crypto_report_cipher(skb, alg)) | ||
| 142 | goto nla_put_failure; | ||
| 143 | |||
| 144 | break; | ||
| 145 | case CRYPTO_ALG_TYPE_COMPRESS: | ||
| 146 | if (crypto_report_comp(skb, alg)) | ||
| 147 | goto nla_put_failure; | ||
| 148 | |||
| 149 | break; | ||
| 150 | } | ||
| 151 | |||
| 152 | out: | ||
| 153 | return 0; | ||
| 154 | |||
| 155 | nla_put_failure: | ||
| 156 | return -EMSGSIZE; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int crypto_report_alg(struct crypto_alg *alg, | ||
| 160 | struct crypto_dump_info *info) | ||
| 161 | { | ||
| 162 | struct sk_buff *in_skb = info->in_skb; | ||
| 163 | struct sk_buff *skb = info->out_skb; | ||
| 164 | struct nlmsghdr *nlh; | ||
| 165 | struct crypto_user_alg *ualg; | ||
| 166 | int err = 0; | ||
| 167 | |||
| 168 | nlh = nlmsg_put(skb, NETLINK_CB(in_skb).pid, info->nlmsg_seq, | ||
| 169 | CRYPTO_MSG_GETALG, sizeof(*ualg), info->nlmsg_flags); | ||
| 170 | if (!nlh) { | ||
| 171 | err = -EMSGSIZE; | ||
| 172 | goto out; | ||
| 173 | } | ||
| 174 | |||
| 175 | ualg = nlmsg_data(nlh); | ||
| 176 | |||
| 177 | err = crypto_report_one(alg, ualg, skb); | ||
| 178 | if (err) { | ||
| 179 | nlmsg_cancel(skb, nlh); | ||
| 180 | goto out; | ||
| 181 | } | ||
| 182 | |||
| 183 | nlmsg_end(skb, nlh); | ||
| 184 | |||
| 185 | out: | ||
| 186 | return err; | ||
| 187 | } | ||
| 188 | |||
| 189 | static int crypto_report(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, | ||
| 190 | struct nlattr **attrs) | ||
| 191 | { | ||
| 192 | struct crypto_user_alg *p = nlmsg_data(in_nlh); | ||
| 193 | struct crypto_alg *alg; | ||
| 194 | struct sk_buff *skb; | ||
| 195 | struct crypto_dump_info info; | ||
| 196 | int err; | ||
| 197 | |||
| 198 | if (!p->cru_driver_name) | ||
| 199 | return -EINVAL; | ||
| 200 | |||
| 201 | alg = crypto_alg_match(p, 1); | ||
| 202 | if (!alg) | ||
| 203 | return -ENOENT; | ||
| 204 | |||
| 205 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); | ||
| 206 | if (!skb) | ||
| 207 | return -ENOMEM; | ||
| 208 | |||
| 209 | info.in_skb = in_skb; | ||
| 210 | info.out_skb = skb; | ||
| 211 | info.nlmsg_seq = in_nlh->nlmsg_seq; | ||
| 212 | info.nlmsg_flags = 0; | ||
| 213 | |||
| 214 | err = crypto_report_alg(alg, &info); | ||
| 215 | if (err) | ||
| 216 | return err; | ||
| 217 | |||
| 218 | return nlmsg_unicast(crypto_nlsk, skb, NETLINK_CB(in_skb).pid); | ||
| 219 | } | ||
| 220 | |||
| 221 | static int crypto_dump_report(struct sk_buff *skb, struct netlink_callback *cb) | ||
| 222 | { | ||
| 223 | struct crypto_alg *alg; | ||
| 224 | struct crypto_dump_info info; | ||
| 225 | int err; | ||
| 226 | |||
| 227 | if (cb->args[0]) | ||
| 228 | goto out; | ||
| 229 | |||
| 230 | cb->args[0] = 1; | ||
| 231 | |||
| 232 | info.in_skb = cb->skb; | ||
| 233 | info.out_skb = skb; | ||
| 234 | info.nlmsg_seq = cb->nlh->nlmsg_seq; | ||
| 235 | info.nlmsg_flags = NLM_F_MULTI; | ||
| 236 | |||
| 237 | list_for_each_entry(alg, &crypto_alg_list, cra_list) { | ||
| 238 | err = crypto_report_alg(alg, &info); | ||
| 239 | if (err) | ||
| 240 | goto out_err; | ||
| 241 | } | ||
| 242 | |||
| 243 | out: | ||
| 244 | return skb->len; | ||
| 245 | out_err: | ||
| 246 | return err; | ||
| 247 | } | ||
| 248 | |||
| 249 | static int crypto_dump_report_done(struct netlink_callback *cb) | ||
| 250 | { | ||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | |||
| 254 | static int crypto_update_alg(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
| 255 | struct nlattr **attrs) | ||
| 256 | { | ||
| 257 | struct crypto_alg *alg; | ||
| 258 | struct crypto_user_alg *p = nlmsg_data(nlh); | ||
| 259 | struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL]; | ||
| 260 | LIST_HEAD(list); | ||
| 261 | |||
| 262 | if (priority && !strlen(p->cru_driver_name)) | ||
| 263 | return -EINVAL; | ||
| 264 | |||
| 265 | alg = crypto_alg_match(p, 1); | ||
| 266 | if (!alg) | ||
| 267 | return -ENOENT; | ||
| 268 | |||
| 269 | down_write(&crypto_alg_sem); | ||
| 270 | |||
| 271 | crypto_remove_spawns(alg, &list, NULL); | ||
| 272 | |||
| 273 | if (priority) | ||
| 274 | alg->cra_priority = nla_get_u32(priority); | ||
| 275 | |||
| 276 | up_write(&crypto_alg_sem); | ||
| 277 | |||
| 278 | crypto_remove_final(&list); | ||
| 279 | |||
| 280 | return 0; | ||
| 281 | } | ||
| 282 | |||
| 283 | static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
| 284 | struct nlattr **attrs) | ||
| 285 | { | ||
| 286 | struct crypto_alg *alg; | ||
| 287 | struct crypto_user_alg *p = nlmsg_data(nlh); | ||
| 288 | |||
| 289 | alg = crypto_alg_match(p, 1); | ||
| 290 | if (!alg) | ||
| 291 | return -ENOENT; | ||
| 292 | |||
| 293 | /* We can not unregister core algorithms such as aes-generic. | ||
| 294 | * We would loose the reference in the crypto_alg_list to this algorithm | ||
| 295 | * if we try to unregister. Unregistering such an algorithm without | ||
| 296 | * removing the module is not possible, so we restrict to crypto | ||
| 297 | * instances that are build from templates. */ | ||
| 298 | if (!(alg->cra_flags & CRYPTO_ALG_INSTANCE)) | ||
| 299 | return -EINVAL; | ||
| 300 | |||
| 301 | if (atomic_read(&alg->cra_refcnt) != 1) | ||
| 302 | return -EBUSY; | ||
| 303 | |||
| 304 | return crypto_unregister_alg(alg); | ||
| 305 | } | ||
| 306 | |||
| 307 | static int crypto_add_alg(struct sk_buff *skb, struct nlmsghdr *nlh, | ||
| 308 | struct nlattr **attrs) | ||
| 309 | { | ||
| 310 | int exact; | ||
| 311 | const char *name; | ||
| 312 | struct crypto_alg *alg; | ||
| 313 | struct crypto_user_alg *p = nlmsg_data(nlh); | ||
| 314 | struct nlattr *priority = attrs[CRYPTOCFGA_PRIORITY_VAL]; | ||
| 315 | |||
| 316 | if (strlen(p->cru_driver_name)) | ||
| 317 | exact = 1; | ||
| 318 | |||
| 319 | if (priority && !exact) | ||
| 320 | return -EINVAL; | ||
| 321 | |||
| 322 | alg = crypto_alg_match(p, exact); | ||
| 323 | if (alg) | ||
| 324 | return -EEXIST; | ||
| 325 | |||
| 326 | if (strlen(p->cru_driver_name)) | ||
| 327 | name = p->cru_driver_name; | ||
| 328 | else | ||
| 329 | name = p->cru_name; | ||
| 330 | |||
| 331 | alg = crypto_alg_mod_lookup(name, p->cru_type, p->cru_mask); | ||
| 332 | if (IS_ERR(alg)) | ||
| 333 | return PTR_ERR(alg); | ||
| 334 | |||
| 335 | down_write(&crypto_alg_sem); | ||
| 336 | |||
| 337 | if (priority) | ||
| 338 | alg->cra_priority = nla_get_u32(priority); | ||
| 339 | |||
| 340 | up_write(&crypto_alg_sem); | ||
| 341 | |||
| 342 | crypto_mod_put(alg); | ||
| 343 | |||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | #define MSGSIZE(type) sizeof(struct type) | ||
| 348 | |||
| 349 | static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = { | ||
| 350 | [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), | ||
| 351 | [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), | ||
| 352 | [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), | ||
| 353 | [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg), | ||
| 354 | }; | ||
| 355 | |||
| 356 | static const struct nla_policy crypto_policy[CRYPTOCFGA_MAX+1] = { | ||
| 357 | [CRYPTOCFGA_PRIORITY_VAL] = { .type = NLA_U32}, | ||
| 358 | }; | ||
| 359 | |||
| 360 | #undef MSGSIZE | ||
| 361 | |||
| 362 | static struct crypto_link { | ||
| 363 | int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **); | ||
| 364 | int (*dump)(struct sk_buff *, struct netlink_callback *); | ||
| 365 | int (*done)(struct netlink_callback *); | ||
| 366 | } crypto_dispatch[CRYPTO_NR_MSGTYPES] = { | ||
| 367 | [CRYPTO_MSG_NEWALG - CRYPTO_MSG_BASE] = { .doit = crypto_add_alg}, | ||
| 368 | [CRYPTO_MSG_DELALG - CRYPTO_MSG_BASE] = { .doit = crypto_del_alg}, | ||
| 369 | [CRYPTO_MSG_UPDATEALG - CRYPTO_MSG_BASE] = { .doit = crypto_update_alg}, | ||
| 370 | [CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE] = { .doit = crypto_report, | ||
| 371 | .dump = crypto_dump_report, | ||
| 372 | .done = crypto_dump_report_done}, | ||
| 373 | }; | ||
| 374 | |||
| 375 | static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | ||
| 376 | { | ||
| 377 | struct nlattr *attrs[CRYPTOCFGA_MAX+1]; | ||
| 378 | struct crypto_link *link; | ||
| 379 | int type, err; | ||
| 380 | |||
| 381 | type = nlh->nlmsg_type; | ||
| 382 | if (type > CRYPTO_MSG_MAX) | ||
| 383 | return -EINVAL; | ||
| 384 | |||
| 385 | type -= CRYPTO_MSG_BASE; | ||
| 386 | link = &crypto_dispatch[type]; | ||
| 387 | |||
| 388 | if (security_netlink_recv(skb, CAP_NET_ADMIN)) | ||
| 389 | return -EPERM; | ||
| 390 | |||
| 391 | if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && | ||
| 392 | (nlh->nlmsg_flags & NLM_F_DUMP))) { | ||
| 393 | if (link->dump == NULL) | ||
| 394 | return -EINVAL; | ||
| 395 | |||
| 396 | return netlink_dump_start(crypto_nlsk, skb, nlh, | ||
| 397 | link->dump, link->done, 0); | ||
| 398 | } | ||
| 399 | |||
| 400 | err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX, | ||
| 401 | crypto_policy); | ||
| 402 | if (err < 0) | ||
| 403 | return err; | ||
| 404 | |||
| 405 | if (link->doit == NULL) | ||
| 406 | return -EINVAL; | ||
| 407 | |||
| 408 | return link->doit(skb, nlh, attrs); | ||
| 409 | } | ||
| 410 | |||
| 411 | static void crypto_netlink_rcv(struct sk_buff *skb) | ||
| 412 | { | ||
| 413 | mutex_lock(&crypto_cfg_mutex); | ||
| 414 | netlink_rcv_skb(skb, &crypto_user_rcv_msg); | ||
| 415 | mutex_unlock(&crypto_cfg_mutex); | ||
| 416 | } | ||
| 417 | |||
| 418 | static int __init crypto_user_init(void) | ||
| 419 | { | ||
| 420 | crypto_nlsk = netlink_kernel_create(&init_net, NETLINK_CRYPTO, | ||
| 421 | 0, crypto_netlink_rcv, | ||
| 422 | NULL, THIS_MODULE); | ||
| 423 | if (!crypto_nlsk) | ||
| 424 | return -ENOMEM; | ||
| 425 | |||
| 426 | return 0; | ||
| 427 | } | ||
| 428 | |||
| 429 | static void __exit crypto_user_exit(void) | ||
| 430 | { | ||
| 431 | netlink_kernel_release(crypto_nlsk); | ||
| 432 | } | ||
| 433 | |||
| 434 | module_init(crypto_user_init); | ||
| 435 | module_exit(crypto_user_exit); | ||
| 436 | MODULE_LICENSE("GPL"); | ||
| 437 | MODULE_AUTHOR("Steffen Klassert <steffen.klassert@secunet.com>"); | ||
| 438 | MODULE_DESCRIPTION("Crypto userspace configuration API"); | ||
diff --git a/crypto/internal.h b/crypto/internal.h index d4384b08ab29..b865ca1a8613 100644 --- a/crypto/internal.h +++ b/crypto/internal.h | |||
| @@ -86,6 +86,9 @@ struct crypto_alg *crypto_larval_lookup(const char *name, u32 type, u32 mask); | |||
| 86 | void crypto_larval_error(const char *name, u32 type, u32 mask); | 86 | void crypto_larval_error(const char *name, u32 type, u32 mask); |
| 87 | void crypto_alg_tested(const char *name, int err); | 87 | void crypto_alg_tested(const char *name, int err); |
| 88 | 88 | ||
| 89 | void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, | ||
| 90 | struct crypto_alg *nalg); | ||
| 91 | void crypto_remove_final(struct list_head *list); | ||
| 89 | void crypto_shoot_alg(struct crypto_alg *alg); | 92 | void crypto_shoot_alg(struct crypto_alg *alg); |
| 90 | struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, | 93 | struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg, u32 type, |
| 91 | u32 mask); | 94 | u32 mask); |
diff --git a/crypto/pcompress.c b/crypto/pcompress.c index f7c4a7d7412e..fefda78a6a2a 100644 --- a/crypto/pcompress.c +++ b/crypto/pcompress.c | |||
| @@ -24,6 +24,8 @@ | |||
| 24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 25 | #include <linux/seq_file.h> | 25 | #include <linux/seq_file.h> |
| 26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
| 27 | #include <linux/cryptouser.h> | ||
| 28 | #include <net/netlink.h> | ||
| 27 | 29 | ||
| 28 | #include <crypto/compress.h> | 30 | #include <crypto/compress.h> |
| 29 | #include <crypto/internal/compress.h> | 31 | #include <crypto/internal/compress.h> |
| @@ -46,6 +48,21 @@ static int crypto_pcomp_init_tfm(struct crypto_tfm *tfm) | |||
| 46 | return 0; | 48 | return 0; |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 51 | static int crypto_pcomp_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 52 | { | ||
| 53 | struct crypto_report_comp rpcomp; | ||
| 54 | |||
| 55 | snprintf(rpcomp.type, CRYPTO_MAX_ALG_NAME, "%s", "pcomp"); | ||
| 56 | |||
| 57 | NLA_PUT(skb, CRYPTOCFGA_REPORT_COMPRESS, | ||
| 58 | sizeof(struct crypto_report_comp), &rpcomp); | ||
| 59 | |||
| 60 | return 0; | ||
| 61 | |||
| 62 | nla_put_failure: | ||
| 63 | return -EMSGSIZE; | ||
| 64 | } | ||
| 65 | |||
| 49 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) | 66 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) |
| 50 | __attribute__ ((unused)); | 67 | __attribute__ ((unused)); |
| 51 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) | 68 | static void crypto_pcomp_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -60,6 +77,7 @@ static const struct crypto_type crypto_pcomp_type = { | |||
| 60 | #ifdef CONFIG_PROC_FS | 77 | #ifdef CONFIG_PROC_FS |
| 61 | .show = crypto_pcomp_show, | 78 | .show = crypto_pcomp_show, |
| 62 | #endif | 79 | #endif |
| 80 | .report = crypto_pcomp_report, | ||
| 63 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, | 81 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, |
| 64 | .maskset = CRYPTO_ALG_TYPE_MASK, | 82 | .maskset = CRYPTO_ALG_TYPE_MASK, |
| 65 | .type = CRYPTO_ALG_TYPE_PCOMPRESS, | 83 | .type = CRYPTO_ALG_TYPE_PCOMPRESS, |
diff --git a/crypto/rng.c b/crypto/rng.c index 45229ae782be..feb7de00f437 100644 --- a/crypto/rng.c +++ b/crypto/rng.c | |||
| @@ -21,6 +21,8 @@ | |||
| 21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/string.h> | 23 | #include <linux/string.h> |
| 24 | #include <linux/cryptouser.h> | ||
| 25 | #include <net/netlink.h> | ||
| 24 | 26 | ||
| 25 | static DEFINE_MUTEX(crypto_default_rng_lock); | 27 | static DEFINE_MUTEX(crypto_default_rng_lock); |
| 26 | struct crypto_rng *crypto_default_rng; | 28 | struct crypto_rng *crypto_default_rng; |
| @@ -58,6 +60,23 @@ static int crypto_init_rng_ops(struct crypto_tfm *tfm, u32 type, u32 mask) | |||
| 58 | return 0; | 60 | return 0; |
| 59 | } | 61 | } |
| 60 | 62 | ||
| 63 | static int crypto_rng_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 64 | { | ||
| 65 | struct crypto_report_rng rrng; | ||
| 66 | |||
| 67 | snprintf(rrng.type, CRYPTO_MAX_ALG_NAME, "%s", "rng"); | ||
| 68 | |||
| 69 | rrng.seedsize = alg->cra_rng.seedsize; | ||
| 70 | |||
| 71 | NLA_PUT(skb, CRYPTOCFGA_REPORT_RNG, | ||
| 72 | sizeof(struct crypto_report_rng), &rrng); | ||
| 73 | |||
| 74 | return 0; | ||
| 75 | |||
| 76 | nla_put_failure: | ||
| 77 | return -EMSGSIZE; | ||
| 78 | } | ||
| 79 | |||
| 61 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) | 80 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) |
| 62 | __attribute__ ((unused)); | 81 | __attribute__ ((unused)); |
| 63 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) | 82 | static void crypto_rng_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -78,6 +97,7 @@ const struct crypto_type crypto_rng_type = { | |||
| 78 | #ifdef CONFIG_PROC_FS | 97 | #ifdef CONFIG_PROC_FS |
| 79 | .show = crypto_rng_show, | 98 | .show = crypto_rng_show, |
| 80 | #endif | 99 | #endif |
| 100 | .report = crypto_rng_report, | ||
| 81 | }; | 101 | }; |
| 82 | EXPORT_SYMBOL_GPL(crypto_rng_type); | 102 | EXPORT_SYMBOL_GPL(crypto_rng_type); |
| 83 | 103 | ||
diff --git a/crypto/sha1_generic.c b/crypto/sha1_generic.c index 00ae60eb9254..42794803c480 100644 --- a/crypto/sha1_generic.c +++ b/crypto/sha1_generic.c | |||
| @@ -36,7 +36,7 @@ static int sha1_init(struct shash_desc *desc) | |||
| 36 | return 0; | 36 | return 0; |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | static int sha1_update(struct shash_desc *desc, const u8 *data, | 39 | int crypto_sha1_update(struct shash_desc *desc, const u8 *data, |
| 40 | unsigned int len) | 40 | unsigned int len) |
| 41 | { | 41 | { |
| 42 | struct sha1_state *sctx = shash_desc_ctx(desc); | 42 | struct sha1_state *sctx = shash_desc_ctx(desc); |
| @@ -71,6 +71,7 @@ static int sha1_update(struct shash_desc *desc, const u8 *data, | |||
| 71 | 71 | ||
| 72 | return 0; | 72 | return 0; |
| 73 | } | 73 | } |
| 74 | EXPORT_SYMBOL(crypto_sha1_update); | ||
| 74 | 75 | ||
| 75 | 76 | ||
| 76 | /* Add padding and return the message digest. */ | 77 | /* Add padding and return the message digest. */ |
| @@ -87,10 +88,10 @@ static int sha1_final(struct shash_desc *desc, u8 *out) | |||
| 87 | /* Pad out to 56 mod 64 */ | 88 | /* Pad out to 56 mod 64 */ |
| 88 | index = sctx->count & 0x3f; | 89 | index = sctx->count & 0x3f; |
| 89 | padlen = (index < 56) ? (56 - index) : ((64+56) - index); | 90 | padlen = (index < 56) ? (56 - index) : ((64+56) - index); |
| 90 | sha1_update(desc, padding, padlen); | 91 | crypto_sha1_update(desc, padding, padlen); |
| 91 | 92 | ||
| 92 | /* Append length */ | 93 | /* Append length */ |
| 93 | sha1_update(desc, (const u8 *)&bits, sizeof(bits)); | 94 | crypto_sha1_update(desc, (const u8 *)&bits, sizeof(bits)); |
| 94 | 95 | ||
| 95 | /* Store state in digest */ | 96 | /* Store state in digest */ |
| 96 | for (i = 0; i < 5; i++) | 97 | for (i = 0; i < 5; i++) |
| @@ -121,7 +122,7 @@ static int sha1_import(struct shash_desc *desc, const void *in) | |||
| 121 | static struct shash_alg alg = { | 122 | static struct shash_alg alg = { |
| 122 | .digestsize = SHA1_DIGEST_SIZE, | 123 | .digestsize = SHA1_DIGEST_SIZE, |
| 123 | .init = sha1_init, | 124 | .init = sha1_init, |
| 124 | .update = sha1_update, | 125 | .update = crypto_sha1_update, |
| 125 | .final = sha1_final, | 126 | .final = sha1_final, |
| 126 | .export = sha1_export, | 127 | .export = sha1_export, |
| 127 | .import = sha1_import, | 128 | .import = sha1_import, |
diff --git a/crypto/shash.c b/crypto/shash.c index 76f74b963151..ea8a9c6e21e3 100644 --- a/crypto/shash.c +++ b/crypto/shash.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
| 20 | #include <linux/cryptouser.h> | ||
| 21 | #include <net/netlink.h> | ||
| 20 | 22 | ||
| 21 | #include "internal.h" | 23 | #include "internal.h" |
| 22 | 24 | ||
| @@ -522,6 +524,24 @@ static unsigned int crypto_shash_extsize(struct crypto_alg *alg) | |||
| 522 | return alg->cra_ctxsize; | 524 | return alg->cra_ctxsize; |
| 523 | } | 525 | } |
| 524 | 526 | ||
| 527 | static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) | ||
| 528 | { | ||
| 529 | struct crypto_report_hash rhash; | ||
| 530 | struct shash_alg *salg = __crypto_shash_alg(alg); | ||
| 531 | |||
| 532 | snprintf(rhash.type, CRYPTO_MAX_ALG_NAME, "%s", "shash"); | ||
| 533 | rhash.blocksize = alg->cra_blocksize; | ||
| 534 | rhash.digestsize = salg->digestsize; | ||
| 535 | |||
| 536 | NLA_PUT(skb, CRYPTOCFGA_REPORT_HASH, | ||
| 537 | sizeof(struct crypto_report_hash), &rhash); | ||
| 538 | |||
| 539 | return 0; | ||
| 540 | |||
| 541 | nla_put_failure: | ||
| 542 | return -EMSGSIZE; | ||
| 543 | } | ||
| 544 | |||
| 525 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) | 545 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) |
| 526 | __attribute__ ((unused)); | 546 | __attribute__ ((unused)); |
| 527 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) | 547 | static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) |
| @@ -541,6 +561,7 @@ static const struct crypto_type crypto_shash_type = { | |||
| 541 | #ifdef CONFIG_PROC_FS | 561 | #ifdef CONFIG_PROC_FS |
| 542 | .show = crypto_shash_show, | 562 | .show = crypto_shash_show, |
| 543 | #endif | 563 | #endif |
| 564 | .report = crypto_shash_report, | ||
| 544 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, | 565 | .maskclear = ~CRYPTO_ALG_TYPE_MASK, |
| 545 | .maskset = CRYPTO_ALG_TYPE_MASK, | 566 | .maskset = CRYPTO_ALG_TYPE_MASK, |
| 546 | .type = CRYPTO_ALG_TYPE_SHASH, | 567 | .type = CRYPTO_ALG_TYPE_SHASH, |
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 2222617b3bed..0c4e80f34651 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c | |||
| @@ -782,11 +782,13 @@ static int do_test(int m) | |||
| 782 | case 7: | 782 | case 7: |
| 783 | ret += tcrypt_test("ecb(blowfish)"); | 783 | ret += tcrypt_test("ecb(blowfish)"); |
| 784 | ret += tcrypt_test("cbc(blowfish)"); | 784 | ret += tcrypt_test("cbc(blowfish)"); |
| 785 | ret += tcrypt_test("ctr(blowfish)"); | ||
| 785 | break; | 786 | break; |
| 786 | 787 | ||
| 787 | case 8: | 788 | case 8: |
| 788 | ret += tcrypt_test("ecb(twofish)"); | 789 | ret += tcrypt_test("ecb(twofish)"); |
| 789 | ret += tcrypt_test("cbc(twofish)"); | 790 | ret += tcrypt_test("cbc(twofish)"); |
| 791 | ret += tcrypt_test("ctr(twofish)"); | ||
| 790 | break; | 792 | break; |
| 791 | 793 | ||
| 792 | case 9: | 794 | case 9: |
| @@ -1039,6 +1041,10 @@ static int do_test(int m) | |||
| 1039 | speed_template_16_24_32); | 1041 | speed_template_16_24_32); |
| 1040 | test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0, | 1042 | test_cipher_speed("cbc(twofish)", DECRYPT, sec, NULL, 0, |
| 1041 | speed_template_16_24_32); | 1043 | speed_template_16_24_32); |
| 1044 | test_cipher_speed("ctr(twofish)", ENCRYPT, sec, NULL, 0, | ||
| 1045 | speed_template_16_24_32); | ||
| 1046 | test_cipher_speed("ctr(twofish)", DECRYPT, sec, NULL, 0, | ||
| 1047 | speed_template_16_24_32); | ||
| 1042 | break; | 1048 | break; |
| 1043 | 1049 | ||
| 1044 | case 203: | 1050 | case 203: |
| @@ -1050,6 +1056,10 @@ static int do_test(int m) | |||
| 1050 | speed_template_8_32); | 1056 | speed_template_8_32); |
| 1051 | test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0, | 1057 | test_cipher_speed("cbc(blowfish)", DECRYPT, sec, NULL, 0, |
| 1052 | speed_template_8_32); | 1058 | speed_template_8_32); |
| 1059 | test_cipher_speed("ctr(blowfish)", ENCRYPT, sec, NULL, 0, | ||
| 1060 | speed_template_8_32); | ||
| 1061 | test_cipher_speed("ctr(blowfish)", DECRYPT, sec, NULL, 0, | ||
| 1062 | speed_template_8_32); | ||
| 1053 | break; | 1063 | break; |
| 1054 | 1064 | ||
| 1055 | case 204: | 1065 | case 204: |
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index b6b93d416351..e91c1eb1722a 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c | |||
| @@ -1756,6 +1756,36 @@ static const struct alg_test_desc alg_test_descs[] = { | |||
| 1756 | } | 1756 | } |
| 1757 | } | 1757 | } |
| 1758 | }, { | 1758 | }, { |
| 1759 | .alg = "ctr(blowfish)", | ||
| 1760 | .test = alg_test_skcipher, | ||
| 1761 | .suite = { | ||
| 1762 | .cipher = { | ||
| 1763 | .enc = { | ||
| 1764 | .vecs = bf_ctr_enc_tv_template, | ||
| 1765 | .count = BF_CTR_ENC_TEST_VECTORS | ||
| 1766 | }, | ||
| 1767 | .dec = { | ||
| 1768 | .vecs = bf_ctr_dec_tv_template, | ||
| 1769 | .count = BF_CTR_DEC_TEST_VECTORS | ||
| 1770 | } | ||
| 1771 | } | ||
| 1772 | } | ||
| 1773 | }, { | ||
| 1774 | .alg = "ctr(twofish)", | ||
| 1775 | .test = alg_test_skcipher, | ||
| 1776 | .suite = { | ||
| 1777 | .cipher = { | ||
| 1778 | .enc = { | ||
| 1779 | .vecs = tf_ctr_enc_tv_template, | ||
| 1780 | .count = TF_CTR_ENC_TEST_VECTORS | ||
| 1781 | }, | ||
| 1782 | .dec = { | ||
| 1783 | .vecs = tf_ctr_dec_tv_template, | ||
| 1784 | .count = TF_CTR_DEC_TEST_VECTORS | ||
| 1785 | } | ||
| 1786 | } | ||
| 1787 | } | ||
| 1788 | }, { | ||
| 1759 | .alg = "cts(cbc(aes))", | 1789 | .alg = "cts(cbc(aes))", |
| 1760 | .test = alg_test_skcipher, | 1790 | .test = alg_test_skcipher, |
| 1761 | .suite = { | 1791 | .suite = { |
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 27adc92842ba..37b4d8f45447 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h | |||
| @@ -2391,10 +2391,12 @@ static struct cipher_testvec des3_ede_cbc_dec_tv_template[] = { | |||
| 2391 | /* | 2391 | /* |
| 2392 | * Blowfish test vectors. | 2392 | * Blowfish test vectors. |
| 2393 | */ | 2393 | */ |
| 2394 | #define BF_ENC_TEST_VECTORS 6 | 2394 | #define BF_ENC_TEST_VECTORS 7 |
| 2395 | #define BF_DEC_TEST_VECTORS 6 | 2395 | #define BF_DEC_TEST_VECTORS 7 |
| 2396 | #define BF_CBC_ENC_TEST_VECTORS 1 | 2396 | #define BF_CBC_ENC_TEST_VECTORS 2 |
| 2397 | #define BF_CBC_DEC_TEST_VECTORS 1 | 2397 | #define BF_CBC_DEC_TEST_VECTORS 2 |
| 2398 | #define BF_CTR_ENC_TEST_VECTORS 2 | ||
| 2399 | #define BF_CTR_DEC_TEST_VECTORS 2 | ||
| 2398 | 2400 | ||
| 2399 | static struct cipher_testvec bf_enc_tv_template[] = { | 2401 | static struct cipher_testvec bf_enc_tv_template[] = { |
| 2400 | { /* DES test vectors from OpenSSL */ | 2402 | { /* DES test vectors from OpenSSL */ |
| @@ -2448,6 +2450,24 @@ static struct cipher_testvec bf_enc_tv_template[] = { | |||
| 2448 | .ilen = 8, | 2450 | .ilen = 8, |
| 2449 | .result = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53", | 2451 | .result = "\xc0\x45\x04\x01\x2e\x4e\x1f\x53", |
| 2450 | .rlen = 8, | 2452 | .rlen = 8, |
| 2453 | }, { /* Generated with Crypto++ */ | ||
| 2454 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2455 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2456 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2457 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2458 | .klen = 32, | ||
| 2459 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2460 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2461 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2462 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2463 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9", | ||
| 2464 | .ilen = 40, | ||
| 2465 | .result = "\x96\x87\x3D\x0C\x7B\xFB\xBD\x1F" | ||
| 2466 | "\xE3\xC1\x99\x6D\x39\xD4\xC2\x7D" | ||
| 2467 | "\xD7\x87\xA1\xF2\xDF\x51\x71\x26" | ||
| 2468 | "\xC2\xF4\x6D\xFF\xF6\xCD\x6B\x40" | ||
| 2469 | "\xE1\xB3\xBF\xD4\x38\x2B\xC8\x3B", | ||
| 2470 | .rlen = 40, | ||
| 2451 | }, | 2471 | }, |
| 2452 | }; | 2472 | }; |
| 2453 | 2473 | ||
| @@ -2503,6 +2523,24 @@ static struct cipher_testvec bf_dec_tv_template[] = { | |||
| 2503 | .ilen = 8, | 2523 | .ilen = 8, |
| 2504 | .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10", | 2524 | .result = "\xfe\xdc\xba\x98\x76\x54\x32\x10", |
| 2505 | .rlen = 8, | 2525 | .rlen = 8, |
| 2526 | }, { /* Generated with Crypto++ */ | ||
| 2527 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2528 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2529 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2530 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2531 | .klen = 32, | ||
| 2532 | .input = "\x96\x87\x3D\x0C\x7B\xFB\xBD\x1F" | ||
| 2533 | "\xE3\xC1\x99\x6D\x39\xD4\xC2\x7D" | ||
| 2534 | "\xD7\x87\xA1\xF2\xDF\x51\x71\x26" | ||
| 2535 | "\xC2\xF4\x6D\xFF\xF6\xCD\x6B\x40" | ||
| 2536 | "\xE1\xB3\xBF\xD4\x38\x2B\xC8\x3B", | ||
| 2537 | .ilen = 40, | ||
| 2538 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2539 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2540 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2541 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2542 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9", | ||
| 2543 | .rlen = 40, | ||
| 2506 | }, | 2544 | }, |
| 2507 | }; | 2545 | }; |
| 2508 | 2546 | ||
| @@ -2522,6 +2560,25 @@ static struct cipher_testvec bf_cbc_enc_tv_template[] = { | |||
| 2522 | "\x58\xde\xb9\xe7\x15\x46\x16\xd9" | 2560 | "\x58\xde\xb9\xe7\x15\x46\x16\xd9" |
| 2523 | "\x59\xf1\x65\x2b\xd5\xff\x92\xcc", | 2561 | "\x59\xf1\x65\x2b\xd5\xff\x92\xcc", |
| 2524 | .rlen = 32, | 2562 | .rlen = 32, |
| 2563 | }, { /* Generated with Crypto++ */ | ||
| 2564 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2565 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2566 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2567 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2568 | .klen = 32, | ||
| 2569 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F", | ||
| 2570 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2571 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2572 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2573 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2574 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9", | ||
| 2575 | .ilen = 40, | ||
| 2576 | .result = "\xB4\xFE\xA5\xBB\x3D\x2C\x27\x06" | ||
| 2577 | "\x06\x2B\x3A\x92\xB2\xF5\x5E\x62" | ||
| 2578 | "\x84\xCD\xF7\x66\x7E\x41\x6C\x8E" | ||
| 2579 | "\x1B\xD9\x02\xB6\x48\xB0\x87\x25" | ||
| 2580 | "\x01\x9C\x93\x63\x51\x60\x82\xD2", | ||
| 2581 | .rlen = 40, | ||
| 2525 | }, | 2582 | }, |
| 2526 | }; | 2583 | }; |
| 2527 | 2584 | ||
| @@ -2541,16 +2598,125 @@ static struct cipher_testvec bf_cbc_dec_tv_template[] = { | |||
| 2541 | "\x68\x65\x20\x74\x69\x6d\x65\x20" | 2598 | "\x68\x65\x20\x74\x69\x6d\x65\x20" |
| 2542 | "\x66\x6f\x72\x20\x00\x00\x00\x00", | 2599 | "\x66\x6f\x72\x20\x00\x00\x00\x00", |
| 2543 | .rlen = 32, | 2600 | .rlen = 32, |
| 2601 | }, { /* Generated with Crypto++ */ | ||
| 2602 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2603 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2604 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2605 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2606 | .klen = 32, | ||
| 2607 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F", | ||
| 2608 | .input = "\xB4\xFE\xA5\xBB\x3D\x2C\x27\x06" | ||
| 2609 | "\x06\x2B\x3A\x92\xB2\xF5\x5E\x62" | ||
| 2610 | "\x84\xCD\xF7\x66\x7E\x41\x6C\x8E" | ||
| 2611 | "\x1B\xD9\x02\xB6\x48\xB0\x87\x25" | ||
| 2612 | "\x01\x9C\x93\x63\x51\x60\x82\xD2", | ||
| 2613 | .ilen = 40, | ||
| 2614 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2615 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2616 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2617 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2618 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9", | ||
| 2619 | .rlen = 40, | ||
| 2620 | }, | ||
| 2621 | }; | ||
| 2622 | |||
| 2623 | static struct cipher_testvec bf_ctr_enc_tv_template[] = { | ||
| 2624 | { /* Generated with Crypto++ */ | ||
| 2625 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2626 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2627 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2628 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2629 | .klen = 32, | ||
| 2630 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F", | ||
| 2631 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2632 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2633 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2634 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2635 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9", | ||
| 2636 | .ilen = 40, | ||
| 2637 | .result = "\xC7\xA3\xDF\xB9\x05\xF4\x9E\x8D" | ||
| 2638 | "\x9E\xDF\x38\x18\x83\x07\xEF\xC1" | ||
| 2639 | "\x93\x3C\xAA\xAA\xFE\x06\x42\xCC" | ||
| 2640 | "\x0D\x70\x86\x5A\x44\xAD\x85\x17" | ||
| 2641 | "\xE4\x1F\x5E\xA5\x89\xAC\x32\xBC", | ||
| 2642 | .rlen = 40, | ||
| 2643 | }, { /* Generated with Crypto++ */ | ||
| 2644 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2645 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2646 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2647 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2648 | .klen = 32, | ||
| 2649 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F", | ||
| 2650 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2651 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2652 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2653 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2654 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2655 | "\x6D\x04\x9B", | ||
| 2656 | .ilen = 43, | ||
| 2657 | .result = "\xC7\xA3\xDF\xB9\x05\xF4\x9E\x8D" | ||
| 2658 | "\x9E\xDF\x38\x18\x83\x07\xEF\xC1" | ||
| 2659 | "\x93\x3C\xAA\xAA\xFE\x06\x42\xCC" | ||
| 2660 | "\x0D\x70\x86\x5A\x44\xAD\x85\x17" | ||
| 2661 | "\xE4\x1F\x5E\xA5\x89\xAC\x32\xBC" | ||
| 2662 | "\x3D\xA7\xE9", | ||
| 2663 | .rlen = 43, | ||
| 2664 | }, | ||
| 2665 | }; | ||
| 2666 | |||
| 2667 | static struct cipher_testvec bf_ctr_dec_tv_template[] = { | ||
| 2668 | { /* Generated with Crypto++ */ | ||
| 2669 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2670 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2671 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2672 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2673 | .klen = 32, | ||
| 2674 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F", | ||
| 2675 | .input = "\xC7\xA3\xDF\xB9\x05\xF4\x9E\x8D" | ||
| 2676 | "\x9E\xDF\x38\x18\x83\x07\xEF\xC1" | ||
| 2677 | "\x93\x3C\xAA\xAA\xFE\x06\x42\xCC" | ||
| 2678 | "\x0D\x70\x86\x5A\x44\xAD\x85\x17" | ||
| 2679 | "\xE4\x1F\x5E\xA5\x89\xAC\x32\xBC", | ||
| 2680 | .ilen = 40, | ||
| 2681 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2682 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2683 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2684 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2685 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9", | ||
| 2686 | .rlen = 40, | ||
| 2687 | }, { /* Generated with Crypto++ */ | ||
| 2688 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2689 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2690 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2691 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2692 | .klen = 32, | ||
| 2693 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F", | ||
| 2694 | .input = "\xC7\xA3\xDF\xB9\x05\xF4\x9E\x8D" | ||
| 2695 | "\x9E\xDF\x38\x18\x83\x07\xEF\xC1" | ||
| 2696 | "\x93\x3C\xAA\xAA\xFE\x06\x42\xCC" | ||
| 2697 | "\x0D\x70\x86\x5A\x44\xAD\x85\x17" | ||
| 2698 | "\xE4\x1F\x5E\xA5\x89\xAC\x32\xBC" | ||
| 2699 | "\x3D\xA7\xE9", | ||
| 2700 | .ilen = 43, | ||
| 2701 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2702 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2703 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2704 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2705 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2706 | "\x6D\x04\x9B", | ||
| 2707 | .rlen = 43, | ||
| 2544 | }, | 2708 | }, |
| 2545 | }; | 2709 | }; |
| 2546 | 2710 | ||
| 2547 | /* | 2711 | /* |
| 2548 | * Twofish test vectors. | 2712 | * Twofish test vectors. |
| 2549 | */ | 2713 | */ |
| 2550 | #define TF_ENC_TEST_VECTORS 3 | 2714 | #define TF_ENC_TEST_VECTORS 4 |
| 2551 | #define TF_DEC_TEST_VECTORS 3 | 2715 | #define TF_DEC_TEST_VECTORS 4 |
| 2552 | #define TF_CBC_ENC_TEST_VECTORS 4 | 2716 | #define TF_CBC_ENC_TEST_VECTORS 5 |
| 2553 | #define TF_CBC_DEC_TEST_VECTORS 4 | 2717 | #define TF_CBC_DEC_TEST_VECTORS 5 |
| 2718 | #define TF_CTR_ENC_TEST_VECTORS 2 | ||
| 2719 | #define TF_CTR_DEC_TEST_VECTORS 2 | ||
| 2554 | 2720 | ||
| 2555 | static struct cipher_testvec tf_enc_tv_template[] = { | 2721 | static struct cipher_testvec tf_enc_tv_template[] = { |
| 2556 | { | 2722 | { |
| @@ -2582,6 +2748,30 @@ static struct cipher_testvec tf_enc_tv_template[] = { | |||
| 2582 | .result = "\x37\x52\x7b\xe0\x05\x23\x34\xb8" | 2748 | .result = "\x37\x52\x7b\xe0\x05\x23\x34\xb8" |
| 2583 | "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20", | 2749 | "\x9f\x0c\xfc\xca\xe8\x7c\xfa\x20", |
| 2584 | .rlen = 16, | 2750 | .rlen = 16, |
| 2751 | }, { /* Generated with Crypto++ */ | ||
| 2752 | .key = "\x3F\x85\x62\x3F\x1C\xF9\xD6\x1C" | ||
| 2753 | "\xF9\xD6\xB3\x90\x6D\x4A\x90\x6D" | ||
| 2754 | "\x4A\x27\x04\xE1\x27\x04\xE1\xBE" | ||
| 2755 | "\x9B\x78\xBE\x9B\x78\x55\x32\x0F", | ||
| 2756 | .klen = 32, | ||
| 2757 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2758 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2759 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2760 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2761 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2762 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 2763 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 2764 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", | ||
| 2765 | .ilen = 64, | ||
| 2766 | .result = "\x88\xCB\x1E\xC2\xAF\x8A\x97\xFF" | ||
| 2767 | "\xF6\x90\x46\x9C\x4A\x0F\x08\xDC" | ||
| 2768 | "\xDE\xAB\xAD\xFA\xFC\xA8\xC2\x3D" | ||
| 2769 | "\xE0\xE4\x8B\x3F\xD5\xA3\xF7\x14" | ||
| 2770 | "\x34\x9E\xB6\x08\xB2\xDD\xA8\xF5" | ||
| 2771 | "\xDF\xFA\xC7\xE8\x09\x50\x76\x08" | ||
| 2772 | "\xA2\xB6\x6A\x59\xC0\x2B\x6D\x05" | ||
| 2773 | "\x89\xF6\x82\xF0\xD3\xDB\x06\x02", | ||
| 2774 | .rlen = 64, | ||
| 2585 | }, | 2775 | }, |
| 2586 | }; | 2776 | }; |
| 2587 | 2777 | ||
| @@ -2615,6 +2805,30 @@ static struct cipher_testvec tf_dec_tv_template[] = { | |||
| 2615 | .ilen = 16, | 2805 | .ilen = 16, |
| 2616 | .result = zeroed_string, | 2806 | .result = zeroed_string, |
| 2617 | .rlen = 16, | 2807 | .rlen = 16, |
| 2808 | }, { /* Generated with Crypto++ */ | ||
| 2809 | .key = "\x3F\x85\x62\x3F\x1C\xF9\xD6\x1C" | ||
| 2810 | "\xF9\xD6\xB3\x90\x6D\x4A\x90\x6D" | ||
| 2811 | "\x4A\x27\x04\xE1\x27\x04\xE1\xBE" | ||
| 2812 | "\x9B\x78\xBE\x9B\x78\x55\x32\x0F", | ||
| 2813 | .klen = 32, | ||
| 2814 | .input = "\x88\xCB\x1E\xC2\xAF\x8A\x97\xFF" | ||
| 2815 | "\xF6\x90\x46\x9C\x4A\x0F\x08\xDC" | ||
| 2816 | "\xDE\xAB\xAD\xFA\xFC\xA8\xC2\x3D" | ||
| 2817 | "\xE0\xE4\x8B\x3F\xD5\xA3\xF7\x14" | ||
| 2818 | "\x34\x9E\xB6\x08\xB2\xDD\xA8\xF5" | ||
| 2819 | "\xDF\xFA\xC7\xE8\x09\x50\x76\x08" | ||
| 2820 | "\xA2\xB6\x6A\x59\xC0\x2B\x6D\x05" | ||
| 2821 | "\x89\xF6\x82\xF0\xD3\xDB\x06\x02", | ||
| 2822 | .ilen = 64, | ||
| 2823 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2824 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2825 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2826 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2827 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2828 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 2829 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 2830 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", | ||
| 2831 | .rlen = 64, | ||
| 2618 | }, | 2832 | }, |
| 2619 | }; | 2833 | }; |
| 2620 | 2834 | ||
| @@ -2661,6 +2875,32 @@ static struct cipher_testvec tf_cbc_enc_tv_template[] = { | |||
| 2661 | "\x05\xef\x8c\x61\xa8\x11\x58\x26" | 2875 | "\x05\xef\x8c\x61\xa8\x11\x58\x26" |
| 2662 | "\x34\xba\x5c\xb7\x10\x6a\xa6\x41", | 2876 | "\x34\xba\x5c\xb7\x10\x6a\xa6\x41", |
| 2663 | .rlen = 48, | 2877 | .rlen = 48, |
| 2878 | }, { /* Generated with Crypto++ */ | ||
| 2879 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2880 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2881 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2882 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2883 | .klen = 32, | ||
| 2884 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F" | ||
| 2885 | "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64", | ||
| 2886 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2887 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2888 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2889 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2890 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2891 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 2892 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 2893 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", | ||
| 2894 | .ilen = 64, | ||
| 2895 | .result = "\xC8\xFF\xF2\x53\xA6\x27\x09\xD1" | ||
| 2896 | "\x33\x38\xC2\xC0\x0C\x14\x7E\xB5" | ||
| 2897 | "\x26\x1B\x05\x0C\x05\x12\x3F\xC0" | ||
| 2898 | "\xF9\x1C\x02\x28\x40\x96\x6F\xD0" | ||
| 2899 | "\x3D\x32\xDF\xDA\x56\x00\x6E\xEE" | ||
| 2900 | "\x5B\x2A\x72\x9D\xC2\x4D\x19\xBC" | ||
| 2901 | "\x8C\x53\xFA\x87\x6F\xDD\x81\xA3" | ||
| 2902 | "\xB1\xD3\x44\x65\xDF\xE7\x63\x38", | ||
| 2903 | .rlen = 64, | ||
| 2664 | }, | 2904 | }, |
| 2665 | }; | 2905 | }; |
| 2666 | 2906 | ||
| @@ -2707,6 +2947,148 @@ static struct cipher_testvec tf_cbc_dec_tv_template[] = { | |||
| 2707 | .ilen = 48, | 2947 | .ilen = 48, |
| 2708 | .result = zeroed_string, | 2948 | .result = zeroed_string, |
| 2709 | .rlen = 48, | 2949 | .rlen = 48, |
| 2950 | }, { /* Generated with Crypto++ */ | ||
| 2951 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2952 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2953 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2954 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2955 | .klen = 32, | ||
| 2956 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F" | ||
| 2957 | "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64", | ||
| 2958 | .input = "\xC8\xFF\xF2\x53\xA6\x27\x09\xD1" | ||
| 2959 | "\x33\x38\xC2\xC0\x0C\x14\x7E\xB5" | ||
| 2960 | "\x26\x1B\x05\x0C\x05\x12\x3F\xC0" | ||
| 2961 | "\xF9\x1C\x02\x28\x40\x96\x6F\xD0" | ||
| 2962 | "\x3D\x32\xDF\xDA\x56\x00\x6E\xEE" | ||
| 2963 | "\x5B\x2A\x72\x9D\xC2\x4D\x19\xBC" | ||
| 2964 | "\x8C\x53\xFA\x87\x6F\xDD\x81\xA3" | ||
| 2965 | "\xB1\xD3\x44\x65\xDF\xE7\x63\x38", | ||
| 2966 | .ilen = 64, | ||
| 2967 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2968 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2969 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2970 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2971 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2972 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 2973 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 2974 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", | ||
| 2975 | .rlen = 64, | ||
| 2976 | }, | ||
| 2977 | }; | ||
| 2978 | |||
| 2979 | static struct cipher_testvec tf_ctr_enc_tv_template[] = { | ||
| 2980 | { /* Generated with Crypto++ */ | ||
| 2981 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 2982 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 2983 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 2984 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 2985 | .klen = 32, | ||
| 2986 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F" | ||
| 2987 | "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64", | ||
| 2988 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 2989 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 2990 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 2991 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 2992 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 2993 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 2994 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 2995 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", | ||
| 2996 | .ilen = 64, | ||
| 2997 | .result = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE" | ||
| 2998 | "\x70\x9E\xC5\x4B\xC9\xD4\xA1\x30" | ||
| 2999 | "\x26\x9B\x89\xA1\xEE\x43\xE0\x52" | ||
| 3000 | "\x55\x17\x4E\xC7\x0E\x33\x1F\xF1" | ||
| 3001 | "\x9F\x8D\x40\x9F\x24\xFD\x92\xA0" | ||
| 3002 | "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" | ||
| 3003 | "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" | ||
| 3004 | "\x01\x41\x21\x12\x38\xAB\x52\x4F", | ||
| 3005 | .rlen = 64, | ||
| 3006 | }, { /* Generated with Crypto++ */ | ||
| 3007 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 3008 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 3009 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 3010 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 3011 | .klen = 32, | ||
| 3012 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F" | ||
| 3013 | "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64", | ||
| 3014 | .input = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 3015 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 3016 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 3017 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 3018 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 3019 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 3020 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 3021 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" | ||
| 3022 | "\xC3\x37\xCE", | ||
| 3023 | .ilen = 67, | ||
| 3024 | .result = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE" | ||
| 3025 | "\x70\x9E\xC5\x4B\xC9\xD4\xA1\x30" | ||
| 3026 | "\x26\x9B\x89\xA1\xEE\x43\xE0\x52" | ||
| 3027 | "\x55\x17\x4E\xC7\x0E\x33\x1F\xF1" | ||
| 3028 | "\x9F\x8D\x40\x9F\x24\xFD\x92\xA0" | ||
| 3029 | "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" | ||
| 3030 | "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" | ||
| 3031 | "\x01\x41\x21\x12\x38\xAB\x52\x4F" | ||
| 3032 | "\xA8\x57\x20", | ||
| 3033 | .rlen = 67, | ||
| 3034 | }, | ||
| 3035 | }; | ||
| 3036 | |||
| 3037 | static struct cipher_testvec tf_ctr_dec_tv_template[] = { | ||
| 3038 | { /* Generated with Crypto++ */ | ||
| 3039 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 3040 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 3041 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 3042 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 3043 | .klen = 32, | ||
| 3044 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F" | ||
| 3045 | "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64", | ||
| 3046 | .input = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE" | ||
| 3047 | "\x70\x9E\xC5\x4B\xC9\xD4\xA1\x30" | ||
| 3048 | "\x26\x9B\x89\xA1\xEE\x43\xE0\x52" | ||
| 3049 | "\x55\x17\x4E\xC7\x0E\x33\x1F\xF1" | ||
| 3050 | "\x9F\x8D\x40\x9F\x24\xFD\x92\xA0" | ||
| 3051 | "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" | ||
| 3052 | "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" | ||
| 3053 | "\x01\x41\x21\x12\x38\xAB\x52\x4F", | ||
| 3054 | .ilen = 64, | ||
| 3055 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 3056 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 3057 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 3058 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 3059 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 3060 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 3061 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 3062 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C", | ||
| 3063 | .rlen = 64, | ||
| 3064 | }, { /* Generated with Crypto++ */ | ||
| 3065 | .key = "\x85\x62\x3F\x1C\xF9\xD6\x1C\xF9" | ||
| 3066 | "\xD6\xB3\x90\x6D\x4A\x90\x6D\x4A" | ||
| 3067 | "\x27\x04\xE1\x27\x04\xE1\xBE\x9B" | ||
| 3068 | "\x78\xBE\x9B\x78\x55\x32\x0F\x55", | ||
| 3069 | .klen = 32, | ||
| 3070 | .iv = "\xE2\x24\x89\xEE\x53\xB8\x1D\x5F" | ||
| 3071 | "\xC4\x29\x8E\xF3\x35\x9A\xFF\x64", | ||
| 3072 | .input = "\xDF\xDD\x69\xFA\xB0\x2E\xFD\xFE" | ||
| 3073 | "\x70\x9E\xC5\x4B\xC9\xD4\xA1\x30" | ||
| 3074 | "\x26\x9B\x89\xA1\xEE\x43\xE0\x52" | ||
| 3075 | "\x55\x17\x4E\xC7\x0E\x33\x1F\xF1" | ||
| 3076 | "\x9F\x8D\x40\x9F\x24\xFD\x92\xA0" | ||
| 3077 | "\xBC\x8F\x35\xDD\x67\x38\xD8\xAA" | ||
| 3078 | "\xCF\xF8\x48\xCA\xFB\xE4\x5C\x60" | ||
| 3079 | "\x01\x41\x21\x12\x38\xAB\x52\x4F" | ||
| 3080 | "\xA8\x57\x20", | ||
| 3081 | .ilen = 67, | ||
| 3082 | .result = "\x56\xED\x84\x1B\x8F\x26\xBD\x31" | ||
| 3083 | "\xC8\x5F\xF6\x6A\x01\x98\x0C\xA3" | ||
| 3084 | "\x3A\xD1\x45\xDC\x73\x0A\x7E\x15" | ||
| 3085 | "\xAC\x20\xB7\x4E\xE5\x59\xF0\x87" | ||
| 3086 | "\x1E\x92\x29\xC0\x34\xCB\x62\xF9" | ||
| 3087 | "\x6D\x04\x9B\x0F\xA6\x3D\xD4\x48" | ||
| 3088 | "\xDF\x76\x0D\x81\x18\xAF\x23\xBA" | ||
| 3089 | "\x51\xE8\x5C\xF3\x8A\x21\x95\x2C" | ||
| 3090 | "\xC3\x37\xCE", | ||
| 3091 | .rlen = 67, | ||
| 2710 | }, | 3092 | }, |
| 2711 | }; | 3093 | }; |
| 2712 | 3094 | ||
diff --git a/crypto/wp512.c b/crypto/wp512.c index 723427273687..71719a2be25a 100644 --- a/crypto/wp512.c +++ b/crypto/wp512.c | |||
| @@ -762,11 +762,17 @@ static const u64 C7[256] = { | |||
| 762 | 0x86228644a411c286ULL, | 762 | 0x86228644a411c286ULL, |
| 763 | }; | 763 | }; |
| 764 | 764 | ||
| 765 | static const u64 rc[WHIRLPOOL_ROUNDS + 1] = { | 765 | static const u64 rc[WHIRLPOOL_ROUNDS] = { |
| 766 | 0x0000000000000000ULL, 0x1823c6e887b8014fULL, 0x36a6d2f5796f9152ULL, | 766 | 0x1823c6e887b8014fULL, |
| 767 | 0x60bc9b8ea30c7b35ULL, 0x1de0d7c22e4bfe57ULL, 0x157737e59ff04adaULL, | 767 | 0x36a6d2f5796f9152ULL, |
| 768 | 0x58c9290ab1a06b85ULL, 0xbd5d10f4cb3e0567ULL, 0xe427418ba77d95d8ULL, | 768 | 0x60bc9b8ea30c7b35ULL, |
| 769 | 0xfbee7c66dd17479eULL, 0xca2dbf07ad5a8333ULL, | 769 | 0x1de0d7c22e4bfe57ULL, |
| 770 | 0x157737e59ff04adaULL, | ||
| 771 | 0x58c9290ab1a06b85ULL, | ||
| 772 | 0xbd5d10f4cb3e0567ULL, | ||
| 773 | 0xe427418ba77d95d8ULL, | ||
| 774 | 0xfbee7c66dd17479eULL, | ||
| 775 | 0xca2dbf07ad5a8333ULL, | ||
| 770 | }; | 776 | }; |
| 771 | 777 | ||
| 772 | /** | 778 | /** |
| @@ -793,7 +799,7 @@ static void wp512_process_buffer(struct wp512_ctx *wctx) { | |||
| 793 | state[6] = block[6] ^ (K[6] = wctx->hash[6]); | 799 | state[6] = block[6] ^ (K[6] = wctx->hash[6]); |
| 794 | state[7] = block[7] ^ (K[7] = wctx->hash[7]); | 800 | state[7] = block[7] ^ (K[7] = wctx->hash[7]); |
| 795 | 801 | ||
| 796 | for (r = 1; r <= WHIRLPOOL_ROUNDS; r++) { | 802 | for (r = 0; r < WHIRLPOOL_ROUNDS; r++) { |
| 797 | 803 | ||
| 798 | L[0] = C0[(int)(K[0] >> 56) ] ^ | 804 | L[0] = C0[(int)(K[0] >> 56) ] ^ |
| 799 | C1[(int)(K[7] >> 48) & 0xff] ^ | 805 | C1[(int)(K[7] >> 48) & 0xff] ^ |
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index e0b25de1e339..6d16b4b0d7a0 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig | |||
| @@ -200,6 +200,7 @@ config CRYPTO_DEV_HIFN_795X | |||
| 200 | select CRYPTO_BLKCIPHER | 200 | select CRYPTO_BLKCIPHER |
| 201 | select HW_RANDOM if CRYPTO_DEV_HIFN_795X_RNG | 201 | select HW_RANDOM if CRYPTO_DEV_HIFN_795X_RNG |
| 202 | depends on PCI | 202 | depends on PCI |
| 203 | depends on !ARCH_DMA_ADDR_T_64BIT | ||
| 203 | help | 204 | help |
| 204 | This option allows you to have support for HIFN 795x crypto adapters. | 205 | This option allows you to have support for HIFN 795x crypto adapters. |
| 205 | 206 | ||
| @@ -266,7 +267,7 @@ config CRYPTO_DEV_OMAP_AES | |||
| 266 | 267 | ||
| 267 | config CRYPTO_DEV_PICOXCELL | 268 | config CRYPTO_DEV_PICOXCELL |
| 268 | tristate "Support for picoXcell IPSEC and Layer2 crypto engines" | 269 | tristate "Support for picoXcell IPSEC and Layer2 crypto engines" |
| 269 | depends on ARCH_PICOXCELL | 270 | depends on ARCH_PICOXCELL && HAVE_CLK |
| 270 | select CRYPTO_AES | 271 | select CRYPTO_AES |
| 271 | select CRYPTO_AUTHENC | 272 | select CRYPTO_AUTHENC |
| 272 | select CRYPTO_ALGAPI | 273 | select CRYPTO_ALGAPI |
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index a84250a5dd51..fe765f49de58 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c | |||
| @@ -2744,10 +2744,8 @@ static int __init hifn_init(void) | |||
| 2744 | unsigned int freq; | 2744 | unsigned int freq; |
| 2745 | int err; | 2745 | int err; |
| 2746 | 2746 | ||
| 2747 | if (sizeof(dma_addr_t) > 4) { | 2747 | /* HIFN supports only 32-bit addresses */ |
| 2748 | printk(KERN_INFO "HIFN supports only 32-bit addresses.\n"); | 2748 | BUILD_BUG_ON(sizeof(dma_addr_t) != 4); |
| 2749 | return -EINVAL; | ||
| 2750 | } | ||
| 2751 | 2749 | ||
| 2752 | if (strncmp(hifn_pll_ref, "ext", 3) && | 2750 | if (strncmp(hifn_pll_ref, "ext", 3) && |
| 2753 | strncmp(hifn_pll_ref, "pci", 3)) { | 2751 | strncmp(hifn_pll_ref, "pci", 3)) { |
diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index d0183ddb3076..8944dabc0e3c 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c | |||
| @@ -1006,9 +1006,9 @@ static int n2_do_ecb(struct ablkcipher_request *req, bool encrypt) | |||
| 1006 | 1006 | ||
| 1007 | spin_unlock_irqrestore(&qp->lock, flags); | 1007 | spin_unlock_irqrestore(&qp->lock, flags); |
| 1008 | 1008 | ||
| 1009 | out: | ||
| 1009 | put_cpu(); | 1010 | put_cpu(); |
| 1010 | 1011 | ||
| 1011 | out: | ||
| 1012 | n2_chunk_complete(req, NULL); | 1012 | n2_chunk_complete(req, NULL); |
| 1013 | return err; | 1013 | return err; |
| 1014 | } | 1014 | } |
| @@ -1096,9 +1096,9 @@ static int n2_do_chaining(struct ablkcipher_request *req, bool encrypt) | |||
| 1096 | 1096 | ||
| 1097 | spin_unlock_irqrestore(&qp->lock, flags); | 1097 | spin_unlock_irqrestore(&qp->lock, flags); |
| 1098 | 1098 | ||
| 1099 | out: | ||
| 1099 | put_cpu(); | 1100 | put_cpu(); |
| 1100 | 1101 | ||
| 1101 | out: | ||
| 1102 | n2_chunk_complete(req, err ? NULL : final_iv_addr); | 1102 | n2_chunk_complete(req, err ? NULL : final_iv_addr); |
| 1103 | return err; | 1103 | return err; |
| 1104 | } | 1104 | } |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index db33d300aa23..29b9469f8378 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
| @@ -508,10 +508,8 @@ static int __init padlock_init(void) | |||
| 508 | int ret; | 508 | int ret; |
| 509 | struct cpuinfo_x86 *c = &cpu_data(0); | 509 | struct cpuinfo_x86 *c = &cpu_data(0); |
| 510 | 510 | ||
| 511 | if (!cpu_has_xcrypt) { | 511 | if (!cpu_has_xcrypt) |
| 512 | printk(KERN_NOTICE PFX "VIA PadLock not detected.\n"); | ||
| 513 | return -ENODEV; | 512 | return -ENODEV; |
| 514 | } | ||
| 515 | 513 | ||
| 516 | if (!cpu_has_xcrypt_enabled) { | 514 | if (!cpu_has_xcrypt_enabled) { |
| 517 | printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); | 515 | printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); |
diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c index 230b5b8cda1f..a2b553eabbdb 100644 --- a/drivers/crypto/picoxcell_crypto.c +++ b/drivers/crypto/picoxcell_crypto.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/io.h> | 34 | #include <linux/io.h> |
| 35 | #include <linux/list.h> | 35 | #include <linux/list.h> |
| 36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
| 37 | #include <linux/of.h> | ||
| 37 | #include <linux/platform_device.h> | 38 | #include <linux/platform_device.h> |
| 38 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
| 39 | #include <linux/rtnetlink.h> | 40 | #include <linux/rtnetlink.h> |
| @@ -1241,8 +1242,8 @@ static void spacc_spacc_complete(unsigned long data) | |||
| 1241 | spin_unlock_irqrestore(&engine->hw_lock, flags); | 1242 | spin_unlock_irqrestore(&engine->hw_lock, flags); |
| 1242 | 1243 | ||
| 1243 | list_for_each_entry_safe(req, tmp, &completed, list) { | 1244 | list_for_each_entry_safe(req, tmp, &completed, list) { |
| 1244 | req->complete(req); | ||
| 1245 | list_del(&req->list); | 1245 | list_del(&req->list); |
| 1246 | req->complete(req); | ||
| 1246 | } | 1247 | } |
| 1247 | } | 1248 | } |
| 1248 | 1249 | ||
| @@ -1657,10 +1658,33 @@ static struct spacc_alg l2_engine_algs[] = { | |||
| 1657 | }, | 1658 | }, |
| 1658 | }; | 1659 | }; |
| 1659 | 1660 | ||
| 1660 | static int __devinit spacc_probe(struct platform_device *pdev, | 1661 | #ifdef CONFIG_OF |
| 1661 | unsigned max_ctxs, size_t cipher_pg_sz, | 1662 | static const struct of_device_id spacc_of_id_table[] = { |
| 1662 | size_t hash_pg_sz, size_t fifo_sz, | 1663 | { .compatible = "picochip,spacc-ipsec" }, |
| 1663 | struct spacc_alg *algs, size_t num_algs) | 1664 | { .compatible = "picochip,spacc-l2" }, |
| 1665 | {} | ||
| 1666 | }; | ||
| 1667 | #else /* CONFIG_OF */ | ||
| 1668 | #define spacc_of_id_table NULL | ||
| 1669 | #endif /* CONFIG_OF */ | ||
| 1670 | |||
| 1671 | static bool spacc_is_compatible(struct platform_device *pdev, | ||
| 1672 | const char *spacc_type) | ||
| 1673 | { | ||
| 1674 | const struct platform_device_id *platid = platform_get_device_id(pdev); | ||
| 1675 | |||
| 1676 | if (platid && !strcmp(platid->name, spacc_type)) | ||
| 1677 | return true; | ||
| 1678 | |||
| 1679 | #ifdef CONFIG_OF | ||
| 1680 | if (of_device_is_compatible(pdev->dev.of_node, spacc_type)) | ||
| 1681 | return true; | ||
| 1682 | #endif /* CONFIG_OF */ | ||
| 1683 | |||
| 1684 | return false; | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | static int __devinit spacc_probe(struct platform_device *pdev) | ||
| 1664 | { | 1688 | { |
| 1665 | int i, err, ret = -EINVAL; | 1689 | int i, err, ret = -EINVAL; |
| 1666 | struct resource *mem, *irq; | 1690 | struct resource *mem, *irq; |
| @@ -1669,13 +1693,25 @@ static int __devinit spacc_probe(struct platform_device *pdev, | |||
| 1669 | if (!engine) | 1693 | if (!engine) |
| 1670 | return -ENOMEM; | 1694 | return -ENOMEM; |
| 1671 | 1695 | ||
| 1672 | engine->max_ctxs = max_ctxs; | 1696 | if (spacc_is_compatible(pdev, "picochip,spacc-ipsec")) { |
| 1673 | engine->cipher_pg_sz = cipher_pg_sz; | 1697 | engine->max_ctxs = SPACC_CRYPTO_IPSEC_MAX_CTXS; |
| 1674 | engine->hash_pg_sz = hash_pg_sz; | 1698 | engine->cipher_pg_sz = SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ; |
| 1675 | engine->fifo_sz = fifo_sz; | 1699 | engine->hash_pg_sz = SPACC_CRYPTO_IPSEC_HASH_PG_SZ; |
| 1676 | engine->algs = algs; | 1700 | engine->fifo_sz = SPACC_CRYPTO_IPSEC_FIFO_SZ; |
| 1677 | engine->num_algs = num_algs; | 1701 | engine->algs = ipsec_engine_algs; |
| 1678 | engine->name = dev_name(&pdev->dev); | 1702 | engine->num_algs = ARRAY_SIZE(ipsec_engine_algs); |
| 1703 | } else if (spacc_is_compatible(pdev, "picochip,spacc-l2")) { | ||
| 1704 | engine->max_ctxs = SPACC_CRYPTO_L2_MAX_CTXS; | ||
| 1705 | engine->cipher_pg_sz = SPACC_CRYPTO_L2_CIPHER_PG_SZ; | ||
| 1706 | engine->hash_pg_sz = SPACC_CRYPTO_L2_HASH_PG_SZ; | ||
| 1707 | engine->fifo_sz = SPACC_CRYPTO_L2_FIFO_SZ; | ||
| 1708 | engine->algs = l2_engine_algs; | ||
| 1709 | engine->num_algs = ARRAY_SIZE(l2_engine_algs); | ||
| 1710 | } else { | ||
| 1711 | return -EINVAL; | ||
| 1712 | } | ||
| 1713 | |||
| 1714 | engine->name = dev_name(&pdev->dev); | ||
| 1679 | 1715 | ||
| 1680 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1716 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1681 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1717 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
| @@ -1711,7 +1747,7 @@ static int __devinit spacc_probe(struct platform_device *pdev, | |||
| 1711 | 1747 | ||
| 1712 | spin_lock_init(&engine->hw_lock); | 1748 | spin_lock_init(&engine->hw_lock); |
| 1713 | 1749 | ||
| 1714 | engine->clk = clk_get(&pdev->dev, NULL); | 1750 | engine->clk = clk_get(&pdev->dev, "ref"); |
| 1715 | if (IS_ERR(engine->clk)) { | 1751 | if (IS_ERR(engine->clk)) { |
| 1716 | dev_info(&pdev->dev, "clk unavailable\n"); | 1752 | dev_info(&pdev->dev, "clk unavailable\n"); |
| 1717 | device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh); | 1753 | device_remove_file(&pdev->dev, &dev_attr_stat_irq_thresh); |
| @@ -1800,72 +1836,33 @@ static int __devexit spacc_remove(struct platform_device *pdev) | |||
| 1800 | return 0; | 1836 | return 0; |
| 1801 | } | 1837 | } |
| 1802 | 1838 | ||
| 1803 | static int __devinit ipsec_probe(struct platform_device *pdev) | 1839 | static const struct platform_device_id spacc_id_table[] = { |
| 1804 | { | 1840 | { "picochip,spacc-ipsec", }, |
| 1805 | return spacc_probe(pdev, SPACC_CRYPTO_IPSEC_MAX_CTXS, | 1841 | { "picochip,spacc-l2", }, |
| 1806 | SPACC_CRYPTO_IPSEC_CIPHER_PG_SZ, | ||
| 1807 | SPACC_CRYPTO_IPSEC_HASH_PG_SZ, | ||
| 1808 | SPACC_CRYPTO_IPSEC_FIFO_SZ, ipsec_engine_algs, | ||
| 1809 | ARRAY_SIZE(ipsec_engine_algs)); | ||
| 1810 | } | ||
| 1811 | |||
| 1812 | static struct platform_driver ipsec_driver = { | ||
| 1813 | .probe = ipsec_probe, | ||
| 1814 | .remove = __devexit_p(spacc_remove), | ||
| 1815 | .driver = { | ||
| 1816 | .name = "picoxcell-ipsec", | ||
| 1817 | #ifdef CONFIG_PM | ||
| 1818 | .pm = &spacc_pm_ops, | ||
| 1819 | #endif /* CONFIG_PM */ | ||
| 1820 | }, | ||
| 1821 | }; | 1842 | }; |
| 1822 | 1843 | ||
| 1823 | static int __devinit l2_probe(struct platform_device *pdev) | 1844 | static struct platform_driver spacc_driver = { |
| 1824 | { | 1845 | .probe = spacc_probe, |
| 1825 | return spacc_probe(pdev, SPACC_CRYPTO_L2_MAX_CTXS, | ||
| 1826 | SPACC_CRYPTO_L2_CIPHER_PG_SZ, | ||
| 1827 | SPACC_CRYPTO_L2_HASH_PG_SZ, SPACC_CRYPTO_L2_FIFO_SZ, | ||
| 1828 | l2_engine_algs, ARRAY_SIZE(l2_engine_algs)); | ||
| 1829 | } | ||
| 1830 | |||
| 1831 | static struct platform_driver l2_driver = { | ||
| 1832 | .probe = l2_probe, | ||
| 1833 | .remove = __devexit_p(spacc_remove), | 1846 | .remove = __devexit_p(spacc_remove), |
| 1834 | .driver = { | 1847 | .driver = { |
| 1835 | .name = "picoxcell-l2", | 1848 | .name = "picochip,spacc", |
| 1836 | #ifdef CONFIG_PM | 1849 | #ifdef CONFIG_PM |
| 1837 | .pm = &spacc_pm_ops, | 1850 | .pm = &spacc_pm_ops, |
| 1838 | #endif /* CONFIG_PM */ | 1851 | #endif /* CONFIG_PM */ |
| 1852 | .of_match_table = spacc_of_id_table, | ||
| 1839 | }, | 1853 | }, |
| 1854 | .id_table = spacc_id_table, | ||
| 1840 | }; | 1855 | }; |
| 1841 | 1856 | ||
| 1842 | static int __init spacc_init(void) | 1857 | static int __init spacc_init(void) |
| 1843 | { | 1858 | { |
| 1844 | int ret = platform_driver_register(&ipsec_driver); | 1859 | return platform_driver_register(&spacc_driver); |
| 1845 | if (ret) { | ||
| 1846 | pr_err("failed to register ipsec spacc driver"); | ||
| 1847 | goto out; | ||
| 1848 | } | ||
| 1849 | |||
| 1850 | ret = platform_driver_register(&l2_driver); | ||
| 1851 | if (ret) { | ||
| 1852 | pr_err("failed to register l2 spacc driver"); | ||
| 1853 | goto l2_failed; | ||
| 1854 | } | ||
| 1855 | |||
| 1856 | return 0; | ||
| 1857 | |||
| 1858 | l2_failed: | ||
| 1859 | platform_driver_unregister(&ipsec_driver); | ||
| 1860 | out: | ||
| 1861 | return ret; | ||
| 1862 | } | 1860 | } |
| 1863 | module_init(spacc_init); | 1861 | module_init(spacc_init); |
| 1864 | 1862 | ||
| 1865 | static void __exit spacc_exit(void) | 1863 | static void __exit spacc_exit(void) |
| 1866 | { | 1864 | { |
| 1867 | platform_driver_unregister(&ipsec_driver); | 1865 | platform_driver_unregister(&spacc_driver); |
| 1868 | platform_driver_unregister(&l2_driver); | ||
| 1869 | } | 1866 | } |
| 1870 | module_exit(spacc_exit); | 1867 | module_exit(spacc_exit); |
| 1871 | 1868 | ||
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 8a0bb417aa11..dbe76b5df9cf 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
| @@ -416,7 +416,7 @@ static void talitos_done(unsigned long data) | |||
| 416 | /* | 416 | /* |
| 417 | * locate current (offending) descriptor | 417 | * locate current (offending) descriptor |
| 418 | */ | 418 | */ |
| 419 | static struct talitos_desc *current_desc(struct device *dev, int ch) | 419 | static u32 current_desc_hdr(struct device *dev, int ch) |
| 420 | { | 420 | { |
| 421 | struct talitos_private *priv = dev_get_drvdata(dev); | 421 | struct talitos_private *priv = dev_get_drvdata(dev); |
| 422 | int tail = priv->chan[ch].tail; | 422 | int tail = priv->chan[ch].tail; |
| @@ -428,23 +428,25 @@ static struct talitos_desc *current_desc(struct device *dev, int ch) | |||
| 428 | tail = (tail + 1) & (priv->fifo_len - 1); | 428 | tail = (tail + 1) & (priv->fifo_len - 1); |
| 429 | if (tail == priv->chan[ch].tail) { | 429 | if (tail == priv->chan[ch].tail) { |
| 430 | dev_err(dev, "couldn't locate current descriptor\n"); | 430 | dev_err(dev, "couldn't locate current descriptor\n"); |
| 431 | return NULL; | 431 | return 0; |
| 432 | } | 432 | } |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | return priv->chan[ch].fifo[tail].desc; | 435 | return priv->chan[ch].fifo[tail].desc->hdr; |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | /* | 438 | /* |
| 439 | * user diagnostics; report root cause of error based on execution unit status | 439 | * user diagnostics; report root cause of error based on execution unit status |
| 440 | */ | 440 | */ |
| 441 | static void report_eu_error(struct device *dev, int ch, | 441 | static void report_eu_error(struct device *dev, int ch, u32 desc_hdr) |
| 442 | struct talitos_desc *desc) | ||
| 443 | { | 442 | { |
| 444 | struct talitos_private *priv = dev_get_drvdata(dev); | 443 | struct talitos_private *priv = dev_get_drvdata(dev); |
| 445 | int i; | 444 | int i; |
| 446 | 445 | ||
| 447 | switch (desc->hdr & DESC_HDR_SEL0_MASK) { | 446 | if (!desc_hdr) |
| 447 | desc_hdr = in_be32(priv->reg + TALITOS_DESCBUF(ch)); | ||
| 448 | |||
| 449 | switch (desc_hdr & DESC_HDR_SEL0_MASK) { | ||
| 448 | case DESC_HDR_SEL0_AFEU: | 450 | case DESC_HDR_SEL0_AFEU: |
| 449 | dev_err(dev, "AFEUISR 0x%08x_%08x\n", | 451 | dev_err(dev, "AFEUISR 0x%08x_%08x\n", |
| 450 | in_be32(priv->reg + TALITOS_AFEUISR), | 452 | in_be32(priv->reg + TALITOS_AFEUISR), |
| @@ -488,7 +490,7 @@ static void report_eu_error(struct device *dev, int ch, | |||
| 488 | break; | 490 | break; |
| 489 | } | 491 | } |
| 490 | 492 | ||
| 491 | switch (desc->hdr & DESC_HDR_SEL1_MASK) { | 493 | switch (desc_hdr & DESC_HDR_SEL1_MASK) { |
| 492 | case DESC_HDR_SEL1_MDEUA: | 494 | case DESC_HDR_SEL1_MDEUA: |
| 493 | case DESC_HDR_SEL1_MDEUB: | 495 | case DESC_HDR_SEL1_MDEUB: |
| 494 | dev_err(dev, "MDEUISR 0x%08x_%08x\n", | 496 | dev_err(dev, "MDEUISR 0x%08x_%08x\n", |
| @@ -550,7 +552,7 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo) | |||
| 550 | if (v_lo & TALITOS_CCPSR_LO_IEU) | 552 | if (v_lo & TALITOS_CCPSR_LO_IEU) |
| 551 | dev_err(dev, "invalid execution unit error\n"); | 553 | dev_err(dev, "invalid execution unit error\n"); |
| 552 | if (v_lo & TALITOS_CCPSR_LO_EU) | 554 | if (v_lo & TALITOS_CCPSR_LO_EU) |
| 553 | report_eu_error(dev, ch, current_desc(dev, ch)); | 555 | report_eu_error(dev, ch, current_desc_hdr(dev, ch)); |
| 554 | if (v_lo & TALITOS_CCPSR_LO_GB) | 556 | if (v_lo & TALITOS_CCPSR_LO_GB) |
| 555 | dev_err(dev, "gather boundary error\n"); | 557 | dev_err(dev, "gather boundary error\n"); |
| 556 | if (v_lo & TALITOS_CCPSR_LO_GRL) | 558 | if (v_lo & TALITOS_CCPSR_LO_GRL) |
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h index 59c3e5bd2c06..ecc721def10c 100644 --- a/include/crypto/algapi.h +++ b/include/crypto/algapi.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/crypto.h> | 15 | #include <linux/crypto.h> |
| 16 | #include <linux/list.h> | 16 | #include <linux/list.h> |
| 17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
| 18 | #include <linux/skbuff.h> | ||
| 18 | 19 | ||
| 19 | struct module; | 20 | struct module; |
| 20 | struct rtattr; | 21 | struct rtattr; |
| @@ -26,6 +27,7 @@ struct crypto_type { | |||
| 26 | int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); | 27 | int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask); |
| 27 | int (*init_tfm)(struct crypto_tfm *tfm); | 28 | int (*init_tfm)(struct crypto_tfm *tfm); |
| 28 | void (*show)(struct seq_file *m, struct crypto_alg *alg); | 29 | void (*show)(struct seq_file *m, struct crypto_alg *alg); |
| 30 | int (*report)(struct sk_buff *skb, struct crypto_alg *alg); | ||
| 29 | struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask); | 31 | struct crypto_alg *(*lookup)(const char *name, u32 type, u32 mask); |
| 30 | 32 | ||
| 31 | unsigned int type; | 33 | unsigned int type; |
diff --git a/include/crypto/blowfish.h b/include/crypto/blowfish.h new file mode 100644 index 000000000000..1450d4a27980 --- /dev/null +++ b/include/crypto/blowfish.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | /* | ||
| 2 | * Common values for blowfish algorithms | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef _CRYPTO_BLOWFISH_H | ||
| 6 | #define _CRYPTO_BLOWFISH_H | ||
| 7 | |||
| 8 | #include <linux/types.h> | ||
| 9 | #include <linux/crypto.h> | ||
| 10 | |||
| 11 | #define BF_BLOCK_SIZE 8 | ||
| 12 | #define BF_MIN_KEY_SIZE 4 | ||
| 13 | #define BF_MAX_KEY_SIZE 56 | ||
| 14 | |||
| 15 | struct bf_ctx { | ||
| 16 | u32 p[18]; | ||
| 17 | u32 s[1024]; | ||
| 18 | }; | ||
| 19 | |||
| 20 | int blowfish_setkey(struct crypto_tfm *tfm, const u8 *key, | ||
| 21 | unsigned int key_len); | ||
| 22 | |||
| 23 | #endif | ||
diff --git a/include/crypto/sha.h b/include/crypto/sha.h index 069e85ba97e1..c6c9c1fe460c 100644 --- a/include/crypto/sha.h +++ b/include/crypto/sha.h | |||
| @@ -82,4 +82,9 @@ struct sha512_state { | |||
| 82 | u8 buf[SHA512_BLOCK_SIZE]; | 82 | u8 buf[SHA512_BLOCK_SIZE]; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | struct shash_desc; | ||
| 86 | |||
| 87 | extern int crypto_sha1_update(struct shash_desc *desc, const u8 *data, | ||
| 88 | unsigned int len); | ||
| 89 | |||
| 85 | #endif | 90 | #endif |
diff --git a/include/linux/crypto.h b/include/linux/crypto.h index e5e468e9133d..de9adec5693c 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h | |||
| @@ -72,6 +72,11 @@ | |||
| 72 | #define CRYPTO_ALG_TESTED 0x00000400 | 72 | #define CRYPTO_ALG_TESTED 0x00000400 |
| 73 | 73 | ||
| 74 | /* | 74 | /* |
| 75 | * Set if the algorithm is an instance that is build from templates. | ||
| 76 | */ | ||
| 77 | #define CRYPTO_ALG_INSTANCE 0x00000800 | ||
| 78 | |||
| 79 | /* | ||
| 75 | * Transform masks and values (for crt_flags). | 80 | * Transform masks and values (for crt_flags). |
| 76 | */ | 81 | */ |
| 77 | #define CRYPTO_TFM_REQ_MASK 0x000fff00 | 82 | #define CRYPTO_TFM_REQ_MASK 0x000fff00 |
diff --git a/include/linux/cryptouser.h b/include/linux/cryptouser.h new file mode 100644 index 000000000000..532fb58f16bf --- /dev/null +++ b/include/linux/cryptouser.h | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /* | ||
| 2 | * Crypto user configuration API. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2011 secunet Security Networks AG | ||
| 5 | * Copyright (C) 2011 Steffen Klassert <steffen.klassert@secunet.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms and conditions of the GNU General Public License, | ||
| 9 | * version 2, as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 14 | * more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along with | ||
| 17 | * this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* Netlink configuration messages. */ | ||
| 22 | enum { | ||
| 23 | CRYPTO_MSG_BASE = 0x10, | ||
| 24 | CRYPTO_MSG_NEWALG = 0x10, | ||
| 25 | CRYPTO_MSG_DELALG, | ||
| 26 | CRYPTO_MSG_UPDATEALG, | ||
| 27 | CRYPTO_MSG_GETALG, | ||
| 28 | __CRYPTO_MSG_MAX | ||
| 29 | }; | ||
| 30 | #define CRYPTO_MSG_MAX (__CRYPTO_MSG_MAX - 1) | ||
| 31 | #define CRYPTO_NR_MSGTYPES (CRYPTO_MSG_MAX + 1 - CRYPTO_MSG_BASE) | ||
| 32 | |||
| 33 | #define CRYPTO_MAX_NAME CRYPTO_MAX_ALG_NAME | ||
| 34 | |||
| 35 | /* Netlink message attributes. */ | ||
| 36 | enum crypto_attr_type_t { | ||
| 37 | CRYPTOCFGA_UNSPEC, | ||
| 38 | CRYPTOCFGA_PRIORITY_VAL, /* __u32 */ | ||
| 39 | CRYPTOCFGA_REPORT_LARVAL, /* struct crypto_report_larval */ | ||
| 40 | CRYPTOCFGA_REPORT_HASH, /* struct crypto_report_hash */ | ||
| 41 | CRYPTOCFGA_REPORT_BLKCIPHER, /* struct crypto_report_blkcipher */ | ||
| 42 | CRYPTOCFGA_REPORT_AEAD, /* struct crypto_report_aead */ | ||
| 43 | CRYPTOCFGA_REPORT_COMPRESS, /* struct crypto_report_comp */ | ||
| 44 | CRYPTOCFGA_REPORT_RNG, /* struct crypto_report_rng */ | ||
| 45 | CRYPTOCFGA_REPORT_CIPHER, /* struct crypto_report_cipher */ | ||
| 46 | __CRYPTOCFGA_MAX | ||
| 47 | |||
| 48 | #define CRYPTOCFGA_MAX (__CRYPTOCFGA_MAX - 1) | ||
| 49 | }; | ||
| 50 | |||
| 51 | struct crypto_user_alg { | ||
| 52 | char cru_name[CRYPTO_MAX_ALG_NAME]; | ||
| 53 | char cru_driver_name[CRYPTO_MAX_ALG_NAME]; | ||
| 54 | char cru_module_name[CRYPTO_MAX_ALG_NAME]; | ||
| 55 | __u32 cru_type; | ||
| 56 | __u32 cru_mask; | ||
| 57 | __u32 cru_refcnt; | ||
| 58 | __u32 cru_flags; | ||
| 59 | }; | ||
| 60 | |||
| 61 | struct crypto_report_larval { | ||
| 62 | char type[CRYPTO_MAX_NAME]; | ||
| 63 | }; | ||
| 64 | |||
| 65 | struct crypto_report_hash { | ||
| 66 | char type[CRYPTO_MAX_NAME]; | ||
| 67 | unsigned int blocksize; | ||
| 68 | unsigned int digestsize; | ||
| 69 | }; | ||
| 70 | |||
| 71 | struct crypto_report_cipher { | ||
| 72 | char type[CRYPTO_MAX_ALG_NAME]; | ||
| 73 | unsigned int blocksize; | ||
| 74 | unsigned int min_keysize; | ||
| 75 | unsigned int max_keysize; | ||
| 76 | }; | ||
| 77 | |||
| 78 | struct crypto_report_blkcipher { | ||
| 79 | char type[CRYPTO_MAX_NAME]; | ||
| 80 | char geniv[CRYPTO_MAX_NAME]; | ||
| 81 | unsigned int blocksize; | ||
| 82 | unsigned int min_keysize; | ||
| 83 | unsigned int max_keysize; | ||
| 84 | unsigned int ivsize; | ||
| 85 | }; | ||
| 86 | |||
| 87 | struct crypto_report_aead { | ||
| 88 | char type[CRYPTO_MAX_NAME]; | ||
| 89 | char geniv[CRYPTO_MAX_NAME]; | ||
| 90 | unsigned int blocksize; | ||
| 91 | unsigned int maxauthsize; | ||
| 92 | unsigned int ivsize; | ||
| 93 | }; | ||
| 94 | |||
| 95 | struct crypto_report_comp { | ||
| 96 | char type[CRYPTO_MAX_NAME]; | ||
| 97 | }; | ||
| 98 | |||
| 99 | struct crypto_report_rng { | ||
| 100 | char type[CRYPTO_MAX_NAME]; | ||
| 101 | unsigned int seedsize; | ||
| 102 | }; | ||
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 8180cd9d73d5..8374d2967362 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */ | 25 | #define NETLINK_SCSITRANSPORT 18 /* SCSI Transports */ |
| 26 | #define NETLINK_ECRYPTFS 19 | 26 | #define NETLINK_ECRYPTFS 19 |
| 27 | #define NETLINK_RDMA 20 | 27 | #define NETLINK_RDMA 20 |
| 28 | #define NETLINK_CRYPTO 21 /* Crypto layer */ | ||
| 28 | 29 | ||
| 29 | #define MAX_LINKS 32 | 30 | #define MAX_LINKS 32 |
| 30 | 31 | ||
