Skip to content

Commit 4c8136d

Browse files
committed
AES: Add function pointer trampoline to avoid delocator issue
On AArch64, the delocator can patch up the computation of function pointers only if the pointers can be computed with a PC-relative offset in the range (-1MB, 1MB). For the function pointer computations in aes/mode_wrappers.c, this bounds condition is about to be violated by further code additions to AWS-LC, as witnessed in AES-unrelated PRs. This commit preventatively fixes the issue by adding function pointer trampolines to crypto/fipsmodule/aes/mode_wrappers.c: These are stub functions immediately branching into the desired assembly routines, but close enough to the C code computing their address to ensure that their addresses will be computable using a PC-relative offset. This fix is similar to #2165. Mid/Long-term, it should be considered whether the delocator can introduce the necessary indirections automatically. Signed-off-by: Hanno Becker <beckphan@amazon.co.uk>
1 parent 1cbed51 commit 4c8136d

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

crypto/fipsmodule/aes/mode_wrappers.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,29 @@
5454
#include "../modes/internal.h"
5555
#include "../cipher/internal.h"
5656

57+
// The following wrappers ensure that the delocator can handle the
58+
// function pointer calculation in AES_ctr128_encrypt. Without it,
59+
// on AArch64 there is risk of the calculations requiring a PC-relative
60+
// offset outside of the range (-1MB,1MB) addressable using `ADR`.
61+
//
62+
// We don't add a wrapper for aes_hw_ctr32_encrypt_blocks which is
63+
// used for X86 only and does not seem to face the same issue.
64+
#if defined(VPAES)
65+
#if defined(VPAES_CTR32)
66+
static inline void vpaes_ctr32_encrypt_blocks_wrapper(const uint8_t *in,
67+
uint8_t *out, size_t len,
68+
const AES_KEY *key,
69+
const uint8_t ivec[16]) {
70+
vpaes_ctr32_encrypt_blocks(in, out, len, key, ivec);
71+
}
72+
#else // VPAES_CTR32
73+
static inline void vpaes_encrypt_wrapper(const uint8_t *in, uint8_t *out,
74+
const AES_KEY *key) {
75+
vpaes_encrypt(in, out, key);
76+
}
77+
#endif // !VPAES_CTR32
78+
#endif // VPAES
79+
5780
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
5881
const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE],
5982
uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num) {
@@ -65,10 +88,10 @@ void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
6588
// TODO(davidben): On ARM, where |BSAES| is additionally defined, this could
6689
// use |vpaes_ctr32_encrypt_blocks_with_bsaes|.
6790
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,
68-
vpaes_ctr32_encrypt_blocks);
91+
vpaes_ctr32_encrypt_blocks_wrapper);
6992
#else
7093
CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num,
71-
vpaes_encrypt);
94+
vpaes_encrypt_wrapper);
7295
#endif
7396
} else {
7497
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,

0 commit comments

Comments
 (0)