summaryrefslogtreecommitdiff
path: root/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2012-12-14 11:37:15 +0000
committerRobin Watts <robin.watts@artifex.com>2012-12-14 12:51:40 +0000
commit25ee437eb784a8eb241b9463e79dad429b60e933 (patch)
treebb0b66f88008e73b8b1f40f3ed36763d06a2b5f9 /fitz
parentdf835b0f23b4976b453d3bdd63c60804b2376c16 (diff)
downloadmupdf-25ee437eb784a8eb241b9463e79dad429b60e933.tar.xz
Bug 693503: Fix SEGV/memory problems in AES.
If an illegal keysize is passed into the AES crypt filter, we currently exit without setting up the AES context. This causes us to fail in all manner of ways later on. We now return failure and callers throw an exception. This appears to solve all the SEGVs and memory exceptions found in crypt_aes by Mateusz "j00ru" Jurczyk and Gynvael Coldwind of the Google Security Team using Address Sanitizer. Many thanks!
Diffstat (limited to 'fitz')
-rw-r--r--fitz/crypt_aes.c14
-rw-r--r--fitz/filt_basic.c3
-rw-r--r--fitz/fitz-internal.h4
3 files changed, 13 insertions, 8 deletions
diff --git a/fitz/crypt_aes.c b/fitz/crypt_aes.c
index 4d8c4498..27db64fc 100644
--- a/fitz/crypt_aes.c
+++ b/fitz/crypt_aes.c
@@ -176,7 +176,7 @@ static void aes_gen_tables( void )
/*
* AES key schedule (encryption)
*/
-void aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
+int aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
{
int i;
unsigned long *RK;
@@ -194,7 +194,7 @@ void aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
case 128: ctx->nr = 10; break;
case 192: ctx->nr = 12; break;
case 256: ctx->nr = 14; break;
- default : return;
+ default : return 1;
}
#if defined(PADLOCK_ALIGN16)
@@ -274,12 +274,13 @@ void aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
break;
}
+ return 0;
}
/*
* AES key schedule (decryption)
*/
-void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize )
+int aes_setkey_dec(aes_context *ctx, const unsigned char *key, int keysize)
{
int i, j;
aes_context cty;
@@ -291,7 +292,7 @@ void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize )
case 128: ctx->nr = 10; break;
case 192: ctx->nr = 12; break;
case 256: ctx->nr = 14; break;
- default : return;
+ default: return 1;
}
#if defined(PADLOCK_ALIGN16)
@@ -300,7 +301,9 @@ void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize )
ctx->rk = RK = ctx->buf;
#endif
- aes_setkey_enc( &cty, key, keysize );
+ i = aes_setkey_enc( &cty, key, keysize );
+ if (i)
+ return i;
SK = cty.rk + cty.nr * 4;
*RK++ = *SK++;
@@ -325,6 +328,7 @@ void aes_setkey_dec( aes_context *ctx, const unsigned char *key, int keysize )
*RK++ = *SK++;
memset( &cty, 0, sizeof( aes_context ) );
+ return 0;
}
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
diff --git a/fitz/filt_basic.c b/fitz/filt_basic.c
index db95533d..6f07edd6 100644
--- a/fitz/filt_basic.c
+++ b/fitz/filt_basic.c
@@ -653,7 +653,8 @@ fz_open_aesd(fz_stream *chain, unsigned char *key, unsigned keylen)
{
state = fz_malloc_struct(ctx, fz_aesd);
state->chain = chain;
- aes_setkey_dec(&state->aes, key, keylen * 8);
+ if (aes_setkey_dec(&state->aes, key, keylen * 8))
+ fz_throw(ctx, "AES key init failed (keylen=%d)", keylen * 8);
state->ivcount = 0;
state->rp = state->bp;
state->wp = state->bp;
diff --git a/fitz/fitz-internal.h b/fitz/fitz-internal.h
index c90474dd..0de2e4c2 100644
--- a/fitz/fitz-internal.h
+++ b/fitz/fitz-internal.h
@@ -393,8 +393,8 @@ struct fz_aes_s
unsigned long buf[68]; /* unaligned data */
};
-void aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize );
-void aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize );
+int aes_setkey_enc( fz_aes *ctx, const unsigned char *key, int keysize );
+int aes_setkey_dec( fz_aes *ctx, const unsigned char *key, int keysize );
void aes_crypt_cbc( fz_aes *ctx, int mode, int length,
unsigned char iv[16],
const unsigned char *input,