Move aes_nohw, bsaes, and vpaes prototypes to aes/internal.h.
This is in preparation for adding ABI tests to them. In doing so, update delocate.go so that OPENSSL_ia32cap_get is consistently callable outside the module. Right now it's callable both inside and outside normally, but not in FIPS mode because the function is generated. This is needed for tests and the module to share headers that touch OPENSSL_ia32cap_P. Change-Id: Idbc7d694acfb974e0b04adac907dab621e87de62 Reviewed-on: https://boringssl-review.googlesource.com/c/34188 Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
committed by
CQ bot account: commit-bot@chromium.org
parent
e592d595c4
commit
c0f4dbe4e2
@@ -534,8 +534,8 @@ static const uint32_t rcon[] = {
|
||||
// for 128-bit blocks, Rijndael never uses more than 10 rcon values
|
||||
};
|
||||
|
||||
static int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey) {
|
||||
int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey) {
|
||||
uint32_t *rk;
|
||||
int i = 0;
|
||||
uint32_t temp;
|
||||
@@ -630,8 +630,8 @@ static int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey) {
|
||||
int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey) {
|
||||
uint32_t *rk;
|
||||
int i, j, status;
|
||||
uint32_t temp;
|
||||
@@ -679,8 +679,7 @@ static int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aes_nohw_encrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
const uint32_t *rk;
|
||||
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
int r;
|
||||
@@ -741,8 +740,7 @@ static void aes_nohw_encrypt(const uint8_t *in, uint8_t *out,
|
||||
PUTU32(out + 12, s3);
|
||||
}
|
||||
|
||||
static void aes_nohw_decrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
const uint32_t *rk;
|
||||
uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
int r;
|
||||
@@ -808,17 +806,7 @@ static void aes_nohw_decrypt(const uint8_t *in, uint8_t *out,
|
||||
PUTU32(out + 12, s3);
|
||||
}
|
||||
|
||||
#else // NO_ASM || (!X86 && !X86_64 && !ARM)
|
||||
|
||||
// If not implemented in C, these functions will be provided by assembly code.
|
||||
void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey);
|
||||
int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey);
|
||||
|
||||
#endif
|
||||
#endif // NO_ASM || (!X86 && !X86_64 && !ARM)
|
||||
|
||||
// Be aware that on x86(-64), the |aes_nohw_*| functions are incompatible with
|
||||
// the aes_hw_* functions. The latter set |AES_KEY.rounds| to one less than the
|
||||
|
||||
@@ -30,19 +30,34 @@ extern "C" {
|
||||
#define HWAES
|
||||
#define HWAES_ECB
|
||||
|
||||
static int hwaes_capable(void) {
|
||||
OPENSSL_INLINE int hwaes_capable(void) {
|
||||
return (OPENSSL_ia32cap_get()[1] & (1 << (57 - 32))) != 0;
|
||||
}
|
||||
|
||||
#define VPAES
|
||||
OPENSSL_INLINE char vpaes_capable(void) {
|
||||
return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0;
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_X86_64)
|
||||
#define BSAES
|
||||
OPENSSL_INLINE char bsaes_capable(void) { return vpaes_capable(); }
|
||||
#endif // X86_64
|
||||
|
||||
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
|
||||
#define HWAES
|
||||
|
||||
static int hwaes_capable(void) {
|
||||
return CRYPTO_is_ARMv8_AES_capable();
|
||||
}
|
||||
OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); }
|
||||
|
||||
#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
|
||||
#define BSAES
|
||||
OPENSSL_INLINE char bsaes_capable(void) { return CRYPTO_is_NEON_capable(); }
|
||||
#endif
|
||||
|
||||
#elif defined(OPENSSL_PPC64LE)
|
||||
#define HWAES
|
||||
|
||||
static int hwaes_capable(void) {
|
||||
OPENSSL_INLINE int hwaes_capable(void) {
|
||||
return CRYPTO_is_PPC64LE_vcrypto_capable();
|
||||
}
|
||||
#endif
|
||||
@@ -67,36 +82,37 @@ void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
|
||||
|
||||
// If HWAES isn't defined then we provide dummy functions for each of the hwaes
|
||||
// functions.
|
||||
static int hwaes_capable(void) { return 0; }
|
||||
OPENSSL_INLINE int hwaes_capable(void) { return 0; }
|
||||
|
||||
static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
|
||||
AES_KEY *key) {
|
||||
OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
|
||||
AES_KEY *key) {
|
||||
OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t *ivec, int enc) {
|
||||
OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
uint8_t *ivec, int enc) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
const uint8_t ivec[16]) {
|
||||
OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
const uint8_t ivec[16]) {
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -106,8 +122,90 @@ static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
|
||||
#if defined(HWAES_ECB)
|
||||
void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, const int enc);
|
||||
#endif // HWAES_ECB
|
||||
|
||||
|
||||
#if defined(BSAES)
|
||||
// On platforms where BSAES gets defined (just above), then these functions are
|
||||
// provided by asm.
|
||||
void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t ivec[16], int enc);
|
||||
void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, const uint8_t ivec[16]);
|
||||
#else
|
||||
OPENSSL_INLINE char bsaes_capable(void) { return 0; }
|
||||
|
||||
// On other platforms, bsaes_capable() will always return false and so the
|
||||
// following will never be called.
|
||||
OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
uint8_t ivec[16], int enc) {
|
||||
abort();
|
||||
}
|
||||
|
||||
OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
const uint8_t ivec[16]) {
|
||||
abort();
|
||||
}
|
||||
#endif // !BSAES
|
||||
|
||||
|
||||
#if defined(VPAES)
|
||||
// On platforms where VPAES gets defined (just above), then these functions are
|
||||
// provided by asm.
|
||||
int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
|
||||
int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
|
||||
|
||||
void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
|
||||
void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t *ivec, int enc);
|
||||
#else
|
||||
OPENSSL_INLINE char vpaes_capable(void) { return 0; }
|
||||
|
||||
// On other platforms, vpaes_capable() will always return false and so the
|
||||
// following will never be called.
|
||||
OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out,
|
||||
const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
uint8_t *ivec, int enc) {
|
||||
abort();
|
||||
}
|
||||
#endif // !VPAES
|
||||
|
||||
|
||||
void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey);
|
||||
int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
|
||||
AES_KEY *aeskey);
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
|
||||
#define AES_NOHW_CBC
|
||||
void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, uint8_t *ivec, const int enc);
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern C
|
||||
#endif
|
||||
|
||||
@@ -72,11 +72,6 @@ void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key,
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
|
||||
void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, uint8_t *ivec, const int enc);
|
||||
#endif
|
||||
|
||||
void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, uint8_t *ivec, const int enc) {
|
||||
if (hwaes_capable()) {
|
||||
@@ -84,8 +79,7 @@ void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
|
||||
#if defined(AES_NOHW_CBC)
|
||||
aes_nohw_cbc_encrypt(in, out, len, key, ivec, enc);
|
||||
#else
|
||||
if (enc) {
|
||||
|
||||
@@ -98,97 +98,6 @@ typedef struct {
|
||||
ctr128_f ctr;
|
||||
} EVP_AES_GCM_CTX;
|
||||
|
||||
#if !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
|
||||
#define VPAES
|
||||
static char vpaes_capable(void) {
|
||||
return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0;
|
||||
}
|
||||
|
||||
#if defined(OPENSSL_X86_64)
|
||||
#define BSAES
|
||||
static char bsaes_capable(void) {
|
||||
return vpaes_capable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif !defined(OPENSSL_NO_ASM) && \
|
||||
(defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
|
||||
|
||||
#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
|
||||
#define BSAES
|
||||
static char bsaes_capable(void) {
|
||||
return CRYPTO_is_NEON_capable();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(BSAES)
|
||||
// On platforms where BSAES gets defined (just above), then these functions are
|
||||
// provided by asm.
|
||||
void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t ivec[16], int enc);
|
||||
void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
|
||||
const AES_KEY *key, const uint8_t ivec[16]);
|
||||
#else
|
||||
static char bsaes_capable(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On other platforms, bsaes_capable() will always return false and so the
|
||||
// following will never be called.
|
||||
static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t ivec[16], int enc) {
|
||||
abort();
|
||||
}
|
||||
|
||||
static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
const uint8_t ivec[16]) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VPAES)
|
||||
// On platforms where VPAES gets defined (just above), then these functions are
|
||||
// provided by asm.
|
||||
int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
|
||||
int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
|
||||
|
||||
void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
|
||||
|
||||
void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t *ivec, int enc);
|
||||
#else
|
||||
static char vpaes_capable(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On other platforms, vpaes_capable() will always return false and so the
|
||||
// following will never be called.
|
||||
static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
|
||||
AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
|
||||
abort();
|
||||
}
|
||||
static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
|
||||
const AES_KEY *key, uint8_t *ivec, int enc) {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
|
||||
const uint8_t *iv, int enc) {
|
||||
int ret, mode;
|
||||
|
||||
@@ -1216,6 +1216,9 @@ func transform(w stringWriter, inputs []inputFile) error {
|
||||
// .file directive. Zero is not a valid number.
|
||||
maxObservedFileNumber := 0
|
||||
|
||||
// OPENSSL_ia32cap_get will be synthesized by this script.
|
||||
symbols["OPENSSL_ia32cap_get"] = struct{}{}
|
||||
|
||||
for _, input := range inputs {
|
||||
forEachPath(input.ast.up, func(node *node32) {
|
||||
symbol := input.contents[node.begin:node.end]
|
||||
@@ -1394,6 +1397,8 @@ func transform(w stringWriter, inputs []inputFile) error {
|
||||
}
|
||||
|
||||
w.WriteString(".type OPENSSL_ia32cap_get, @function\n")
|
||||
w.WriteString(".globl OPENSSL_ia32cap_get\n")
|
||||
w.WriteString(localTargetName("OPENSSL_ia32cap_get") + ":\n")
|
||||
w.WriteString("OPENSSL_ia32cap_get:\n")
|
||||
w.WriteString("\tleaq OPENSSL_ia32cap_P(%rip), %rax\n")
|
||||
w.WriteString("\tret\n")
|
||||
|
||||
@@ -66,6 +66,8 @@ z_bss_get:
|
||||
leaq .Lz_local_target(%rip), %rax
|
||||
ret
|
||||
.type OPENSSL_ia32cap_get, @function
|
||||
.globl OPENSSL_ia32cap_get
|
||||
.LOPENSSL_ia32cap_get_local_target:
|
||||
OPENSSL_ia32cap_get:
|
||||
leaq OPENSSL_ia32cap_P(%rip), %rax
|
||||
ret
|
||||
|
||||
@@ -59,6 +59,8 @@ foo:
|
||||
.loc 2 2 0
|
||||
BORINGSSL_bcm_text_end:
|
||||
.type OPENSSL_ia32cap_get, @function
|
||||
.globl OPENSSL_ia32cap_get
|
||||
.LOPENSSL_ia32cap_get_local_target:
|
||||
OPENSSL_ia32cap_get:
|
||||
leaq OPENSSL_ia32cap_P(%rip), %rax
|
||||
ret
|
||||
|
||||
@@ -148,7 +148,7 @@ foo:
|
||||
# WAS movq foobar_bss_get@GOTPCREL(%rip), %r11
|
||||
leaq foobar_bss_get(%rip), %r11
|
||||
# WAS movq OPENSSL_ia32cap_get@GOTPCREL(%rip), %r11
|
||||
leaq OPENSSL_ia32cap_get(%rip), %r11
|
||||
leaq .LOPENSSL_ia32cap_get_local_target(%rip), %r11
|
||||
|
||||
# Transforming moves run the transform in-place after the load.
|
||||
# WAS vpbroadcastq stderr@GOTPCREL(%rip), %xmm0
|
||||
@@ -186,6 +186,8 @@ stderr_GOTPCREL_external:
|
||||
.long stderr@GOTPCREL
|
||||
.long 0
|
||||
.type OPENSSL_ia32cap_get, @function
|
||||
.globl OPENSSL_ia32cap_get
|
||||
.LOPENSSL_ia32cap_get_local_target:
|
||||
OPENSSL_ia32cap_get:
|
||||
leaq OPENSSL_ia32cap_P(%rip), %rax
|
||||
ret
|
||||
|
||||
@@ -39,7 +39,7 @@ bar:
|
||||
|
||||
# Synthesized symbols are treated as local ones.
|
||||
# WAS call OPENSSL_ia32cap_get@PLT
|
||||
call OPENSSL_ia32cap_get
|
||||
call .LOPENSSL_ia32cap_get_local_target
|
||||
|
||||
# References to local labels are left as-is in the first file.
|
||||
.Llocal_label:
|
||||
@@ -90,6 +90,8 @@ BORINGSSL_bcm_text_end:
|
||||
bcm_redirector_memcpy:
|
||||
jmp memcpy@PLT
|
||||
.type OPENSSL_ia32cap_get, @function
|
||||
.globl OPENSSL_ia32cap_get
|
||||
.LOPENSSL_ia32cap_get_local_target:
|
||||
OPENSSL_ia32cap_get:
|
||||
leaq OPENSSL_ia32cap_P(%rip), %rax
|
||||
ret
|
||||
|
||||
@@ -48,6 +48,8 @@ foo:
|
||||
.loc 1 2 0
|
||||
BORINGSSL_bcm_text_end:
|
||||
.type OPENSSL_ia32cap_get, @function
|
||||
.globl OPENSSL_ia32cap_get
|
||||
.LOPENSSL_ia32cap_get_local_target:
|
||||
OPENSSL_ia32cap_get:
|
||||
leaq OPENSSL_ia32cap_P(%rip), %rax
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user