ANDROID: arm64: only permit certain alternatives in the FIPS140 module

The FIPS140 crypto module takes a HMAC digest of its own .text and
.rodata section in its module_init() hook. This digest is compared to a
digest taken at build time, which means that we need to take some extra
care to ensure that the build time and runtime versions line up.

One thing we cannot tolerate in this case is alternatives patching. In
the general case, we cannot simply ignore alternatives, but fortunately,
there is only a small subset that actually gets instantiated in the
FIPS140 module, and all of these can be ignored if we are willing to
accept that the FIPS140 module does not support VHE hardware, and does
not work when running with pseudo-NMI support enabled. None of this is
important for the use case targeted by the FIPS140 module, so this is
something we should be able to live with.

Bug: 153614920
Bug: 188620248
Change-Id: Ie6666e01d5524a3c33aa451609bab2f29b612f8c
Signed-off-by: Ard Biesheuvel <ardb@google.com>
This commit is contained in:
Ard Biesheuvel
2021-06-03 15:18:35 +00:00
parent 9c556792b7
commit ddea30c684

View File

@@ -9,6 +9,7 @@
/* A64 instructions are always 32 bits. */ /* A64 instructions are always 32 bits. */
#define AARCH64_INSN_SIZE 4 #define AARCH64_INSN_SIZE 4
#ifndef BUILD_FIPS140_KO
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
#include <linux/stringify.h> #include <linux/stringify.h>
@@ -214,4 +215,33 @@ alternative_endif
#define ALTERNATIVE(oldinstr, newinstr, ...) \ #define ALTERNATIVE(oldinstr, newinstr, ...) \
_ALTERNATIVE_CFG(oldinstr, newinstr, __VA_ARGS__, 1) _ALTERNATIVE_CFG(oldinstr, newinstr, __VA_ARGS__, 1)
#else
/*
* The FIPS140 module does not support alternatives patching, as this
* invalidates the HMAC digest of the .text section. However, some alternatives
* are known to be irrelevant so we can tolerate them in the FIPS140 module, as
* they will never be applied in the first place in the use cases that the
* FIPS140 module targets (Android running on a production phone). Any other
* uses of alternatives should be avoided, as it is not safe in the general
* case to simply use the default sequence in one place (the fips module) and
* the alternative sequence everywhere else.
*
* Below is an allowlist of features that we can ignore, by simply taking the
* safe default instruction sequence. Note that this implies that the FIPS140
* module is not compatible with VHE, or with pseudo-NMI support.
*/
#define __ALT_ARM64_HAS_LDAPR 0,
#define __ALT_ARM64_HAS_VIRT_HOST_EXTN 0,
#define __ALT_ARM64_HAS_IRQ_PRIO_MASKING 0,
#define ALTERNATIVE(oldinstr, newinstr, feature, ...) \
_ALTERNATIVE(oldinstr, __ALT_ ## feature, #feature)
#define _ALTERNATIVE(oldinstr, feature, feature_str) \
__take_second_arg(feature oldinstr, \
".err Feature " feature_str " not supported in fips140 module")
#endif /* BUILD_FIPS140_KO */
#endif /* __ASM_ALTERNATIVE_MACROS_H */ #endif /* __ASM_ALTERNATIVE_MACROS_H */