Page MenuHome GnuPG

Incorrect HWCAP2 check for AArch32
Open, NormalPublic

Description

Hello.
Checking available extension to arm architecture in function detect_arm_at_hwcap in file src/hwf-arm.c is done by testing flags of HWCAP2 auxv value against predefined values.
Flags itself are defined like this:

#ifndef HWCAP2_AES
# define HWCAP2_AES    1
#endif
#ifndef HWCAP2_PMULL
# define HWCAP2_PMULL  2
#endif
#ifndef HWCAP2_SHA1
# define HWCAP2_SHA1   3
#endif
#ifndef HWCAP2_SHA2
# define HWCAP2_SHA2   4
#endif

static const struct feature_map_s arm_features[] =
  {
#ifdef ENABLE_NEON_SUPPORT
    { HWCAP_NEON, 0, " neon", HWF_ARM_NEON },
#endif
#ifdef ENABLE_ARM_CRYPTO_SUPPORT
    { 0, HWCAP2_AES, " aes", HWF_ARM_AES },
    { 0, HWCAP2_SHA1," sha1", HWF_ARM_SHA1 },
    { 0, HWCAP2_SHA2, " sha2", HWF_ARM_SHA2 },
    { 0, HWCAP2_PMULL, " pmull", HWF_ARM_PMULL },
#endif
  };

If you look at HWCAP2 flags you will see that they in fact not flags, but corresponding bit numbers.
On machines that not support SHA1/SHA2 crypto extensions, but support AES, PMULL or/and CRC32 extension this causes libgcrypt to incorrectly think that SHA1/SHA2 crypto extensions are present, which in the end causes SIGILL when SHA instructions are being executed.

Correctly there must be flags, not bits numbers:

#ifndef HWCAP2_SHA1
# define HWCAP2_SHA1   4
#endif
#ifndef HWCAP2_SHA2
# define HWCAP2_SHA2   8
#endif