aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorPhil Carmody <ext-phil.2.carmody@nokia.com>2009-07-24 13:59:17 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2009-07-24 13:59:17 +0800
commit7b4ffcf953f091a815df081911c5e75c8a38418d (patch)
tree9592ddafb6399806b3e1bbfe86333572ed782e9a /crypto
parent0044f3eda9a778ab63c2a5eafede3803f01b0b97 (diff)
crypto: aes - Undefined behaviour in crypto_aes_expand_key
It's undefined behaviour in C to write outside the bounds of an array. The key expansion routine takes a shortcut of creating 8 words at a time, but this creates 4 additional words which don't fit in the array. As everyone is hopefully now aware, GCC is at liberty to make any assumptions and optimisations it likes in situations where it can detect that UB has occured, up to and including nasal demons, and as the indices being accessed in the array are trivially calculable, it's rash to invite gcc to do take any liberties at all. Signed-off-by: Phil Carmody <ext-phil.2.carmody@nokia.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/aes_generic.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/crypto/aes_generic.c b/crypto/aes_generic.c
index b8b66ec3883..e78b7ee44a7 100644
--- a/crypto/aes_generic.c
+++ b/crypto/aes_generic.c
@@ -1174,7 +1174,7 @@ EXPORT_SYMBOL_GPL(crypto_il_tab);
ctx->key_enc[6 * i + 11] = t; \
} while (0)
-#define loop8(i) do { \
+#define loop8tophalf(i) do { \
t = ror32(t, 8); \
t = ls_box(t) ^ rco_tab[i]; \
t ^= ctx->key_enc[8 * i]; \
@@ -1185,6 +1185,10 @@ EXPORT_SYMBOL_GPL(crypto_il_tab);
ctx->key_enc[8 * i + 10] = t; \
t ^= ctx->key_enc[8 * i + 3]; \
ctx->key_enc[8 * i + 11] = t; \
+} while (0)
+
+#define loop8(i) do { \
+ loop8tophalf(i); \
t = ctx->key_enc[8 * i + 4] ^ ls_box(t); \
ctx->key_enc[8 * i + 12] = t; \
t ^= ctx->key_enc[8 * i + 5]; \
@@ -1245,8 +1249,9 @@ int crypto_aes_expand_key(struct crypto_aes_ctx *ctx, const u8 *in_key,
ctx->key_enc[5] = le32_to_cpu(key[5]);
ctx->key_enc[6] = le32_to_cpu(key[6]);
t = ctx->key_enc[7] = le32_to_cpu(key[7]);
- for (i = 0; i < 7; ++i)
+ for (i = 0; i < 6; ++i)
loop8(i);
+ loop8tophalf(i);
break;
}