Skip to content

Commit cce6b79

Browse files
authored
AES: Add function pointer trampoline to avoid delocator issue (#2294)
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license. -------- 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 (specifically #2176). 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 <[email protected]>
1 parent a39439b commit cce6b79

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

crypto/fipsmodule/aes/mode_wrappers.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,47 @@
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+
static inline void aes_hw_ctr32_encrypt_blocks_wrapper(const uint8_t *in,
62+
uint8_t *out, size_t len,
63+
const AES_KEY *key,
64+
const uint8_t ivec[16])
65+
{
66+
aes_hw_ctr32_encrypt_blocks(in, out, len, key, ivec);
67+
}
68+
69+
#if defined(VPAES_CTR32)
70+
static inline void vpaes_ctr32_encrypt_blocks_wrapper(const uint8_t *in,
71+
uint8_t *out, size_t len,
72+
const AES_KEY *key,
73+
const uint8_t ivec[16]) {
74+
vpaes_ctr32_encrypt_blocks(in, out, len, key, ivec);
75+
}
76+
#else // VPAES_CTR32
77+
static inline void vpaes_encrypt_wrapper(const uint8_t *in, uint8_t *out,
78+
const AES_KEY *key) {
79+
vpaes_encrypt(in, out, key);
80+
}
81+
#endif // !VPAES_CTR32
82+
5783
void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
5884
const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE],
5985
uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num) {
6086
if (hwaes_capable()) {
6187
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,
62-
aes_hw_ctr32_encrypt_blocks);
88+
aes_hw_ctr32_encrypt_blocks_wrapper);
6389
} else if (vpaes_capable()) {
6490
#if defined(VPAES_CTR32)
6591
// TODO(davidben): On ARM, where |BSAES| is additionally defined, this could
6692
// use |vpaes_ctr32_encrypt_blocks_with_bsaes|.
6793
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,
68-
vpaes_ctr32_encrypt_blocks);
94+
vpaes_ctr32_encrypt_blocks_wrapper);
6995
#else
7096
CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num,
71-
vpaes_encrypt);
97+
vpaes_encrypt_wrapper);
7298
#endif
7399
} else {
74100
CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, ivec, ecount_buf, num,

0 commit comments

Comments
 (0)