aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Krause <minipli@googlemail.com>2014-12-30 16:50:54 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2015-01-05 05:35:02 -0500
commit0b1e95b2fa0934c3a08db483979c70d3b287f50e (patch)
tree3494012be5e6e4911c9069e1dcaccdf2203ab2f9
parent7e77bdebff5cb1e9876c561f69710b9ab8fa1f7e (diff)
crypto: aesni - fix "by8" variant for 128 bit keys
The "by8" counter mode optimization is broken for 128 bit keys with input data longer than 128 bytes. It uses the wrong key material for en- and decryption. The key registers xkey0, xkey4, xkey8 and xkey12 need to be preserved in case we're handling more than 128 bytes of input data -- they won't get reloaded after the initial load. They must therefore be (a) loaded on the first iteration and (b) be preserved for the latter ones. The implementation for 128 bit keys does not comply with (a) nor (b). Fix this by bringing the implementation back to its original source and correctly load the key registers and preserve their values by *not* re-using the registers for other purposes. Kudos to James for reporting the issue and providing a test case showing the discrepancies. Reported-by: James Yonan <james@openvpn.net> Cc: Chandramouli Narayanan <mouli@linux.intel.com> Cc: <stable@vger.kernel.org> # v3.18 Signed-off-by: Mathias Krause <minipli@googlemail.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r--arch/x86/crypto/aes_ctrby8_avx-x86_64.S46
1 files changed, 35 insertions, 11 deletions
diff --git a/arch/x86/crypto/aes_ctrby8_avx-x86_64.S b/arch/x86/crypto/aes_ctrby8_avx-x86_64.S
index 2df2a0298f5a..a916c4a61165 100644
--- a/arch/x86/crypto/aes_ctrby8_avx-x86_64.S
+++ b/arch/x86/crypto/aes_ctrby8_avx-x86_64.S
@@ -208,7 +208,7 @@ ddq_add_8:
208 208
209 .if (klen == KEY_128) 209 .if (klen == KEY_128)
210 .if (load_keys) 210 .if (load_keys)
211 vmovdqa 3*16(p_keys), xkeyA 211 vmovdqa 3*16(p_keys), xkey4
212 .endif 212 .endif
213 .else 213 .else
214 vmovdqa 3*16(p_keys), xkeyA 214 vmovdqa 3*16(p_keys), xkeyA
@@ -224,7 +224,7 @@ ddq_add_8:
224 add $(16*by), p_in 224 add $(16*by), p_in
225 225
226 .if (klen == KEY_128) 226 .if (klen == KEY_128)
227 vmovdqa 4*16(p_keys), xkey4 227 vmovdqa 4*16(p_keys), xkeyB
228 .else 228 .else
229 .if (load_keys) 229 .if (load_keys)
230 vmovdqa 4*16(p_keys), xkey4 230 vmovdqa 4*16(p_keys), xkey4
@@ -234,7 +234,12 @@ ddq_add_8:
234 .set i, 0 234 .set i, 0
235 .rept by 235 .rept by
236 club XDATA, i 236 club XDATA, i
237 vaesenc xkeyA, var_xdata, var_xdata /* key 3 */ 237 /* key 3 */
238 .if (klen == KEY_128)
239 vaesenc xkey4, var_xdata, var_xdata
240 .else
241 vaesenc xkeyA, var_xdata, var_xdata
242 .endif
238 .set i, (i +1) 243 .set i, (i +1)
239 .endr 244 .endr
240 245
@@ -243,13 +248,18 @@ ddq_add_8:
243 .set i, 0 248 .set i, 0
244 .rept by 249 .rept by
245 club XDATA, i 250 club XDATA, i
246 vaesenc xkey4, var_xdata, var_xdata /* key 4 */ 251 /* key 4 */
252 .if (klen == KEY_128)
253 vaesenc xkeyB, var_xdata, var_xdata
254 .else
255 vaesenc xkey4, var_xdata, var_xdata
256 .endif
247 .set i, (i +1) 257 .set i, (i +1)
248 .endr 258 .endr
249 259
250 .if (klen == KEY_128) 260 .if (klen == KEY_128)
251 .if (load_keys) 261 .if (load_keys)
252 vmovdqa 6*16(p_keys), xkeyB 262 vmovdqa 6*16(p_keys), xkey8
253 .endif 263 .endif
254 .else 264 .else
255 vmovdqa 6*16(p_keys), xkeyB 265 vmovdqa 6*16(p_keys), xkeyB
@@ -267,12 +277,17 @@ ddq_add_8:
267 .set i, 0 277 .set i, 0
268 .rept by 278 .rept by
269 club XDATA, i 279 club XDATA, i
270 vaesenc xkeyB, var_xdata, var_xdata /* key 6 */ 280 /* key 6 */
281 .if (klen == KEY_128)
282 vaesenc xkey8, var_xdata, var_xdata
283 .else
284 vaesenc xkeyB, var_xdata, var_xdata
285 .endif
271 .set i, (i +1) 286 .set i, (i +1)
272 .endr 287 .endr
273 288
274 .if (klen == KEY_128) 289 .if (klen == KEY_128)
275 vmovdqa 8*16(p_keys), xkey8 290 vmovdqa 8*16(p_keys), xkeyB
276 .else 291 .else
277 .if (load_keys) 292 .if (load_keys)
278 vmovdqa 8*16(p_keys), xkey8 293 vmovdqa 8*16(p_keys), xkey8
@@ -288,7 +303,7 @@ ddq_add_8:
288 303
289 .if (klen == KEY_128) 304 .if (klen == KEY_128)
290 .if (load_keys) 305 .if (load_keys)
291 vmovdqa 9*16(p_keys), xkeyA 306 vmovdqa 9*16(p_keys), xkey12
292 .endif 307 .endif
293 .else 308 .else
294 vmovdqa 9*16(p_keys), xkeyA 309 vmovdqa 9*16(p_keys), xkeyA
@@ -297,7 +312,12 @@ ddq_add_8:
297 .set i, 0 312 .set i, 0
298 .rept by 313 .rept by
299 club XDATA, i 314 club XDATA, i
300 vaesenc xkey8, var_xdata, var_xdata /* key 8 */ 315 /* key 8 */
316 .if (klen == KEY_128)
317 vaesenc xkeyB, var_xdata, var_xdata
318 .else
319 vaesenc xkey8, var_xdata, var_xdata
320 .endif
301 .set i, (i +1) 321 .set i, (i +1)
302 .endr 322 .endr
303 323
@@ -306,7 +326,12 @@ ddq_add_8:
306 .set i, 0 326 .set i, 0
307 .rept by 327 .rept by
308 club XDATA, i 328 club XDATA, i
309 vaesenc xkeyA, var_xdata, var_xdata /* key 9 */ 329 /* key 9 */
330 .if (klen == KEY_128)
331 vaesenc xkey12, var_xdata, var_xdata
332 .else
333 vaesenc xkeyA, var_xdata, var_xdata
334 .endif
310 .set i, (i +1) 335 .set i, (i +1)
311 .endr 336 .endr
312 337
@@ -412,7 +437,6 @@ ddq_add_8:
412/* main body of aes ctr load */ 437/* main body of aes ctr load */
413 438
414.macro do_aes_ctrmain key_len 439.macro do_aes_ctrmain key_len
415
416 cmp $16, num_bytes 440 cmp $16, num_bytes
417 jb .Ldo_return2\key_len 441 jb .Ldo_return2\key_len
418 442