Hi,
Using the VIA Advanced Encryption Engine (ACE, Padlock) with OpenSSL
seems to work fine, except for small blocks of data, as may be
illustrated by the following OpenVPN execution.
[root@home17 var] openvpn --test-crypto --secret key
--cipher AES-128-CBC --engine padlock
Wed Apr 6 10:40:26 2005 OpenVPN 2.0_rc16 i386-redhat-linux [SSL] [LZO]
[EPOLL]built on Feb 27 2005
Wed Apr 6 10:40:26 2005 OpenVPN 2.0_rc16 i386-redhat-linux [SSL] [LZO]
[EPOLL]built on Feb 27 2005
Wed Apr 6 10:40:26 2005 Initializing OpenSSL support for engine
'padlock'
Wed Apr 6 10:40:26 2005 Entering OpenVPN crypto self-test mode.
Wed Apr 6 10:40:26 2005 TESTING ENCRYPT/DECRYPT of packet length=1
Wed Apr 6 10:40:26 2005 TESTING ENCRYPT/DECRYPT of packet length=2
Wed Apr 6 10:40:26 2005 Authenticate/Decrypt packet error: cipher
final failed
Wed Apr 6 10:40:26 2005 SELF TEST FAILED, src.len=2 buf.len=0
Wed Apr 6 10:40:26 2005 Exiting
[root@home17 var]
This is just a test run, but without the padlock engine no error shows
up. Actually using OpenVPN with padlock works very well, except for
small packets caused by the "ping" option.
Slowing down the ebove test process by intruducing printf's of usleep's
in the test loop solves the problem. Given this fact I changed the
OpenSSL padlock code instead of the OpenVPN code to reproduce this
solution, and guess what: IT WORKS! Look at the following diff:
--- crypto/engine/hw_padlock.c.orig 2005-04-06
09:16:20.000000000 +0200
+++ crypto/engine/hw_padlock.c 2005-04-06 10:40:36.408585556
+0200
@@ -8,6 +8,8 @@
* valuable work on this engine!
*/
+#define DUMMY() { time_t t; time (&t); }
+
/*
====================================================================
* Copyright (c) 1999-2001 The OpenSSL Project. All rights
reserved.
*
@@ -857,6 +859,7 @@
memset(cdata->iv, 0, AES_BLOCK_SIZE);
+DUMMY ();
return 1;
}
@@ -1026,6 +1029,7 @@
memset(cdata->iv, 0, AES_BLOCK_SIZE);
+DUMMY ();
return 1;
}
This patch adds a dummy system call just before completion of the padlock_aes_cipher_omnivorous
and padlock_aes_cipher functions. So actually no considerable
slowdown is needed, this system call also solves the problem. At this
point I think I have a solution (but I'm not sure yet), so I think
expertise from others is needed. Not being a Padlock expert myself, I
think the following may be an explanation for what's happening:
- The VIA technical info mentions ACE pipelines If I'm correct.
- Pipelines need to be flushed, but that may not be always the case.
- Encryptions and Decryptions of large amounts of data may be
interrupted by context switches, harware interrupts etc. Possibly
interrupt handling forces this pipeline flush. (I run kernel 2.6 which
has HZ=1000).
- Doing a system call is a sort of software interrupt which may
also force a pipeline flush.
But... a small delay may also do the trick - I'm just guessing.
So how to proceed?
- Can anybody with sufficient technical knowledge verify the
described problem and potential solution?
(VIA ace support will be sent this message as well)
- Can we empirically verify the described problem en potential
solution?
- Are there other ways (than interrupts) to flush the pipeline - if
that actually is the problem?
Well, I hope this helps solving my (and maybe other people's) padlock
problem.
Cheers!
Rolf Fokkens
|