Re: alg: cipher: Test 1 failed on encryption for aes-asm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2008-12-20 at 11:21 +0800, Herbert Xu wrote:
> Weird.  I've got exactly the same versions as you, using yesterday's
> Linus git tree, and it works just fine on a Core 2 Quad Q6600.  From
> /proc/crypto after boot:
> 
> name         : aes
> driver       : aes-asm
> module       : aes_x86_64
> priority     : 200
> refcnt       : 1
> selftest     : passed
> type         : cipher
> blocksize    : 16
> min keysize  : 16
> max keysize  : 32
> 
> name         : aes
> driver       : aes-generic
> module       : aes_generic
> priority     : 100
> refcnt       : 1
> selftest     : passed
> type         : cipher
> blocksize    : 16
> min keysize  : 16
> max keysize  : 32
> 
> Are you in 64-bit mode or legacy mode? I'm in 64.

I get the same error on 64-bit mode. If aes_x86_64 is compiled as
module, everything is OK. But if it is compiled as built-in, the error
message print during system boot. Because aes_x86_64 may be registered
before aes_generic, but the tables used by AES have not been generated
when aes_x86_64 is registered.

This can be resolved by the following patch.
------------------------------------------------------------------->
Fix a bug of aes_x86_64, aes_generic initialization order issue.

If aes_x86_64 and aes_generic are compiled as builtin, the
initialization order is undetermined. That is, aes_x86_64 may be
initilized before aes_generic is initilized, but aes_x86_64 depends on
tables generated in aes_generic initialization code. aes_x86_64 can
not work before aes_generic is initialized, so that cause register
time testing failed with following error message:

[    0.657034] alg: cipher: Test 1 failed on encryption for aes-asm
[    0.657111] 00000000: 00 01 02 03 04 05 06 07 08 08 08 08 08 08 08 08 

This patch fixes this bug via making crypto_aes_gen_tabs public and
invoking it in aes_x86_64 and aes_generic.

Signed-off-by: Huang Ying <ying.huang@xxxxxxxxx>

---
 arch/x86/crypto/aes_glue.c |    1 +
 crypto/aes_generic.c       |   20 +++++++++++++++++++-
 include/crypto/aes.h       |    1 +
 3 files changed, 21 insertions(+), 1 deletion(-)

--- a/crypto/aes_generic.c
+++ b/crypto/aes_generic.c
@@ -157,6 +157,24 @@ static void __init gen_tabs(void)
 	}
 }
 
+/*
+ * gen_tabs() will only be called from init sectoin. Named to *_ops to
+ * avoid unnecessary section mismatch warning.
+ */
+static void (*gen_tabs_ops)(void) = gen_tabs;
+
+/**
+ * crypto_aes_gen_tabs - Generate tables for AES algorithm
+ */
+void crypto_aes_gen_tabs(void)
+{
+	if (gen_tabs_ops) {
+		gen_tabs_ops();
+		gen_tabs_ops = NULL;
+	}
+}
+EXPORT_SYMBOL_GPL(crypto_aes_gen_tabs);
+
 /* initialise the key schedule from the user supplied key */
 
 #define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b)
@@ -491,7 +509,7 @@ static struct crypto_alg aes_alg = {
 
 static int __init aes_init(void)
 {
-	gen_tabs();
+	crypto_aes_gen_tabs();
 	return crypto_register_alg(&aes_alg);
 }
 
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -28,6 +28,7 @@ extern u32 crypto_fl_tab[4][256];
 extern u32 crypto_it_tab[4][256];
 extern u32 crypto_il_tab[4][256];
 
+void crypto_aes_gen_tabs(void);
 int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
 		unsigned int key_len);
 int crypto_aes_expand_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
--- a/arch/x86/crypto/aes_glue.c
+++ b/arch/x86/crypto/aes_glue.c
@@ -40,6 +40,7 @@ static struct crypto_alg aes_alg = {
 
 static int __init aes_init(void)
 {
+	crypto_aes_gen_tabs();
 	return crypto_register_alg(&aes_alg);
 }
 

Attachment: signature.asc
Description: This is a digitally signed message part


[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux