Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -1084,6 +1084,7 @@ __INTEL_COMPILER
__KEIL__
__KEY_DATA_H__
__LINUX__
__LITTLE_ENDIAN__
__LP64
__LP64__
__MACH__
Expand All @@ -1098,6 +1099,7 @@ __OS2__
__OpenBSD__
__PIC__
__PIE__
__POWER9_VECTOR__
__POWERPC__
__PPC__
__PPU
Expand Down
76 changes: 76 additions & 0 deletions wolfcrypt/src/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,79 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,

#elif (defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM))

#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
/* POWER8+ has vector AES (vcipher/vncipher...) instructions. When built in,
* select the "_crypto" implementations at run time if the CPU supports them.
*
* A run-time flag with direct calls is used rather than a function pointer: an
* indirect call would require an ELFv1 function descriptor, whereas direct
* calls work under both the ELFv1 and ELFv2 ABIs. The dispatch is expressed as
* self-referential macros - the base name inside each macro is not re-expanded
* (C99 6.10.3.4), so it names the real base function. In a PPC build the ARM
* branches that also call these names are #if'd out, so only the live PPC call
* sites are redirected. */

/* -1 = not yet determined, 0 = base, 1 = vector-crypto */
static int aes_ppc64_use_crypto = -1;

/* Detect CPU support via the central cpuid module. Idempotent - safe to call
* from multiple threads as all callers compute the same value. Called from the
* key-setup path before any AES_*_crypto use. */
static void Aes_SetCrypto(void)
{
if (aes_ppc64_use_crypto < 0) {
aes_ppc64_use_crypto = IS_PPC64_VEC_CRYPTO(cpuid_get_flags()) != 0;
}
}

#define AES_set_encrypt_key(key, len, ks) \
(aes_ppc64_use_crypto > 0 ? \
AES_set_encrypt_key_crypto((key), (len), (ks)) : \
AES_set_encrypt_key((key), (len), (ks)))
#define AES_invert_key(ks, rounds) \
(aes_ppc64_use_crypto > 0 ? \
AES_invert_key_crypto((ks), (rounds)) : \
AES_invert_key((ks), (rounds)))
#define AES_ECB_encrypt(in, out, len, ks, nr) \
(aes_ppc64_use_crypto > 0 ? \
AES_ECB_encrypt_crypto((in), (out), (len), (ks), (nr)) : \
AES_ECB_encrypt((in), (out), (len), (ks), (nr)))
#define AES_ECB_decrypt(in, out, len, ks, nr) \
(aes_ppc64_use_crypto > 0 ? \
AES_ECB_decrypt_crypto((in), (out), (len), (ks), (nr)) : \
AES_ECB_decrypt((in), (out), (len), (ks), (nr)))
#define AES_CBC_encrypt(in, out, len, ks, nr, iv) \
(aes_ppc64_use_crypto > 0 ? \
AES_CBC_encrypt_crypto((in), (out), (len), (ks), (nr), (iv)) : \
AES_CBC_encrypt((in), (out), (len), (ks), (nr), (iv)))
#define AES_CBC_decrypt(in, out, len, ks, nr, iv) \
(aes_ppc64_use_crypto > 0 ? \
AES_CBC_decrypt_crypto((in), (out), (len), (ks), (nr), (iv)) : \
AES_CBC_decrypt((in), (out), (len), (ks), (nr), (iv)))
#define AES_CTR_encrypt(in, out, len, ks, nr, ctr) \
(aes_ppc64_use_crypto > 0 ? \
AES_CTR_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) : \
AES_CTR_encrypt((in), (out), (len), (ks), (nr), (ctr)))
#define AES_GCM_encrypt(in, out, len, ks, nr, ctr) \
(aes_ppc64_use_crypto > 0 ? \
AES_GCM_encrypt_crypto((in), (out), (len), (ks), (nr), (ctr)) : \
AES_GCM_encrypt((in), (out), (len), (ks), (nr), (ctr)))
#if defined(WOLFSSL_AES_XTS)
#define AES_XTS_encrypt(in, out, sz, i, key, key2, tmp, nr) \
(aes_ppc64_use_crypto > 0 ? \
AES_XTS_encrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp), \
(nr)) : \
AES_XTS_encrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
#define AES_XTS_decrypt(in, out, sz, i, key, key2, tmp, nr) \
(aes_ppc64_use_crypto > 0 ? \
AES_XTS_decrypt_crypto((in), (out), (sz), (i), (key), (key2), (tmp), \
(nr)) : \
AES_XTS_decrypt((in), (out), (sz), (i), (key), (key2), (tmp), (nr)))
#endif /* WOLFSSL_AES_XTS */
#else
#define Aes_SetCrypto() WC_DO_NOTHING
#endif /* WOLFSSL_PPC64_ASM && WOLFSSL_PPC64_ASM_CRYPTO */

#if defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESCCM) || \
defined(WOLFSSL_AESGCM_STREAM) || defined(HAVE_AESGCM)
static WARN_UNUSED_RESULT int wc_AesEncrypt(Aes* aes, const byte* inBlock,
Expand Down Expand Up @@ -4955,6 +5028,9 @@ static WARN_UNUSED_RESULT int wc_AesDecrypt(Aes* aes, const byte* inBlock,
aes->keylen = (int)keylen;
aes->rounds = (keylen/4) + 6;

/* Determine base vs vector-crypto before the (dispatched) key setup so
* the schedule matches the mode functions that later consume it. */
Aes_SetCrypto();
AES_set_encrypt_key(userKey, keylen * 8, (byte*)aes->key);

#ifdef HAVE_AES_DECRYPT
Expand Down
Loading
Loading