Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (46 commits)
hwrng: via_rng - Fix memory scribbling on some CPUs
crypto: padlock - Move padlock.h into include/crypto
hwrng: via_rng - Fix asm constraints
crypto: n2 - use __devexit not __exit in n2_unregister_algs
crypto: mark crypto workqueues CPU_INTENSIVE
crypto: mv_cesa - dont return PTR_ERR() of wrong pointer
crypto: ripemd - Set module author and update email address
crypto: omap-sham - backlog handling fix
crypto: gf128mul - Remove experimental tag
crypto: af_alg - fix af_alg memory_allocated data type
crypto: aesni-intel - Fixed build with binutils 2.16
crypto: af_alg - Make sure sk_security is initialized on accept()ed sockets
net: Add missing lockdep class names for af_alg
include: Install linux/if_alg.h for user-space crypto API
crypto: omap-aes - checkpatch --file warning fixes
crypto: omap-aes - initialize aes module once per request
crypto: omap-aes - unnecessary code removed
crypto: omap-aes - error handling implementation improved
crypto: omap-aes - redundant locking is removed
crypto: omap-aes - DMA initialization fixes for OMAP off mode
...

+4781 -466
+1802 -30
arch/x86/crypto/aesni-intel_asm.S
··· 9 9 * Vinodh Gopal <vinodh.gopal@intel.com> 10 10 * Kahraman Akdemir 11 11 * 12 + * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD 13 + * interface for 64-bit kernels. 14 + * Authors: Erdinc Ozturk (erdinc.ozturk@intel.com) 15 + * Aidan O'Mahony (aidan.o.mahony@intel.com) 16 + * Adrian Hoban <adrian.hoban@intel.com> 17 + * James Guilford (james.guilford@intel.com) 18 + * Gabriele Paoloni <gabriele.paoloni@intel.com> 19 + * Tadeusz Struk (tadeusz.struk@intel.com) 20 + * Wajdi Feghali (wajdi.k.feghali@intel.com) 21 + * Copyright (c) 2010, Intel Corporation. 22 + * 23 + * Ported x86_64 version to x86: 24 + * Author: Mathias Krause <minipli@googlemail.com> 25 + * 12 26 * This program is free software; you can redistribute it and/or modify 13 27 * it under the terms of the GNU General Public License as published by 14 28 * the Free Software Foundation; either version 2 of the License, or ··· 32 18 #include <linux/linkage.h> 33 19 #include <asm/inst.h> 34 20 21 + #ifdef __x86_64__ 22 + .data 23 + POLY: .octa 0xC2000000000000000000000000000001 24 + TWOONE: .octa 0x00000001000000000000000000000001 25 + 26 + # order of these constants should not change. 27 + # more specifically, ALL_F should follow SHIFT_MASK, 28 + # and ZERO should follow ALL_F 29 + 30 + SHUF_MASK: .octa 0x000102030405060708090A0B0C0D0E0F 31 + MASK1: .octa 0x0000000000000000ffffffffffffffff 32 + MASK2: .octa 0xffffffffffffffff0000000000000000 33 + SHIFT_MASK: .octa 0x0f0e0d0c0b0a09080706050403020100 34 + ALL_F: .octa 0xffffffffffffffffffffffffffffffff 35 + ZERO: .octa 0x00000000000000000000000000000000 36 + ONE: .octa 0x00000000000000000000000000000001 37 + F_MIN_MASK: .octa 0xf1f2f3f4f5f6f7f8f9fafbfcfdfeff0 38 + dec: .octa 0x1 39 + enc: .octa 0x2 40 + 41 + 35 42 .text 43 + 44 + 45 + #define STACK_OFFSET 8*3 46 + #define HashKey 16*0 // store HashKey <<1 mod poly here 47 + #define HashKey_2 16*1 // store HashKey^2 <<1 mod poly here 48 + #define HashKey_3 16*2 // store HashKey^3 <<1 mod poly here 49 + #define HashKey_4 16*3 // store HashKey^4 <<1 mod poly here 50 + #define HashKey_k 16*4 // store XOR of High 64 bits and Low 64 51 + // bits of HashKey <<1 mod poly here 52 + //(for Karatsuba purposes) 53 + #define HashKey_2_k 16*5 // store XOR of High 64 bits and Low 64 54 + // bits of HashKey^2 <<1 mod poly here 55 + // (for Karatsuba purposes) 56 + #define HashKey_3_k 16*6 // store XOR of High 64 bits and Low 64 57 + // bits of HashKey^3 <<1 mod poly here 58 + // (for Karatsuba purposes) 59 + #define HashKey_4_k 16*7 // store XOR of High 64 bits and Low 64 60 + // bits of HashKey^4 <<1 mod poly here 61 + // (for Karatsuba purposes) 62 + #define VARIABLE_OFFSET 16*8 63 + 64 + #define arg1 rdi 65 + #define arg2 rsi 66 + #define arg3 rdx 67 + #define arg4 rcx 68 + #define arg5 r8 69 + #define arg6 r9 70 + #define arg7 STACK_OFFSET+8(%r14) 71 + #define arg8 STACK_OFFSET+16(%r14) 72 + #define arg9 STACK_OFFSET+24(%r14) 73 + #define arg10 STACK_OFFSET+32(%r14) 74 + #endif 75 + 36 76 37 77 #define STATE1 %xmm0 38 78 #define STATE2 %xmm4 ··· 100 32 #define IN IN1 101 33 #define KEY %xmm2 102 34 #define IV %xmm3 35 + 103 36 #define BSWAP_MASK %xmm10 104 37 #define CTR %xmm11 105 38 #define INC %xmm12 106 39 40 + #ifdef __x86_64__ 41 + #define AREG %rax 107 42 #define KEYP %rdi 108 43 #define OUTP %rsi 44 + #define UKEYP OUTP 109 45 #define INP %rdx 110 46 #define LEN %rcx 111 47 #define IVP %r8 ··· 118 46 #define TKEYP T1 119 47 #define T2 %r11 120 48 #define TCTR_LOW T2 49 + #else 50 + #define AREG %eax 51 + #define KEYP %edi 52 + #define OUTP AREG 53 + #define UKEYP OUTP 54 + #define INP %edx 55 + #define LEN %esi 56 + #define IVP %ebp 57 + #define KLEN %ebx 58 + #define T1 %ecx 59 + #define TKEYP T1 60 + #endif 61 + 62 + 63 + #ifdef __x86_64__ 64 + /* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) 65 + * 66 + * 67 + * Input: A and B (128-bits each, bit-reflected) 68 + * Output: C = A*B*x mod poly, (i.e. >>1 ) 69 + * To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input 70 + * GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly. 71 + * 72 + */ 73 + .macro GHASH_MUL GH HK TMP1 TMP2 TMP3 TMP4 TMP5 74 + movdqa \GH, \TMP1 75 + pshufd $78, \GH, \TMP2 76 + pshufd $78, \HK, \TMP3 77 + pxor \GH, \TMP2 # TMP2 = a1+a0 78 + pxor \HK, \TMP3 # TMP3 = b1+b0 79 + PCLMULQDQ 0x11, \HK, \TMP1 # TMP1 = a1*b1 80 + PCLMULQDQ 0x00, \HK, \GH # GH = a0*b0 81 + PCLMULQDQ 0x00, \TMP3, \TMP2 # TMP2 = (a0+a1)*(b1+b0) 82 + pxor \GH, \TMP2 83 + pxor \TMP1, \TMP2 # TMP2 = (a0*b0)+(a1*b0) 84 + movdqa \TMP2, \TMP3 85 + pslldq $8, \TMP3 # left shift TMP3 2 DWs 86 + psrldq $8, \TMP2 # right shift TMP2 2 DWs 87 + pxor \TMP3, \GH 88 + pxor \TMP2, \TMP1 # TMP2:GH holds the result of GH*HK 89 + 90 + # first phase of the reduction 91 + 92 + movdqa \GH, \TMP2 93 + movdqa \GH, \TMP3 94 + movdqa \GH, \TMP4 # copy GH into TMP2,TMP3 and TMP4 95 + # in in order to perform 96 + # independent shifts 97 + pslld $31, \TMP2 # packed right shift <<31 98 + pslld $30, \TMP3 # packed right shift <<30 99 + pslld $25, \TMP4 # packed right shift <<25 100 + pxor \TMP3, \TMP2 # xor the shifted versions 101 + pxor \TMP4, \TMP2 102 + movdqa \TMP2, \TMP5 103 + psrldq $4, \TMP5 # right shift TMP5 1 DW 104 + pslldq $12, \TMP2 # left shift TMP2 3 DWs 105 + pxor \TMP2, \GH 106 + 107 + # second phase of the reduction 108 + 109 + movdqa \GH,\TMP2 # copy GH into TMP2,TMP3 and TMP4 110 + # in in order to perform 111 + # independent shifts 112 + movdqa \GH,\TMP3 113 + movdqa \GH,\TMP4 114 + psrld $1,\TMP2 # packed left shift >>1 115 + psrld $2,\TMP3 # packed left shift >>2 116 + psrld $7,\TMP4 # packed left shift >>7 117 + pxor \TMP3,\TMP2 # xor the shifted versions 118 + pxor \TMP4,\TMP2 119 + pxor \TMP5, \TMP2 120 + pxor \TMP2, \GH 121 + pxor \TMP1, \GH # result is in TMP1 122 + .endm 123 + 124 + /* 125 + * if a = number of total plaintext bytes 126 + * b = floor(a/16) 127 + * num_initial_blocks = b mod 4 128 + * encrypt the initial num_initial_blocks blocks and apply ghash on 129 + * the ciphertext 130 + * %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers 131 + * are clobbered 132 + * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified 133 + */ 134 + 135 + 136 + .macro INITIAL_BLOCKS_DEC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ 137 + XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation 138 + mov arg7, %r10 # %r10 = AAD 139 + mov arg8, %r12 # %r12 = aadLen 140 + mov %r12, %r11 141 + pxor %xmm\i, %xmm\i 142 + _get_AAD_loop\num_initial_blocks\operation: 143 + movd (%r10), \TMP1 144 + pslldq $12, \TMP1 145 + psrldq $4, %xmm\i 146 + pxor \TMP1, %xmm\i 147 + add $4, %r10 148 + sub $4, %r12 149 + jne _get_AAD_loop\num_initial_blocks\operation 150 + cmp $16, %r11 151 + je _get_AAD_loop2_done\num_initial_blocks\operation 152 + mov $16, %r12 153 + _get_AAD_loop2\num_initial_blocks\operation: 154 + psrldq $4, %xmm\i 155 + sub $4, %r12 156 + cmp %r11, %r12 157 + jne _get_AAD_loop2\num_initial_blocks\operation 158 + _get_AAD_loop2_done\num_initial_blocks\operation: 159 + movdqa SHUF_MASK(%rip), %xmm14 160 + PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data 161 + 162 + xor %r11, %r11 # initialise the data pointer offset as zero 163 + 164 + # start AES for num_initial_blocks blocks 165 + 166 + mov %arg5, %rax # %rax = *Y0 167 + movdqu (%rax), \XMM0 # XMM0 = Y0 168 + movdqa SHUF_MASK(%rip), %xmm14 169 + PSHUFB_XMM %xmm14, \XMM0 170 + 171 + .if (\i == 5) || (\i == 6) || (\i == 7) 172 + .irpc index, \i_seq 173 + paddd ONE(%rip), \XMM0 # INCR Y0 174 + movdqa \XMM0, %xmm\index 175 + movdqa SHUF_MASK(%rip), %xmm14 176 + PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap 177 + 178 + .endr 179 + .irpc index, \i_seq 180 + pxor 16*0(%arg1), %xmm\index 181 + .endr 182 + .irpc index, \i_seq 183 + movaps 0x10(%rdi), \TMP1 184 + AESENC \TMP1, %xmm\index # Round 1 185 + .endr 186 + .irpc index, \i_seq 187 + movaps 0x20(%arg1), \TMP1 188 + AESENC \TMP1, %xmm\index # Round 2 189 + .endr 190 + .irpc index, \i_seq 191 + movaps 0x30(%arg1), \TMP1 192 + AESENC \TMP1, %xmm\index # Round 2 193 + .endr 194 + .irpc index, \i_seq 195 + movaps 0x40(%arg1), \TMP1 196 + AESENC \TMP1, %xmm\index # Round 2 197 + .endr 198 + .irpc index, \i_seq 199 + movaps 0x50(%arg1), \TMP1 200 + AESENC \TMP1, %xmm\index # Round 2 201 + .endr 202 + .irpc index, \i_seq 203 + movaps 0x60(%arg1), \TMP1 204 + AESENC \TMP1, %xmm\index # Round 2 205 + .endr 206 + .irpc index, \i_seq 207 + movaps 0x70(%arg1), \TMP1 208 + AESENC \TMP1, %xmm\index # Round 2 209 + .endr 210 + .irpc index, \i_seq 211 + movaps 0x80(%arg1), \TMP1 212 + AESENC \TMP1, %xmm\index # Round 2 213 + .endr 214 + .irpc index, \i_seq 215 + movaps 0x90(%arg1), \TMP1 216 + AESENC \TMP1, %xmm\index # Round 2 217 + .endr 218 + .irpc index, \i_seq 219 + movaps 0xa0(%arg1), \TMP1 220 + AESENCLAST \TMP1, %xmm\index # Round 10 221 + .endr 222 + .irpc index, \i_seq 223 + movdqu (%arg3 , %r11, 1), \TMP1 224 + pxor \TMP1, %xmm\index 225 + movdqu %xmm\index, (%arg2 , %r11, 1) 226 + # write back plaintext/ciphertext for num_initial_blocks 227 + add $16, %r11 228 + 229 + movdqa \TMP1, %xmm\index 230 + movdqa SHUF_MASK(%rip), %xmm14 231 + PSHUFB_XMM %xmm14, %xmm\index 232 + 233 + # prepare plaintext/ciphertext for GHASH computation 234 + .endr 235 + .endif 236 + GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 237 + # apply GHASH on num_initial_blocks blocks 238 + 239 + .if \i == 5 240 + pxor %xmm5, %xmm6 241 + GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 242 + pxor %xmm6, %xmm7 243 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 244 + pxor %xmm7, %xmm8 245 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 246 + .elseif \i == 6 247 + pxor %xmm6, %xmm7 248 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 249 + pxor %xmm7, %xmm8 250 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 251 + .elseif \i == 7 252 + pxor %xmm7, %xmm8 253 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 254 + .endif 255 + cmp $64, %r13 256 + jl _initial_blocks_done\num_initial_blocks\operation 257 + # no need for precomputed values 258 + /* 259 + * 260 + * Precomputations for HashKey parallel with encryption of first 4 blocks. 261 + * Haskey_i_k holds XORed values of the low and high parts of the Haskey_i 262 + */ 263 + paddd ONE(%rip), \XMM0 # INCR Y0 264 + movdqa \XMM0, \XMM1 265 + movdqa SHUF_MASK(%rip), %xmm14 266 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap 267 + 268 + paddd ONE(%rip), \XMM0 # INCR Y0 269 + movdqa \XMM0, \XMM2 270 + movdqa SHUF_MASK(%rip), %xmm14 271 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap 272 + 273 + paddd ONE(%rip), \XMM0 # INCR Y0 274 + movdqa \XMM0, \XMM3 275 + movdqa SHUF_MASK(%rip), %xmm14 276 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap 277 + 278 + paddd ONE(%rip), \XMM0 # INCR Y0 279 + movdqa \XMM0, \XMM4 280 + movdqa SHUF_MASK(%rip), %xmm14 281 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap 282 + 283 + pxor 16*0(%arg1), \XMM1 284 + pxor 16*0(%arg1), \XMM2 285 + pxor 16*0(%arg1), \XMM3 286 + pxor 16*0(%arg1), \XMM4 287 + movdqa \TMP3, \TMP5 288 + pshufd $78, \TMP3, \TMP1 289 + pxor \TMP3, \TMP1 290 + movdqa \TMP1, HashKey_k(%rsp) 291 + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 292 + # TMP5 = HashKey^2<<1 (mod poly) 293 + movdqa \TMP5, HashKey_2(%rsp) 294 + # HashKey_2 = HashKey^2<<1 (mod poly) 295 + pshufd $78, \TMP5, \TMP1 296 + pxor \TMP5, \TMP1 297 + movdqa \TMP1, HashKey_2_k(%rsp) 298 + .irpc index, 1234 # do 4 rounds 299 + movaps 0x10*\index(%arg1), \TMP1 300 + AESENC \TMP1, \XMM1 301 + AESENC \TMP1, \XMM2 302 + AESENC \TMP1, \XMM3 303 + AESENC \TMP1, \XMM4 304 + .endr 305 + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 306 + # TMP5 = HashKey^3<<1 (mod poly) 307 + movdqa \TMP5, HashKey_3(%rsp) 308 + pshufd $78, \TMP5, \TMP1 309 + pxor \TMP5, \TMP1 310 + movdqa \TMP1, HashKey_3_k(%rsp) 311 + .irpc index, 56789 # do next 5 rounds 312 + movaps 0x10*\index(%arg1), \TMP1 313 + AESENC \TMP1, \XMM1 314 + AESENC \TMP1, \XMM2 315 + AESENC \TMP1, \XMM3 316 + AESENC \TMP1, \XMM4 317 + .endr 318 + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 319 + # TMP5 = HashKey^3<<1 (mod poly) 320 + movdqa \TMP5, HashKey_4(%rsp) 321 + pshufd $78, \TMP5, \TMP1 322 + pxor \TMP5, \TMP1 323 + movdqa \TMP1, HashKey_4_k(%rsp) 324 + movaps 0xa0(%arg1), \TMP2 325 + AESENCLAST \TMP2, \XMM1 326 + AESENCLAST \TMP2, \XMM2 327 + AESENCLAST \TMP2, \XMM3 328 + AESENCLAST \TMP2, \XMM4 329 + movdqu 16*0(%arg3 , %r11 , 1), \TMP1 330 + pxor \TMP1, \XMM1 331 + movdqu \XMM1, 16*0(%arg2 , %r11 , 1) 332 + movdqa \TMP1, \XMM1 333 + movdqu 16*1(%arg3 , %r11 , 1), \TMP1 334 + pxor \TMP1, \XMM2 335 + movdqu \XMM2, 16*1(%arg2 , %r11 , 1) 336 + movdqa \TMP1, \XMM2 337 + movdqu 16*2(%arg3 , %r11 , 1), \TMP1 338 + pxor \TMP1, \XMM3 339 + movdqu \XMM3, 16*2(%arg2 , %r11 , 1) 340 + movdqa \TMP1, \XMM3 341 + movdqu 16*3(%arg3 , %r11 , 1), \TMP1 342 + pxor \TMP1, \XMM4 343 + movdqu \XMM4, 16*3(%arg2 , %r11 , 1) 344 + movdqa \TMP1, \XMM4 345 + add $64, %r11 346 + movdqa SHUF_MASK(%rip), %xmm14 347 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap 348 + pxor \XMMDst, \XMM1 349 + # combine GHASHed value with the corresponding ciphertext 350 + movdqa SHUF_MASK(%rip), %xmm14 351 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap 352 + movdqa SHUF_MASK(%rip), %xmm14 353 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap 354 + movdqa SHUF_MASK(%rip), %xmm14 355 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap 356 + 357 + _initial_blocks_done\num_initial_blocks\operation: 358 + 359 + .endm 360 + 361 + 362 + /* 363 + * if a = number of total plaintext bytes 364 + * b = floor(a/16) 365 + * num_initial_blocks = b mod 4 366 + * encrypt the initial num_initial_blocks blocks and apply ghash on 367 + * the ciphertext 368 + * %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers 369 + * are clobbered 370 + * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified 371 + */ 372 + 373 + 374 + .macro INITIAL_BLOCKS_ENC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ 375 + XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation 376 + mov arg7, %r10 # %r10 = AAD 377 + mov arg8, %r12 # %r12 = aadLen 378 + mov %r12, %r11 379 + pxor %xmm\i, %xmm\i 380 + _get_AAD_loop\num_initial_blocks\operation: 381 + movd (%r10), \TMP1 382 + pslldq $12, \TMP1 383 + psrldq $4, %xmm\i 384 + pxor \TMP1, %xmm\i 385 + add $4, %r10 386 + sub $4, %r12 387 + jne _get_AAD_loop\num_initial_blocks\operation 388 + cmp $16, %r11 389 + je _get_AAD_loop2_done\num_initial_blocks\operation 390 + mov $16, %r12 391 + _get_AAD_loop2\num_initial_blocks\operation: 392 + psrldq $4, %xmm\i 393 + sub $4, %r12 394 + cmp %r11, %r12 395 + jne _get_AAD_loop2\num_initial_blocks\operation 396 + _get_AAD_loop2_done\num_initial_blocks\operation: 397 + movdqa SHUF_MASK(%rip), %xmm14 398 + PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data 399 + 400 + xor %r11, %r11 # initialise the data pointer offset as zero 401 + 402 + # start AES for num_initial_blocks blocks 403 + 404 + mov %arg5, %rax # %rax = *Y0 405 + movdqu (%rax), \XMM0 # XMM0 = Y0 406 + movdqa SHUF_MASK(%rip), %xmm14 407 + PSHUFB_XMM %xmm14, \XMM0 408 + 409 + .if (\i == 5) || (\i == 6) || (\i == 7) 410 + .irpc index, \i_seq 411 + paddd ONE(%rip), \XMM0 # INCR Y0 412 + movdqa \XMM0, %xmm\index 413 + movdqa SHUF_MASK(%rip), %xmm14 414 + PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap 415 + 416 + .endr 417 + .irpc index, \i_seq 418 + pxor 16*0(%arg1), %xmm\index 419 + .endr 420 + .irpc index, \i_seq 421 + movaps 0x10(%rdi), \TMP1 422 + AESENC \TMP1, %xmm\index # Round 1 423 + .endr 424 + .irpc index, \i_seq 425 + movaps 0x20(%arg1), \TMP1 426 + AESENC \TMP1, %xmm\index # Round 2 427 + .endr 428 + .irpc index, \i_seq 429 + movaps 0x30(%arg1), \TMP1 430 + AESENC \TMP1, %xmm\index # Round 2 431 + .endr 432 + .irpc index, \i_seq 433 + movaps 0x40(%arg1), \TMP1 434 + AESENC \TMP1, %xmm\index # Round 2 435 + .endr 436 + .irpc index, \i_seq 437 + movaps 0x50(%arg1), \TMP1 438 + AESENC \TMP1, %xmm\index # Round 2 439 + .endr 440 + .irpc index, \i_seq 441 + movaps 0x60(%arg1), \TMP1 442 + AESENC \TMP1, %xmm\index # Round 2 443 + .endr 444 + .irpc index, \i_seq 445 + movaps 0x70(%arg1), \TMP1 446 + AESENC \TMP1, %xmm\index # Round 2 447 + .endr 448 + .irpc index, \i_seq 449 + movaps 0x80(%arg1), \TMP1 450 + AESENC \TMP1, %xmm\index # Round 2 451 + .endr 452 + .irpc index, \i_seq 453 + movaps 0x90(%arg1), \TMP1 454 + AESENC \TMP1, %xmm\index # Round 2 455 + .endr 456 + .irpc index, \i_seq 457 + movaps 0xa0(%arg1), \TMP1 458 + AESENCLAST \TMP1, %xmm\index # Round 10 459 + .endr 460 + .irpc index, \i_seq 461 + movdqu (%arg3 , %r11, 1), \TMP1 462 + pxor \TMP1, %xmm\index 463 + movdqu %xmm\index, (%arg2 , %r11, 1) 464 + # write back plaintext/ciphertext for num_initial_blocks 465 + add $16, %r11 466 + 467 + movdqa SHUF_MASK(%rip), %xmm14 468 + PSHUFB_XMM %xmm14, %xmm\index 469 + 470 + # prepare plaintext/ciphertext for GHASH computation 471 + .endr 472 + .endif 473 + GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 474 + # apply GHASH on num_initial_blocks blocks 475 + 476 + .if \i == 5 477 + pxor %xmm5, %xmm6 478 + GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 479 + pxor %xmm6, %xmm7 480 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 481 + pxor %xmm7, %xmm8 482 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 483 + .elseif \i == 6 484 + pxor %xmm6, %xmm7 485 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 486 + pxor %xmm7, %xmm8 487 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 488 + .elseif \i == 7 489 + pxor %xmm7, %xmm8 490 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 491 + .endif 492 + cmp $64, %r13 493 + jl _initial_blocks_done\num_initial_blocks\operation 494 + # no need for precomputed values 495 + /* 496 + * 497 + * Precomputations for HashKey parallel with encryption of first 4 blocks. 498 + * Haskey_i_k holds XORed values of the low and high parts of the Haskey_i 499 + */ 500 + paddd ONE(%rip), \XMM0 # INCR Y0 501 + movdqa \XMM0, \XMM1 502 + movdqa SHUF_MASK(%rip), %xmm14 503 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap 504 + 505 + paddd ONE(%rip), \XMM0 # INCR Y0 506 + movdqa \XMM0, \XMM2 507 + movdqa SHUF_MASK(%rip), %xmm14 508 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap 509 + 510 + paddd ONE(%rip), \XMM0 # INCR Y0 511 + movdqa \XMM0, \XMM3 512 + movdqa SHUF_MASK(%rip), %xmm14 513 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap 514 + 515 + paddd ONE(%rip), \XMM0 # INCR Y0 516 + movdqa \XMM0, \XMM4 517 + movdqa SHUF_MASK(%rip), %xmm14 518 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap 519 + 520 + pxor 16*0(%arg1), \XMM1 521 + pxor 16*0(%arg1), \XMM2 522 + pxor 16*0(%arg1), \XMM3 523 + pxor 16*0(%arg1), \XMM4 524 + movdqa \TMP3, \TMP5 525 + pshufd $78, \TMP3, \TMP1 526 + pxor \TMP3, \TMP1 527 + movdqa \TMP1, HashKey_k(%rsp) 528 + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 529 + # TMP5 = HashKey^2<<1 (mod poly) 530 + movdqa \TMP5, HashKey_2(%rsp) 531 + # HashKey_2 = HashKey^2<<1 (mod poly) 532 + pshufd $78, \TMP5, \TMP1 533 + pxor \TMP5, \TMP1 534 + movdqa \TMP1, HashKey_2_k(%rsp) 535 + .irpc index, 1234 # do 4 rounds 536 + movaps 0x10*\index(%arg1), \TMP1 537 + AESENC \TMP1, \XMM1 538 + AESENC \TMP1, \XMM2 539 + AESENC \TMP1, \XMM3 540 + AESENC \TMP1, \XMM4 541 + .endr 542 + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 543 + # TMP5 = HashKey^3<<1 (mod poly) 544 + movdqa \TMP5, HashKey_3(%rsp) 545 + pshufd $78, \TMP5, \TMP1 546 + pxor \TMP5, \TMP1 547 + movdqa \TMP1, HashKey_3_k(%rsp) 548 + .irpc index, 56789 # do next 5 rounds 549 + movaps 0x10*\index(%arg1), \TMP1 550 + AESENC \TMP1, \XMM1 551 + AESENC \TMP1, \XMM2 552 + AESENC \TMP1, \XMM3 553 + AESENC \TMP1, \XMM4 554 + .endr 555 + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 556 + # TMP5 = HashKey^3<<1 (mod poly) 557 + movdqa \TMP5, HashKey_4(%rsp) 558 + pshufd $78, \TMP5, \TMP1 559 + pxor \TMP5, \TMP1 560 + movdqa \TMP1, HashKey_4_k(%rsp) 561 + movaps 0xa0(%arg1), \TMP2 562 + AESENCLAST \TMP2, \XMM1 563 + AESENCLAST \TMP2, \XMM2 564 + AESENCLAST \TMP2, \XMM3 565 + AESENCLAST \TMP2, \XMM4 566 + movdqu 16*0(%arg3 , %r11 , 1), \TMP1 567 + pxor \TMP1, \XMM1 568 + movdqu 16*1(%arg3 , %r11 , 1), \TMP1 569 + pxor \TMP1, \XMM2 570 + movdqu 16*2(%arg3 , %r11 , 1), \TMP1 571 + pxor \TMP1, \XMM3 572 + movdqu 16*3(%arg3 , %r11 , 1), \TMP1 573 + pxor \TMP1, \XMM4 574 + movdqu \XMM1, 16*0(%arg2 , %r11 , 1) 575 + movdqu \XMM2, 16*1(%arg2 , %r11 , 1) 576 + movdqu \XMM3, 16*2(%arg2 , %r11 , 1) 577 + movdqu \XMM4, 16*3(%arg2 , %r11 , 1) 578 + 579 + add $64, %r11 580 + movdqa SHUF_MASK(%rip), %xmm14 581 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap 582 + pxor \XMMDst, \XMM1 583 + # combine GHASHed value with the corresponding ciphertext 584 + movdqa SHUF_MASK(%rip), %xmm14 585 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap 586 + movdqa SHUF_MASK(%rip), %xmm14 587 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap 588 + movdqa SHUF_MASK(%rip), %xmm14 589 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap 590 + 591 + _initial_blocks_done\num_initial_blocks\operation: 592 + 593 + .endm 594 + 595 + /* 596 + * encrypt 4 blocks at a time 597 + * ghash the 4 previously encrypted ciphertext blocks 598 + * arg1, %arg2, %arg3 are used as pointers only, not modified 599 + * %r11 is the data offset value 600 + */ 601 + .macro GHASH_4_ENCRYPT_4_PARALLEL_ENC TMP1 TMP2 TMP3 TMP4 TMP5 \ 602 + TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation 603 + 604 + movdqa \XMM1, \XMM5 605 + movdqa \XMM2, \XMM6 606 + movdqa \XMM3, \XMM7 607 + movdqa \XMM4, \XMM8 608 + 609 + movdqa SHUF_MASK(%rip), %xmm15 610 + # multiply TMP5 * HashKey using karatsuba 611 + 612 + movdqa \XMM5, \TMP4 613 + pshufd $78, \XMM5, \TMP6 614 + pxor \XMM5, \TMP6 615 + paddd ONE(%rip), \XMM0 # INCR CNT 616 + movdqa HashKey_4(%rsp), \TMP5 617 + PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1 618 + movdqa \XMM0, \XMM1 619 + paddd ONE(%rip), \XMM0 # INCR CNT 620 + movdqa \XMM0, \XMM2 621 + paddd ONE(%rip), \XMM0 # INCR CNT 622 + movdqa \XMM0, \XMM3 623 + paddd ONE(%rip), \XMM0 # INCR CNT 624 + movdqa \XMM0, \XMM4 625 + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap 626 + PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 627 + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap 628 + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap 629 + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap 630 + 631 + pxor (%arg1), \XMM1 632 + pxor (%arg1), \XMM2 633 + pxor (%arg1), \XMM3 634 + pxor (%arg1), \XMM4 635 + movdqa HashKey_4_k(%rsp), \TMP5 636 + PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0) 637 + movaps 0x10(%arg1), \TMP1 638 + AESENC \TMP1, \XMM1 # Round 1 639 + AESENC \TMP1, \XMM2 640 + AESENC \TMP1, \XMM3 641 + AESENC \TMP1, \XMM4 642 + movaps 0x20(%arg1), \TMP1 643 + AESENC \TMP1, \XMM1 # Round 2 644 + AESENC \TMP1, \XMM2 645 + AESENC \TMP1, \XMM3 646 + AESENC \TMP1, \XMM4 647 + movdqa \XMM6, \TMP1 648 + pshufd $78, \XMM6, \TMP2 649 + pxor \XMM6, \TMP2 650 + movdqa HashKey_3(%rsp), \TMP5 651 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1 652 + movaps 0x30(%arg1), \TMP3 653 + AESENC \TMP3, \XMM1 # Round 3 654 + AESENC \TMP3, \XMM2 655 + AESENC \TMP3, \XMM3 656 + AESENC \TMP3, \XMM4 657 + PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0 658 + movaps 0x40(%arg1), \TMP3 659 + AESENC \TMP3, \XMM1 # Round 4 660 + AESENC \TMP3, \XMM2 661 + AESENC \TMP3, \XMM3 662 + AESENC \TMP3, \XMM4 663 + movdqa HashKey_3_k(%rsp), \TMP5 664 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 665 + movaps 0x50(%arg1), \TMP3 666 + AESENC \TMP3, \XMM1 # Round 5 667 + AESENC \TMP3, \XMM2 668 + AESENC \TMP3, \XMM3 669 + AESENC \TMP3, \XMM4 670 + pxor \TMP1, \TMP4 671 + # accumulate the results in TMP4:XMM5, TMP6 holds the middle part 672 + pxor \XMM6, \XMM5 673 + pxor \TMP2, \TMP6 674 + movdqa \XMM7, \TMP1 675 + pshufd $78, \XMM7, \TMP2 676 + pxor \XMM7, \TMP2 677 + movdqa HashKey_2(%rsp ), \TMP5 678 + 679 + # Multiply TMP5 * HashKey using karatsuba 680 + 681 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 682 + movaps 0x60(%arg1), \TMP3 683 + AESENC \TMP3, \XMM1 # Round 6 684 + AESENC \TMP3, \XMM2 685 + AESENC \TMP3, \XMM3 686 + AESENC \TMP3, \XMM4 687 + PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0 688 + movaps 0x70(%arg1), \TMP3 689 + AESENC \TMP3, \XMM1 # Round 7 690 + AESENC \TMP3, \XMM2 691 + AESENC \TMP3, \XMM3 692 + AESENC \TMP3, \XMM4 693 + movdqa HashKey_2_k(%rsp), \TMP5 694 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 695 + movaps 0x80(%arg1), \TMP3 696 + AESENC \TMP3, \XMM1 # Round 8 697 + AESENC \TMP3, \XMM2 698 + AESENC \TMP3, \XMM3 699 + AESENC \TMP3, \XMM4 700 + pxor \TMP1, \TMP4 701 + # accumulate the results in TMP4:XMM5, TMP6 holds the middle part 702 + pxor \XMM7, \XMM5 703 + pxor \TMP2, \TMP6 704 + 705 + # Multiply XMM8 * HashKey 706 + # XMM8 and TMP5 hold the values for the two operands 707 + 708 + movdqa \XMM8, \TMP1 709 + pshufd $78, \XMM8, \TMP2 710 + pxor \XMM8, \TMP2 711 + movdqa HashKey(%rsp), \TMP5 712 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 713 + movaps 0x90(%arg1), \TMP3 714 + AESENC \TMP3, \XMM1 # Round 9 715 + AESENC \TMP3, \XMM2 716 + AESENC \TMP3, \XMM3 717 + AESENC \TMP3, \XMM4 718 + PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0 719 + movaps 0xa0(%arg1), \TMP3 720 + AESENCLAST \TMP3, \XMM1 # Round 10 721 + AESENCLAST \TMP3, \XMM2 722 + AESENCLAST \TMP3, \XMM3 723 + AESENCLAST \TMP3, \XMM4 724 + movdqa HashKey_k(%rsp), \TMP5 725 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 726 + movdqu (%arg3,%r11,1), \TMP3 727 + pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK 728 + movdqu 16(%arg3,%r11,1), \TMP3 729 + pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK 730 + movdqu 32(%arg3,%r11,1), \TMP3 731 + pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK 732 + movdqu 48(%arg3,%r11,1), \TMP3 733 + pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK 734 + movdqu \XMM1, (%arg2,%r11,1) # Write to the ciphertext buffer 735 + movdqu \XMM2, 16(%arg2,%r11,1) # Write to the ciphertext buffer 736 + movdqu \XMM3, 32(%arg2,%r11,1) # Write to the ciphertext buffer 737 + movdqu \XMM4, 48(%arg2,%r11,1) # Write to the ciphertext buffer 738 + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap 739 + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap 740 + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap 741 + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap 742 + 743 + pxor \TMP4, \TMP1 744 + pxor \XMM8, \XMM5 745 + pxor \TMP6, \TMP2 746 + pxor \TMP1, \TMP2 747 + pxor \XMM5, \TMP2 748 + movdqa \TMP2, \TMP3 749 + pslldq $8, \TMP3 # left shift TMP3 2 DWs 750 + psrldq $8, \TMP2 # right shift TMP2 2 DWs 751 + pxor \TMP3, \XMM5 752 + pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5 753 + 754 + # first phase of reduction 755 + 756 + movdqa \XMM5, \TMP2 757 + movdqa \XMM5, \TMP3 758 + movdqa \XMM5, \TMP4 759 + # move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently 760 + pslld $31, \TMP2 # packed right shift << 31 761 + pslld $30, \TMP3 # packed right shift << 30 762 + pslld $25, \TMP4 # packed right shift << 25 763 + pxor \TMP3, \TMP2 # xor the shifted versions 764 + pxor \TMP4, \TMP2 765 + movdqa \TMP2, \TMP5 766 + psrldq $4, \TMP5 # right shift T5 1 DW 767 + pslldq $12, \TMP2 # left shift T2 3 DWs 768 + pxor \TMP2, \XMM5 769 + 770 + # second phase of reduction 771 + 772 + movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4 773 + movdqa \XMM5,\TMP3 774 + movdqa \XMM5,\TMP4 775 + psrld $1, \TMP2 # packed left shift >>1 776 + psrld $2, \TMP3 # packed left shift >>2 777 + psrld $7, \TMP4 # packed left shift >>7 778 + pxor \TMP3,\TMP2 # xor the shifted versions 779 + pxor \TMP4,\TMP2 780 + pxor \TMP5, \TMP2 781 + pxor \TMP2, \XMM5 782 + pxor \TMP1, \XMM5 # result is in TMP1 783 + 784 + pxor \XMM5, \XMM1 785 + .endm 786 + 787 + /* 788 + * decrypt 4 blocks at a time 789 + * ghash the 4 previously decrypted ciphertext blocks 790 + * arg1, %arg2, %arg3 are used as pointers only, not modified 791 + * %r11 is the data offset value 792 + */ 793 + .macro GHASH_4_ENCRYPT_4_PARALLEL_DEC TMP1 TMP2 TMP3 TMP4 TMP5 \ 794 + TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation 795 + 796 + movdqa \XMM1, \XMM5 797 + movdqa \XMM2, \XMM6 798 + movdqa \XMM3, \XMM7 799 + movdqa \XMM4, \XMM8 800 + 801 + movdqa SHUF_MASK(%rip), %xmm15 802 + # multiply TMP5 * HashKey using karatsuba 803 + 804 + movdqa \XMM5, \TMP4 805 + pshufd $78, \XMM5, \TMP6 806 + pxor \XMM5, \TMP6 807 + paddd ONE(%rip), \XMM0 # INCR CNT 808 + movdqa HashKey_4(%rsp), \TMP5 809 + PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1 810 + movdqa \XMM0, \XMM1 811 + paddd ONE(%rip), \XMM0 # INCR CNT 812 + movdqa \XMM0, \XMM2 813 + paddd ONE(%rip), \XMM0 # INCR CNT 814 + movdqa \XMM0, \XMM3 815 + paddd ONE(%rip), \XMM0 # INCR CNT 816 + movdqa \XMM0, \XMM4 817 + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap 818 + PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 819 + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap 820 + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap 821 + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap 822 + 823 + pxor (%arg1), \XMM1 824 + pxor (%arg1), \XMM2 825 + pxor (%arg1), \XMM3 826 + pxor (%arg1), \XMM4 827 + movdqa HashKey_4_k(%rsp), \TMP5 828 + PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0) 829 + movaps 0x10(%arg1), \TMP1 830 + AESENC \TMP1, \XMM1 # Round 1 831 + AESENC \TMP1, \XMM2 832 + AESENC \TMP1, \XMM3 833 + AESENC \TMP1, \XMM4 834 + movaps 0x20(%arg1), \TMP1 835 + AESENC \TMP1, \XMM1 # Round 2 836 + AESENC \TMP1, \XMM2 837 + AESENC \TMP1, \XMM3 838 + AESENC \TMP1, \XMM4 839 + movdqa \XMM6, \TMP1 840 + pshufd $78, \XMM6, \TMP2 841 + pxor \XMM6, \TMP2 842 + movdqa HashKey_3(%rsp), \TMP5 843 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1 844 + movaps 0x30(%arg1), \TMP3 845 + AESENC \TMP3, \XMM1 # Round 3 846 + AESENC \TMP3, \XMM2 847 + AESENC \TMP3, \XMM3 848 + AESENC \TMP3, \XMM4 849 + PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0 850 + movaps 0x40(%arg1), \TMP3 851 + AESENC \TMP3, \XMM1 # Round 4 852 + AESENC \TMP3, \XMM2 853 + AESENC \TMP3, \XMM3 854 + AESENC \TMP3, \XMM4 855 + movdqa HashKey_3_k(%rsp), \TMP5 856 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 857 + movaps 0x50(%arg1), \TMP3 858 + AESENC \TMP3, \XMM1 # Round 5 859 + AESENC \TMP3, \XMM2 860 + AESENC \TMP3, \XMM3 861 + AESENC \TMP3, \XMM4 862 + pxor \TMP1, \TMP4 863 + # accumulate the results in TMP4:XMM5, TMP6 holds the middle part 864 + pxor \XMM6, \XMM5 865 + pxor \TMP2, \TMP6 866 + movdqa \XMM7, \TMP1 867 + pshufd $78, \XMM7, \TMP2 868 + pxor \XMM7, \TMP2 869 + movdqa HashKey_2(%rsp ), \TMP5 870 + 871 + # Multiply TMP5 * HashKey using karatsuba 872 + 873 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 874 + movaps 0x60(%arg1), \TMP3 875 + AESENC \TMP3, \XMM1 # Round 6 876 + AESENC \TMP3, \XMM2 877 + AESENC \TMP3, \XMM3 878 + AESENC \TMP3, \XMM4 879 + PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0 880 + movaps 0x70(%arg1), \TMP3 881 + AESENC \TMP3, \XMM1 # Round 7 882 + AESENC \TMP3, \XMM2 883 + AESENC \TMP3, \XMM3 884 + AESENC \TMP3, \XMM4 885 + movdqa HashKey_2_k(%rsp), \TMP5 886 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 887 + movaps 0x80(%arg1), \TMP3 888 + AESENC \TMP3, \XMM1 # Round 8 889 + AESENC \TMP3, \XMM2 890 + AESENC \TMP3, \XMM3 891 + AESENC \TMP3, \XMM4 892 + pxor \TMP1, \TMP4 893 + # accumulate the results in TMP4:XMM5, TMP6 holds the middle part 894 + pxor \XMM7, \XMM5 895 + pxor \TMP2, \TMP6 896 + 897 + # Multiply XMM8 * HashKey 898 + # XMM8 and TMP5 hold the values for the two operands 899 + 900 + movdqa \XMM8, \TMP1 901 + pshufd $78, \XMM8, \TMP2 902 + pxor \XMM8, \TMP2 903 + movdqa HashKey(%rsp), \TMP5 904 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 905 + movaps 0x90(%arg1), \TMP3 906 + AESENC \TMP3, \XMM1 # Round 9 907 + AESENC \TMP3, \XMM2 908 + AESENC \TMP3, \XMM3 909 + AESENC \TMP3, \XMM4 910 + PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0 911 + movaps 0xa0(%arg1), \TMP3 912 + AESENCLAST \TMP3, \XMM1 # Round 10 913 + AESENCLAST \TMP3, \XMM2 914 + AESENCLAST \TMP3, \XMM3 915 + AESENCLAST \TMP3, \XMM4 916 + movdqa HashKey_k(%rsp), \TMP5 917 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 918 + movdqu (%arg3,%r11,1), \TMP3 919 + pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK 920 + movdqu \XMM1, (%arg2,%r11,1) # Write to plaintext buffer 921 + movdqa \TMP3, \XMM1 922 + movdqu 16(%arg3,%r11,1), \TMP3 923 + pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK 924 + movdqu \XMM2, 16(%arg2,%r11,1) # Write to plaintext buffer 925 + movdqa \TMP3, \XMM2 926 + movdqu 32(%arg3,%r11,1), \TMP3 927 + pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK 928 + movdqu \XMM3, 32(%arg2,%r11,1) # Write to plaintext buffer 929 + movdqa \TMP3, \XMM3 930 + movdqu 48(%arg3,%r11,1), \TMP3 931 + pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK 932 + movdqu \XMM4, 48(%arg2,%r11,1) # Write to plaintext buffer 933 + movdqa \TMP3, \XMM4 934 + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap 935 + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap 936 + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap 937 + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap 938 + 939 + pxor \TMP4, \TMP1 940 + pxor \XMM8, \XMM5 941 + pxor \TMP6, \TMP2 942 + pxor \TMP1, \TMP2 943 + pxor \XMM5, \TMP2 944 + movdqa \TMP2, \TMP3 945 + pslldq $8, \TMP3 # left shift TMP3 2 DWs 946 + psrldq $8, \TMP2 # right shift TMP2 2 DWs 947 + pxor \TMP3, \XMM5 948 + pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5 949 + 950 + # first phase of reduction 951 + 952 + movdqa \XMM5, \TMP2 953 + movdqa \XMM5, \TMP3 954 + movdqa \XMM5, \TMP4 955 + # move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently 956 + pslld $31, \TMP2 # packed right shift << 31 957 + pslld $30, \TMP3 # packed right shift << 30 958 + pslld $25, \TMP4 # packed right shift << 25 959 + pxor \TMP3, \TMP2 # xor the shifted versions 960 + pxor \TMP4, \TMP2 961 + movdqa \TMP2, \TMP5 962 + psrldq $4, \TMP5 # right shift T5 1 DW 963 + pslldq $12, \TMP2 # left shift T2 3 DWs 964 + pxor \TMP2, \XMM5 965 + 966 + # second phase of reduction 967 + 968 + movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4 969 + movdqa \XMM5,\TMP3 970 + movdqa \XMM5,\TMP4 971 + psrld $1, \TMP2 # packed left shift >>1 972 + psrld $2, \TMP3 # packed left shift >>2 973 + psrld $7, \TMP4 # packed left shift >>7 974 + pxor \TMP3,\TMP2 # xor the shifted versions 975 + pxor \TMP4,\TMP2 976 + pxor \TMP5, \TMP2 977 + pxor \TMP2, \XMM5 978 + pxor \TMP1, \XMM5 # result is in TMP1 979 + 980 + pxor \XMM5, \XMM1 981 + .endm 982 + 983 + /* GHASH the last 4 ciphertext blocks. */ 984 + .macro GHASH_LAST_4 TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 \ 985 + TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst 986 + 987 + # Multiply TMP6 * HashKey (using Karatsuba) 988 + 989 + movdqa \XMM1, \TMP6 990 + pshufd $78, \XMM1, \TMP2 991 + pxor \XMM1, \TMP2 992 + movdqa HashKey_4(%rsp), \TMP5 993 + PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1 994 + PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0 995 + movdqa HashKey_4_k(%rsp), \TMP4 996 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 997 + movdqa \XMM1, \XMMDst 998 + movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1 999 + 1000 + # Multiply TMP1 * HashKey (using Karatsuba) 1001 + 1002 + movdqa \XMM2, \TMP1 1003 + pshufd $78, \XMM2, \TMP2 1004 + pxor \XMM2, \TMP2 1005 + movdqa HashKey_3(%rsp), \TMP5 1006 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 1007 + PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0 1008 + movdqa HashKey_3_k(%rsp), \TMP4 1009 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 1010 + pxor \TMP1, \TMP6 1011 + pxor \XMM2, \XMMDst 1012 + pxor \TMP2, \XMM1 1013 + # results accumulated in TMP6, XMMDst, XMM1 1014 + 1015 + # Multiply TMP1 * HashKey (using Karatsuba) 1016 + 1017 + movdqa \XMM3, \TMP1 1018 + pshufd $78, \XMM3, \TMP2 1019 + pxor \XMM3, \TMP2 1020 + movdqa HashKey_2(%rsp), \TMP5 1021 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 1022 + PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0 1023 + movdqa HashKey_2_k(%rsp), \TMP4 1024 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 1025 + pxor \TMP1, \TMP6 1026 + pxor \XMM3, \XMMDst 1027 + pxor \TMP2, \XMM1 # results accumulated in TMP6, XMMDst, XMM1 1028 + 1029 + # Multiply TMP1 * HashKey (using Karatsuba) 1030 + movdqa \XMM4, \TMP1 1031 + pshufd $78, \XMM4, \TMP2 1032 + pxor \XMM4, \TMP2 1033 + movdqa HashKey(%rsp), \TMP5 1034 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 1035 + PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0 1036 + movdqa HashKey_k(%rsp), \TMP4 1037 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) 1038 + pxor \TMP1, \TMP6 1039 + pxor \XMM4, \XMMDst 1040 + pxor \XMM1, \TMP2 1041 + pxor \TMP6, \TMP2 1042 + pxor \XMMDst, \TMP2 1043 + # middle section of the temp results combined as in karatsuba algorithm 1044 + movdqa \TMP2, \TMP4 1045 + pslldq $8, \TMP4 # left shift TMP4 2 DWs 1046 + psrldq $8, \TMP2 # right shift TMP2 2 DWs 1047 + pxor \TMP4, \XMMDst 1048 + pxor \TMP2, \TMP6 1049 + # TMP6:XMMDst holds the result of the accumulated carry-less multiplications 1050 + # first phase of the reduction 1051 + movdqa \XMMDst, \TMP2 1052 + movdqa \XMMDst, \TMP3 1053 + movdqa \XMMDst, \TMP4 1054 + # move XMMDst into TMP2, TMP3, TMP4 in order to perform 3 shifts independently 1055 + pslld $31, \TMP2 # packed right shifting << 31 1056 + pslld $30, \TMP3 # packed right shifting << 30 1057 + pslld $25, \TMP4 # packed right shifting << 25 1058 + pxor \TMP3, \TMP2 # xor the shifted versions 1059 + pxor \TMP4, \TMP2 1060 + movdqa \TMP2, \TMP7 1061 + psrldq $4, \TMP7 # right shift TMP7 1 DW 1062 + pslldq $12, \TMP2 # left shift TMP2 3 DWs 1063 + pxor \TMP2, \XMMDst 1064 + 1065 + # second phase of the reduction 1066 + movdqa \XMMDst, \TMP2 1067 + # make 3 copies of XMMDst for doing 3 shift operations 1068 + movdqa \XMMDst, \TMP3 1069 + movdqa \XMMDst, \TMP4 1070 + psrld $1, \TMP2 # packed left shift >> 1 1071 + psrld $2, \TMP3 # packed left shift >> 2 1072 + psrld $7, \TMP4 # packed left shift >> 7 1073 + pxor \TMP3, \TMP2 # xor the shifted versions 1074 + pxor \TMP4, \TMP2 1075 + pxor \TMP7, \TMP2 1076 + pxor \TMP2, \XMMDst 1077 + pxor \TMP6, \XMMDst # reduced result is in XMMDst 1078 + .endm 1079 + 1080 + /* Encryption of a single block done*/ 1081 + .macro ENCRYPT_SINGLE_BLOCK XMM0 TMP1 1082 + 1083 + pxor (%arg1), \XMM0 1084 + movaps 16(%arg1), \TMP1 1085 + AESENC \TMP1, \XMM0 1086 + movaps 32(%arg1), \TMP1 1087 + AESENC \TMP1, \XMM0 1088 + movaps 48(%arg1), \TMP1 1089 + AESENC \TMP1, \XMM0 1090 + movaps 64(%arg1), \TMP1 1091 + AESENC \TMP1, \XMM0 1092 + movaps 80(%arg1), \TMP1 1093 + AESENC \TMP1, \XMM0 1094 + movaps 96(%arg1), \TMP1 1095 + AESENC \TMP1, \XMM0 1096 + movaps 112(%arg1), \TMP1 1097 + AESENC \TMP1, \XMM0 1098 + movaps 128(%arg1), \TMP1 1099 + AESENC \TMP1, \XMM0 1100 + movaps 144(%arg1), \TMP1 1101 + AESENC \TMP1, \XMM0 1102 + movaps 160(%arg1), \TMP1 1103 + AESENCLAST \TMP1, \XMM0 1104 + .endm 1105 + 1106 + 1107 + /***************************************************************************** 1108 + * void aesni_gcm_dec(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary. 1109 + * u8 *out, // Plaintext output. Encrypt in-place is allowed. 1110 + * const u8 *in, // Ciphertext input 1111 + * u64 plaintext_len, // Length of data in bytes for decryption. 1112 + * u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association) 1113 + * // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload) 1114 + * // concatenated with 0x00000001. 16-byte aligned pointer. 1115 + * u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary. 1116 + * const u8 *aad, // Additional Authentication Data (AAD) 1117 + * u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes 1118 + * u8 *auth_tag, // Authenticated Tag output. The driver will compare this to the 1119 + * // given authentication tag and only return the plaintext if they match. 1120 + * u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 1121 + * // (most likely), 12 or 8. 1122 + * 1123 + * Assumptions: 1124 + * 1125 + * keys: 1126 + * keys are pre-expanded and aligned to 16 bytes. we are using the first 1127 + * set of 11 keys in the data structure void *aes_ctx 1128 + * 1129 + * iv: 1130 + * 0 1 2 3 1131 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1132 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1133 + * | Salt (From the SA) | 1134 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1135 + * | Initialization Vector | 1136 + * | (This is the sequence number from IPSec header) | 1137 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1138 + * | 0x1 | 1139 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1140 + * 1141 + * 1142 + * 1143 + * AAD: 1144 + * AAD padded to 128 bits with 0 1145 + * for example, assume AAD is a u32 vector 1146 + * 1147 + * if AAD is 8 bytes: 1148 + * AAD[3] = {A0, A1}; 1149 + * padded AAD in xmm register = {A1 A0 0 0} 1150 + * 1151 + * 0 1 2 3 1152 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1153 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1154 + * | SPI (A1) | 1155 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1156 + * | 32-bit Sequence Number (A0) | 1157 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1158 + * | 0x0 | 1159 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1160 + * 1161 + * AAD Format with 32-bit Sequence Number 1162 + * 1163 + * if AAD is 12 bytes: 1164 + * AAD[3] = {A0, A1, A2}; 1165 + * padded AAD in xmm register = {A2 A1 A0 0} 1166 + * 1167 + * 0 1 2 3 1168 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1169 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1170 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1171 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1172 + * | SPI (A2) | 1173 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1174 + * | 64-bit Extended Sequence Number {A1,A0} | 1175 + * | | 1176 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1177 + * | 0x0 | 1178 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1179 + * 1180 + * AAD Format with 64-bit Extended Sequence Number 1181 + * 1182 + * aadLen: 1183 + * from the definition of the spec, aadLen can only be 8 or 12 bytes. 1184 + * The code supports 16 too but for other sizes, the code will fail. 1185 + * 1186 + * TLen: 1187 + * from the definition of the spec, TLen can only be 8, 12 or 16 bytes. 1188 + * For other sizes, the code will fail. 1189 + * 1190 + * poly = x^128 + x^127 + x^126 + x^121 + 1 1191 + * 1192 + *****************************************************************************/ 1193 + 1194 + ENTRY(aesni_gcm_dec) 1195 + push %r12 1196 + push %r13 1197 + push %r14 1198 + mov %rsp, %r14 1199 + /* 1200 + * states of %xmm registers %xmm6:%xmm15 not saved 1201 + * all %xmm registers are clobbered 1202 + */ 1203 + sub $VARIABLE_OFFSET, %rsp 1204 + and $~63, %rsp # align rsp to 64 bytes 1205 + mov %arg6, %r12 1206 + movdqu (%r12), %xmm13 # %xmm13 = HashKey 1207 + movdqa SHUF_MASK(%rip), %xmm2 1208 + PSHUFB_XMM %xmm2, %xmm13 1209 + 1210 + 1211 + # Precompute HashKey<<1 (mod poly) from the hash key (required for GHASH) 1212 + 1213 + movdqa %xmm13, %xmm2 1214 + psllq $1, %xmm13 1215 + psrlq $63, %xmm2 1216 + movdqa %xmm2, %xmm1 1217 + pslldq $8, %xmm2 1218 + psrldq $8, %xmm1 1219 + por %xmm2, %xmm13 1220 + 1221 + # Reduction 1222 + 1223 + pshufd $0x24, %xmm1, %xmm2 1224 + pcmpeqd TWOONE(%rip), %xmm2 1225 + pand POLY(%rip), %xmm2 1226 + pxor %xmm2, %xmm13 # %xmm13 holds the HashKey<<1 (mod poly) 1227 + 1228 + 1229 + # Decrypt first few blocks 1230 + 1231 + movdqa %xmm13, HashKey(%rsp) # store HashKey<<1 (mod poly) 1232 + mov %arg4, %r13 # save the number of bytes of plaintext/ciphertext 1233 + and $-16, %r13 # %r13 = %r13 - (%r13 mod 16) 1234 + mov %r13, %r12 1235 + and $(3<<4), %r12 1236 + jz _initial_num_blocks_is_0_decrypt 1237 + cmp $(2<<4), %r12 1238 + jb _initial_num_blocks_is_1_decrypt 1239 + je _initial_num_blocks_is_2_decrypt 1240 + _initial_num_blocks_is_3_decrypt: 1241 + INITIAL_BLOCKS_DEC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1242 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, dec 1243 + sub $48, %r13 1244 + jmp _initial_blocks_decrypted 1245 + _initial_num_blocks_is_2_decrypt: 1246 + INITIAL_BLOCKS_DEC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1247 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, dec 1248 + sub $32, %r13 1249 + jmp _initial_blocks_decrypted 1250 + _initial_num_blocks_is_1_decrypt: 1251 + INITIAL_BLOCKS_DEC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1252 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, dec 1253 + sub $16, %r13 1254 + jmp _initial_blocks_decrypted 1255 + _initial_num_blocks_is_0_decrypt: 1256 + INITIAL_BLOCKS_DEC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1257 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, dec 1258 + _initial_blocks_decrypted: 1259 + cmp $0, %r13 1260 + je _zero_cipher_left_decrypt 1261 + sub $64, %r13 1262 + je _four_cipher_left_decrypt 1263 + _decrypt_by_4: 1264 + GHASH_4_ENCRYPT_4_PARALLEL_DEC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ 1265 + %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, dec 1266 + add $64, %r11 1267 + sub $64, %r13 1268 + jne _decrypt_by_4 1269 + _four_cipher_left_decrypt: 1270 + GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \ 1271 + %xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8 1272 + _zero_cipher_left_decrypt: 1273 + mov %arg4, %r13 1274 + and $15, %r13 # %r13 = arg4 (mod 16) 1275 + je _multiple_of_16_bytes_decrypt 1276 + 1277 + # Handle the last <16 byte block seperately 1278 + 1279 + paddd ONE(%rip), %xmm0 # increment CNT to get Yn 1280 + movdqa SHUF_MASK(%rip), %xmm10 1281 + PSHUFB_XMM %xmm10, %xmm0 1282 + 1283 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Yn) 1284 + sub $16, %r11 1285 + add %r13, %r11 1286 + movdqu (%arg3,%r11,1), %xmm1 # recieve the last <16 byte block 1287 + lea SHIFT_MASK+16(%rip), %r12 1288 + sub %r13, %r12 1289 + # adjust the shuffle mask pointer to be able to shift 16-%r13 bytes 1290 + # (%r13 is the number of bytes in plaintext mod 16) 1291 + movdqu (%r12), %xmm2 # get the appropriate shuffle mask 1292 + PSHUFB_XMM %xmm2, %xmm1 # right shift 16-%r13 butes 1293 + 1294 + movdqa %xmm1, %xmm2 1295 + pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn) 1296 + movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 1297 + # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0 1298 + pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0 1299 + pand %xmm1, %xmm2 1300 + movdqa SHUF_MASK(%rip), %xmm10 1301 + PSHUFB_XMM %xmm10 ,%xmm2 1302 + 1303 + pxor %xmm2, %xmm8 1304 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 1305 + # GHASH computation for the last <16 byte block 1306 + sub %r13, %r11 1307 + add $16, %r11 1308 + 1309 + # output %r13 bytes 1310 + MOVQ_R64_XMM %xmm0, %rax 1311 + cmp $8, %r13 1312 + jle _less_than_8_bytes_left_decrypt 1313 + mov %rax, (%arg2 , %r11, 1) 1314 + add $8, %r11 1315 + psrldq $8, %xmm0 1316 + MOVQ_R64_XMM %xmm0, %rax 1317 + sub $8, %r13 1318 + _less_than_8_bytes_left_decrypt: 1319 + mov %al, (%arg2, %r11, 1) 1320 + add $1, %r11 1321 + shr $8, %rax 1322 + sub $1, %r13 1323 + jne _less_than_8_bytes_left_decrypt 1324 + _multiple_of_16_bytes_decrypt: 1325 + mov arg8, %r12 # %r13 = aadLen (number of bytes) 1326 + shl $3, %r12 # convert into number of bits 1327 + movd %r12d, %xmm15 # len(A) in %xmm15 1328 + shl $3, %arg4 # len(C) in bits (*128) 1329 + MOVQ_R64_XMM %arg4, %xmm1 1330 + pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 1331 + pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) 1332 + pxor %xmm15, %xmm8 1333 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 1334 + # final GHASH computation 1335 + movdqa SHUF_MASK(%rip), %xmm10 1336 + PSHUFB_XMM %xmm10, %xmm8 1337 + 1338 + mov %arg5, %rax # %rax = *Y0 1339 + movdqu (%rax), %xmm0 # %xmm0 = Y0 1340 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Y0) 1341 + pxor %xmm8, %xmm0 1342 + _return_T_decrypt: 1343 + mov arg9, %r10 # %r10 = authTag 1344 + mov arg10, %r11 # %r11 = auth_tag_len 1345 + cmp $16, %r11 1346 + je _T_16_decrypt 1347 + cmp $12, %r11 1348 + je _T_12_decrypt 1349 + _T_8_decrypt: 1350 + MOVQ_R64_XMM %xmm0, %rax 1351 + mov %rax, (%r10) 1352 + jmp _return_T_done_decrypt 1353 + _T_12_decrypt: 1354 + MOVQ_R64_XMM %xmm0, %rax 1355 + mov %rax, (%r10) 1356 + psrldq $8, %xmm0 1357 + movd %xmm0, %eax 1358 + mov %eax, 8(%r10) 1359 + jmp _return_T_done_decrypt 1360 + _T_16_decrypt: 1361 + movdqu %xmm0, (%r10) 1362 + _return_T_done_decrypt: 1363 + mov %r14, %rsp 1364 + pop %r14 1365 + pop %r13 1366 + pop %r12 1367 + ret 1368 + 1369 + 1370 + /***************************************************************************** 1371 + * void aesni_gcm_enc(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary. 1372 + * u8 *out, // Ciphertext output. Encrypt in-place is allowed. 1373 + * const u8 *in, // Plaintext input 1374 + * u64 plaintext_len, // Length of data in bytes for encryption. 1375 + * u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association) 1376 + * // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload) 1377 + * // concatenated with 0x00000001. 16-byte aligned pointer. 1378 + * u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary. 1379 + * const u8 *aad, // Additional Authentication Data (AAD) 1380 + * u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes 1381 + * u8 *auth_tag, // Authenticated Tag output. 1382 + * u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 (most likely), 1383 + * // 12 or 8. 1384 + * 1385 + * Assumptions: 1386 + * 1387 + * keys: 1388 + * keys are pre-expanded and aligned to 16 bytes. we are using the 1389 + * first set of 11 keys in the data structure void *aes_ctx 1390 + * 1391 + * 1392 + * iv: 1393 + * 0 1 2 3 1394 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1395 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1396 + * | Salt (From the SA) | 1397 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1398 + * | Initialization Vector | 1399 + * | (This is the sequence number from IPSec header) | 1400 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1401 + * | 0x1 | 1402 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1403 + * 1404 + * 1405 + * 1406 + * AAD: 1407 + * AAD padded to 128 bits with 0 1408 + * for example, assume AAD is a u32 vector 1409 + * 1410 + * if AAD is 8 bytes: 1411 + * AAD[3] = {A0, A1}; 1412 + * padded AAD in xmm register = {A1 A0 0 0} 1413 + * 1414 + * 0 1 2 3 1415 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1416 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1417 + * | SPI (A1) | 1418 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1419 + * | 32-bit Sequence Number (A0) | 1420 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1421 + * | 0x0 | 1422 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1423 + * 1424 + * AAD Format with 32-bit Sequence Number 1425 + * 1426 + * if AAD is 12 bytes: 1427 + * AAD[3] = {A0, A1, A2}; 1428 + * padded AAD in xmm register = {A2 A1 A0 0} 1429 + * 1430 + * 0 1 2 3 1431 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 1432 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1433 + * | SPI (A2) | 1434 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1435 + * | 64-bit Extended Sequence Number {A1,A0} | 1436 + * | | 1437 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1438 + * | 0x0 | 1439 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 1440 + * 1441 + * AAD Format with 64-bit Extended Sequence Number 1442 + * 1443 + * aadLen: 1444 + * from the definition of the spec, aadLen can only be 8 or 12 bytes. 1445 + * The code supports 16 too but for other sizes, the code will fail. 1446 + * 1447 + * TLen: 1448 + * from the definition of the spec, TLen can only be 8, 12 or 16 bytes. 1449 + * For other sizes, the code will fail. 1450 + * 1451 + * poly = x^128 + x^127 + x^126 + x^121 + 1 1452 + ***************************************************************************/ 1453 + ENTRY(aesni_gcm_enc) 1454 + push %r12 1455 + push %r13 1456 + push %r14 1457 + mov %rsp, %r14 1458 + # 1459 + # states of %xmm registers %xmm6:%xmm15 not saved 1460 + # all %xmm registers are clobbered 1461 + # 1462 + sub $VARIABLE_OFFSET, %rsp 1463 + and $~63, %rsp 1464 + mov %arg6, %r12 1465 + movdqu (%r12), %xmm13 1466 + movdqa SHUF_MASK(%rip), %xmm2 1467 + PSHUFB_XMM %xmm2, %xmm13 1468 + 1469 + 1470 + # precompute HashKey<<1 mod poly from the HashKey (required for GHASH) 1471 + 1472 + movdqa %xmm13, %xmm2 1473 + psllq $1, %xmm13 1474 + psrlq $63, %xmm2 1475 + movdqa %xmm2, %xmm1 1476 + pslldq $8, %xmm2 1477 + psrldq $8, %xmm1 1478 + por %xmm2, %xmm13 1479 + 1480 + # reduce HashKey<<1 1481 + 1482 + pshufd $0x24, %xmm1, %xmm2 1483 + pcmpeqd TWOONE(%rip), %xmm2 1484 + pand POLY(%rip), %xmm2 1485 + pxor %xmm2, %xmm13 1486 + movdqa %xmm13, HashKey(%rsp) 1487 + mov %arg4, %r13 # %xmm13 holds HashKey<<1 (mod poly) 1488 + and $-16, %r13 1489 + mov %r13, %r12 1490 + 1491 + # Encrypt first few blocks 1492 + 1493 + and $(3<<4), %r12 1494 + jz _initial_num_blocks_is_0_encrypt 1495 + cmp $(2<<4), %r12 1496 + jb _initial_num_blocks_is_1_encrypt 1497 + je _initial_num_blocks_is_2_encrypt 1498 + _initial_num_blocks_is_3_encrypt: 1499 + INITIAL_BLOCKS_ENC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1500 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, enc 1501 + sub $48, %r13 1502 + jmp _initial_blocks_encrypted 1503 + _initial_num_blocks_is_2_encrypt: 1504 + INITIAL_BLOCKS_ENC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1505 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, enc 1506 + sub $32, %r13 1507 + jmp _initial_blocks_encrypted 1508 + _initial_num_blocks_is_1_encrypt: 1509 + INITIAL_BLOCKS_ENC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1510 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, enc 1511 + sub $16, %r13 1512 + jmp _initial_blocks_encrypted 1513 + _initial_num_blocks_is_0_encrypt: 1514 + INITIAL_BLOCKS_ENC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ 1515 + %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, enc 1516 + _initial_blocks_encrypted: 1517 + 1518 + # Main loop - Encrypt remaining blocks 1519 + 1520 + cmp $0, %r13 1521 + je _zero_cipher_left_encrypt 1522 + sub $64, %r13 1523 + je _four_cipher_left_encrypt 1524 + _encrypt_by_4_encrypt: 1525 + GHASH_4_ENCRYPT_4_PARALLEL_ENC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ 1526 + %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, enc 1527 + add $64, %r11 1528 + sub $64, %r13 1529 + jne _encrypt_by_4_encrypt 1530 + _four_cipher_left_encrypt: 1531 + GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \ 1532 + %xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8 1533 + _zero_cipher_left_encrypt: 1534 + mov %arg4, %r13 1535 + and $15, %r13 # %r13 = arg4 (mod 16) 1536 + je _multiple_of_16_bytes_encrypt 1537 + 1538 + # Handle the last <16 Byte block seperately 1539 + paddd ONE(%rip), %xmm0 # INCR CNT to get Yn 1540 + movdqa SHUF_MASK(%rip), %xmm10 1541 + PSHUFB_XMM %xmm10, %xmm0 1542 + 1543 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn) 1544 + sub $16, %r11 1545 + add %r13, %r11 1546 + movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte blocks 1547 + lea SHIFT_MASK+16(%rip), %r12 1548 + sub %r13, %r12 1549 + # adjust the shuffle mask pointer to be able to shift 16-r13 bytes 1550 + # (%r13 is the number of bytes in plaintext mod 16) 1551 + movdqu (%r12), %xmm2 # get the appropriate shuffle mask 1552 + PSHUFB_XMM %xmm2, %xmm1 # shift right 16-r13 byte 1553 + pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn) 1554 + movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 1555 + # get the appropriate mask to mask out top 16-r13 bytes of xmm0 1556 + pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0 1557 + movdqa SHUF_MASK(%rip), %xmm10 1558 + PSHUFB_XMM %xmm10,%xmm0 1559 + 1560 + pxor %xmm0, %xmm8 1561 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 1562 + # GHASH computation for the last <16 byte block 1563 + sub %r13, %r11 1564 + add $16, %r11 1565 + PSHUFB_XMM %xmm10, %xmm1 1566 + 1567 + # shuffle xmm0 back to output as ciphertext 1568 + 1569 + # Output %r13 bytes 1570 + MOVQ_R64_XMM %xmm0, %rax 1571 + cmp $8, %r13 1572 + jle _less_than_8_bytes_left_encrypt 1573 + mov %rax, (%arg2 , %r11, 1) 1574 + add $8, %r11 1575 + psrldq $8, %xmm0 1576 + MOVQ_R64_XMM %xmm0, %rax 1577 + sub $8, %r13 1578 + _less_than_8_bytes_left_encrypt: 1579 + mov %al, (%arg2, %r11, 1) 1580 + add $1, %r11 1581 + shr $8, %rax 1582 + sub $1, %r13 1583 + jne _less_than_8_bytes_left_encrypt 1584 + _multiple_of_16_bytes_encrypt: 1585 + mov arg8, %r12 # %r12 = addLen (number of bytes) 1586 + shl $3, %r12 1587 + movd %r12d, %xmm15 # len(A) in %xmm15 1588 + shl $3, %arg4 # len(C) in bits (*128) 1589 + MOVQ_R64_XMM %arg4, %xmm1 1590 + pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 1591 + pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) 1592 + pxor %xmm15, %xmm8 1593 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 1594 + # final GHASH computation 1595 + movdqa SHUF_MASK(%rip), %xmm10 1596 + PSHUFB_XMM %xmm10, %xmm8 # perform a 16 byte swap 1597 + 1598 + mov %arg5, %rax # %rax = *Y0 1599 + movdqu (%rax), %xmm0 # %xmm0 = Y0 1600 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm15 # Encrypt(K, Y0) 1601 + pxor %xmm8, %xmm0 1602 + _return_T_encrypt: 1603 + mov arg9, %r10 # %r10 = authTag 1604 + mov arg10, %r11 # %r11 = auth_tag_len 1605 + cmp $16, %r11 1606 + je _T_16_encrypt 1607 + cmp $12, %r11 1608 + je _T_12_encrypt 1609 + _T_8_encrypt: 1610 + MOVQ_R64_XMM %xmm0, %rax 1611 + mov %rax, (%r10) 1612 + jmp _return_T_done_encrypt 1613 + _T_12_encrypt: 1614 + MOVQ_R64_XMM %xmm0, %rax 1615 + mov %rax, (%r10) 1616 + psrldq $8, %xmm0 1617 + movd %xmm0, %eax 1618 + mov %eax, 8(%r10) 1619 + jmp _return_T_done_encrypt 1620 + _T_16_encrypt: 1621 + movdqu %xmm0, (%r10) 1622 + _return_T_done_encrypt: 1623 + mov %r14, %rsp 1624 + pop %r14 1625 + pop %r13 1626 + pop %r12 1627 + ret 1628 + 1629 + #endif 1630 + 121 1631 122 1632 _key_expansion_128: 123 1633 _key_expansion_256a: ··· 1709 55 shufps $0b10001100, %xmm0, %xmm4 1710 56 pxor %xmm4, %xmm0 1711 57 pxor %xmm1, %xmm0 1712 - movaps %xmm0, (%rcx) 1713 - add $0x10, %rcx 58 + movaps %xmm0, (TKEYP) 59 + add $0x10, TKEYP 1714 60 ret 1715 61 62 + .align 4 1716 63 _key_expansion_192a: 1717 64 pshufd $0b01010101, %xmm1, %xmm1 1718 65 shufps $0b00010000, %xmm0, %xmm4 ··· 1731 76 1732 77 movaps %xmm0, %xmm1 1733 78 shufps $0b01000100, %xmm0, %xmm6 1734 - movaps %xmm6, (%rcx) 79 + movaps %xmm6, (TKEYP) 1735 80 shufps $0b01001110, %xmm2, %xmm1 1736 - movaps %xmm1, 16(%rcx) 1737 - add $0x20, %rcx 81 + movaps %xmm1, 0x10(TKEYP) 82 + add $0x20, TKEYP 1738 83 ret 1739 84 85 + .align 4 1740 86 _key_expansion_192b: 1741 87 pshufd $0b01010101, %xmm1, %xmm1 1742 88 shufps $0b00010000, %xmm0, %xmm4 ··· 1752 96 pxor %xmm3, %xmm2 1753 97 pxor %xmm5, %xmm2 1754 98 1755 - movaps %xmm0, (%rcx) 1756 - add $0x10, %rcx 99 + movaps %xmm0, (TKEYP) 100 + add $0x10, TKEYP 1757 101 ret 1758 102 103 + .align 4 1759 104 _key_expansion_256b: 1760 105 pshufd $0b10101010, %xmm1, %xmm1 1761 106 shufps $0b00010000, %xmm2, %xmm4 ··· 1764 107 shufps $0b10001100, %xmm2, %xmm4 1765 108 pxor %xmm4, %xmm2 1766 109 pxor %xmm1, %xmm2 1767 - movaps %xmm2, (%rcx) 1768 - add $0x10, %rcx 110 + movaps %xmm2, (TKEYP) 111 + add $0x10, TKEYP 1769 112 ret 1770 113 1771 114 /* ··· 1773 116 * unsigned int key_len) 1774 117 */ 1775 118 ENTRY(aesni_set_key) 1776 - movups (%rsi), %xmm0 # user key (first 16 bytes) 1777 - movaps %xmm0, (%rdi) 1778 - lea 0x10(%rdi), %rcx # key addr 1779 - movl %edx, 480(%rdi) 119 + #ifndef __x86_64__ 120 + pushl KEYP 121 + movl 8(%esp), KEYP # ctx 122 + movl 12(%esp), UKEYP # in_key 123 + movl 16(%esp), %edx # key_len 124 + #endif 125 + movups (UKEYP), %xmm0 # user key (first 16 bytes) 126 + movaps %xmm0, (KEYP) 127 + lea 0x10(KEYP), TKEYP # key addr 128 + movl %edx, 480(KEYP) 1780 129 pxor %xmm4, %xmm4 # xmm4 is assumed 0 in _key_expansion_x 1781 130 cmp $24, %dl 1782 131 jb .Lenc_key128 1783 132 je .Lenc_key192 1784 - movups 0x10(%rsi), %xmm2 # other user key 1785 - movaps %xmm2, (%rcx) 1786 - add $0x10, %rcx 133 + movups 0x10(UKEYP), %xmm2 # other user key 134 + movaps %xmm2, (TKEYP) 135 + add $0x10, TKEYP 1787 136 AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 1788 137 call _key_expansion_256a 1789 138 AESKEYGENASSIST 0x1 %xmm0 %xmm1 ··· 1818 155 call _key_expansion_256a 1819 156 jmp .Ldec_key 1820 157 .Lenc_key192: 1821 - movq 0x10(%rsi), %xmm2 # other user key 158 + movq 0x10(UKEYP), %xmm2 # other user key 1822 159 AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 1823 160 call _key_expansion_192a 1824 161 AESKEYGENASSIST 0x2 %xmm2 %xmm1 # round 2 ··· 1858 195 AESKEYGENASSIST 0x36 %xmm0 %xmm1 # round 10 1859 196 call _key_expansion_128 1860 197 .Ldec_key: 1861 - sub $0x10, %rcx 1862 - movaps (%rdi), %xmm0 1863 - movaps (%rcx), %xmm1 1864 - movaps %xmm0, 240(%rcx) 1865 - movaps %xmm1, 240(%rdi) 1866 - add $0x10, %rdi 1867 - lea 240-16(%rcx), %rsi 198 + sub $0x10, TKEYP 199 + movaps (KEYP), %xmm0 200 + movaps (TKEYP), %xmm1 201 + movaps %xmm0, 240(TKEYP) 202 + movaps %xmm1, 240(KEYP) 203 + add $0x10, KEYP 204 + lea 240-16(TKEYP), UKEYP 1868 205 .align 4 1869 206 .Ldec_key_loop: 1870 - movaps (%rdi), %xmm0 207 + movaps (KEYP), %xmm0 1871 208 AESIMC %xmm0 %xmm1 1872 - movaps %xmm1, (%rsi) 1873 - add $0x10, %rdi 1874 - sub $0x10, %rsi 1875 - cmp %rcx, %rdi 209 + movaps %xmm1, (UKEYP) 210 + add $0x10, KEYP 211 + sub $0x10, UKEYP 212 + cmp TKEYP, KEYP 1876 213 jb .Ldec_key_loop 1877 - xor %rax, %rax 214 + xor AREG, AREG 215 + #ifndef __x86_64__ 216 + popl KEYP 217 + #endif 1878 218 ret 1879 219 1880 220 /* 1881 221 * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) 1882 222 */ 1883 223 ENTRY(aesni_enc) 224 + #ifndef __x86_64__ 225 + pushl KEYP 226 + pushl KLEN 227 + movl 12(%esp), KEYP 228 + movl 16(%esp), OUTP 229 + movl 20(%esp), INP 230 + #endif 1884 231 movl 480(KEYP), KLEN # key length 1885 232 movups (INP), STATE # input 1886 233 call _aesni_enc1 1887 234 movups STATE, (OUTP) # output 235 + #ifndef __x86_64__ 236 + popl KLEN 237 + popl KEYP 238 + #endif 1888 239 ret 1889 240 1890 241 /* ··· 1913 236 * KEY 1914 237 * TKEYP (T1) 1915 238 */ 239 + .align 4 1916 240 _aesni_enc1: 1917 241 movaps (KEYP), KEY # key 1918 242 mov KEYP, TKEYP ··· 1976 298 * KEY 1977 299 * TKEYP (T1) 1978 300 */ 301 + .align 4 1979 302 _aesni_enc4: 1980 303 movaps (KEYP), KEY # key 1981 304 mov KEYP, TKEYP ··· 2070 391 * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) 2071 392 */ 2072 393 ENTRY(aesni_dec) 394 + #ifndef __x86_64__ 395 + pushl KEYP 396 + pushl KLEN 397 + movl 12(%esp), KEYP 398 + movl 16(%esp), OUTP 399 + movl 20(%esp), INP 400 + #endif 2073 401 mov 480(KEYP), KLEN # key length 2074 402 add $240, KEYP 2075 403 movups (INP), STATE # input 2076 404 call _aesni_dec1 2077 405 movups STATE, (OUTP) #output 406 + #ifndef __x86_64__ 407 + popl KLEN 408 + popl KEYP 409 + #endif 2078 410 ret 2079 411 2080 412 /* ··· 2100 410 * KEY 2101 411 * TKEYP (T1) 2102 412 */ 413 + .align 4 2103 414 _aesni_dec1: 2104 415 movaps (KEYP), KEY # key 2105 416 mov KEYP, TKEYP ··· 2163 472 * KEY 2164 473 * TKEYP (T1) 2165 474 */ 475 + .align 4 2166 476 _aesni_dec4: 2167 477 movaps (KEYP), KEY # key 2168 478 mov KEYP, TKEYP ··· 2258 566 * size_t len) 2259 567 */ 2260 568 ENTRY(aesni_ecb_enc) 569 + #ifndef __x86_64__ 570 + pushl LEN 571 + pushl KEYP 572 + pushl KLEN 573 + movl 16(%esp), KEYP 574 + movl 20(%esp), OUTP 575 + movl 24(%esp), INP 576 + movl 28(%esp), LEN 577 + #endif 2261 578 test LEN, LEN # check length 2262 579 jz .Lecb_enc_ret 2263 580 mov 480(KEYP), KLEN ··· 2303 602 cmp $16, LEN 2304 603 jge .Lecb_enc_loop1 2305 604 .Lecb_enc_ret: 605 + #ifndef __x86_64__ 606 + popl KLEN 607 + popl KEYP 608 + popl LEN 609 + #endif 2306 610 ret 2307 611 2308 612 /* ··· 2315 609 * size_t len); 2316 610 */ 2317 611 ENTRY(aesni_ecb_dec) 612 + #ifndef __x86_64__ 613 + pushl LEN 614 + pushl KEYP 615 + pushl KLEN 616 + movl 16(%esp), KEYP 617 + movl 20(%esp), OUTP 618 + movl 24(%esp), INP 619 + movl 28(%esp), LEN 620 + #endif 2318 621 test LEN, LEN 2319 622 jz .Lecb_dec_ret 2320 623 mov 480(KEYP), KLEN ··· 2361 646 cmp $16, LEN 2362 647 jge .Lecb_dec_loop1 2363 648 .Lecb_dec_ret: 649 + #ifndef __x86_64__ 650 + popl KLEN 651 + popl KEYP 652 + popl LEN 653 + #endif 2364 654 ret 2365 655 2366 656 /* ··· 2373 653 * size_t len, u8 *iv) 2374 654 */ 2375 655 ENTRY(aesni_cbc_enc) 656 + #ifndef __x86_64__ 657 + pushl IVP 658 + pushl LEN 659 + pushl KEYP 660 + pushl KLEN 661 + movl 20(%esp), KEYP 662 + movl 24(%esp), OUTP 663 + movl 28(%esp), INP 664 + movl 32(%esp), LEN 665 + movl 36(%esp), IVP 666 + #endif 2376 667 cmp $16, LEN 2377 668 jb .Lcbc_enc_ret 2378 669 mov 480(KEYP), KLEN ··· 2401 670 jge .Lcbc_enc_loop 2402 671 movups STATE, (IVP) 2403 672 .Lcbc_enc_ret: 673 + #ifndef __x86_64__ 674 + popl KLEN 675 + popl KEYP 676 + popl LEN 677 + popl IVP 678 + #endif 2404 679 ret 2405 680 2406 681 /* ··· 2414 677 * size_t len, u8 *iv) 2415 678 */ 2416 679 ENTRY(aesni_cbc_dec) 680 + #ifndef __x86_64__ 681 + pushl IVP 682 + pushl LEN 683 + pushl KEYP 684 + pushl KLEN 685 + movl 20(%esp), KEYP 686 + movl 24(%esp), OUTP 687 + movl 28(%esp), INP 688 + movl 32(%esp), LEN 689 + movl 36(%esp), IVP 690 + #endif 2417 691 cmp $16, LEN 2418 692 jb .Lcbc_dec_just_ret 2419 693 mov 480(KEYP), KLEN ··· 2438 690 movaps IN1, STATE1 2439 691 movups 0x10(INP), IN2 2440 692 movaps IN2, STATE2 693 + #ifdef __x86_64__ 2441 694 movups 0x20(INP), IN3 2442 695 movaps IN3, STATE3 2443 696 movups 0x30(INP), IN4 2444 697 movaps IN4, STATE4 698 + #else 699 + movups 0x20(INP), IN1 700 + movaps IN1, STATE3 701 + movups 0x30(INP), IN2 702 + movaps IN2, STATE4 703 + #endif 2445 704 call _aesni_dec4 2446 705 pxor IV, STATE1 706 + #ifdef __x86_64__ 2447 707 pxor IN1, STATE2 2448 708 pxor IN2, STATE3 2449 709 pxor IN3, STATE4 2450 710 movaps IN4, IV 711 + #else 712 + pxor (INP), STATE2 713 + pxor 0x10(INP), STATE3 714 + pxor IN1, STATE4 715 + movaps IN2, IV 716 + #endif 2451 717 movups STATE1, (OUTP) 2452 718 movups STATE2, 0x10(OUTP) 2453 719 movups STATE3, 0x20(OUTP) ··· 2489 727 .Lcbc_dec_ret: 2490 728 movups IV, (IVP) 2491 729 .Lcbc_dec_just_ret: 730 + #ifndef __x86_64__ 731 + popl KLEN 732 + popl KEYP 733 + popl LEN 734 + popl IVP 735 + #endif 2492 736 ret 2493 737 738 + #ifdef __x86_64__ 2494 739 .align 16 2495 740 .Lbswap_mask: 2496 741 .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 ··· 2513 744 * INC: == 1, in little endian 2514 745 * BSWAP_MASK == endian swapping mask 2515 746 */ 747 + .align 4 2516 748 _aesni_inc_init: 2517 749 movaps .Lbswap_mask, BSWAP_MASK 2518 750 movaps IV, CTR ··· 2538 768 * CTR: == output IV, in little endian 2539 769 * TCTR_LOW: == lower qword of CTR 2540 770 */ 771 + .align 4 2541 772 _aesni_inc: 2542 773 paddq INC, CTR 2543 774 add $1, TCTR_LOW ··· 2610 839 movups IV, (IVP) 2611 840 .Lctr_enc_just_ret: 2612 841 ret 842 + #endif
+533 -7
arch/x86/crypto/aesni-intel_glue.c
··· 5 5 * Copyright (C) 2008, Intel Corp. 6 6 * Author: Huang Ying <ying.huang@intel.com> 7 7 * 8 + * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD 9 + * interface for 64-bit kernels. 10 + * Authors: Adrian Hoban <adrian.hoban@intel.com> 11 + * Gabriele Paoloni <gabriele.paoloni@intel.com> 12 + * Tadeusz Struk (tadeusz.struk@intel.com) 13 + * Aidan O'Mahony (aidan.o.mahony@intel.com) 14 + * Copyright (c) 2010, Intel Corporation. 15 + * 8 16 * This program is free software; you can redistribute it and/or modify 9 17 * it under the terms of the GNU General Public License as published by 10 18 * the Free Software Foundation; either version 2 of the License, or ··· 29 21 #include <crypto/ctr.h> 30 22 #include <asm/i387.h> 31 23 #include <asm/aes.h> 24 + #include <crypto/scatterwalk.h> 25 + #include <crypto/internal/aead.h> 26 + #include <linux/workqueue.h> 27 + #include <linux/spinlock.h> 32 28 33 29 #if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE) 34 30 #define HAS_CTR ··· 54 42 struct cryptd_ablkcipher *cryptd_tfm; 55 43 }; 56 44 57 - #define AESNI_ALIGN 16 45 + /* This data is stored at the end of the crypto_tfm struct. 46 + * It's a type of per "session" data storage location. 47 + * This needs to be 16 byte aligned. 48 + */ 49 + struct aesni_rfc4106_gcm_ctx { 50 + u8 hash_subkey[16]; 51 + struct crypto_aes_ctx aes_key_expanded; 52 + u8 nonce[4]; 53 + struct cryptd_aead *cryptd_tfm; 54 + }; 55 + 56 + struct aesni_gcm_set_hash_subkey_result { 57 + int err; 58 + struct completion completion; 59 + }; 60 + 61 + struct aesni_hash_subkey_req_data { 62 + u8 iv[16]; 63 + struct aesni_gcm_set_hash_subkey_result result; 64 + struct scatterlist sg; 65 + }; 66 + 67 + #define AESNI_ALIGN (16) 58 68 #define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1)) 69 + #define RFC4106_HASH_SUBKEY_SIZE 16 59 70 60 71 asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key, 61 72 unsigned int key_len); ··· 94 59 const u8 *in, unsigned int len, u8 *iv); 95 60 asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, 96 61 const u8 *in, unsigned int len, u8 *iv); 62 + #ifdef CONFIG_X86_64 97 63 asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, 98 64 const u8 *in, unsigned int len, u8 *iv); 65 + 66 + /* asmlinkage void aesni_gcm_enc() 67 + * void *ctx, AES Key schedule. Starts on a 16 byte boundary. 68 + * u8 *out, Ciphertext output. Encrypt in-place is allowed. 69 + * const u8 *in, Plaintext input 70 + * unsigned long plaintext_len, Length of data in bytes for encryption. 71 + * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association) 72 + * concatenated with 8 byte Initialisation Vector (from IPSec ESP 73 + * Payload) concatenated with 0x00000001. 16-byte aligned pointer. 74 + * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary. 75 + * const u8 *aad, Additional Authentication Data (AAD) 76 + * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this 77 + * is going to be 8 or 12 bytes 78 + * u8 *auth_tag, Authenticated Tag output. 79 + * unsigned long auth_tag_len), Authenticated Tag Length in bytes. 80 + * Valid values are 16 (most likely), 12 or 8. 81 + */ 82 + asmlinkage void aesni_gcm_enc(void *ctx, u8 *out, 83 + const u8 *in, unsigned long plaintext_len, u8 *iv, 84 + u8 *hash_subkey, const u8 *aad, unsigned long aad_len, 85 + u8 *auth_tag, unsigned long auth_tag_len); 86 + 87 + /* asmlinkage void aesni_gcm_dec() 88 + * void *ctx, AES Key schedule. Starts on a 16 byte boundary. 89 + * u8 *out, Plaintext output. Decrypt in-place is allowed. 90 + * const u8 *in, Ciphertext input 91 + * unsigned long ciphertext_len, Length of data in bytes for decryption. 92 + * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association) 93 + * concatenated with 8 byte Initialisation Vector (from IPSec ESP 94 + * Payload) concatenated with 0x00000001. 16-byte aligned pointer. 95 + * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary. 96 + * const u8 *aad, Additional Authentication Data (AAD) 97 + * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this is going 98 + * to be 8 or 12 bytes 99 + * u8 *auth_tag, Authenticated Tag output. 100 + * unsigned long auth_tag_len) Authenticated Tag Length in bytes. 101 + * Valid values are 16 (most likely), 12 or 8. 102 + */ 103 + asmlinkage void aesni_gcm_dec(void *ctx, u8 *out, 104 + const u8 *in, unsigned long ciphertext_len, u8 *iv, 105 + u8 *hash_subkey, const u8 *aad, unsigned long aad_len, 106 + u8 *auth_tag, unsigned long auth_tag_len); 107 + 108 + static inline struct 109 + aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm) 110 + { 111 + return 112 + (struct aesni_rfc4106_gcm_ctx *) 113 + PTR_ALIGN((u8 *) 114 + crypto_tfm_ctx(crypto_aead_tfm(tfm)), AESNI_ALIGN); 115 + } 116 + #endif 99 117 100 118 static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) 101 119 { ··· 412 324 }, 413 325 }; 414 326 327 + #ifdef CONFIG_X86_64 415 328 static void ctr_crypt_final(struct crypto_aes_ctx *ctx, 416 329 struct blkcipher_walk *walk) 417 330 { ··· 478 389 }, 479 390 }, 480 391 }; 392 + #endif 481 393 482 394 static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, 483 395 unsigned int key_len) ··· 626 536 }, 627 537 }; 628 538 539 + #ifdef CONFIG_X86_64 629 540 static int ablk_ctr_init(struct crypto_tfm *tfm) 630 541 { 631 542 struct cryptd_ablkcipher *cryptd_tfm; ··· 702 611 }, 703 612 }, 704 613 }; 614 + #endif 705 615 #endif 706 616 707 617 #ifdef HAS_LRW ··· 822 730 }; 823 731 #endif 824 732 733 + #ifdef CONFIG_X86_64 734 + static int rfc4106_init(struct crypto_tfm *tfm) 735 + { 736 + struct cryptd_aead *cryptd_tfm; 737 + struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *) 738 + PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); 739 + cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0); 740 + if (IS_ERR(cryptd_tfm)) 741 + return PTR_ERR(cryptd_tfm); 742 + ctx->cryptd_tfm = cryptd_tfm; 743 + tfm->crt_aead.reqsize = sizeof(struct aead_request) 744 + + crypto_aead_reqsize(&cryptd_tfm->base); 745 + return 0; 746 + } 747 + 748 + static void rfc4106_exit(struct crypto_tfm *tfm) 749 + { 750 + struct aesni_rfc4106_gcm_ctx *ctx = 751 + (struct aesni_rfc4106_gcm_ctx *) 752 + PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); 753 + if (!IS_ERR(ctx->cryptd_tfm)) 754 + cryptd_free_aead(ctx->cryptd_tfm); 755 + return; 756 + } 757 + 758 + static void 759 + rfc4106_set_hash_subkey_done(struct crypto_async_request *req, int err) 760 + { 761 + struct aesni_gcm_set_hash_subkey_result *result = req->data; 762 + 763 + if (err == -EINPROGRESS) 764 + return; 765 + result->err = err; 766 + complete(&result->completion); 767 + } 768 + 769 + static int 770 + rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len) 771 + { 772 + struct crypto_ablkcipher *ctr_tfm; 773 + struct ablkcipher_request *req; 774 + int ret = -EINVAL; 775 + struct aesni_hash_subkey_req_data *req_data; 776 + 777 + ctr_tfm = crypto_alloc_ablkcipher("ctr(aes)", 0, 0); 778 + if (IS_ERR(ctr_tfm)) 779 + return PTR_ERR(ctr_tfm); 780 + 781 + crypto_ablkcipher_clear_flags(ctr_tfm, ~0); 782 + 783 + ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len); 784 + if (ret) { 785 + crypto_free_ablkcipher(ctr_tfm); 786 + return ret; 787 + } 788 + 789 + req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL); 790 + if (!req) { 791 + crypto_free_ablkcipher(ctr_tfm); 792 + return -EINVAL; 793 + } 794 + 795 + req_data = kmalloc(sizeof(*req_data), GFP_KERNEL); 796 + if (!req_data) { 797 + crypto_free_ablkcipher(ctr_tfm); 798 + return -ENOMEM; 799 + } 800 + memset(req_data->iv, 0, sizeof(req_data->iv)); 801 + 802 + /* Clear the data in the hash sub key container to zero.*/ 803 + /* We want to cipher all zeros to create the hash sub key. */ 804 + memset(hash_subkey, 0, RFC4106_HASH_SUBKEY_SIZE); 805 + 806 + init_completion(&req_data->result.completion); 807 + sg_init_one(&req_data->sg, hash_subkey, RFC4106_HASH_SUBKEY_SIZE); 808 + ablkcipher_request_set_tfm(req, ctr_tfm); 809 + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | 810 + CRYPTO_TFM_REQ_MAY_BACKLOG, 811 + rfc4106_set_hash_subkey_done, 812 + &req_data->result); 813 + 814 + ablkcipher_request_set_crypt(req, &req_data->sg, 815 + &req_data->sg, RFC4106_HASH_SUBKEY_SIZE, req_data->iv); 816 + 817 + ret = crypto_ablkcipher_encrypt(req); 818 + if (ret == -EINPROGRESS || ret == -EBUSY) { 819 + ret = wait_for_completion_interruptible 820 + (&req_data->result.completion); 821 + if (!ret) 822 + ret = req_data->result.err; 823 + } 824 + ablkcipher_request_free(req); 825 + kfree(req_data); 826 + crypto_free_ablkcipher(ctr_tfm); 827 + return ret; 828 + } 829 + 830 + static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, 831 + unsigned int key_len) 832 + { 833 + int ret = 0; 834 + struct crypto_tfm *tfm = crypto_aead_tfm(parent); 835 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); 836 + u8 *new_key_mem = NULL; 837 + 838 + if (key_len < 4) { 839 + crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 840 + return -EINVAL; 841 + } 842 + /*Account for 4 byte nonce at the end.*/ 843 + key_len -= 4; 844 + if (key_len != AES_KEYSIZE_128) { 845 + crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); 846 + return -EINVAL; 847 + } 848 + 849 + memcpy(ctx->nonce, key + key_len, sizeof(ctx->nonce)); 850 + /*This must be on a 16 byte boundary!*/ 851 + if ((unsigned long)(&(ctx->aes_key_expanded.key_enc[0])) % AESNI_ALIGN) 852 + return -EINVAL; 853 + 854 + if ((unsigned long)key % AESNI_ALIGN) { 855 + /*key is not aligned: use an auxuliar aligned pointer*/ 856 + new_key_mem = kmalloc(key_len+AESNI_ALIGN, GFP_KERNEL); 857 + if (!new_key_mem) 858 + return -ENOMEM; 859 + 860 + new_key_mem = PTR_ALIGN(new_key_mem, AESNI_ALIGN); 861 + memcpy(new_key_mem, key, key_len); 862 + key = new_key_mem; 863 + } 864 + 865 + if (!irq_fpu_usable()) 866 + ret = crypto_aes_expand_key(&(ctx->aes_key_expanded), 867 + key, key_len); 868 + else { 869 + kernel_fpu_begin(); 870 + ret = aesni_set_key(&(ctx->aes_key_expanded), key, key_len); 871 + kernel_fpu_end(); 872 + } 873 + /*This must be on a 16 byte boundary!*/ 874 + if ((unsigned long)(&(ctx->hash_subkey[0])) % AESNI_ALIGN) { 875 + ret = -EINVAL; 876 + goto exit; 877 + } 878 + ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len); 879 + exit: 880 + kfree(new_key_mem); 881 + return ret; 882 + } 883 + 884 + /* This is the Integrity Check Value (aka the authentication tag length and can 885 + * be 8, 12 or 16 bytes long. */ 886 + static int rfc4106_set_authsize(struct crypto_aead *parent, 887 + unsigned int authsize) 888 + { 889 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); 890 + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 891 + 892 + switch (authsize) { 893 + case 8: 894 + case 12: 895 + case 16: 896 + break; 897 + default: 898 + return -EINVAL; 899 + } 900 + crypto_aead_crt(parent)->authsize = authsize; 901 + crypto_aead_crt(cryptd_child)->authsize = authsize; 902 + return 0; 903 + } 904 + 905 + static int rfc4106_encrypt(struct aead_request *req) 906 + { 907 + int ret; 908 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 909 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 910 + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 911 + 912 + if (!irq_fpu_usable()) { 913 + struct aead_request *cryptd_req = 914 + (struct aead_request *) aead_request_ctx(req); 915 + memcpy(cryptd_req, req, sizeof(*req)); 916 + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 917 + return crypto_aead_encrypt(cryptd_req); 918 + } else { 919 + kernel_fpu_begin(); 920 + ret = cryptd_child->base.crt_aead.encrypt(req); 921 + kernel_fpu_end(); 922 + return ret; 923 + } 924 + } 925 + 926 + static int rfc4106_decrypt(struct aead_request *req) 927 + { 928 + int ret; 929 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 930 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 931 + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); 932 + 933 + if (!irq_fpu_usable()) { 934 + struct aead_request *cryptd_req = 935 + (struct aead_request *) aead_request_ctx(req); 936 + memcpy(cryptd_req, req, sizeof(*req)); 937 + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 938 + return crypto_aead_decrypt(cryptd_req); 939 + } else { 940 + kernel_fpu_begin(); 941 + ret = cryptd_child->base.crt_aead.decrypt(req); 942 + kernel_fpu_end(); 943 + return ret; 944 + } 945 + } 946 + 947 + static struct crypto_alg rfc4106_alg = { 948 + .cra_name = "rfc4106(gcm(aes))", 949 + .cra_driver_name = "rfc4106-gcm-aesni", 950 + .cra_priority = 400, 951 + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, 952 + .cra_blocksize = 1, 953 + .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN, 954 + .cra_alignmask = 0, 955 + .cra_type = &crypto_nivaead_type, 956 + .cra_module = THIS_MODULE, 957 + .cra_list = LIST_HEAD_INIT(rfc4106_alg.cra_list), 958 + .cra_init = rfc4106_init, 959 + .cra_exit = rfc4106_exit, 960 + .cra_u = { 961 + .aead = { 962 + .setkey = rfc4106_set_key, 963 + .setauthsize = rfc4106_set_authsize, 964 + .encrypt = rfc4106_encrypt, 965 + .decrypt = rfc4106_decrypt, 966 + .geniv = "seqiv", 967 + .ivsize = 8, 968 + .maxauthsize = 16, 969 + }, 970 + }, 971 + }; 972 + 973 + static int __driver_rfc4106_encrypt(struct aead_request *req) 974 + { 975 + u8 one_entry_in_sg = 0; 976 + u8 *src, *dst, *assoc; 977 + __be32 counter = cpu_to_be32(1); 978 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 979 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 980 + void *aes_ctx = &(ctx->aes_key_expanded); 981 + unsigned long auth_tag_len = crypto_aead_authsize(tfm); 982 + u8 iv_tab[16+AESNI_ALIGN]; 983 + u8* iv = (u8 *) PTR_ALIGN((u8 *)iv_tab, AESNI_ALIGN); 984 + struct scatter_walk src_sg_walk; 985 + struct scatter_walk assoc_sg_walk; 986 + struct scatter_walk dst_sg_walk; 987 + unsigned int i; 988 + 989 + /* Assuming we are supporting rfc4106 64-bit extended */ 990 + /* sequence numbers We need to have the AAD length equal */ 991 + /* to 8 or 12 bytes */ 992 + if (unlikely(req->assoclen != 8 && req->assoclen != 12)) 993 + return -EINVAL; 994 + /* IV below built */ 995 + for (i = 0; i < 4; i++) 996 + *(iv+i) = ctx->nonce[i]; 997 + for (i = 0; i < 8; i++) 998 + *(iv+4+i) = req->iv[i]; 999 + *((__be32 *)(iv+12)) = counter; 1000 + 1001 + if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) { 1002 + one_entry_in_sg = 1; 1003 + scatterwalk_start(&src_sg_walk, req->src); 1004 + scatterwalk_start(&assoc_sg_walk, req->assoc); 1005 + src = scatterwalk_map(&src_sg_walk, 0); 1006 + assoc = scatterwalk_map(&assoc_sg_walk, 0); 1007 + dst = src; 1008 + if (unlikely(req->src != req->dst)) { 1009 + scatterwalk_start(&dst_sg_walk, req->dst); 1010 + dst = scatterwalk_map(&dst_sg_walk, 0); 1011 + } 1012 + 1013 + } else { 1014 + /* Allocate memory for src, dst, assoc */ 1015 + src = kmalloc(req->cryptlen + auth_tag_len + req->assoclen, 1016 + GFP_ATOMIC); 1017 + if (unlikely(!src)) 1018 + return -ENOMEM; 1019 + assoc = (src + req->cryptlen + auth_tag_len); 1020 + scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); 1021 + scatterwalk_map_and_copy(assoc, req->assoc, 0, 1022 + req->assoclen, 0); 1023 + dst = src; 1024 + } 1025 + 1026 + aesni_gcm_enc(aes_ctx, dst, src, (unsigned long)req->cryptlen, iv, 1027 + ctx->hash_subkey, assoc, (unsigned long)req->assoclen, dst 1028 + + ((unsigned long)req->cryptlen), auth_tag_len); 1029 + 1030 + /* The authTag (aka the Integrity Check Value) needs to be written 1031 + * back to the packet. */ 1032 + if (one_entry_in_sg) { 1033 + if (unlikely(req->src != req->dst)) { 1034 + scatterwalk_unmap(dst, 0); 1035 + scatterwalk_done(&dst_sg_walk, 0, 0); 1036 + } 1037 + scatterwalk_unmap(src, 0); 1038 + scatterwalk_unmap(assoc, 0); 1039 + scatterwalk_done(&src_sg_walk, 0, 0); 1040 + scatterwalk_done(&assoc_sg_walk, 0, 0); 1041 + } else { 1042 + scatterwalk_map_and_copy(dst, req->dst, 0, 1043 + req->cryptlen + auth_tag_len, 1); 1044 + kfree(src); 1045 + } 1046 + return 0; 1047 + } 1048 + 1049 + static int __driver_rfc4106_decrypt(struct aead_request *req) 1050 + { 1051 + u8 one_entry_in_sg = 0; 1052 + u8 *src, *dst, *assoc; 1053 + unsigned long tempCipherLen = 0; 1054 + __be32 counter = cpu_to_be32(1); 1055 + int retval = 0; 1056 + struct crypto_aead *tfm = crypto_aead_reqtfm(req); 1057 + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); 1058 + void *aes_ctx = &(ctx->aes_key_expanded); 1059 + unsigned long auth_tag_len = crypto_aead_authsize(tfm); 1060 + u8 iv_and_authTag[32+AESNI_ALIGN]; 1061 + u8 *iv = (u8 *) PTR_ALIGN((u8 *)iv_and_authTag, AESNI_ALIGN); 1062 + u8 *authTag = iv + 16; 1063 + struct scatter_walk src_sg_walk; 1064 + struct scatter_walk assoc_sg_walk; 1065 + struct scatter_walk dst_sg_walk; 1066 + unsigned int i; 1067 + 1068 + if (unlikely((req->cryptlen < auth_tag_len) || 1069 + (req->assoclen != 8 && req->assoclen != 12))) 1070 + return -EINVAL; 1071 + /* Assuming we are supporting rfc4106 64-bit extended */ 1072 + /* sequence numbers We need to have the AAD length */ 1073 + /* equal to 8 or 12 bytes */ 1074 + 1075 + tempCipherLen = (unsigned long)(req->cryptlen - auth_tag_len); 1076 + /* IV below built */ 1077 + for (i = 0; i < 4; i++) 1078 + *(iv+i) = ctx->nonce[i]; 1079 + for (i = 0; i < 8; i++) 1080 + *(iv+4+i) = req->iv[i]; 1081 + *((__be32 *)(iv+12)) = counter; 1082 + 1083 + if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) { 1084 + one_entry_in_sg = 1; 1085 + scatterwalk_start(&src_sg_walk, req->src); 1086 + scatterwalk_start(&assoc_sg_walk, req->assoc); 1087 + src = scatterwalk_map(&src_sg_walk, 0); 1088 + assoc = scatterwalk_map(&assoc_sg_walk, 0); 1089 + dst = src; 1090 + if (unlikely(req->src != req->dst)) { 1091 + scatterwalk_start(&dst_sg_walk, req->dst); 1092 + dst = scatterwalk_map(&dst_sg_walk, 0); 1093 + } 1094 + 1095 + } else { 1096 + /* Allocate memory for src, dst, assoc */ 1097 + src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); 1098 + if (!src) 1099 + return -ENOMEM; 1100 + assoc = (src + req->cryptlen + auth_tag_len); 1101 + scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); 1102 + scatterwalk_map_and_copy(assoc, req->assoc, 0, 1103 + req->assoclen, 0); 1104 + dst = src; 1105 + } 1106 + 1107 + aesni_gcm_dec(aes_ctx, dst, src, tempCipherLen, iv, 1108 + ctx->hash_subkey, assoc, (unsigned long)req->assoclen, 1109 + authTag, auth_tag_len); 1110 + 1111 + /* Compare generated tag with passed in tag. */ 1112 + retval = memcmp(src + tempCipherLen, authTag, auth_tag_len) ? 1113 + -EBADMSG : 0; 1114 + 1115 + if (one_entry_in_sg) { 1116 + if (unlikely(req->src != req->dst)) { 1117 + scatterwalk_unmap(dst, 0); 1118 + scatterwalk_done(&dst_sg_walk, 0, 0); 1119 + } 1120 + scatterwalk_unmap(src, 0); 1121 + scatterwalk_unmap(assoc, 0); 1122 + scatterwalk_done(&src_sg_walk, 0, 0); 1123 + scatterwalk_done(&assoc_sg_walk, 0, 0); 1124 + } else { 1125 + scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); 1126 + kfree(src); 1127 + } 1128 + return retval; 1129 + } 1130 + 1131 + static struct crypto_alg __rfc4106_alg = { 1132 + .cra_name = "__gcm-aes-aesni", 1133 + .cra_driver_name = "__driver-gcm-aes-aesni", 1134 + .cra_priority = 0, 1135 + .cra_flags = CRYPTO_ALG_TYPE_AEAD, 1136 + .cra_blocksize = 1, 1137 + .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN, 1138 + .cra_alignmask = 0, 1139 + .cra_type = &crypto_aead_type, 1140 + .cra_module = THIS_MODULE, 1141 + .cra_list = LIST_HEAD_INIT(__rfc4106_alg.cra_list), 1142 + .cra_u = { 1143 + .aead = { 1144 + .encrypt = __driver_rfc4106_encrypt, 1145 + .decrypt = __driver_rfc4106_decrypt, 1146 + }, 1147 + }, 1148 + }; 1149 + #endif 1150 + 825 1151 static int __init aesni_init(void) 826 1152 { 827 1153 int err; ··· 1248 738 printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); 1249 739 return -ENODEV; 1250 740 } 741 + 1251 742 if ((err = crypto_register_alg(&aesni_alg))) 1252 743 goto aes_err; 1253 744 if ((err = crypto_register_alg(&__aesni_alg))) ··· 1257 746 goto blk_ecb_err; 1258 747 if ((err = crypto_register_alg(&blk_cbc_alg))) 1259 748 goto blk_cbc_err; 1260 - if ((err = crypto_register_alg(&blk_ctr_alg))) 1261 - goto blk_ctr_err; 1262 749 if ((err = crypto_register_alg(&ablk_ecb_alg))) 1263 750 goto ablk_ecb_err; 1264 751 if ((err = crypto_register_alg(&ablk_cbc_alg))) 1265 752 goto ablk_cbc_err; 753 + #ifdef CONFIG_X86_64 754 + if ((err = crypto_register_alg(&blk_ctr_alg))) 755 + goto blk_ctr_err; 1266 756 if ((err = crypto_register_alg(&ablk_ctr_alg))) 1267 757 goto ablk_ctr_err; 758 + if ((err = crypto_register_alg(&__rfc4106_alg))) 759 + goto __aead_gcm_err; 760 + if ((err = crypto_register_alg(&rfc4106_alg))) 761 + goto aead_gcm_err; 1268 762 #ifdef HAS_CTR 1269 763 if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg))) 1270 764 goto ablk_rfc3686_ctr_err; 765 + #endif 1271 766 #endif 1272 767 #ifdef HAS_LRW 1273 768 if ((err = crypto_register_alg(&ablk_lrw_alg))) ··· 1287 770 if ((err = crypto_register_alg(&ablk_xts_alg))) 1288 771 goto ablk_xts_err; 1289 772 #endif 1290 - 1291 773 return err; 1292 774 1293 775 #ifdef HAS_XTS ··· 1300 784 crypto_unregister_alg(&ablk_lrw_alg); 1301 785 ablk_lrw_err: 1302 786 #endif 787 + #ifdef CONFIG_X86_64 1303 788 #ifdef HAS_CTR 1304 789 crypto_unregister_alg(&ablk_rfc3686_ctr_alg); 1305 790 ablk_rfc3686_ctr_err: 1306 791 #endif 792 + crypto_unregister_alg(&rfc4106_alg); 793 + aead_gcm_err: 794 + crypto_unregister_alg(&__rfc4106_alg); 795 + __aead_gcm_err: 1307 796 crypto_unregister_alg(&ablk_ctr_alg); 1308 797 ablk_ctr_err: 798 + crypto_unregister_alg(&blk_ctr_alg); 799 + blk_ctr_err: 800 + #endif 1309 801 crypto_unregister_alg(&ablk_cbc_alg); 1310 802 ablk_cbc_err: 1311 803 crypto_unregister_alg(&ablk_ecb_alg); 1312 804 ablk_ecb_err: 1313 - crypto_unregister_alg(&blk_ctr_alg); 1314 - blk_ctr_err: 1315 805 crypto_unregister_alg(&blk_cbc_alg); 1316 806 blk_cbc_err: 1317 807 crypto_unregister_alg(&blk_ecb_alg); ··· 1340 818 #ifdef HAS_LRW 1341 819 crypto_unregister_alg(&ablk_lrw_alg); 1342 820 #endif 821 + #ifdef CONFIG_X86_64 1343 822 #ifdef HAS_CTR 1344 823 crypto_unregister_alg(&ablk_rfc3686_ctr_alg); 1345 824 #endif 825 + crypto_unregister_alg(&rfc4106_alg); 826 + crypto_unregister_alg(&__rfc4106_alg); 1346 827 crypto_unregister_alg(&ablk_ctr_alg); 828 + crypto_unregister_alg(&blk_ctr_alg); 829 + #endif 1347 830 crypto_unregister_alg(&ablk_cbc_alg); 1348 831 crypto_unregister_alg(&ablk_ecb_alg); 1349 - crypto_unregister_alg(&blk_ctr_alg); 1350 832 crypto_unregister_alg(&blk_cbc_alg); 1351 833 crypto_unregister_alg(&blk_ecb_alg); 1352 834 crypto_unregister_alg(&__aesni_alg);
+28 -6
crypto/Kconfig
··· 110 110 111 111 config CRYPTO_GF128MUL 112 112 tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" 113 - depends on EXPERIMENTAL 114 113 help 115 114 Efficient table driven implementation of multiplications in the 116 115 field GF(2^128). This is needed by some cypher modes. This ··· 538 539 539 540 config CRYPTO_AES_NI_INTEL 540 541 tristate "AES cipher algorithms (AES-NI)" 541 - depends on (X86 || UML_X86) && 64BIT 542 - select CRYPTO_AES_X86_64 542 + depends on (X86 || UML_X86) 543 + select CRYPTO_AES_X86_64 if 64BIT 544 + select CRYPTO_AES_586 if !64BIT 543 545 select CRYPTO_CRYPTD 544 546 select CRYPTO_ALGAPI 545 547 select CRYPTO_FPU ··· 563 563 564 564 See <http://csrc.nist.gov/encryption/aes/> for more information. 565 565 566 - In addition to AES cipher algorithm support, the 567 - acceleration for some popular block cipher mode is supported 568 - too, including ECB, CBC, CTR, LRW, PCBC, XTS. 566 + In addition to AES cipher algorithm support, the acceleration 567 + for some popular block cipher mode is supported too, including 568 + ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional 569 + acceleration for CTR. 569 570 570 571 config CRYPTO_ANUBIS 571 572 tristate "Anubis cipher algorithm" ··· 841 840 for cryptographic modules. Uses the Algorithm specified in 842 841 ANSI X9.31 A.2.4. Note that this option must be enabled if 843 842 CRYPTO_FIPS is selected 843 + 844 + config CRYPTO_USER_API 845 + tristate 846 + 847 + config CRYPTO_USER_API_HASH 848 + tristate "User-space interface for hash algorithms" 849 + depends on NET 850 + select CRYPTO_HASH 851 + select CRYPTO_USER_API 852 + help 853 + This option enables the user-spaces interface for hash 854 + algorithms. 855 + 856 + config CRYPTO_USER_API_SKCIPHER 857 + tristate "User-space interface for symmetric key cipher algorithms" 858 + depends on NET 859 + select CRYPTO_BLKCIPHER 860 + select CRYPTO_USER_API 861 + help 862 + This option enables the user-spaces interface for symmetric 863 + key cipher algorithms. 844 864 845 865 source "drivers/crypto/Kconfig" 846 866
+10 -7
crypto/Makefile
··· 3 3 # 4 4 5 5 obj-$(CONFIG_CRYPTO) += crypto.o 6 - crypto-objs := api.o cipher.o compress.o 6 + crypto-y := api.o cipher.o compress.o 7 7 8 8 obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o 9 9 10 10 obj-$(CONFIG_CRYPTO_FIPS) += fips.o 11 11 12 12 crypto_algapi-$(CONFIG_PROC_FS) += proc.o 13 - crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y) 13 + crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y) 14 14 obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o 15 15 16 16 obj-$(CONFIG_CRYPTO_AEAD2) += aead.o 17 17 18 - crypto_blkcipher-objs := ablkcipher.o 19 - crypto_blkcipher-objs += blkcipher.o 18 + crypto_blkcipher-y := ablkcipher.o 19 + crypto_blkcipher-y += blkcipher.o 20 20 obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o 21 21 obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o 22 22 obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o 23 23 obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o 24 24 25 - crypto_hash-objs += ahash.o 26 - crypto_hash-objs += shash.o 25 + crypto_hash-y += ahash.o 26 + crypto_hash-y += shash.o 27 27 obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o 28 28 29 29 obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o 30 30 31 - cryptomgr-objs := algboss.o testmgr.o 31 + cryptomgr-y := algboss.o testmgr.o 32 32 33 33 obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o 34 34 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o ··· 85 85 obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o 86 86 obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o 87 87 obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o 88 + obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o 89 + obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o 90 + obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o 88 91 89 92 # 90 93 # generic algorithms and the async_tx api
+483
crypto/af_alg.c
··· 1 + /* 2 + * af_alg: User-space algorithm interface 3 + * 4 + * This file provides the user-space API for algorithms. 5 + * 6 + * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 7 + * 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the Free 10 + * Software Foundation; either version 2 of the License, or (at your option) 11 + * any later version. 12 + * 13 + */ 14 + 15 + #include <asm/atomic.h> 16 + #include <crypto/if_alg.h> 17 + #include <linux/crypto.h> 18 + #include <linux/init.h> 19 + #include <linux/kernel.h> 20 + #include <linux/list.h> 21 + #include <linux/module.h> 22 + #include <linux/net.h> 23 + #include <linux/rwsem.h> 24 + 25 + struct alg_type_list { 26 + const struct af_alg_type *type; 27 + struct list_head list; 28 + }; 29 + 30 + static atomic_long_t alg_memory_allocated; 31 + 32 + static struct proto alg_proto = { 33 + .name = "ALG", 34 + .owner = THIS_MODULE, 35 + .memory_allocated = &alg_memory_allocated, 36 + .obj_size = sizeof(struct alg_sock), 37 + }; 38 + 39 + static LIST_HEAD(alg_types); 40 + static DECLARE_RWSEM(alg_types_sem); 41 + 42 + static const struct af_alg_type *alg_get_type(const char *name) 43 + { 44 + const struct af_alg_type *type = ERR_PTR(-ENOENT); 45 + struct alg_type_list *node; 46 + 47 + down_read(&alg_types_sem); 48 + list_for_each_entry(node, &alg_types, list) { 49 + if (strcmp(node->type->name, name)) 50 + continue; 51 + 52 + if (try_module_get(node->type->owner)) 53 + type = node->type; 54 + break; 55 + } 56 + up_read(&alg_types_sem); 57 + 58 + return type; 59 + } 60 + 61 + int af_alg_register_type(const struct af_alg_type *type) 62 + { 63 + struct alg_type_list *node; 64 + int err = -EEXIST; 65 + 66 + down_write(&alg_types_sem); 67 + list_for_each_entry(node, &alg_types, list) { 68 + if (!strcmp(node->type->name, type->name)) 69 + goto unlock; 70 + } 71 + 72 + node = kmalloc(sizeof(*node), GFP_KERNEL); 73 + err = -ENOMEM; 74 + if (!node) 75 + goto unlock; 76 + 77 + type->ops->owner = THIS_MODULE; 78 + node->type = type; 79 + list_add(&node->list, &alg_types); 80 + err = 0; 81 + 82 + unlock: 83 + up_write(&alg_types_sem); 84 + 85 + return err; 86 + } 87 + EXPORT_SYMBOL_GPL(af_alg_register_type); 88 + 89 + int af_alg_unregister_type(const struct af_alg_type *type) 90 + { 91 + struct alg_type_list *node; 92 + int err = -ENOENT; 93 + 94 + down_write(&alg_types_sem); 95 + list_for_each_entry(node, &alg_types, list) { 96 + if (strcmp(node->type->name, type->name)) 97 + continue; 98 + 99 + list_del(&node->list); 100 + kfree(node); 101 + err = 0; 102 + break; 103 + } 104 + up_write(&alg_types_sem); 105 + 106 + return err; 107 + } 108 + EXPORT_SYMBOL_GPL(af_alg_unregister_type); 109 + 110 + static void alg_do_release(const struct af_alg_type *type, void *private) 111 + { 112 + if (!type) 113 + return; 114 + 115 + type->release(private); 116 + module_put(type->owner); 117 + } 118 + 119 + int af_alg_release(struct socket *sock) 120 + { 121 + if (sock->sk) 122 + sock_put(sock->sk); 123 + return 0; 124 + } 125 + EXPORT_SYMBOL_GPL(af_alg_release); 126 + 127 + static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 128 + { 129 + struct sock *sk = sock->sk; 130 + struct alg_sock *ask = alg_sk(sk); 131 + struct sockaddr_alg *sa = (void *)uaddr; 132 + const struct af_alg_type *type; 133 + void *private; 134 + 135 + if (sock->state == SS_CONNECTED) 136 + return -EINVAL; 137 + 138 + if (addr_len != sizeof(*sa)) 139 + return -EINVAL; 140 + 141 + sa->salg_type[sizeof(sa->salg_type) - 1] = 0; 142 + sa->salg_name[sizeof(sa->salg_name) - 1] = 0; 143 + 144 + type = alg_get_type(sa->salg_type); 145 + if (IS_ERR(type) && PTR_ERR(type) == -ENOENT) { 146 + request_module("algif-%s", sa->salg_type); 147 + type = alg_get_type(sa->salg_type); 148 + } 149 + 150 + if (IS_ERR(type)) 151 + return PTR_ERR(type); 152 + 153 + private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask); 154 + if (IS_ERR(private)) { 155 + module_put(type->owner); 156 + return PTR_ERR(private); 157 + } 158 + 159 + lock_sock(sk); 160 + 161 + swap(ask->type, type); 162 + swap(ask->private, private); 163 + 164 + release_sock(sk); 165 + 166 + alg_do_release(type, private); 167 + 168 + return 0; 169 + } 170 + 171 + static int alg_setkey(struct sock *sk, char __user *ukey, 172 + unsigned int keylen) 173 + { 174 + struct alg_sock *ask = alg_sk(sk); 175 + const struct af_alg_type *type = ask->type; 176 + u8 *key; 177 + int err; 178 + 179 + key = sock_kmalloc(sk, keylen, GFP_KERNEL); 180 + if (!key) 181 + return -ENOMEM; 182 + 183 + err = -EFAULT; 184 + if (copy_from_user(key, ukey, keylen)) 185 + goto out; 186 + 187 + err = type->setkey(ask->private, key, keylen); 188 + 189 + out: 190 + sock_kfree_s(sk, key, keylen); 191 + 192 + return err; 193 + } 194 + 195 + static int alg_setsockopt(struct socket *sock, int level, int optname, 196 + char __user *optval, unsigned int optlen) 197 + { 198 + struct sock *sk = sock->sk; 199 + struct alg_sock *ask = alg_sk(sk); 200 + const struct af_alg_type *type; 201 + int err = -ENOPROTOOPT; 202 + 203 + lock_sock(sk); 204 + type = ask->type; 205 + 206 + if (level != SOL_ALG || !type) 207 + goto unlock; 208 + 209 + switch (optname) { 210 + case ALG_SET_KEY: 211 + if (sock->state == SS_CONNECTED) 212 + goto unlock; 213 + if (!type->setkey) 214 + goto unlock; 215 + 216 + err = alg_setkey(sk, optval, optlen); 217 + } 218 + 219 + unlock: 220 + release_sock(sk); 221 + 222 + return err; 223 + } 224 + 225 + int af_alg_accept(struct sock *sk, struct socket *newsock) 226 + { 227 + struct alg_sock *ask = alg_sk(sk); 228 + const struct af_alg_type *type; 229 + struct sock *sk2; 230 + int err; 231 + 232 + lock_sock(sk); 233 + type = ask->type; 234 + 235 + err = -EINVAL; 236 + if (!type) 237 + goto unlock; 238 + 239 + sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto); 240 + err = -ENOMEM; 241 + if (!sk2) 242 + goto unlock; 243 + 244 + sock_init_data(newsock, sk2); 245 + sock_graft(sk2, newsock); 246 + 247 + err = type->accept(ask->private, sk2); 248 + if (err) { 249 + sk_free(sk2); 250 + goto unlock; 251 + } 252 + 253 + sk2->sk_family = PF_ALG; 254 + 255 + sock_hold(sk); 256 + alg_sk(sk2)->parent = sk; 257 + alg_sk(sk2)->type = type; 258 + 259 + newsock->ops = type->ops; 260 + newsock->state = SS_CONNECTED; 261 + 262 + err = 0; 263 + 264 + unlock: 265 + release_sock(sk); 266 + 267 + return err; 268 + } 269 + EXPORT_SYMBOL_GPL(af_alg_accept); 270 + 271 + static int alg_accept(struct socket *sock, struct socket *newsock, int flags) 272 + { 273 + return af_alg_accept(sock->sk, newsock); 274 + } 275 + 276 + static const struct proto_ops alg_proto_ops = { 277 + .family = PF_ALG, 278 + .owner = THIS_MODULE, 279 + 280 + .connect = sock_no_connect, 281 + .socketpair = sock_no_socketpair, 282 + .getname = sock_no_getname, 283 + .ioctl = sock_no_ioctl, 284 + .listen = sock_no_listen, 285 + .shutdown = sock_no_shutdown, 286 + .getsockopt = sock_no_getsockopt, 287 + .mmap = sock_no_mmap, 288 + .sendpage = sock_no_sendpage, 289 + .sendmsg = sock_no_sendmsg, 290 + .recvmsg = sock_no_recvmsg, 291 + .poll = sock_no_poll, 292 + 293 + .bind = alg_bind, 294 + .release = af_alg_release, 295 + .setsockopt = alg_setsockopt, 296 + .accept = alg_accept, 297 + }; 298 + 299 + static void alg_sock_destruct(struct sock *sk) 300 + { 301 + struct alg_sock *ask = alg_sk(sk); 302 + 303 + alg_do_release(ask->type, ask->private); 304 + } 305 + 306 + static int alg_create(struct net *net, struct socket *sock, int protocol, 307 + int kern) 308 + { 309 + struct sock *sk; 310 + int err; 311 + 312 + if (sock->type != SOCK_SEQPACKET) 313 + return -ESOCKTNOSUPPORT; 314 + if (protocol != 0) 315 + return -EPROTONOSUPPORT; 316 + 317 + err = -ENOMEM; 318 + sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto); 319 + if (!sk) 320 + goto out; 321 + 322 + sock->ops = &alg_proto_ops; 323 + sock_init_data(sock, sk); 324 + 325 + sk->sk_family = PF_ALG; 326 + sk->sk_destruct = alg_sock_destruct; 327 + 328 + return 0; 329 + out: 330 + return err; 331 + } 332 + 333 + static const struct net_proto_family alg_family = { 334 + .family = PF_ALG, 335 + .create = alg_create, 336 + .owner = THIS_MODULE, 337 + }; 338 + 339 + int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, 340 + int write) 341 + { 342 + unsigned long from = (unsigned long)addr; 343 + unsigned long npages; 344 + unsigned off; 345 + int err; 346 + int i; 347 + 348 + err = -EFAULT; 349 + if (!access_ok(write ? VERIFY_READ : VERIFY_WRITE, addr, len)) 350 + goto out; 351 + 352 + off = from & ~PAGE_MASK; 353 + npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; 354 + if (npages > ALG_MAX_PAGES) 355 + npages = ALG_MAX_PAGES; 356 + 357 + err = get_user_pages_fast(from, npages, write, sgl->pages); 358 + if (err < 0) 359 + goto out; 360 + 361 + npages = err; 362 + err = -EINVAL; 363 + if (WARN_ON(npages == 0)) 364 + goto out; 365 + 366 + err = 0; 367 + 368 + sg_init_table(sgl->sg, npages); 369 + 370 + for (i = 0; i < npages; i++) { 371 + int plen = min_t(int, len, PAGE_SIZE - off); 372 + 373 + sg_set_page(sgl->sg + i, sgl->pages[i], plen, off); 374 + 375 + off = 0; 376 + len -= plen; 377 + err += plen; 378 + } 379 + 380 + out: 381 + return err; 382 + } 383 + EXPORT_SYMBOL_GPL(af_alg_make_sg); 384 + 385 + void af_alg_free_sg(struct af_alg_sgl *sgl) 386 + { 387 + int i; 388 + 389 + i = 0; 390 + do { 391 + put_page(sgl->pages[i]); 392 + } while (!sg_is_last(sgl->sg + (i++))); 393 + } 394 + EXPORT_SYMBOL_GPL(af_alg_free_sg); 395 + 396 + int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) 397 + { 398 + struct cmsghdr *cmsg; 399 + 400 + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { 401 + if (!CMSG_OK(msg, cmsg)) 402 + return -EINVAL; 403 + if (cmsg->cmsg_level != SOL_ALG) 404 + continue; 405 + 406 + switch(cmsg->cmsg_type) { 407 + case ALG_SET_IV: 408 + if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv))) 409 + return -EINVAL; 410 + con->iv = (void *)CMSG_DATA(cmsg); 411 + if (cmsg->cmsg_len < CMSG_LEN(con->iv->ivlen + 412 + sizeof(*con->iv))) 413 + return -EINVAL; 414 + break; 415 + 416 + case ALG_SET_OP: 417 + if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32))) 418 + return -EINVAL; 419 + con->op = *(u32 *)CMSG_DATA(cmsg); 420 + break; 421 + 422 + default: 423 + return -EINVAL; 424 + } 425 + } 426 + 427 + return 0; 428 + } 429 + EXPORT_SYMBOL_GPL(af_alg_cmsg_send); 430 + 431 + int af_alg_wait_for_completion(int err, struct af_alg_completion *completion) 432 + { 433 + switch (err) { 434 + case -EINPROGRESS: 435 + case -EBUSY: 436 + wait_for_completion(&completion->completion); 437 + INIT_COMPLETION(completion->completion); 438 + err = completion->err; 439 + break; 440 + }; 441 + 442 + return err; 443 + } 444 + EXPORT_SYMBOL_GPL(af_alg_wait_for_completion); 445 + 446 + void af_alg_complete(struct crypto_async_request *req, int err) 447 + { 448 + struct af_alg_completion *completion = req->data; 449 + 450 + completion->err = err; 451 + complete(&completion->completion); 452 + } 453 + EXPORT_SYMBOL_GPL(af_alg_complete); 454 + 455 + static int __init af_alg_init(void) 456 + { 457 + int err = proto_register(&alg_proto, 0); 458 + 459 + if (err) 460 + goto out; 461 + 462 + err = sock_register(&alg_family); 463 + if (err != 0) 464 + goto out_unregister_proto; 465 + 466 + out: 467 + return err; 468 + 469 + out_unregister_proto: 470 + proto_unregister(&alg_proto); 471 + goto out; 472 + } 473 + 474 + static void __exit af_alg_exit(void) 475 + { 476 + sock_unregister(PF_ALG); 477 + proto_unregister(&alg_proto); 478 + } 479 + 480 + module_init(af_alg_init); 481 + module_exit(af_alg_exit); 482 + MODULE_LICENSE("GPL"); 483 + MODULE_ALIAS_NETPROTO(AF_ALG);
+319
crypto/algif_hash.c
··· 1 + /* 2 + * algif_hash: User-space interface for hash algorithms 3 + * 4 + * This file provides the user-space API for hash algorithms. 5 + * 6 + * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 7 + * 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the Free 10 + * Software Foundation; either version 2 of the License, or (at your option) 11 + * any later version. 12 + * 13 + */ 14 + 15 + #include <crypto/hash.h> 16 + #include <crypto/if_alg.h> 17 + #include <linux/init.h> 18 + #include <linux/kernel.h> 19 + #include <linux/mm.h> 20 + #include <linux/module.h> 21 + #include <linux/net.h> 22 + #include <net/sock.h> 23 + 24 + struct hash_ctx { 25 + struct af_alg_sgl sgl; 26 + 27 + u8 *result; 28 + 29 + struct af_alg_completion completion; 30 + 31 + unsigned int len; 32 + bool more; 33 + 34 + struct ahash_request req; 35 + }; 36 + 37 + static int hash_sendmsg(struct kiocb *unused, struct socket *sock, 38 + struct msghdr *msg, size_t ignored) 39 + { 40 + int limit = ALG_MAX_PAGES * PAGE_SIZE; 41 + struct sock *sk = sock->sk; 42 + struct alg_sock *ask = alg_sk(sk); 43 + struct hash_ctx *ctx = ask->private; 44 + unsigned long iovlen; 45 + struct iovec *iov; 46 + long copied = 0; 47 + int err; 48 + 49 + if (limit > sk->sk_sndbuf) 50 + limit = sk->sk_sndbuf; 51 + 52 + lock_sock(sk); 53 + if (!ctx->more) { 54 + err = crypto_ahash_init(&ctx->req); 55 + if (err) 56 + goto unlock; 57 + } 58 + 59 + ctx->more = 0; 60 + 61 + for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; 62 + iovlen--, iov++) { 63 + unsigned long seglen = iov->iov_len; 64 + char __user *from = iov->iov_base; 65 + 66 + while (seglen) { 67 + int len = min_t(unsigned long, seglen, limit); 68 + int newlen; 69 + 70 + newlen = af_alg_make_sg(&ctx->sgl, from, len, 0); 71 + if (newlen < 0) 72 + goto unlock; 73 + 74 + ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL, 75 + newlen); 76 + 77 + err = af_alg_wait_for_completion( 78 + crypto_ahash_update(&ctx->req), 79 + &ctx->completion); 80 + 81 + af_alg_free_sg(&ctx->sgl); 82 + 83 + if (err) 84 + goto unlock; 85 + 86 + seglen -= newlen; 87 + from += newlen; 88 + copied += newlen; 89 + } 90 + } 91 + 92 + err = 0; 93 + 94 + ctx->more = msg->msg_flags & MSG_MORE; 95 + if (!ctx->more) { 96 + ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); 97 + err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), 98 + &ctx->completion); 99 + } 100 + 101 + unlock: 102 + release_sock(sk); 103 + 104 + return err ?: copied; 105 + } 106 + 107 + static ssize_t hash_sendpage(struct socket *sock, struct page *page, 108 + int offset, size_t size, int flags) 109 + { 110 + struct sock *sk = sock->sk; 111 + struct alg_sock *ask = alg_sk(sk); 112 + struct hash_ctx *ctx = ask->private; 113 + int err; 114 + 115 + lock_sock(sk); 116 + sg_init_table(ctx->sgl.sg, 1); 117 + sg_set_page(ctx->sgl.sg, page, size, offset); 118 + 119 + ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, ctx->result, size); 120 + 121 + if (!(flags & MSG_MORE)) { 122 + if (ctx->more) 123 + err = crypto_ahash_finup(&ctx->req); 124 + else 125 + err = crypto_ahash_digest(&ctx->req); 126 + } else { 127 + if (!ctx->more) { 128 + err = crypto_ahash_init(&ctx->req); 129 + if (err) 130 + goto unlock; 131 + } 132 + 133 + err = crypto_ahash_update(&ctx->req); 134 + } 135 + 136 + err = af_alg_wait_for_completion(err, &ctx->completion); 137 + if (err) 138 + goto unlock; 139 + 140 + ctx->more = flags & MSG_MORE; 141 + 142 + unlock: 143 + release_sock(sk); 144 + 145 + return err ?: size; 146 + } 147 + 148 + static int hash_recvmsg(struct kiocb *unused, struct socket *sock, 149 + struct msghdr *msg, size_t len, int flags) 150 + { 151 + struct sock *sk = sock->sk; 152 + struct alg_sock *ask = alg_sk(sk); 153 + struct hash_ctx *ctx = ask->private; 154 + unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req)); 155 + int err; 156 + 157 + if (len > ds) 158 + len = ds; 159 + else if (len < ds) 160 + msg->msg_flags |= MSG_TRUNC; 161 + 162 + lock_sock(sk); 163 + if (ctx->more) { 164 + ctx->more = 0; 165 + ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); 166 + err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), 167 + &ctx->completion); 168 + if (err) 169 + goto unlock; 170 + } 171 + 172 + err = memcpy_toiovec(msg->msg_iov, ctx->result, len); 173 + 174 + unlock: 175 + release_sock(sk); 176 + 177 + return err ?: len; 178 + } 179 + 180 + static int hash_accept(struct socket *sock, struct socket *newsock, int flags) 181 + { 182 + struct sock *sk = sock->sk; 183 + struct alg_sock *ask = alg_sk(sk); 184 + struct hash_ctx *ctx = ask->private; 185 + struct ahash_request *req = &ctx->req; 186 + char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))]; 187 + struct sock *sk2; 188 + struct alg_sock *ask2; 189 + struct hash_ctx *ctx2; 190 + int err; 191 + 192 + err = crypto_ahash_export(req, state); 193 + if (err) 194 + return err; 195 + 196 + err = af_alg_accept(ask->parent, newsock); 197 + if (err) 198 + return err; 199 + 200 + sk2 = newsock->sk; 201 + ask2 = alg_sk(sk2); 202 + ctx2 = ask2->private; 203 + ctx2->more = 1; 204 + 205 + err = crypto_ahash_import(&ctx2->req, state); 206 + if (err) { 207 + sock_orphan(sk2); 208 + sock_put(sk2); 209 + } 210 + 211 + return err; 212 + } 213 + 214 + static struct proto_ops algif_hash_ops = { 215 + .family = PF_ALG, 216 + 217 + .connect = sock_no_connect, 218 + .socketpair = sock_no_socketpair, 219 + .getname = sock_no_getname, 220 + .ioctl = sock_no_ioctl, 221 + .listen = sock_no_listen, 222 + .shutdown = sock_no_shutdown, 223 + .getsockopt = sock_no_getsockopt, 224 + .mmap = sock_no_mmap, 225 + .bind = sock_no_bind, 226 + .setsockopt = sock_no_setsockopt, 227 + .poll = sock_no_poll, 228 + 229 + .release = af_alg_release, 230 + .sendmsg = hash_sendmsg, 231 + .sendpage = hash_sendpage, 232 + .recvmsg = hash_recvmsg, 233 + .accept = hash_accept, 234 + }; 235 + 236 + static void *hash_bind(const char *name, u32 type, u32 mask) 237 + { 238 + return crypto_alloc_ahash(name, type, mask); 239 + } 240 + 241 + static void hash_release(void *private) 242 + { 243 + crypto_free_ahash(private); 244 + } 245 + 246 + static int hash_setkey(void *private, const u8 *key, unsigned int keylen) 247 + { 248 + return crypto_ahash_setkey(private, key, keylen); 249 + } 250 + 251 + static void hash_sock_destruct(struct sock *sk) 252 + { 253 + struct alg_sock *ask = alg_sk(sk); 254 + struct hash_ctx *ctx = ask->private; 255 + 256 + sock_kfree_s(sk, ctx->result, 257 + crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req))); 258 + sock_kfree_s(sk, ctx, ctx->len); 259 + af_alg_release_parent(sk); 260 + } 261 + 262 + static int hash_accept_parent(void *private, struct sock *sk) 263 + { 264 + struct hash_ctx *ctx; 265 + struct alg_sock *ask = alg_sk(sk); 266 + unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private); 267 + unsigned ds = crypto_ahash_digestsize(private); 268 + 269 + ctx = sock_kmalloc(sk, len, GFP_KERNEL); 270 + if (!ctx) 271 + return -ENOMEM; 272 + 273 + ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL); 274 + if (!ctx->result) { 275 + sock_kfree_s(sk, ctx, len); 276 + return -ENOMEM; 277 + } 278 + 279 + memset(ctx->result, 0, ds); 280 + 281 + ctx->len = len; 282 + ctx->more = 0; 283 + af_alg_init_completion(&ctx->completion); 284 + 285 + ask->private = ctx; 286 + 287 + ahash_request_set_tfm(&ctx->req, private); 288 + ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, 289 + af_alg_complete, &ctx->completion); 290 + 291 + sk->sk_destruct = hash_sock_destruct; 292 + 293 + return 0; 294 + } 295 + 296 + static const struct af_alg_type algif_type_hash = { 297 + .bind = hash_bind, 298 + .release = hash_release, 299 + .setkey = hash_setkey, 300 + .accept = hash_accept_parent, 301 + .ops = &algif_hash_ops, 302 + .name = "hash", 303 + .owner = THIS_MODULE 304 + }; 305 + 306 + static int __init algif_hash_init(void) 307 + { 308 + return af_alg_register_type(&algif_type_hash); 309 + } 310 + 311 + static void __exit algif_hash_exit(void) 312 + { 313 + int err = af_alg_unregister_type(&algif_type_hash); 314 + BUG_ON(err); 315 + } 316 + 317 + module_init(algif_hash_init); 318 + module_exit(algif_hash_exit); 319 + MODULE_LICENSE("GPL");
+632
crypto/algif_skcipher.c
··· 1 + /* 2 + * algif_skcipher: User-space interface for skcipher algorithms 3 + * 4 + * This file provides the user-space API for symmetric key ciphers. 5 + * 6 + * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 7 + * 8 + * This program is free software; you can redistribute it and/or modify it 9 + * under the terms of the GNU General Public License as published by the Free 10 + * Software Foundation; either version 2 of the License, or (at your option) 11 + * any later version. 12 + * 13 + */ 14 + 15 + #include <crypto/scatterwalk.h> 16 + #include <crypto/skcipher.h> 17 + #include <crypto/if_alg.h> 18 + #include <linux/init.h> 19 + #include <linux/list.h> 20 + #include <linux/kernel.h> 21 + #include <linux/mm.h> 22 + #include <linux/module.h> 23 + #include <linux/net.h> 24 + #include <net/sock.h> 25 + 26 + struct skcipher_sg_list { 27 + struct list_head list; 28 + 29 + int cur; 30 + 31 + struct scatterlist sg[0]; 32 + }; 33 + 34 + struct skcipher_ctx { 35 + struct list_head tsgl; 36 + struct af_alg_sgl rsgl; 37 + 38 + void *iv; 39 + 40 + struct af_alg_completion completion; 41 + 42 + unsigned used; 43 + 44 + unsigned int len; 45 + bool more; 46 + bool merge; 47 + bool enc; 48 + 49 + struct ablkcipher_request req; 50 + }; 51 + 52 + #define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \ 53 + sizeof(struct scatterlist) - 1) 54 + 55 + static inline int skcipher_sndbuf(struct sock *sk) 56 + { 57 + struct alg_sock *ask = alg_sk(sk); 58 + struct skcipher_ctx *ctx = ask->private; 59 + 60 + return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - 61 + ctx->used, 0); 62 + } 63 + 64 + static inline bool skcipher_writable(struct sock *sk) 65 + { 66 + return PAGE_SIZE <= skcipher_sndbuf(sk); 67 + } 68 + 69 + static int skcipher_alloc_sgl(struct sock *sk) 70 + { 71 + struct alg_sock *ask = alg_sk(sk); 72 + struct skcipher_ctx *ctx = ask->private; 73 + struct skcipher_sg_list *sgl; 74 + struct scatterlist *sg = NULL; 75 + 76 + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 77 + if (!list_empty(&ctx->tsgl)) 78 + sg = sgl->sg; 79 + 80 + if (!sg || sgl->cur >= MAX_SGL_ENTS) { 81 + sgl = sock_kmalloc(sk, sizeof(*sgl) + 82 + sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1), 83 + GFP_KERNEL); 84 + if (!sgl) 85 + return -ENOMEM; 86 + 87 + sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); 88 + sgl->cur = 0; 89 + 90 + if (sg) 91 + scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); 92 + 93 + list_add_tail(&sgl->list, &ctx->tsgl); 94 + } 95 + 96 + return 0; 97 + } 98 + 99 + static void skcipher_pull_sgl(struct sock *sk, int used) 100 + { 101 + struct alg_sock *ask = alg_sk(sk); 102 + struct skcipher_ctx *ctx = ask->private; 103 + struct skcipher_sg_list *sgl; 104 + struct scatterlist *sg; 105 + int i; 106 + 107 + while (!list_empty(&ctx->tsgl)) { 108 + sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, 109 + list); 110 + sg = sgl->sg; 111 + 112 + for (i = 0; i < sgl->cur; i++) { 113 + int plen = min_t(int, used, sg[i].length); 114 + 115 + if (!sg_page(sg + i)) 116 + continue; 117 + 118 + sg[i].length -= plen; 119 + sg[i].offset += plen; 120 + 121 + used -= plen; 122 + ctx->used -= plen; 123 + 124 + if (sg[i].length) 125 + return; 126 + 127 + put_page(sg_page(sg + i)); 128 + sg_assign_page(sg + i, NULL); 129 + } 130 + 131 + list_del(&sgl->list); 132 + sock_kfree_s(sk, sgl, 133 + sizeof(*sgl) + sizeof(sgl->sg[0]) * 134 + (MAX_SGL_ENTS + 1)); 135 + } 136 + 137 + if (!ctx->used) 138 + ctx->merge = 0; 139 + } 140 + 141 + static void skcipher_free_sgl(struct sock *sk) 142 + { 143 + struct alg_sock *ask = alg_sk(sk); 144 + struct skcipher_ctx *ctx = ask->private; 145 + 146 + skcipher_pull_sgl(sk, ctx->used); 147 + } 148 + 149 + static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) 150 + { 151 + long timeout; 152 + DEFINE_WAIT(wait); 153 + int err = -ERESTARTSYS; 154 + 155 + if (flags & MSG_DONTWAIT) 156 + return -EAGAIN; 157 + 158 + set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); 159 + 160 + for (;;) { 161 + if (signal_pending(current)) 162 + break; 163 + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 164 + timeout = MAX_SCHEDULE_TIMEOUT; 165 + if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) { 166 + err = 0; 167 + break; 168 + } 169 + } 170 + finish_wait(sk_sleep(sk), &wait); 171 + 172 + return err; 173 + } 174 + 175 + static void skcipher_wmem_wakeup(struct sock *sk) 176 + { 177 + struct socket_wq *wq; 178 + 179 + if (!skcipher_writable(sk)) 180 + return; 181 + 182 + rcu_read_lock(); 183 + wq = rcu_dereference(sk->sk_wq); 184 + if (wq_has_sleeper(wq)) 185 + wake_up_interruptible_sync_poll(&wq->wait, POLLIN | 186 + POLLRDNORM | 187 + POLLRDBAND); 188 + sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); 189 + rcu_read_unlock(); 190 + } 191 + 192 + static int skcipher_wait_for_data(struct sock *sk, unsigned flags) 193 + { 194 + struct alg_sock *ask = alg_sk(sk); 195 + struct skcipher_ctx *ctx = ask->private; 196 + long timeout; 197 + DEFINE_WAIT(wait); 198 + int err = -ERESTARTSYS; 199 + 200 + if (flags & MSG_DONTWAIT) { 201 + return -EAGAIN; 202 + } 203 + 204 + set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); 205 + 206 + for (;;) { 207 + if (signal_pending(current)) 208 + break; 209 + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); 210 + timeout = MAX_SCHEDULE_TIMEOUT; 211 + if (sk_wait_event(sk, &timeout, ctx->used)) { 212 + err = 0; 213 + break; 214 + } 215 + } 216 + finish_wait(sk_sleep(sk), &wait); 217 + 218 + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); 219 + 220 + return err; 221 + } 222 + 223 + static void skcipher_data_wakeup(struct sock *sk) 224 + { 225 + struct alg_sock *ask = alg_sk(sk); 226 + struct skcipher_ctx *ctx = ask->private; 227 + struct socket_wq *wq; 228 + 229 + if (!ctx->used) 230 + return; 231 + 232 + rcu_read_lock(); 233 + wq = rcu_dereference(sk->sk_wq); 234 + if (wq_has_sleeper(wq)) 235 + wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | 236 + POLLRDNORM | 237 + POLLRDBAND); 238 + sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); 239 + rcu_read_unlock(); 240 + } 241 + 242 + static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, 243 + struct msghdr *msg, size_t size) 244 + { 245 + struct sock *sk = sock->sk; 246 + struct alg_sock *ask = alg_sk(sk); 247 + struct skcipher_ctx *ctx = ask->private; 248 + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); 249 + unsigned ivsize = crypto_ablkcipher_ivsize(tfm); 250 + struct skcipher_sg_list *sgl; 251 + struct af_alg_control con = {}; 252 + long copied = 0; 253 + bool enc = 0; 254 + int err; 255 + int i; 256 + 257 + if (msg->msg_controllen) { 258 + err = af_alg_cmsg_send(msg, &con); 259 + if (err) 260 + return err; 261 + 262 + switch (con.op) { 263 + case ALG_OP_ENCRYPT: 264 + enc = 1; 265 + break; 266 + case ALG_OP_DECRYPT: 267 + enc = 0; 268 + break; 269 + default: 270 + return -EINVAL; 271 + } 272 + 273 + if (con.iv && con.iv->ivlen != ivsize) 274 + return -EINVAL; 275 + } 276 + 277 + err = -EINVAL; 278 + 279 + lock_sock(sk); 280 + if (!ctx->more && ctx->used) 281 + goto unlock; 282 + 283 + if (!ctx->used) { 284 + ctx->enc = enc; 285 + if (con.iv) 286 + memcpy(ctx->iv, con.iv->iv, ivsize); 287 + } 288 + 289 + while (size) { 290 + struct scatterlist *sg; 291 + unsigned long len = size; 292 + int plen; 293 + 294 + if (ctx->merge) { 295 + sgl = list_entry(ctx->tsgl.prev, 296 + struct skcipher_sg_list, list); 297 + sg = sgl->sg + sgl->cur - 1; 298 + len = min_t(unsigned long, len, 299 + PAGE_SIZE - sg->offset - sg->length); 300 + 301 + err = memcpy_fromiovec(page_address(sg_page(sg)) + 302 + sg->offset + sg->length, 303 + msg->msg_iov, len); 304 + if (err) 305 + goto unlock; 306 + 307 + sg->length += len; 308 + ctx->merge = (sg->offset + sg->length) & 309 + (PAGE_SIZE - 1); 310 + 311 + ctx->used += len; 312 + copied += len; 313 + size -= len; 314 + continue; 315 + } 316 + 317 + if (!skcipher_writable(sk)) { 318 + err = skcipher_wait_for_wmem(sk, msg->msg_flags); 319 + if (err) 320 + goto unlock; 321 + } 322 + 323 + len = min_t(unsigned long, len, skcipher_sndbuf(sk)); 324 + 325 + err = skcipher_alloc_sgl(sk); 326 + if (err) 327 + goto unlock; 328 + 329 + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 330 + sg = sgl->sg; 331 + do { 332 + i = sgl->cur; 333 + plen = min_t(int, len, PAGE_SIZE); 334 + 335 + sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); 336 + err = -ENOMEM; 337 + if (!sg_page(sg + i)) 338 + goto unlock; 339 + 340 + err = memcpy_fromiovec(page_address(sg_page(sg + i)), 341 + msg->msg_iov, plen); 342 + if (err) { 343 + __free_page(sg_page(sg + i)); 344 + sg_assign_page(sg + i, NULL); 345 + goto unlock; 346 + } 347 + 348 + sg[i].length = plen; 349 + len -= plen; 350 + ctx->used += plen; 351 + copied += plen; 352 + size -= plen; 353 + sgl->cur++; 354 + } while (len && sgl->cur < MAX_SGL_ENTS); 355 + 356 + ctx->merge = plen & (PAGE_SIZE - 1); 357 + } 358 + 359 + err = 0; 360 + 361 + ctx->more = msg->msg_flags & MSG_MORE; 362 + if (!ctx->more && !list_empty(&ctx->tsgl)) 363 + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 364 + 365 + unlock: 366 + skcipher_data_wakeup(sk); 367 + release_sock(sk); 368 + 369 + return copied ?: err; 370 + } 371 + 372 + static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, 373 + int offset, size_t size, int flags) 374 + { 375 + struct sock *sk = sock->sk; 376 + struct alg_sock *ask = alg_sk(sk); 377 + struct skcipher_ctx *ctx = ask->private; 378 + struct skcipher_sg_list *sgl; 379 + int err = -EINVAL; 380 + 381 + lock_sock(sk); 382 + if (!ctx->more && ctx->used) 383 + goto unlock; 384 + 385 + if (!size) 386 + goto done; 387 + 388 + if (!skcipher_writable(sk)) { 389 + err = skcipher_wait_for_wmem(sk, flags); 390 + if (err) 391 + goto unlock; 392 + } 393 + 394 + err = skcipher_alloc_sgl(sk); 395 + if (err) 396 + goto unlock; 397 + 398 + ctx->merge = 0; 399 + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 400 + 401 + get_page(page); 402 + sg_set_page(sgl->sg + sgl->cur, page, size, offset); 403 + sgl->cur++; 404 + ctx->used += size; 405 + 406 + done: 407 + ctx->more = flags & MSG_MORE; 408 + if (!ctx->more && !list_empty(&ctx->tsgl)) 409 + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); 410 + 411 + unlock: 412 + skcipher_data_wakeup(sk); 413 + release_sock(sk); 414 + 415 + return err ?: size; 416 + } 417 + 418 + static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, 419 + struct msghdr *msg, size_t ignored, int flags) 420 + { 421 + struct sock *sk = sock->sk; 422 + struct alg_sock *ask = alg_sk(sk); 423 + struct skcipher_ctx *ctx = ask->private; 424 + unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm( 425 + &ctx->req)); 426 + struct skcipher_sg_list *sgl; 427 + struct scatterlist *sg; 428 + unsigned long iovlen; 429 + struct iovec *iov; 430 + int err = -EAGAIN; 431 + int used; 432 + long copied = 0; 433 + 434 + lock_sock(sk); 435 + for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; 436 + iovlen--, iov++) { 437 + unsigned long seglen = iov->iov_len; 438 + char __user *from = iov->iov_base; 439 + 440 + while (seglen) { 441 + sgl = list_first_entry(&ctx->tsgl, 442 + struct skcipher_sg_list, list); 443 + sg = sgl->sg; 444 + 445 + while (!sg->length) 446 + sg++; 447 + 448 + used = ctx->used; 449 + if (!used) { 450 + err = skcipher_wait_for_data(sk, flags); 451 + if (err) 452 + goto unlock; 453 + } 454 + 455 + used = min_t(unsigned long, used, seglen); 456 + 457 + used = af_alg_make_sg(&ctx->rsgl, from, used, 1); 458 + err = used; 459 + if (err < 0) 460 + goto unlock; 461 + 462 + if (ctx->more || used < ctx->used) 463 + used -= used % bs; 464 + 465 + err = -EINVAL; 466 + if (!used) 467 + goto free; 468 + 469 + ablkcipher_request_set_crypt(&ctx->req, sg, 470 + ctx->rsgl.sg, used, 471 + ctx->iv); 472 + 473 + err = af_alg_wait_for_completion( 474 + ctx->enc ? 475 + crypto_ablkcipher_encrypt(&ctx->req) : 476 + crypto_ablkcipher_decrypt(&ctx->req), 477 + &ctx->completion); 478 + 479 + free: 480 + af_alg_free_sg(&ctx->rsgl); 481 + 482 + if (err) 483 + goto unlock; 484 + 485 + copied += used; 486 + from += used; 487 + seglen -= used; 488 + skcipher_pull_sgl(sk, used); 489 + } 490 + } 491 + 492 + err = 0; 493 + 494 + unlock: 495 + skcipher_wmem_wakeup(sk); 496 + release_sock(sk); 497 + 498 + return copied ?: err; 499 + } 500 + 501 + 502 + static unsigned int skcipher_poll(struct file *file, struct socket *sock, 503 + poll_table *wait) 504 + { 505 + struct sock *sk = sock->sk; 506 + struct alg_sock *ask = alg_sk(sk); 507 + struct skcipher_ctx *ctx = ask->private; 508 + unsigned int mask; 509 + 510 + sock_poll_wait(file, sk_sleep(sk), wait); 511 + mask = 0; 512 + 513 + if (ctx->used) 514 + mask |= POLLIN | POLLRDNORM; 515 + 516 + if (skcipher_writable(sk)) 517 + mask |= POLLOUT | POLLWRNORM | POLLWRBAND; 518 + 519 + return mask; 520 + } 521 + 522 + static struct proto_ops algif_skcipher_ops = { 523 + .family = PF_ALG, 524 + 525 + .connect = sock_no_connect, 526 + .socketpair = sock_no_socketpair, 527 + .getname = sock_no_getname, 528 + .ioctl = sock_no_ioctl, 529 + .listen = sock_no_listen, 530 + .shutdown = sock_no_shutdown, 531 + .getsockopt = sock_no_getsockopt, 532 + .mmap = sock_no_mmap, 533 + .bind = sock_no_bind, 534 + .accept = sock_no_accept, 535 + .setsockopt = sock_no_setsockopt, 536 + 537 + .release = af_alg_release, 538 + .sendmsg = skcipher_sendmsg, 539 + .sendpage = skcipher_sendpage, 540 + .recvmsg = skcipher_recvmsg, 541 + .poll = skcipher_poll, 542 + }; 543 + 544 + static void *skcipher_bind(const char *name, u32 type, u32 mask) 545 + { 546 + return crypto_alloc_ablkcipher(name, type, mask); 547 + } 548 + 549 + static void skcipher_release(void *private) 550 + { 551 + crypto_free_ablkcipher(private); 552 + } 553 + 554 + static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) 555 + { 556 + return crypto_ablkcipher_setkey(private, key, keylen); 557 + } 558 + 559 + static void skcipher_sock_destruct(struct sock *sk) 560 + { 561 + struct alg_sock *ask = alg_sk(sk); 562 + struct skcipher_ctx *ctx = ask->private; 563 + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); 564 + 565 + skcipher_free_sgl(sk); 566 + sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); 567 + sock_kfree_s(sk, ctx, ctx->len); 568 + af_alg_release_parent(sk); 569 + } 570 + 571 + static int skcipher_accept_parent(void *private, struct sock *sk) 572 + { 573 + struct skcipher_ctx *ctx; 574 + struct alg_sock *ask = alg_sk(sk); 575 + unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private); 576 + 577 + ctx = sock_kmalloc(sk, len, GFP_KERNEL); 578 + if (!ctx) 579 + return -ENOMEM; 580 + 581 + ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private), 582 + GFP_KERNEL); 583 + if (!ctx->iv) { 584 + sock_kfree_s(sk, ctx, len); 585 + return -ENOMEM; 586 + } 587 + 588 + memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private)); 589 + 590 + INIT_LIST_HEAD(&ctx->tsgl); 591 + ctx->len = len; 592 + ctx->used = 0; 593 + ctx->more = 0; 594 + ctx->merge = 0; 595 + ctx->enc = 0; 596 + af_alg_init_completion(&ctx->completion); 597 + 598 + ask->private = ctx; 599 + 600 + ablkcipher_request_set_tfm(&ctx->req, private); 601 + ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, 602 + af_alg_complete, &ctx->completion); 603 + 604 + sk->sk_destruct = skcipher_sock_destruct; 605 + 606 + return 0; 607 + } 608 + 609 + static const struct af_alg_type algif_type_skcipher = { 610 + .bind = skcipher_bind, 611 + .release = skcipher_release, 612 + .setkey = skcipher_setkey, 613 + .accept = skcipher_accept_parent, 614 + .ops = &algif_skcipher_ops, 615 + .name = "skcipher", 616 + .owner = THIS_MODULE 617 + }; 618 + 619 + static int __init algif_skcipher_init(void) 620 + { 621 + return af_alg_register_type(&algif_type_skcipher); 622 + } 623 + 624 + static void __exit algif_skcipher_exit(void) 625 + { 626 + int err = af_alg_unregister_type(&algif_type_skcipher); 627 + BUG_ON(err); 628 + } 629 + 630 + module_init(algif_skcipher_init); 631 + module_exit(algif_skcipher_exit); 632 + MODULE_LICENSE("GPL");
+4 -18
crypto/authenc.c
··· 107 107 goto out; 108 108 } 109 109 110 - static void authenc_chain(struct scatterlist *head, struct scatterlist *sg, 111 - int chain) 112 - { 113 - if (chain) { 114 - head->length += sg->length; 115 - sg = scatterwalk_sg_next(sg); 116 - } 117 - 118 - if (sg) 119 - scatterwalk_sg_chain(head, 2, sg); 120 - else 121 - sg_mark_end(head); 122 - } 123 - 124 110 static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq, 125 111 int err) 126 112 { ··· 331 345 if (ivsize) { 332 346 sg_init_table(cipher, 2); 333 347 sg_set_buf(cipher, iv, ivsize); 334 - authenc_chain(cipher, dst, vdst == iv + ivsize); 348 + scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2); 335 349 dst = cipher; 336 350 cryptlen += ivsize; 337 351 } ··· 340 354 authenc_ahash_fn = crypto_authenc_ahash; 341 355 sg_init_table(asg, 2); 342 356 sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); 343 - authenc_chain(asg, dst, 0); 357 + scatterwalk_crypto_chain(asg, dst, 0, 2); 344 358 dst = asg; 345 359 cryptlen += req->assoclen; 346 360 } ··· 485 499 if (ivsize) { 486 500 sg_init_table(cipher, 2); 487 501 sg_set_buf(cipher, iv, ivsize); 488 - authenc_chain(cipher, src, vsrc == iv + ivsize); 502 + scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2); 489 503 src = cipher; 490 504 cryptlen += ivsize; 491 505 } ··· 494 508 authenc_ahash_fn = crypto_authenc_ahash; 495 509 sg_init_table(asg, 2); 496 510 sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); 497 - authenc_chain(asg, src, 0); 511 + scatterwalk_crypto_chain(asg, src, 0, 2); 498 512 src = asg; 499 513 cryptlen += req->assoclen; 500 514 }
+24 -50
crypto/cast5.c
··· 604 604 * Rounds 3, 6, 9, 12, and 15 use f function Type 3. 605 605 */ 606 606 607 + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); 608 + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); 609 + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); 610 + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); 611 + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); 612 + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); 613 + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); 614 + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); 615 + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); 616 + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); 617 + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); 618 + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); 607 619 if (!(c->rr)) { 608 - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); 609 - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); 610 - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); 611 - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); 612 - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); 613 - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); 614 - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); 615 - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); 616 - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); 617 - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); 618 - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); 619 - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); 620 620 t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); 621 621 t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); 622 622 t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); 623 623 t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); 624 - } else { 625 - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); 626 - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); 627 - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); 628 - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); 629 - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); 630 - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); 631 - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); 632 - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); 633 - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); 634 - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); 635 - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); 636 - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); 637 624 } 638 625 639 626 /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and ··· 650 663 t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); 651 664 t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); 652 665 t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); 653 - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); 654 - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); 655 - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); 656 - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); 657 - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); 658 - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); 659 - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); 660 - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); 661 - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); 662 - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); 663 - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); 664 - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); 665 - } else { 666 - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); 667 - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); 668 - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); 669 - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); 670 - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); 671 - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); 672 - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); 673 - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); 674 - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); 675 - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); 676 - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); 677 - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); 678 666 } 667 + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); 668 + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); 669 + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); 670 + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); 671 + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); 672 + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); 673 + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); 674 + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); 675 + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); 676 + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); 677 + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); 678 + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); 679 679 680 680 dst[0] = cpu_to_be32(r); 681 681 dst[1] = cpu_to_be32(l);
+2 -1
crypto/crypto_wq.c
··· 20 20 21 21 static int __init crypto_wq_init(void) 22 22 { 23 - kcrypto_wq = create_workqueue("crypto"); 23 + kcrypto_wq = alloc_workqueue("crypto", 24 + WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1); 24 25 if (unlikely(!kcrypto_wq)) 25 26 return -ENOMEM; 26 27 return 0;
+1 -2
crypto/deflate.c
··· 48 48 int ret = 0; 49 49 struct z_stream_s *stream = &ctx->comp_stream; 50 50 51 - stream->workspace = vmalloc(zlib_deflate_workspacesize()); 51 + stream->workspace = vzalloc(zlib_deflate_workspacesize()); 52 52 if (!stream->workspace) { 53 53 ret = -ENOMEM; 54 54 goto out; 55 55 } 56 - memset(stream->workspace, 0, zlib_deflate_workspacesize()); 57 56 ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, 58 57 -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, 59 58 Z_DEFAULT_STRATEGY);
+2 -16
crypto/eseqiv.c
··· 62 62 skcipher_givcrypt_complete(req, err); 63 63 } 64 64 65 - static void eseqiv_chain(struct scatterlist *head, struct scatterlist *sg, 66 - int chain) 67 - { 68 - if (chain) { 69 - head->length += sg->length; 70 - sg = scatterwalk_sg_next(sg); 71 - } 72 - 73 - if (sg) 74 - scatterwalk_sg_chain(head, 2, sg); 75 - else 76 - sg_mark_end(head); 77 - } 78 - 79 65 static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) 80 66 { 81 67 struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); ··· 110 124 111 125 sg_init_table(reqctx->src, 2); 112 126 sg_set_buf(reqctx->src, giv, ivsize); 113 - eseqiv_chain(reqctx->src, osrc, vsrc == giv + ivsize); 127 + scatterwalk_crypto_chain(reqctx->src, osrc, vsrc == giv + ivsize, 2); 114 128 115 129 dst = reqctx->src; 116 130 if (osrc != odst) { 117 131 sg_init_table(reqctx->dst, 2); 118 132 sg_set_buf(reqctx->dst, giv, ivsize); 119 - eseqiv_chain(reqctx->dst, odst, vdst == giv + ivsize); 133 + scatterwalk_crypto_chain(reqctx->dst, odst, vdst == giv + ivsize, 2); 120 134 121 135 dst = reqctx->dst; 122 136 }
+2 -17
crypto/gcm.c
··· 1102 1102 return crypto_aead_setauthsize(ctx->child, authsize); 1103 1103 } 1104 1104 1105 - /* this is the same as crypto_authenc_chain */ 1106 - static void crypto_rfc4543_chain(struct scatterlist *head, 1107 - struct scatterlist *sg, int chain) 1108 - { 1109 - if (chain) { 1110 - head->length += sg->length; 1111 - sg = scatterwalk_sg_next(sg); 1112 - } 1113 - 1114 - if (sg) 1115 - scatterwalk_sg_chain(head, 2, sg); 1116 - else 1117 - sg_mark_end(head); 1118 - } 1119 - 1120 1105 static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, 1121 1106 int enc) 1122 1107 { ··· 1139 1154 1140 1155 sg_init_table(payload, 2); 1141 1156 sg_set_buf(payload, req->iv, 8); 1142 - crypto_rfc4543_chain(payload, dst, vdst == req->iv + 8); 1157 + scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); 1143 1158 assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); 1144 1159 1145 1160 sg_init_table(assoc, 2); 1146 1161 sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, 1147 1162 req->assoc->offset); 1148 - crypto_rfc4543_chain(assoc, payload, 0); 1163 + scatterwalk_crypto_chain(assoc, payload, 0, 2); 1149 1164 1150 1165 aead_request_set_tfm(subreq, ctx->child); 1151 1166 aead_request_set_callback(subreq, req->base.flags, req->base.complete,
+2 -1
crypto/pcrypt.c
··· 455 455 456 456 get_online_cpus(); 457 457 458 - pcrypt->wq = create_workqueue(name); 458 + pcrypt->wq = alloc_workqueue(name, 459 + WQ_MEM_RECLAIM | WQ_CPU_INTENSIVE, 1); 459 460 if (!pcrypt->wq) 460 461 goto err; 461 462
+2 -1
crypto/rmd128.c
··· 5 5 * 6 6 * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC 7 7 * 8 - * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> 8 + * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify it 11 11 * under the terms of the GNU General Public License as published by the Free ··· 325 325 module_exit(rmd128_mod_fini); 326 326 327 327 MODULE_LICENSE("GPL"); 328 + MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); 328 329 MODULE_DESCRIPTION("RIPEMD-128 Message Digest");
+2 -1
crypto/rmd160.c
··· 5 5 * 6 6 * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC 7 7 * 8 - * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> 8 + * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify it 11 11 * under the terms of the GNU General Public License as published by the Free ··· 369 369 module_exit(rmd160_mod_fini); 370 370 371 371 MODULE_LICENSE("GPL"); 372 + MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); 372 373 MODULE_DESCRIPTION("RIPEMD-160 Message Digest");
+2 -1
crypto/rmd256.c
··· 5 5 * 6 6 * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC 7 7 * 8 - * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> 8 + * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify it 11 11 * under the terms of the GNU General Public License as published by the Free ··· 344 344 module_exit(rmd256_mod_fini); 345 345 346 346 MODULE_LICENSE("GPL"); 347 + MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); 347 348 MODULE_DESCRIPTION("RIPEMD-256 Message Digest");
+2 -1
crypto/rmd320.c
··· 5 5 * 6 6 * Based on the reference implementation by Antoon Bosselaers, ESAT-COSIC 7 7 * 8 - * Copyright (c) 2008 Adrian-Ken Rueegsegger <rueegsegger (at) swiss-it.ch> 8 + * Copyright (c) 2008 Adrian-Ken Rueegsegger <ken@codelabs.ch> 9 9 * 10 10 * This program is free software; you can redistribute it and/or modify it 11 11 * under the terms of the GNU General Public License as published by the Free ··· 393 393 module_exit(rmd320_mod_fini); 394 394 395 395 MODULE_LICENSE("GPL"); 396 + MODULE_AUTHOR("Adrian-Ken Rueegsegger <ken@codelabs.ch>"); 396 397 MODULE_DESCRIPTION("RIPEMD-320 Message Digest");
+7 -1
crypto/shash.c
··· 310 310 311 311 static int shash_async_import(struct ahash_request *req, const void *in) 312 312 { 313 - return crypto_shash_import(ahash_request_ctx(req), in); 313 + struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); 314 + struct shash_desc *desc = ahash_request_ctx(req); 315 + 316 + desc->tfm = *ctx; 317 + desc->flags = req->base.flags; 318 + 319 + return crypto_shash_import(desc, in); 314 320 } 315 321 316 322 static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm)
+11
crypto/tcrypt.c
··· 8 8 * Copyright (c) 2002 Jean-Francois Dive <jef@linuxbe.org> 9 9 * Copyright (c) 2007 Nokia Siemens Networks 10 10 * 11 + * Updated RFC4106 AES-GCM testing. 12 + * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) 13 + * Adrian Hoban <adrian.hoban@intel.com> 14 + * Gabriele Paoloni <gabriele.paoloni@intel.com> 15 + * Tadeusz Struk (tadeusz.struk@intel.com) 16 + * Copyright (c) 2010, Intel Corporation. 17 + * 11 18 * This program is free software; you can redistribute it and/or modify it 12 19 * under the terms of the GNU General Public License as published by the Free 13 20 * Software Foundation; either version 2 of the License, or (at your option) ··· 985 978 986 979 case 150: 987 980 ret += tcrypt_test("ansi_cprng"); 981 + break; 982 + 983 + case 151: 984 + ret += tcrypt_test("rfc4106(gcm(aes))"); 988 985 break; 989 986 990 987 case 200:
+24
crypto/testmgr.c
··· 6 6 * Copyright (c) 2007 Nokia Siemens Networks 7 7 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> 8 8 * 9 + * Updated RFC4106 AES-GCM testing. 10 + * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) 11 + * Adrian Hoban <adrian.hoban@intel.com> 12 + * Gabriele Paoloni <gabriele.paoloni@intel.com> 13 + * Tadeusz Struk (tadeusz.struk@intel.com) 14 + * Copyright (c) 2010, Intel Corporation. 15 + * 9 16 * This program is free software; you can redistribute it and/or modify it 10 17 * under the terms of the GNU General Public License as published by the Free 11 18 * Software Foundation; either version 2 of the License, or (at your option) ··· 2249 2242 } 2250 2243 } 2251 2244 }, { 2245 + .alg = "rfc4106(gcm(aes))", 2246 + .test = alg_test_aead, 2247 + .suite = { 2248 + .aead = { 2249 + .enc = { 2250 + .vecs = aes_gcm_rfc4106_enc_tv_template, 2251 + .count = AES_GCM_4106_ENC_TEST_VECTORS 2252 + }, 2253 + .dec = { 2254 + .vecs = aes_gcm_rfc4106_dec_tv_template, 2255 + .count = AES_GCM_4106_DEC_TEST_VECTORS 2256 + } 2257 + } 2258 + } 2259 + }, { 2260 + 2261 + 2252 2262 .alg = "rfc4309(ccm(aes))", 2253 2263 .test = alg_test_aead, 2254 2264 .fips_allowed = 1,
+361
crypto/testmgr.h
··· 6 6 * Copyright (c) 2007 Nokia Siemens Networks 7 7 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au> 8 8 * 9 + * Updated RFC4106 AES-GCM testing. Some test vectors were taken from 10 + * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ 11 + * gcm/gcm-test-vectors.tar.gz 12 + * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) 13 + * Adrian Hoban <adrian.hoban@intel.com> 14 + * Gabriele Paoloni <gabriele.paoloni@intel.com> 15 + * Tadeusz Struk (tadeusz.struk@intel.com) 16 + * Copyright (c) 2010, Intel Corporation. 17 + * 9 18 * This program is free software; you can redistribute it and/or modify it 10 19 * under the terms of the GNU General Public License as published by the Free 11 20 * Software Foundation; either version 2 of the License, or (at your option) ··· 2956 2947 #define AES_CTR_3686_DEC_TEST_VECTORS 6 2957 2948 #define AES_GCM_ENC_TEST_VECTORS 9 2958 2949 #define AES_GCM_DEC_TEST_VECTORS 8 2950 + #define AES_GCM_4106_ENC_TEST_VECTORS 7 2951 + #define AES_GCM_4106_DEC_TEST_VECTORS 7 2959 2952 #define AES_CCM_ENC_TEST_VECTORS 7 2960 2953 #define AES_CCM_DEC_TEST_VECTORS 7 2961 2954 #define AES_CCM_4309_ENC_TEST_VECTORS 7 ··· 5837 5826 "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57" 5838 5827 "\xba\x63\x7b\x39", 5839 5828 .rlen = 60, 5829 + } 5830 + }; 5831 + 5832 + static struct aead_testvec aes_gcm_rfc4106_enc_tv_template[] = { 5833 + { /* Generated using Crypto++ */ 5834 + .key = zeroed_string, 5835 + .klen = 20, 5836 + .iv = zeroed_string, 5837 + .input = zeroed_string, 5838 + .ilen = 16, 5839 + .assoc = zeroed_string, 5840 + .alen = 8, 5841 + .result = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92" 5842 + "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78" 5843 + "\x97\xFE\x4C\x23\x37\x42\x01\xE0" 5844 + "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B", 5845 + .rlen = 32, 5846 + },{ 5847 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 5848 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 5849 + "\x00\x00\x00\x00", 5850 + .klen = 20, 5851 + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" 5852 + "\x00\x00\x00\x00", 5853 + .input = zeroed_string, 5854 + .ilen = 16, 5855 + .assoc = zeroed_string, 5856 + .alen = 8, 5857 + .result = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18" 5858 + "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28" 5859 + "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D" 5860 + "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF", 5861 + .rlen = 32, 5862 + 5863 + }, { 5864 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 5865 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 5866 + "\x00\x00\x00\x00", 5867 + .klen = 20, 5868 + .iv = zeroed_string, 5869 + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" 5870 + "\x01\x01\x01\x01\x01\x01\x01\x01", 5871 + .ilen = 16, 5872 + .assoc = zeroed_string, 5873 + .alen = 8, 5874 + .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" 5875 + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" 5876 + "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C" 5877 + "\xB1\x68\xFD\x14\x52\x64\x61\xB2", 5878 + .rlen = 32, 5879 + }, { 5880 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 5881 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 5882 + "\x00\x00\x00\x00", 5883 + .klen = 20, 5884 + .iv = zeroed_string, 5885 + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" 5886 + "\x01\x01\x01\x01\x01\x01\x01\x01", 5887 + .ilen = 16, 5888 + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", 5889 + .alen = 8, 5890 + .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" 5891 + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" 5892 + "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63" 5893 + "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5", 5894 + .rlen = 32, 5895 + }, { 5896 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 5897 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 5898 + "\x00\x00\x00\x00", 5899 + .klen = 20, 5900 + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" 5901 + "\x00\x00\x00\x00", 5902 + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" 5903 + "\x01\x01\x01\x01\x01\x01\x01\x01", 5904 + .ilen = 16, 5905 + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", 5906 + .alen = 8, 5907 + .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" 5908 + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" 5909 + "\x64\x50\xF9\x32\x13\xFB\x74\x61" 5910 + "\xF4\xED\x52\xD3\xC5\x10\x55\x3C", 5911 + .rlen = 32, 5912 + }, { 5913 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 5914 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 5915 + "\x00\x00\x00\x00", 5916 + .klen = 20, 5917 + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" 5918 + "\x00\x00\x00\x00", 5919 + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" 5920 + "\x01\x01\x01\x01\x01\x01\x01\x01" 5921 + "\x01\x01\x01\x01\x01\x01\x01\x01" 5922 + "\x01\x01\x01\x01\x01\x01\x01\x01" 5923 + "\x01\x01\x01\x01\x01\x01\x01\x01" 5924 + "\x01\x01\x01\x01\x01\x01\x01\x01" 5925 + "\x01\x01\x01\x01\x01\x01\x01\x01" 5926 + "\x01\x01\x01\x01\x01\x01\x01\x01", 5927 + .ilen = 64, 5928 + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", 5929 + .alen = 8, 5930 + .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" 5931 + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" 5932 + "\x98\x14\xA1\x42\x37\x80\xFD\x90" 5933 + "\x68\x12\x01\xA8\x91\x89\xB9\x83" 5934 + "\x5B\x11\x77\x12\x9B\xFF\x24\x89" 5935 + "\x94\x5F\x18\x12\xBA\x27\x09\x39" 5936 + "\x99\x96\x76\x42\x15\x1C\xCD\xCB" 5937 + "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD" 5938 + "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85" 5939 + "\xBD\xCF\x62\x98\x58\x14\xE5\xBD", 5940 + .rlen = 80, 5941 + }, { 5942 + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" 5943 + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" 5944 + "\x00\x00\x00\x00", 5945 + .klen = 20, 5946 + .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef" 5947 + "\x00\x00\x00\x00", 5948 + .input = "\xff\xff\xff\xff\xff\xff\xff\xff" 5949 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5950 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5951 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5952 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5953 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5954 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5955 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5956 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5957 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5958 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5959 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5960 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5961 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5962 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5963 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5964 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5965 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5966 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5967 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5968 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5969 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5970 + "\xff\xff\xff\xff\xff\xff\xff\xff" 5971 + "\xff\xff\xff\xff\xff\xff\xff\xff", 5972 + .ilen = 192, 5973 + .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" 5974 + "\xaa\xaa\xaa\xaa", 5975 + .alen = 12, 5976 + .result = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE" 5977 + "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A" 5978 + "\x44\x6D\xC3\x88\x46\x2E\xC2\x01" 5979 + "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82" 5980 + "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44" 5981 + "\x41\xA9\x82\x6F\x22\xA1\x23\x1A" 5982 + "\xA8\xE3\x16\xFD\x31\x5C\x27\x31" 5983 + "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1" 5984 + "\xCF\x07\x57\x41\x67\xD0\xC4\x42" 5985 + "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F" 5986 + "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B" 5987 + "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE" 5988 + "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C" 5989 + "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF" 5990 + "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59" 5991 + "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA" 5992 + "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25" 5993 + "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B" 5994 + "\x7E\x13\x06\x82\x08\x17\xA4\x35" 5995 + "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F" 5996 + "\xA3\x05\x38\x95\x20\x1A\x47\x04" 5997 + "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35" 5998 + "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E" 5999 + "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B" 6000 + "\x37\x08\x1C\xCF\xBA\x5D\x71\x46" 6001 + "\x80\x72\xB0\x4C\x82\x0D\x60\x3C", 6002 + .rlen = 208, 6003 + } 6004 + }; 6005 + 6006 + static struct aead_testvec aes_gcm_rfc4106_dec_tv_template[] = { 6007 + { /* Generated using Crypto++ */ 6008 + .key = zeroed_string, 6009 + .klen = 20, 6010 + .iv = zeroed_string, 6011 + .input = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92" 6012 + "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78" 6013 + "\x97\xFE\x4C\x23\x37\x42\x01\xE0" 6014 + "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B", 6015 + .ilen = 32, 6016 + .assoc = zeroed_string, 6017 + .alen = 8, 6018 + .result = zeroed_string, 6019 + .rlen = 16, 6020 + 6021 + },{ 6022 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 6023 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 6024 + "\x00\x00\x00\x00", 6025 + .klen = 20, 6026 + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" 6027 + "\x00\x00\x00\x00", 6028 + .input = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18" 6029 + "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28" 6030 + "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D" 6031 + "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF", 6032 + .ilen = 32, 6033 + .assoc = zeroed_string, 6034 + .alen = 8, 6035 + .result = zeroed_string, 6036 + .rlen = 16, 6037 + }, { 6038 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 6039 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 6040 + "\x00\x00\x00\x00", 6041 + .klen = 20, 6042 + .iv = zeroed_string, 6043 + .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" 6044 + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" 6045 + "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C" 6046 + "\xB1\x68\xFD\x14\x52\x64\x61\xB2", 6047 + .ilen = 32, 6048 + .assoc = zeroed_string, 6049 + .alen = 8, 6050 + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" 6051 + "\x01\x01\x01\x01\x01\x01\x01\x01", 6052 + .rlen = 16, 6053 + }, { 6054 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 6055 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 6056 + "\x00\x00\x00\x00", 6057 + .klen = 20, 6058 + .iv = zeroed_string, 6059 + .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" 6060 + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" 6061 + "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63" 6062 + "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5", 6063 + .ilen = 32, 6064 + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", 6065 + .alen = 8, 6066 + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" 6067 + "\x01\x01\x01\x01\x01\x01\x01\x01", 6068 + .rlen = 16, 6069 + 6070 + }, { 6071 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 6072 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 6073 + "\x00\x00\x00\x00", 6074 + .klen = 20, 6075 + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" 6076 + "\x00\x00\x00\x00", 6077 + .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" 6078 + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" 6079 + "\x64\x50\xF9\x32\x13\xFB\x74\x61" 6080 + "\xF4\xED\x52\xD3\xC5\x10\x55\x3C", 6081 + .ilen = 32, 6082 + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", 6083 + .alen = 8, 6084 + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" 6085 + "\x01\x01\x01\x01\x01\x01\x01\x01", 6086 + .rlen = 16, 6087 + }, { 6088 + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" 6089 + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" 6090 + "\x00\x00\x00\x00", 6091 + .klen = 20, 6092 + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" 6093 + "\x00\x00\x00\x00", 6094 + .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" 6095 + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" 6096 + "\x98\x14\xA1\x42\x37\x80\xFD\x90" 6097 + "\x68\x12\x01\xA8\x91\x89\xB9\x83" 6098 + "\x5B\x11\x77\x12\x9B\xFF\x24\x89" 6099 + "\x94\x5F\x18\x12\xBA\x27\x09\x39" 6100 + "\x99\x96\x76\x42\x15\x1C\xCD\xCB" 6101 + "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD" 6102 + "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85" 6103 + "\xBD\xCF\x62\x98\x58\x14\xE5\xBD", 6104 + .ilen = 80, 6105 + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", 6106 + .alen = 8, 6107 + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" 6108 + "\x01\x01\x01\x01\x01\x01\x01\x01" 6109 + "\x01\x01\x01\x01\x01\x01\x01\x01" 6110 + "\x01\x01\x01\x01\x01\x01\x01\x01" 6111 + "\x01\x01\x01\x01\x01\x01\x01\x01" 6112 + "\x01\x01\x01\x01\x01\x01\x01\x01" 6113 + "\x01\x01\x01\x01\x01\x01\x01\x01" 6114 + "\x01\x01\x01\x01\x01\x01\x01\x01", 6115 + .rlen = 64, 6116 + }, { 6117 + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" 6118 + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" 6119 + "\x00\x00\x00\x00", 6120 + .klen = 20, 6121 + .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef" 6122 + "\x00\x00\x00\x00", 6123 + .input = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE" 6124 + "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A" 6125 + "\x44\x6D\xC3\x88\x46\x2E\xC2\x01" 6126 + "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82" 6127 + "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44" 6128 + "\x41\xA9\x82\x6F\x22\xA1\x23\x1A" 6129 + "\xA8\xE3\x16\xFD\x31\x5C\x27\x31" 6130 + "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1" 6131 + "\xCF\x07\x57\x41\x67\xD0\xC4\x42" 6132 + "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F" 6133 + "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B" 6134 + "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE" 6135 + "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C" 6136 + "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF" 6137 + "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59" 6138 + "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA" 6139 + "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25" 6140 + "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B" 6141 + "\x7E\x13\x06\x82\x08\x17\xA4\x35" 6142 + "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F" 6143 + "\xA3\x05\x38\x95\x20\x1A\x47\x04" 6144 + "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35" 6145 + "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E" 6146 + "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B" 6147 + "\x37\x08\x1C\xCF\xBA\x5D\x71\x46" 6148 + "\x80\x72\xB0\x4C\x82\x0D\x60\x3C", 6149 + .ilen = 208, 6150 + .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" 6151 + "\xaa\xaa\xaa\xaa", 6152 + .alen = 12, 6153 + .result = "\xff\xff\xff\xff\xff\xff\xff\xff" 6154 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6155 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6156 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6157 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6158 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6159 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6160 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6161 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6162 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6163 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6164 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6165 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6166 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6167 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6168 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6169 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6170 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6171 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6172 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6173 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6174 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6175 + "\xff\xff\xff\xff\xff\xff\xff\xff" 6176 + "\xff\xff\xff\xff\xff\xff\xff\xff", 6177 + .rlen = 192, 6178 + 5840 6179 } 5841 6180 }; 5842 6181
+1 -2
crypto/zlib.c
··· 95 95 zlib_comp_exit(ctx); 96 96 97 97 workspacesize = zlib_deflate_workspacesize(); 98 - stream->workspace = vmalloc(workspacesize); 98 + stream->workspace = vzalloc(workspacesize); 99 99 if (!stream->workspace) 100 100 return -ENOMEM; 101 101 102 - memset(stream->workspace, 0, workspacesize); 103 102 ret = zlib_deflateInit2(stream, 104 103 tb[ZLIB_COMP_LEVEL] 105 104 ? nla_get_u32(tb[ZLIB_COMP_LEVEL])
+6 -4
drivers/char/hw_random/via-rng.c
··· 24 24 * warranty of any kind, whether express or implied. 25 25 */ 26 26 27 + #include <crypto/padlock.h> 27 28 #include <linux/module.h> 28 29 #include <linux/kernel.h> 29 30 #include <linux/hw_random.h> ··· 35 34 #include <asm/i387.h> 36 35 37 36 38 - #define PFX KBUILD_MODNAME ": " 39 37 40 38 41 39 enum { ··· 81 81 ts_state = irq_ts_save(); 82 82 83 83 asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */" 84 - :"=m"(*addr), "=a"(eax_out) 85 - :"D"(addr), "d"(edx_in)); 84 + : "=m" (*addr), "=a" (eax_out), "+d" (edx_in), "+D" (addr)); 86 85 87 86 irq_ts_restore(ts_state); 88 87 return eax_out; ··· 89 90 90 91 static int via_rng_data_present(struct hwrng *rng, int wait) 91 92 { 93 + char buf[16 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__ 94 + ((aligned(STACK_ALIGN))); 95 + u32 *via_rng_datum = (u32 *)PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT); 92 96 u32 bytes_out; 93 - u32 *via_rng_datum = (u32 *)(&rng->priv); 94 97 int i; 95 98 96 99 /* We choose the recommended 1-byte-per-instruction RNG rate, ··· 116 115 break; 117 116 udelay(10); 118 117 } 118 + rng->priv = *via_rng_datum; 119 119 return bytes_out ? 1 : 0; 120 120 } 121 121
+1 -1
drivers/crypto/mv_cesa.c
··· 857 857 printk(KERN_WARNING MV_CESA 858 858 "Base driver '%s' could not be loaded!\n", 859 859 base_hash_name); 860 - err = PTR_ERR(fallback_tfm); 860 + err = PTR_ERR(base_hash); 861 861 goto err_bad_base; 862 862 } 863 863 }
+1 -1
drivers/crypto/n2_core.c
··· 1542 1542 return err; 1543 1543 } 1544 1544 1545 - static void __exit n2_unregister_algs(void) 1545 + static void __devexit n2_unregister_algs(void) 1546 1546 { 1547 1547 mutex_lock(&spu_lock); 1548 1548 if (!--algs_registered)
+136 -124
drivers/crypto/omap-aes.c
··· 74 74 #define FLAGS_CBC BIT(1) 75 75 #define FLAGS_GIV BIT(2) 76 76 77 - #define FLAGS_NEW_KEY BIT(4) 78 - #define FLAGS_NEW_IV BIT(5) 79 - #define FLAGS_INIT BIT(6) 80 - #define FLAGS_FAST BIT(7) 81 - #define FLAGS_BUSY 8 77 + #define FLAGS_INIT BIT(4) 78 + #define FLAGS_FAST BIT(5) 79 + #define FLAGS_BUSY BIT(6) 82 80 83 81 struct omap_aes_ctx { 84 82 struct omap_aes_dev *dd; ··· 96 98 struct omap_aes_dev { 97 99 struct list_head list; 98 100 unsigned long phys_base; 99 - void __iomem *io_base; 101 + void __iomem *io_base; 100 102 struct clk *iclk; 101 103 struct omap_aes_ctx *ctx; 102 104 struct device *dev; 103 105 unsigned long flags; 106 + int err; 104 107 105 - u32 *iv; 106 - u32 ctrl; 108 + spinlock_t lock; 109 + struct crypto_queue queue; 107 110 108 - spinlock_t lock; 109 - struct crypto_queue queue; 110 - 111 - struct tasklet_struct task; 111 + struct tasklet_struct done_task; 112 + struct tasklet_struct queue_task; 112 113 113 114 struct ablkcipher_request *req; 114 115 size_t total; ··· 176 179 177 180 static int omap_aes_hw_init(struct omap_aes_dev *dd) 178 181 { 179 - int err = 0; 180 - 182 + /* 183 + * clocks are enabled when request starts and disabled when finished. 184 + * It may be long delays between requests. 185 + * Device might go to off mode to save power. 186 + */ 181 187 clk_enable(dd->iclk); 188 + 182 189 if (!(dd->flags & FLAGS_INIT)) { 183 190 /* is it necessary to reset before every operation? */ 184 191 omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET, ··· 194 193 __asm__ __volatile__("nop"); 195 194 __asm__ __volatile__("nop"); 196 195 197 - err = omap_aes_wait(dd, AES_REG_SYSSTATUS, 198 - AES_REG_SYSSTATUS_RESETDONE); 199 - if (!err) 200 - dd->flags |= FLAGS_INIT; 196 + if (omap_aes_wait(dd, AES_REG_SYSSTATUS, 197 + AES_REG_SYSSTATUS_RESETDONE)) 198 + return -ETIMEDOUT; 199 + 200 + dd->flags |= FLAGS_INIT; 201 + dd->err = 0; 201 202 } 202 203 203 - return err; 204 + return 0; 204 205 } 205 206 206 - static void omap_aes_hw_cleanup(struct omap_aes_dev *dd) 207 - { 208 - clk_disable(dd->iclk); 209 - } 210 - 211 - static void omap_aes_write_ctrl(struct omap_aes_dev *dd) 207 + static int omap_aes_write_ctrl(struct omap_aes_dev *dd) 212 208 { 213 209 unsigned int key32; 214 - int i; 210 + int i, err; 215 211 u32 val, mask; 216 212 217 - val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3); 218 - if (dd->flags & FLAGS_CBC) 219 - val |= AES_REG_CTRL_CBC; 220 - if (dd->flags & FLAGS_ENCRYPT) 221 - val |= AES_REG_CTRL_DIRECTION; 222 - 223 - if (dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) && 224 - !(dd->ctx->flags & FLAGS_NEW_KEY)) 225 - goto out; 226 - 227 - /* only need to write control registers for new settings */ 228 - 229 - dd->ctrl = val; 213 + err = omap_aes_hw_init(dd); 214 + if (err) 215 + return err; 230 216 231 217 val = 0; 232 218 if (dd->dma_lch_out >= 0) ··· 225 237 226 238 omap_aes_write_mask(dd, AES_REG_MASK, val, mask); 227 239 228 - pr_debug("Set key\n"); 229 240 key32 = dd->ctx->keylen / sizeof(u32); 230 - /* set a key */ 241 + 242 + /* it seems a key should always be set even if it has not changed */ 231 243 for (i = 0; i < key32; i++) { 232 244 omap_aes_write(dd, AES_REG_KEY(i), 233 245 __le32_to_cpu(dd->ctx->key[i])); 234 246 } 235 - dd->ctx->flags &= ~FLAGS_NEW_KEY; 236 247 237 - if (dd->flags & FLAGS_NEW_IV) { 238 - pr_debug("Set IV\n"); 239 - omap_aes_write_n(dd, AES_REG_IV(0), dd->iv, 4); 240 - dd->flags &= ~FLAGS_NEW_IV; 241 - } 248 + if ((dd->flags & FLAGS_CBC) && dd->req->info) 249 + omap_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4); 250 + 251 + val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3); 252 + if (dd->flags & FLAGS_CBC) 253 + val |= AES_REG_CTRL_CBC; 254 + if (dd->flags & FLAGS_ENCRYPT) 255 + val |= AES_REG_CTRL_DIRECTION; 242 256 243 257 mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION | 244 258 AES_REG_CTRL_KEY_SIZE; 245 259 246 - omap_aes_write_mask(dd, AES_REG_CTRL, dd->ctrl, mask); 260 + omap_aes_write_mask(dd, AES_REG_CTRL, val, mask); 247 261 248 - out: 249 - /* start DMA or disable idle mode */ 250 - omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, 251 - AES_REG_MASK_START); 262 + /* IN */ 263 + omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, 264 + dd->phys_base + AES_REG_DATA, 0, 4); 265 + 266 + omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); 267 + omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); 268 + 269 + /* OUT */ 270 + omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, 271 + dd->phys_base + AES_REG_DATA, 0, 4); 272 + 273 + omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); 274 + omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); 275 + 276 + return 0; 252 277 } 253 278 254 279 static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx) ··· 289 288 { 290 289 struct omap_aes_dev *dd = data; 291 290 292 - if (lch == dd->dma_lch_out) 293 - tasklet_schedule(&dd->task); 291 + if (ch_status != OMAP_DMA_BLOCK_IRQ) { 292 + pr_err("omap-aes DMA error status: 0x%hx\n", ch_status); 293 + dd->err = -EIO; 294 + dd->flags &= ~FLAGS_INIT; /* request to re-initialize */ 295 + } else if (lch == dd->dma_lch_in) { 296 + return; 297 + } 298 + 299 + /* dma_lch_out - completed */ 300 + tasklet_schedule(&dd->done_task); 294 301 } 295 302 296 303 static int omap_aes_dma_init(struct omap_aes_dev *dd) ··· 347 338 dev_err(dd->dev, "Unable to request DMA channel\n"); 348 339 goto err_dma_out; 349 340 } 350 - 351 - omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, 352 - dd->phys_base + AES_REG_DATA, 0, 4); 353 - 354 - omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); 355 - omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); 356 - 357 - omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, 358 - dd->phys_base + AES_REG_DATA, 0, 4); 359 - 360 - omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); 361 - omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); 362 341 363 342 return 0; 364 343 ··· 403 406 if (!count) 404 407 return off; 405 408 409 + /* 410 + * buflen and total are AES_BLOCK_SIZE size aligned, 411 + * so count should be also aligned 412 + */ 413 + 406 414 sg_copy_buf(buf + off, *sg, *offset, count, out); 407 415 408 416 off += count; ··· 463 461 omap_start_dma(dd->dma_lch_in); 464 462 omap_start_dma(dd->dma_lch_out); 465 463 466 - omap_aes_write_ctrl(dd); 464 + /* start DMA or disable idle mode */ 465 + omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, 466 + AES_REG_MASK_START); 467 467 468 468 return 0; 469 469 } ··· 492 488 count = min(dd->total, sg_dma_len(dd->in_sg)); 493 489 count = min(count, sg_dma_len(dd->out_sg)); 494 490 495 - if (count != dd->total) 491 + if (count != dd->total) { 492 + pr_err("request length != buffer length\n"); 496 493 return -EINVAL; 494 + } 497 495 498 496 pr_debug("fast\n"); 499 497 ··· 531 525 532 526 dd->total -= count; 533 527 534 - err = omap_aes_hw_init(dd); 535 - 536 528 err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count); 529 + if (err) { 530 + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); 531 + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); 532 + } 537 533 538 534 return err; 539 535 } 540 536 541 537 static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) 542 538 { 543 - struct omap_aes_ctx *ctx; 539 + struct ablkcipher_request *req = dd->req; 544 540 545 541 pr_debug("err: %d\n", err); 546 542 547 - ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req)); 543 + clk_disable(dd->iclk); 544 + dd->flags &= ~FLAGS_BUSY; 548 545 549 - if (!dd->total) 550 - dd->req->base.complete(&dd->req->base, err); 546 + req->base.complete(&req->base, err); 551 547 } 552 548 553 549 static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) ··· 560 552 pr_debug("total: %d\n", dd->total); 561 553 562 554 omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START); 563 - 564 - omap_aes_hw_cleanup(dd); 565 555 566 556 omap_stop_dma(dd->dma_lch_in); 567 557 omap_stop_dma(dd->dma_lch_out); ··· 580 574 } 581 575 } 582 576 583 - if (err || !dd->total) 584 - omap_aes_finish_req(dd, err); 585 - 586 577 return err; 587 578 } 588 579 589 - static int omap_aes_handle_req(struct omap_aes_dev *dd) 580 + static int omap_aes_handle_queue(struct omap_aes_dev *dd, 581 + struct ablkcipher_request *req) 590 582 { 591 583 struct crypto_async_request *async_req, *backlog; 592 584 struct omap_aes_ctx *ctx; 593 585 struct omap_aes_reqctx *rctx; 594 - struct ablkcipher_request *req; 595 586 unsigned long flags; 596 - 597 - if (dd->total) 598 - goto start; 587 + int err, ret = 0; 599 588 600 589 spin_lock_irqsave(&dd->lock, flags); 590 + if (req) 591 + ret = ablkcipher_enqueue_request(&dd->queue, req); 592 + if (dd->flags & FLAGS_BUSY) { 593 + spin_unlock_irqrestore(&dd->lock, flags); 594 + return ret; 595 + } 601 596 backlog = crypto_get_backlog(&dd->queue); 602 597 async_req = crypto_dequeue_request(&dd->queue); 603 - if (!async_req) 604 - clear_bit(FLAGS_BUSY, &dd->flags); 598 + if (async_req) 599 + dd->flags |= FLAGS_BUSY; 605 600 spin_unlock_irqrestore(&dd->lock, flags); 606 601 607 602 if (!async_req) 608 - return 0; 603 + return ret; 609 604 610 605 if (backlog) 611 606 backlog->complete(backlog, -EINPROGRESS); 612 607 613 608 req = ablkcipher_request_cast(async_req); 614 - 615 - pr_debug("get new req\n"); 616 609 617 610 /* assign new request to device */ 618 611 dd->req = req; ··· 626 621 rctx->mode &= FLAGS_MODE_MASK; 627 622 dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; 628 623 629 - dd->iv = req->info; 630 - if ((dd->flags & FLAGS_CBC) && dd->iv) 631 - dd->flags |= FLAGS_NEW_IV; 632 - else 633 - dd->flags &= ~FLAGS_NEW_IV; 634 - 624 + dd->ctx = ctx; 635 625 ctx->dd = dd; 636 - if (dd->ctx != ctx) { 637 - /* assign new context to device */ 638 - dd->ctx = ctx; 639 - ctx->flags |= FLAGS_NEW_KEY; 626 + 627 + err = omap_aes_write_ctrl(dd); 628 + if (!err) 629 + err = omap_aes_crypt_dma_start(dd); 630 + if (err) { 631 + /* aes_task will not finish it, so do it here */ 632 + omap_aes_finish_req(dd, err); 633 + tasklet_schedule(&dd->queue_task); 640 634 } 641 635 642 - if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) 643 - pr_err("request size is not exact amount of AES blocks\n"); 644 - 645 - start: 646 - return omap_aes_crypt_dma_start(dd); 636 + return ret; /* return ret, which is enqueue return value */ 647 637 } 648 638 649 - static void omap_aes_task(unsigned long data) 639 + static void omap_aes_done_task(unsigned long data) 650 640 { 651 641 struct omap_aes_dev *dd = (struct omap_aes_dev *)data; 652 642 int err; ··· 650 650 651 651 err = omap_aes_crypt_dma_stop(dd); 652 652 653 - err = omap_aes_handle_req(dd); 653 + err = dd->err ? : err; 654 + 655 + if (dd->total && !err) { 656 + err = omap_aes_crypt_dma_start(dd); 657 + if (!err) 658 + return; /* DMA started. Not fininishing. */ 659 + } 660 + 661 + omap_aes_finish_req(dd, err); 662 + omap_aes_handle_queue(dd, NULL); 654 663 655 664 pr_debug("exit\n"); 665 + } 666 + 667 + static void omap_aes_queue_task(unsigned long data) 668 + { 669 + struct omap_aes_dev *dd = (struct omap_aes_dev *)data; 670 + 671 + omap_aes_handle_queue(dd, NULL); 656 672 } 657 673 658 674 static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) ··· 677 661 crypto_ablkcipher_reqtfm(req)); 678 662 struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req); 679 663 struct omap_aes_dev *dd; 680 - unsigned long flags; 681 - int err; 682 664 683 665 pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, 684 666 !!(mode & FLAGS_ENCRYPT), 685 667 !!(mode & FLAGS_CBC)); 668 + 669 + if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { 670 + pr_err("request size is not exact amount of AES blocks\n"); 671 + return -EINVAL; 672 + } 686 673 687 674 dd = omap_aes_find_dev(ctx); 688 675 if (!dd) ··· 693 674 694 675 rctx->mode = mode; 695 676 696 - spin_lock_irqsave(&dd->lock, flags); 697 - err = ablkcipher_enqueue_request(&dd->queue, req); 698 - spin_unlock_irqrestore(&dd->lock, flags); 699 - 700 - if (!test_and_set_bit(FLAGS_BUSY, &dd->flags)) 701 - omap_aes_handle_req(dd); 702 - 703 - pr_debug("exit\n"); 704 - 705 - return err; 677 + return omap_aes_handle_queue(dd, req); 706 678 } 707 679 708 680 /* ********************** ALG API ************************************ */ ··· 711 701 712 702 memcpy(ctx->key, key, keylen); 713 703 ctx->keylen = keylen; 714 - ctx->flags |= FLAGS_NEW_KEY; 715 704 716 705 return 0; 717 706 } ··· 759 750 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 760 751 .cra_blocksize = AES_BLOCK_SIZE, 761 752 .cra_ctxsize = sizeof(struct omap_aes_ctx), 762 - .cra_alignmask = 0, 753 + .cra_alignmask = 0, 763 754 .cra_type = &crypto_ablkcipher_type, 764 755 .cra_module = THIS_MODULE, 765 756 .cra_init = omap_aes_cra_init, ··· 779 770 .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, 780 771 .cra_blocksize = AES_BLOCK_SIZE, 781 772 .cra_ctxsize = sizeof(struct omap_aes_ctx), 782 - .cra_alignmask = 0, 773 + .cra_alignmask = 0, 783 774 .cra_type = &crypto_ablkcipher_type, 784 775 .cra_module = THIS_MODULE, 785 776 .cra_init = omap_aes_cra_init, ··· 858 849 (reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR); 859 850 clk_disable(dd->iclk); 860 851 861 - tasklet_init(&dd->task, omap_aes_task, (unsigned long)dd); 852 + tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd); 853 + tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd); 862 854 863 855 err = omap_aes_dma_init(dd); 864 856 if (err) ··· 886 876 crypto_unregister_alg(&algs[j]); 887 877 omap_aes_dma_cleanup(dd); 888 878 err_dma: 889 - tasklet_kill(&dd->task); 879 + tasklet_kill(&dd->done_task); 880 + tasklet_kill(&dd->queue_task); 890 881 iounmap(dd->io_base); 891 882 err_io: 892 883 clk_put(dd->iclk); ··· 914 903 for (i = 0; i < ARRAY_SIZE(algs); i++) 915 904 crypto_unregister_alg(&algs[i]); 916 905 917 - tasklet_kill(&dd->task); 906 + tasklet_kill(&dd->done_task); 907 + tasklet_kill(&dd->queue_task); 918 908 omap_aes_dma_cleanup(dd); 919 909 iounmap(dd->io_base); 920 910 clk_put(dd->iclk);
+217 -161
drivers/crypto/omap-sham.c
··· 72 72 73 73 #define DEFAULT_TIMEOUT_INTERVAL HZ 74 74 75 - #define FLAGS_FIRST 0x0001 76 75 #define FLAGS_FINUP 0x0002 77 76 #define FLAGS_FINAL 0x0004 78 - #define FLAGS_FAST 0x0008 77 + #define FLAGS_SG 0x0008 79 78 #define FLAGS_SHA1 0x0010 80 79 #define FLAGS_DMA_ACTIVE 0x0020 81 80 #define FLAGS_OUTPUT_READY 0x0040 ··· 82 83 #define FLAGS_INIT 0x0100 83 84 #define FLAGS_CPU 0x0200 84 85 #define FLAGS_HMAC 0x0400 85 - 86 - /* 3rd byte */ 87 - #define FLAGS_BUSY 16 86 + #define FLAGS_ERROR 0x0800 87 + #define FLAGS_BUSY 0x1000 88 88 89 89 #define OP_UPDATE 1 90 90 #define OP_FINAL 2 91 + 92 + #define OMAP_ALIGN_MASK (sizeof(u32)-1) 93 + #define OMAP_ALIGNED __attribute__((aligned(sizeof(u32)))) 94 + 95 + #define BUFLEN PAGE_SIZE 91 96 92 97 struct omap_sham_dev; 93 98 ··· 100 97 unsigned long flags; 101 98 unsigned long op; 102 99 100 + u8 digest[SHA1_DIGEST_SIZE] OMAP_ALIGNED; 103 101 size_t digcnt; 104 - u8 *buffer; 105 102 size_t bufcnt; 106 103 size_t buflen; 107 104 dma_addr_t dma_addr; ··· 110 107 struct scatterlist *sg; 111 108 unsigned int offset; /* offset in current sg */ 112 109 unsigned int total; /* total request */ 110 + 111 + u8 buffer[0] OMAP_ALIGNED; 113 112 }; 114 113 115 114 struct omap_sham_hmac_ctx { ··· 141 136 int irq; 142 137 struct clk *iclk; 143 138 spinlock_t lock; 139 + int err; 144 140 int dma; 145 141 int dma_lch; 146 142 struct tasklet_struct done_task; ··· 200 194 static void omap_sham_copy_hash(struct ahash_request *req, int out) 201 195 { 202 196 struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 197 + u32 *hash = (u32 *)ctx->digest; 198 + int i; 199 + 200 + /* MD5 is almost unused. So copy sha1 size to reduce code */ 201 + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) { 202 + if (out) 203 + hash[i] = omap_sham_read(ctx->dd, 204 + SHA_REG_DIGEST(i)); 205 + else 206 + omap_sham_write(ctx->dd, 207 + SHA_REG_DIGEST(i), hash[i]); 208 + } 209 + } 210 + 211 + static void omap_sham_copy_ready_hash(struct ahash_request *req) 212 + { 213 + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 214 + u32 *in = (u32 *)ctx->digest; 203 215 u32 *hash = (u32 *)req->result; 204 216 int i; 217 + 218 + if (!hash) 219 + return; 205 220 206 221 if (likely(ctx->flags & FLAGS_SHA1)) { 207 222 /* SHA1 results are in big endian */ 208 223 for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) 209 - if (out) 210 - hash[i] = be32_to_cpu(omap_sham_read(ctx->dd, 211 - SHA_REG_DIGEST(i))); 212 - else 213 - omap_sham_write(ctx->dd, SHA_REG_DIGEST(i), 214 - cpu_to_be32(hash[i])); 224 + hash[i] = be32_to_cpu(in[i]); 215 225 } else { 216 226 /* MD5 results are in little endian */ 217 227 for (i = 0; i < MD5_DIGEST_SIZE / sizeof(u32); i++) 218 - if (out) 219 - hash[i] = le32_to_cpu(omap_sham_read(ctx->dd, 220 - SHA_REG_DIGEST(i))); 221 - else 222 - omap_sham_write(ctx->dd, SHA_REG_DIGEST(i), 223 - cpu_to_le32(hash[i])); 228 + hash[i] = le32_to_cpu(in[i]); 224 229 } 225 230 } 226 231 227 - static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, 232 + static int omap_sham_hw_init(struct omap_sham_dev *dd) 233 + { 234 + clk_enable(dd->iclk); 235 + 236 + if (!(dd->flags & FLAGS_INIT)) { 237 + omap_sham_write_mask(dd, SHA_REG_MASK, 238 + SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET); 239 + 240 + if (omap_sham_wait(dd, SHA_REG_SYSSTATUS, 241 + SHA_REG_SYSSTATUS_RESETDONE)) 242 + return -ETIMEDOUT; 243 + 244 + dd->flags |= FLAGS_INIT; 245 + dd->err = 0; 246 + } 247 + 248 + return 0; 249 + } 250 + 251 + static void omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, 228 252 int final, int dma) 229 253 { 230 254 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 231 255 u32 val = length << 5, mask; 232 256 233 - if (unlikely(!ctx->digcnt)) { 234 - 235 - clk_enable(dd->iclk); 236 - 237 - if (!(dd->flags & FLAGS_INIT)) { 238 - omap_sham_write_mask(dd, SHA_REG_MASK, 239 - SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET); 240 - 241 - if (omap_sham_wait(dd, SHA_REG_SYSSTATUS, 242 - SHA_REG_SYSSTATUS_RESETDONE)) 243 - return -ETIMEDOUT; 244 - 245 - dd->flags |= FLAGS_INIT; 246 - } 247 - } else { 257 + if (likely(ctx->digcnt)) 248 258 omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt); 249 - } 250 259 251 260 omap_sham_write_mask(dd, SHA_REG_MASK, 252 261 SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0), ··· 281 260 SHA_REG_CTRL_ALGO | SHA_REG_CTRL_LENGTH; 282 261 283 262 omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask); 284 - 285 - return 0; 286 263 } 287 264 288 265 static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, 289 266 size_t length, int final) 290 267 { 291 268 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 292 - int err, count, len32; 269 + int count, len32; 293 270 const u32 *buffer = (const u32 *)buf; 294 271 295 272 dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", 296 273 ctx->digcnt, length, final); 297 274 298 - err = omap_sham_write_ctrl(dd, length, final, 0); 299 - if (err) 300 - return err; 275 + omap_sham_write_ctrl(dd, length, final, 0); 276 + 277 + /* should be non-zero before next lines to disable clocks later */ 278 + ctx->digcnt += length; 301 279 302 280 if (omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY)) 303 281 return -ETIMEDOUT; 304 - 305 - ctx->digcnt += length; 306 282 307 283 if (final) 308 284 ctx->flags |= FLAGS_FINAL; /* catch last interrupt */ ··· 316 298 size_t length, int final) 317 299 { 318 300 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 319 - int err, len32; 301 + int len32; 320 302 321 303 dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n", 322 304 ctx->digcnt, length, final); 323 - 324 - /* flush cache entries related to our page */ 325 - if (dma_addr == ctx->dma_addr) 326 - dma_sync_single_for_device(dd->dev, dma_addr, length, 327 - DMA_TO_DEVICE); 328 305 329 306 len32 = DIV_ROUND_UP(length, sizeof(u32)); 330 307 ··· 330 317 omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC, 331 318 dma_addr, 0, 0); 332 319 333 - err = omap_sham_write_ctrl(dd, length, final, 1); 334 - if (err) 335 - return err; 320 + omap_sham_write_ctrl(dd, length, final, 1); 336 321 337 322 ctx->digcnt += length; 338 323 ··· 382 371 return 0; 383 372 } 384 373 374 + static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd, 375 + struct omap_sham_reqctx *ctx, 376 + size_t length, int final) 377 + { 378 + ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen, 379 + DMA_TO_DEVICE); 380 + if (dma_mapping_error(dd->dev, ctx->dma_addr)) { 381 + dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen); 382 + return -EINVAL; 383 + } 384 + 385 + ctx->flags &= ~FLAGS_SG; 386 + 387 + /* next call does not fail... so no unmap in the case of error */ 388 + return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final); 389 + } 390 + 385 391 static int omap_sham_update_dma_slow(struct omap_sham_dev *dd) 386 392 { 387 393 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 388 394 unsigned int final; 389 395 size_t count; 390 - 391 - if (!ctx->total) 392 - return 0; 393 396 394 397 omap_sham_append_sg(ctx); 395 398 ··· 415 390 if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) { 416 391 count = ctx->bufcnt; 417 392 ctx->bufcnt = 0; 418 - return omap_sham_xmit_dma(dd, ctx->dma_addr, count, final); 393 + return omap_sham_xmit_dma_map(dd, ctx, count, final); 419 394 } 420 395 421 396 return 0; 422 397 } 423 398 424 - static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) 399 + /* Start address alignment */ 400 + #define SG_AA(sg) (IS_ALIGNED(sg->offset, sizeof(u32))) 401 + /* SHA1 block size alignment */ 402 + #define SG_SA(sg) (IS_ALIGNED(sg->length, SHA1_MD5_BLOCK_SIZE)) 403 + 404 + static int omap_sham_update_dma_start(struct omap_sham_dev *dd) 425 405 { 426 406 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 427 - unsigned int length; 407 + unsigned int length, final, tail; 408 + struct scatterlist *sg; 428 409 429 - ctx->flags |= FLAGS_FAST; 410 + if (!ctx->total) 411 + return 0; 430 412 431 - length = min(ctx->total, sg_dma_len(ctx->sg)); 432 - ctx->total = length; 413 + if (ctx->bufcnt || ctx->offset) 414 + return omap_sham_update_dma_slow(dd); 415 + 416 + dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n", 417 + ctx->digcnt, ctx->bufcnt, ctx->total); 418 + 419 + sg = ctx->sg; 420 + 421 + if (!SG_AA(sg)) 422 + return omap_sham_update_dma_slow(dd); 423 + 424 + if (!sg_is_last(sg) && !SG_SA(sg)) 425 + /* size is not SHA1_BLOCK_SIZE aligned */ 426 + return omap_sham_update_dma_slow(dd); 427 + 428 + length = min(ctx->total, sg->length); 429 + 430 + if (sg_is_last(sg)) { 431 + if (!(ctx->flags & FLAGS_FINUP)) { 432 + /* not last sg must be SHA1_MD5_BLOCK_SIZE aligned */ 433 + tail = length & (SHA1_MD5_BLOCK_SIZE - 1); 434 + /* without finup() we need one block to close hash */ 435 + if (!tail) 436 + tail = SHA1_MD5_BLOCK_SIZE; 437 + length -= tail; 438 + } 439 + } 433 440 434 441 if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) { 435 442 dev_err(dd->dev, "dma_map_sg error\n"); 436 443 return -EINVAL; 437 444 } 438 445 439 - ctx->total -= length; 446 + ctx->flags |= FLAGS_SG; 440 447 441 - return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); 448 + ctx->total -= length; 449 + ctx->offset = length; /* offset where to start slow */ 450 + 451 + final = (ctx->flags & FLAGS_FINUP) && !ctx->total; 452 + 453 + /* next call does not fail... so no unmap in the case of error */ 454 + return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final); 442 455 } 443 456 444 457 static int omap_sham_update_cpu(struct omap_sham_dev *dd) ··· 496 433 struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); 497 434 498 435 omap_stop_dma(dd->dma_lch); 499 - if (ctx->flags & FLAGS_FAST) 436 + if (ctx->flags & FLAGS_SG) { 500 437 dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); 438 + if (ctx->sg->length == ctx->offset) { 439 + ctx->sg = sg_next(ctx->sg); 440 + if (ctx->sg) 441 + ctx->offset = 0; 442 + } 443 + } else { 444 + dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, 445 + DMA_TO_DEVICE); 446 + } 501 447 502 448 return 0; 503 449 } ··· 526 454 spin_unlock_irqrestore(&dd->lock, flags); 527 455 528 456 if (ctx->digcnt) 529 - clk_disable(dd->iclk); 530 - 531 - if (ctx->dma_addr) 532 - dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, 533 - DMA_TO_DEVICE); 534 - 535 - if (ctx->buffer) 536 - free_page((unsigned long)ctx->buffer); 457 + omap_sham_copy_ready_hash(req); 537 458 538 459 dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); 539 460 } ··· 554 489 555 490 ctx->flags = 0; 556 491 557 - ctx->flags |= FLAGS_FIRST; 558 - 559 492 dev_dbg(dd->dev, "init: digest size: %d\n", 560 493 crypto_ahash_digestsize(tfm)); 561 494 ··· 562 499 563 500 ctx->bufcnt = 0; 564 501 ctx->digcnt = 0; 565 - 566 - ctx->buflen = PAGE_SIZE; 567 - ctx->buffer = (void *)__get_free_page( 568 - (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? 569 - GFP_KERNEL : GFP_ATOMIC); 570 - if (!ctx->buffer) 571 - return -ENOMEM; 572 - 573 - ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen, 574 - DMA_TO_DEVICE); 575 - if (dma_mapping_error(dd->dev, ctx->dma_addr)) { 576 - dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen); 577 - free_page((unsigned long)ctx->buffer); 578 - return -EINVAL; 579 - } 502 + ctx->buflen = BUFLEN; 580 503 581 504 if (tctx->flags & FLAGS_HMAC) { 582 505 struct omap_sham_hmac_ctx *bctx = tctx->base; ··· 587 538 588 539 if (ctx->flags & FLAGS_CPU) 589 540 err = omap_sham_update_cpu(dd); 590 - else if (ctx->flags & FLAGS_FAST) 591 - err = omap_sham_update_dma_fast(dd); 592 541 else 593 - err = omap_sham_update_dma_slow(dd); 542 + err = omap_sham_update_dma_start(dd); 594 543 595 544 /* wait for dma completion before can take more data */ 596 545 dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt); ··· 607 560 use_dma = 0; 608 561 609 562 if (use_dma) 610 - err = omap_sham_xmit_dma(dd, ctx->dma_addr, ctx->bufcnt, 1); 563 + err = omap_sham_xmit_dma_map(dd, ctx, ctx->bufcnt, 1); 611 564 else 612 565 err = omap_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1); 613 566 614 567 ctx->bufcnt = 0; 615 - 616 - if (err != -EINPROGRESS) 617 - omap_sham_cleanup(req); 618 568 619 569 dev_dbg(dd->dev, "final_req: err: %d\n", err); 620 570 ··· 620 576 621 577 static int omap_sham_finish_req_hmac(struct ahash_request *req) 622 578 { 579 + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 623 580 struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); 624 581 struct omap_sham_hmac_ctx *bctx = tctx->base; 625 582 int bs = crypto_shash_blocksize(bctx->shash); ··· 635 590 636 591 return crypto_shash_init(&desc.shash) ?: 637 592 crypto_shash_update(&desc.shash, bctx->opad, bs) ?: 638 - crypto_shash_finup(&desc.shash, req->result, ds, req->result); 593 + crypto_shash_finup(&desc.shash, ctx->digest, ds, ctx->digest); 639 594 } 640 595 641 596 static void omap_sham_finish_req(struct ahash_request *req, int err) 642 597 { 643 598 struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 599 + struct omap_sham_dev *dd = ctx->dd; 644 600 645 601 if (!err) { 646 602 omap_sham_copy_hash(ctx->dd->req, 1); 647 603 if (ctx->flags & FLAGS_HMAC) 648 604 err = omap_sham_finish_req_hmac(req); 605 + } else { 606 + ctx->flags |= FLAGS_ERROR; 649 607 } 650 608 651 - if (ctx->flags & FLAGS_FINAL) 609 + if ((ctx->flags & FLAGS_FINAL) || err) 652 610 omap_sham_cleanup(req); 653 611 654 - clear_bit(FLAGS_BUSY, &ctx->dd->flags); 612 + clk_disable(dd->iclk); 613 + dd->flags &= ~FLAGS_BUSY; 655 614 656 615 if (req->base.complete) 657 616 req->base.complete(&req->base, err); 658 617 } 659 618 660 - static int omap_sham_handle_queue(struct omap_sham_dev *dd) 619 + static int omap_sham_handle_queue(struct omap_sham_dev *dd, 620 + struct ahash_request *req) 661 621 { 662 622 struct crypto_async_request *async_req, *backlog; 663 623 struct omap_sham_reqctx *ctx; 664 - struct ahash_request *req, *prev_req; 624 + struct ahash_request *prev_req; 665 625 unsigned long flags; 666 - int err = 0; 667 - 668 - if (test_and_set_bit(FLAGS_BUSY, &dd->flags)) 669 - return 0; 626 + int err = 0, ret = 0; 670 627 671 628 spin_lock_irqsave(&dd->lock, flags); 629 + if (req) 630 + ret = ahash_enqueue_request(&dd->queue, req); 631 + if (dd->flags & FLAGS_BUSY) { 632 + spin_unlock_irqrestore(&dd->lock, flags); 633 + return ret; 634 + } 672 635 backlog = crypto_get_backlog(&dd->queue); 673 636 async_req = crypto_dequeue_request(&dd->queue); 674 - if (!async_req) 675 - clear_bit(FLAGS_BUSY, &dd->flags); 637 + if (async_req) 638 + dd->flags |= FLAGS_BUSY; 676 639 spin_unlock_irqrestore(&dd->lock, flags); 677 640 678 641 if (!async_req) 679 - return 0; 642 + return ret; 680 643 681 644 if (backlog) 682 645 backlog->complete(backlog, -EINPROGRESS); ··· 699 646 dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n", 700 647 ctx->op, req->nbytes); 701 648 702 - if (req != prev_req && ctx->digcnt) 649 + 650 + err = omap_sham_hw_init(dd); 651 + if (err) 652 + goto err1; 653 + 654 + omap_set_dma_dest_params(dd->dma_lch, 0, 655 + OMAP_DMA_AMODE_CONSTANT, 656 + dd->phys_base + SHA_REG_DIN(0), 0, 16); 657 + 658 + omap_set_dma_dest_burst_mode(dd->dma_lch, 659 + OMAP_DMA_DATA_BURST_16); 660 + 661 + omap_set_dma_src_burst_mode(dd->dma_lch, 662 + OMAP_DMA_DATA_BURST_4); 663 + 664 + if (ctx->digcnt) 703 665 /* request has changed - restore hash */ 704 666 omap_sham_copy_hash(req, 0); 705 667 ··· 726 658 } else if (ctx->op == OP_FINAL) { 727 659 err = omap_sham_final_req(dd); 728 660 } 729 - 661 + err1: 730 662 if (err != -EINPROGRESS) { 731 663 /* done_task will not finish it, so do it here */ 732 664 omap_sham_finish_req(req, err); ··· 735 667 736 668 dev_dbg(dd->dev, "exit, err: %d\n", err); 737 669 738 - return err; 670 + return ret; 739 671 } 740 672 741 673 static int omap_sham_enqueue(struct ahash_request *req, unsigned int op) ··· 743 675 struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 744 676 struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); 745 677 struct omap_sham_dev *dd = tctx->dd; 746 - unsigned long flags; 747 - int err; 748 678 749 679 ctx->op = op; 750 680 751 - spin_lock_irqsave(&dd->lock, flags); 752 - err = ahash_enqueue_request(&dd->queue, req); 753 - spin_unlock_irqrestore(&dd->lock, flags); 754 - 755 - omap_sham_handle_queue(dd); 756 - 757 - return err; 681 + return omap_sham_handle_queue(dd, req); 758 682 } 759 683 760 684 static int omap_sham_update(struct ahash_request *req) ··· 769 709 */ 770 710 omap_sham_append_sg(ctx); 771 711 return 0; 772 - } else if (ctx->bufcnt + ctx->total <= 64) { 712 + } else if (ctx->bufcnt + ctx->total <= SHA1_MD5_BLOCK_SIZE) { 713 + /* 714 + * faster to use CPU for short transfers 715 + */ 773 716 ctx->flags |= FLAGS_CPU; 774 - } else if (!ctx->bufcnt && sg_is_last(ctx->sg)) { 775 - /* may be can use faster functions */ 776 - int aligned = IS_ALIGNED((u32)ctx->sg->offset, 777 - sizeof(u32)); 778 - 779 - if (aligned && (ctx->flags & FLAGS_FIRST)) 780 - /* digest: first and final */ 781 - ctx->flags |= FLAGS_FAST; 782 - 783 - ctx->flags &= ~FLAGS_FIRST; 784 717 } 785 - } else if (ctx->bufcnt + ctx->total <= ctx->buflen) { 786 - /* if not finaup -> not fast */ 718 + } else if (ctx->bufcnt + ctx->total < ctx->buflen) { 787 719 omap_sham_append_sg(ctx); 788 720 return 0; 789 721 } ··· 813 761 814 762 ctx->flags |= FLAGS_FINUP; 815 763 816 - /* OMAP HW accel works only with buffers >= 9 */ 817 - /* HMAC is always >= 9 because of ipad */ 818 - if ((ctx->digcnt + ctx->bufcnt) < 9) 819 - err = omap_sham_final_shash(req); 820 - else if (ctx->bufcnt) 821 - return omap_sham_enqueue(req, OP_FINAL); 764 + if (!(ctx->flags & FLAGS_ERROR)) { 765 + /* OMAP HW accel works only with buffers >= 9 */ 766 + /* HMAC is always >= 9 because of ipad */ 767 + if ((ctx->digcnt + ctx->bufcnt) < 9) 768 + err = omap_sham_final_shash(req); 769 + else if (ctx->bufcnt) 770 + return omap_sham_enqueue(req, OP_FINAL); 771 + } 822 772 823 773 omap_sham_cleanup(req); 824 774 ··· 890 836 struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm); 891 837 const char *alg_name = crypto_tfm_alg_name(tfm); 892 838 839 + pr_info("enter\n"); 840 + 893 841 /* Allocate a fallback and abort if it failed. */ 894 842 tctx->fallback = crypto_alloc_shash(alg_name, 0, 895 843 CRYPTO_ALG_NEED_FALLBACK); ··· 902 846 } 903 847 904 848 crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), 905 - sizeof(struct omap_sham_reqctx)); 849 + sizeof(struct omap_sham_reqctx) + BUFLEN); 906 850 907 851 if (alg_base) { 908 852 struct omap_sham_hmac_ctx *bctx = tctx->base; ··· 988 932 CRYPTO_ALG_NEED_FALLBACK, 989 933 .cra_blocksize = SHA1_BLOCK_SIZE, 990 934 .cra_ctxsize = sizeof(struct omap_sham_ctx), 991 - .cra_alignmask = 0, 935 + .cra_alignmask = OMAP_ALIGN_MASK, 992 936 .cra_module = THIS_MODULE, 993 937 .cra_init = omap_sham_cra_init, 994 938 .cra_exit = omap_sham_cra_exit, ··· 1012 956 .cra_blocksize = SHA1_BLOCK_SIZE, 1013 957 .cra_ctxsize = sizeof(struct omap_sham_ctx) + 1014 958 sizeof(struct omap_sham_hmac_ctx), 1015 - .cra_alignmask = 0, 959 + .cra_alignmask = OMAP_ALIGN_MASK, 1016 960 .cra_module = THIS_MODULE, 1017 961 .cra_init = omap_sham_cra_sha1_init, 1018 962 .cra_exit = omap_sham_cra_exit, ··· 1036 980 .cra_blocksize = SHA1_BLOCK_SIZE, 1037 981 .cra_ctxsize = sizeof(struct omap_sham_ctx) + 1038 982 sizeof(struct omap_sham_hmac_ctx), 1039 - .cra_alignmask = 0, 983 + .cra_alignmask = OMAP_ALIGN_MASK, 1040 984 .cra_module = THIS_MODULE, 1041 985 .cra_init = omap_sham_cra_md5_init, 1042 986 .cra_exit = omap_sham_cra_exit, ··· 1049 993 struct omap_sham_dev *dd = (struct omap_sham_dev *)data; 1050 994 struct ahash_request *req = dd->req; 1051 995 struct omap_sham_reqctx *ctx = ahash_request_ctx(req); 1052 - int ready = 1; 996 + int ready = 0, err = 0; 1053 997 1054 998 if (ctx->flags & FLAGS_OUTPUT_READY) { 1055 999 ctx->flags &= ~FLAGS_OUTPUT_READY; ··· 1059 1003 if (dd->flags & FLAGS_DMA_ACTIVE) { 1060 1004 dd->flags &= ~FLAGS_DMA_ACTIVE; 1061 1005 omap_sham_update_dma_stop(dd); 1062 - omap_sham_update_dma_slow(dd); 1006 + if (!dd->err) 1007 + err = omap_sham_update_dma_start(dd); 1063 1008 } 1064 1009 1065 - if (ready && !(dd->flags & FLAGS_DMA_ACTIVE)) { 1066 - dev_dbg(dd->dev, "update done\n"); 1010 + err = dd->err ? : err; 1011 + 1012 + if (err != -EINPROGRESS && (ready || err)) { 1013 + dev_dbg(dd->dev, "update done: err: %d\n", err); 1067 1014 /* finish curent request */ 1068 - omap_sham_finish_req(req, 0); 1015 + omap_sham_finish_req(req, err); 1069 1016 /* start new request */ 1070 - omap_sham_handle_queue(dd); 1017 + omap_sham_handle_queue(dd, NULL); 1071 1018 } 1072 1019 } 1073 1020 ··· 1078 1019 { 1079 1020 struct omap_sham_dev *dd = (struct omap_sham_dev *)data; 1080 1021 1081 - omap_sham_handle_queue(dd); 1022 + omap_sham_handle_queue(dd, NULL); 1082 1023 } 1083 1024 1084 1025 static irqreturn_t omap_sham_irq(int irq, void *dev_id) ··· 1100 1041 omap_sham_read(dd, SHA_REG_CTRL); 1101 1042 1102 1043 ctx->flags |= FLAGS_OUTPUT_READY; 1044 + dd->err = 0; 1103 1045 tasklet_schedule(&dd->done_task); 1104 1046 1105 1047 return IRQ_HANDLED; ··· 1110 1050 { 1111 1051 struct omap_sham_dev *dd = data; 1112 1052 1113 - if (likely(lch == dd->dma_lch)) 1114 - tasklet_schedule(&dd->done_task); 1053 + if (ch_status != OMAP_DMA_BLOCK_IRQ) { 1054 + pr_err("omap-sham DMA error status: 0x%hx\n", ch_status); 1055 + dd->err = -EIO; 1056 + dd->flags &= ~FLAGS_INIT; /* request to re-initialize */ 1057 + } 1058 + 1059 + tasklet_schedule(&dd->done_task); 1115 1060 } 1116 1061 1117 1062 static int omap_sham_dma_init(struct omap_sham_dev *dd) ··· 1131 1066 dev_err(dd->dev, "Unable to request DMA channel\n"); 1132 1067 return err; 1133 1068 } 1134 - omap_set_dma_dest_params(dd->dma_lch, 0, 1135 - OMAP_DMA_AMODE_CONSTANT, 1136 - dd->phys_base + SHA_REG_DIN(0), 0, 16); 1137 - 1138 - omap_set_dma_dest_burst_mode(dd->dma_lch, 1139 - OMAP_DMA_DATA_BURST_16); 1140 - 1141 - omap_set_dma_src_burst_mode(dd->dma_lch, 1142 - OMAP_DMA_DATA_BURST_4); 1143 1069 1144 1070 return 0; 1145 1071 }
+1 -1
drivers/crypto/padlock-aes.c
··· 9 9 10 10 #include <crypto/algapi.h> 11 11 #include <crypto/aes.h> 12 + #include <crypto/padlock.h> 12 13 #include <linux/module.h> 13 14 #include <linux/init.h> 14 15 #include <linux/types.h> ··· 22 21 #include <asm/byteorder.h> 23 22 #include <asm/processor.h> 24 23 #include <asm/i387.h> 25 - #include "padlock.h" 26 24 27 25 /* 28 26 * Number of data blocks actually fetched for each xcrypt insn.
+1 -7
drivers/crypto/padlock-sha.c
··· 13 13 */ 14 14 15 15 #include <crypto/internal/hash.h> 16 + #include <crypto/padlock.h> 16 17 #include <crypto/sha.h> 17 18 #include <linux/err.h> 18 19 #include <linux/module.h> ··· 23 22 #include <linux/kernel.h> 24 23 #include <linux/scatterlist.h> 25 24 #include <asm/i387.h> 26 - #include "padlock.h" 27 - 28 - #ifdef CONFIG_64BIT 29 - #define STACK_ALIGN 16 30 - #else 31 - #define STACK_ALIGN 4 32 - #endif 33 25 34 26 struct padlock_sha_desc { 35 27 struct shash_desc fallback;
+7 -1
drivers/crypto/padlock.h include/crypto/padlock.h
··· 15 15 16 16 #define PADLOCK_ALIGNMENT 16 17 17 18 - #define PFX "padlock: " 18 + #define PFX KBUILD_MODNAME ": " 19 19 20 20 #define PADLOCK_CRA_PRIORITY 300 21 21 #define PADLOCK_COMPOSITE_PRIORITY 400 22 + 23 + #ifdef CONFIG_64BIT 24 + #define STACK_ALIGN 16 25 + #else 26 + #define STACK_ALIGN 4 27 + #endif 22 28 23 29 #endif /* _CRYPTO_PADLOCK_H */
+92
include/crypto/if_alg.h
··· 1 + /* 2 + * if_alg: User-space algorithm interface 3 + * 4 + * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the Free 8 + * Software Foundation; either version 2 of the License, or (at your option) 9 + * any later version. 10 + * 11 + */ 12 + 13 + #ifndef _CRYPTO_IF_ALG_H 14 + #define _CRYPTO_IF_ALG_H 15 + 16 + #include <linux/compiler.h> 17 + #include <linux/completion.h> 18 + #include <linux/if_alg.h> 19 + #include <linux/types.h> 20 + #include <net/sock.h> 21 + 22 + #define ALG_MAX_PAGES 16 23 + 24 + struct crypto_async_request; 25 + 26 + struct alg_sock { 27 + /* struct sock must be the first member of struct alg_sock */ 28 + struct sock sk; 29 + 30 + struct sock *parent; 31 + 32 + const struct af_alg_type *type; 33 + void *private; 34 + }; 35 + 36 + struct af_alg_completion { 37 + struct completion completion; 38 + int err; 39 + }; 40 + 41 + struct af_alg_control { 42 + struct af_alg_iv *iv; 43 + int op; 44 + }; 45 + 46 + struct af_alg_type { 47 + void *(*bind)(const char *name, u32 type, u32 mask); 48 + void (*release)(void *private); 49 + int (*setkey)(void *private, const u8 *key, unsigned int keylen); 50 + int (*accept)(void *private, struct sock *sk); 51 + 52 + struct proto_ops *ops; 53 + struct module *owner; 54 + char name[14]; 55 + }; 56 + 57 + struct af_alg_sgl { 58 + struct scatterlist sg[ALG_MAX_PAGES]; 59 + struct page *pages[ALG_MAX_PAGES]; 60 + }; 61 + 62 + int af_alg_register_type(const struct af_alg_type *type); 63 + int af_alg_unregister_type(const struct af_alg_type *type); 64 + 65 + int af_alg_release(struct socket *sock); 66 + int af_alg_accept(struct sock *sk, struct socket *newsock); 67 + 68 + int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, 69 + int write); 70 + void af_alg_free_sg(struct af_alg_sgl *sgl); 71 + 72 + int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con); 73 + 74 + int af_alg_wait_for_completion(int err, struct af_alg_completion *completion); 75 + void af_alg_complete(struct crypto_async_request *req, int err); 76 + 77 + static inline struct alg_sock *alg_sk(struct sock *sk) 78 + { 79 + return (struct alg_sock *)sk; 80 + } 81 + 82 + static inline void af_alg_release_parent(struct sock *sk) 83 + { 84 + sock_put(alg_sk(sk)->parent); 85 + } 86 + 87 + static inline void af_alg_init_completion(struct af_alg_completion *completion) 88 + { 89 + init_completion(&completion->completion); 90 + } 91 + 92 + #endif /* _CRYPTO_IF_ALG_H */
+15
include/crypto/scatterwalk.h
··· 68 68 return (++sg)->length ? sg : (void *)sg_page(sg); 69 69 } 70 70 71 + static inline void scatterwalk_crypto_chain(struct scatterlist *head, 72 + struct scatterlist *sg, 73 + int chain, int num) 74 + { 75 + if (chain) { 76 + head->length += sg->length; 77 + sg = scatterwalk_sg_next(sg); 78 + } 79 + 80 + if (sg) 81 + scatterwalk_sg_chain(head, num, sg); 82 + else 83 + sg_mark_end(head); 84 + } 85 + 71 86 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in, 72 87 struct scatter_walk *walk_out) 73 88 {
+1
include/linux/Kbuild
··· 158 158 header-y += if.h 159 159 header-y += if_addr.h 160 160 header-y += if_addrlabel.h 161 + header-y += if_alg.h 161 162 header-y += if_arcnet.h 162 163 header-y += if_arp.h 163 164 header-y += if_bonding.h
+40
include/linux/if_alg.h
··· 1 + /* 2 + * if_alg: User-space algorithm interface 3 + * 4 + * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the Free 8 + * Software Foundation; either version 2 of the License, or (at your option) 9 + * any later version. 10 + * 11 + */ 12 + 13 + #ifndef _LINUX_IF_ALG_H 14 + #define _LINUX_IF_ALG_H 15 + 16 + #include <linux/types.h> 17 + 18 + struct sockaddr_alg { 19 + __u16 salg_family; 20 + __u8 salg_type[14]; 21 + __u32 salg_feat; 22 + __u32 salg_mask; 23 + __u8 salg_name[64]; 24 + }; 25 + 26 + struct af_alg_iv { 27 + __u32 ivlen; 28 + __u8 iv[0]; 29 + }; 30 + 31 + /* Socket options */ 32 + #define ALG_SET_KEY 1 33 + #define ALG_SET_IV 2 34 + #define ALG_SET_OP 3 35 + 36 + /* Operations */ 37 + #define ALG_OP_DECRYPT 0 38 + #define ALG_OP_ENCRYPT 1 39 + 40 + #endif /* _LINUX_IF_ALG_H */
+4 -1
include/linux/socket.h
··· 191 191 #define AF_PHONET 35 /* Phonet sockets */ 192 192 #define AF_IEEE802154 36 /* IEEE802154 sockets */ 193 193 #define AF_CAIF 37 /* CAIF sockets */ 194 - #define AF_MAX 38 /* For now.. */ 194 + #define AF_ALG 38 /* Algorithm sockets */ 195 + #define AF_MAX 39 /* For now.. */ 195 196 196 197 /* Protocol families, same as address families. */ 197 198 #define PF_UNSPEC AF_UNSPEC ··· 233 232 #define PF_PHONET AF_PHONET 234 233 #define PF_IEEE802154 AF_IEEE802154 235 234 #define PF_CAIF AF_CAIF 235 + #define PF_ALG AF_ALG 236 236 #define PF_MAX AF_MAX 237 237 238 238 /* Maximum queue length specifiable by listen. */ ··· 307 305 #define SOL_RDS 276 308 306 #define SOL_IUCV 277 309 307 #define SOL_CAIF 278 308 + #define SOL_ALG 279 310 309 311 310 /* IPX options */ 312 311 #define IPX_TYPE 1
+3 -3
net/core/sock.c
··· 157 157 "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , 158 158 "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , 159 159 "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , 160 - "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , 160 + "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , 161 161 "sk_lock-AF_MAX" 162 162 }; 163 163 static const char *const af_family_slock_key_strings[AF_MAX+1] = { ··· 173 173 "slock-27" , "slock-28" , "slock-AF_CAN" , 174 174 "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , 175 175 "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , 176 - "slock-AF_IEEE802154", "slock-AF_CAIF" , 176 + "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , 177 177 "slock-AF_MAX" 178 178 }; 179 179 static const char *const af_family_clock_key_strings[AF_MAX+1] = { ··· 189 189 "clock-27" , "clock-28" , "clock-AF_CAN" , 190 190 "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , 191 191 "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , 192 - "clock-AF_IEEE802154", "clock-AF_CAIF" , 192 + "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , 193 193 "clock-AF_MAX" 194 194 }; 195 195