mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-08-05 19:35:48 +03:00
Fix unaligned access if the context is moved during operation
Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
committed by
Tom Cosgrove
parent
5f1677f582
commit
6978e73939
@@ -983,6 +983,39 @@ void mbedtls_aes_decrypt(mbedtls_aes_context *ctx,
|
|||||||
}
|
}
|
||||||
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
#endif /* !MBEDTLS_DEPRECATED_REMOVED */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_AESNI_HAVE_CODE) || \
|
||||||
|
(defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86))
|
||||||
|
/* VIA Padlock and our intrinsics-based implementation of AESNI require
|
||||||
|
* the round keys to be aligned on a 16-byte boundary. We take care of this
|
||||||
|
* before creating them, but the AES context may have moved (this can happen
|
||||||
|
* if the library is called from a language with managed memory), and in later
|
||||||
|
* calls it might have a different alignment with respect to 16-byte memory.
|
||||||
|
* So we may need to realign.
|
||||||
|
* NOTE: In the LTS branch, the context contains a pointer to within itself,
|
||||||
|
* so if it has been moved, things will probably go pear-shaped. We keep this
|
||||||
|
* code for compatibility with the development branch, in case of future changes.
|
||||||
|
*/
|
||||||
|
static void aes_maybe_realign(mbedtls_aes_context *ctx)
|
||||||
|
{
|
||||||
|
/* We want a 16-byte alignment. Note that rk and buf are pointers to uint32_t
|
||||||
|
* and offset is in units of uint32_t words = 4 bytes. We want a
|
||||||
|
* 4-word alignment. */
|
||||||
|
unsigned current_offset = (unsigned)(ctx->rk - ctx->buf);
|
||||||
|
uintptr_t current_address = (uintptr_t)ctx->rk;
|
||||||
|
unsigned current_alignment = (current_address & 0x0000000f) / 4;
|
||||||
|
if (current_alignment != 0) {
|
||||||
|
unsigned new_offset = current_offset + 4 - current_alignment;
|
||||||
|
if (new_offset >= 4) {
|
||||||
|
new_offset -= 4;
|
||||||
|
}
|
||||||
|
memmove(ctx->buf + new_offset, // new address
|
||||||
|
ctx->buf + current_offset, // current address
|
||||||
|
(ctx->nr + 1) * 16); // number of round keys * bytes per rk
|
||||||
|
ctx->rk = ctx->buf + new_offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AES-ECB block encryption/decryption
|
* AES-ECB block encryption/decryption
|
||||||
*/
|
*/
|
||||||
@@ -999,19 +1032,15 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
|
|||||||
|
|
||||||
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
#if defined(MBEDTLS_AESNI_HAVE_CODE)
|
||||||
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
if (mbedtls_aesni_has_support(MBEDTLS_AESNI_AES)) {
|
||||||
|
aes_maybe_realign(ctx);
|
||||||
return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
|
return mbedtls_aesni_crypt_ecb(ctx, mode, input, output);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
|
#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86)
|
||||||
if (aes_padlock_ace) {
|
if (aes_padlock_ace) {
|
||||||
if (mbedtls_padlock_xcryptecb(ctx, mode, input, output) == 0) {
|
aes_maybe_realign(ctx);
|
||||||
return 0;
|
return mbedtls_padlock_xcryptecb(ctx, mode, input, output);
|
||||||
}
|
|
||||||
|
|
||||||
// If padlock data misaligned, we just fall back to
|
|
||||||
// unaccelerated mode
|
|
||||||
//
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user