From e146c99c34cd29b30ed5993d3d44c3b7ed5cf5e5 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 12 Apr 2021 13:05:54 +0200 Subject: [PATCH] ANDROID: crypto: lib/aes - add vendor hooks for AES library routines Add vendor hooks that will allow the FIPS140 kernel module to override the implementations of the AES library routines. The FIPS 140 versions are identical to the normal ones, but their code and rodata will have been integrity checked at module load time. Original commits: android12-5.10: 9c556792b713 ("ANDROID: crypto: lib/aes - add vendor hooks for AES library routines") android14-5.15: d4966a820397 ("ANDROID: fips140: remove CONFIG_CRYPTO_FIPS140 option") Bug: 153614920 Bug: 188620248 Change-Id: I5711fc42eced903565fd3c8d41ca7cdd82641148 Signed-off-by: Ard Biesheuvel Signed-off-by: Eric Biggers --- drivers/android/vendor_hooks.c | 3 +++ include/trace/hooks/fips140.h | 23 +++++++++++++++++++++++ lib/crypto/aes.c | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/drivers/android/vendor_hooks.c b/drivers/android/vendor_hooks.c index 1a14e7caf785..0bfabee0578a 100644 --- a/drivers/android/vendor_hooks.c +++ b/drivers/android/vendor_hooks.c @@ -140,6 +140,9 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_size_check); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_format_check); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_ftrace_dump_buffer); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_sha256); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_expandkey); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_encrypt); +EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_aes_decrypt); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_free); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_mem_cgroup_alloc); EXPORT_TRACEPOINT_SYMBOL_GPL(android_vh_cma_alloc_bypass); diff --git a/include/trace/hooks/fips140.h b/include/trace/hooks/fips140.h index bfadf5122b1c..aa84f014200e 100644 --- a/include/trace/hooks/fips140.h +++ b/include/trace/hooks/fips140.h @@ -7,6 +7,8 @@ #define _TRACE_HOOK_FIPS140_H #include +struct crypto_aes_ctx; + /* * These hooks exist only for the benefit of the FIPS140 crypto module, which * uses them to swap out the underlying implementation with one that is integrity @@ -20,6 +22,27 @@ DECLARE_HOOK(android_vh_sha256, int *hook_inuse), TP_ARGS(data, len, out, hook_inuse)); +DECLARE_HOOK(android_vh_aes_expandkey, + TP_PROTO(struct crypto_aes_ctx *ctx, + const u8 *in_key, + unsigned int key_len, + int *err), + TP_ARGS(ctx, in_key, key_len, err)); + +DECLARE_HOOK(android_vh_aes_encrypt, + TP_PROTO(const struct crypto_aes_ctx *ctx, + u8 *out, + const u8 *in, + int *hook_inuse), + TP_ARGS(ctx, out, in, hook_inuse)); + +DECLARE_HOOK(android_vh_aes_decrypt, + TP_PROTO(const struct crypto_aes_ctx *ctx, + u8 *out, + const u8 *in, + int *hook_inuse), + TP_ARGS(ctx, out, in, hook_inuse)); + #endif /* _TRACE_HOOK_FIPS140_H */ /* This part must be outside protection */ diff --git a/lib/crypto/aes.c b/lib/crypto/aes.c index eafe14d021f5..796e3df3320b 100644 --- a/lib/crypto/aes.c +++ b/lib/crypto/aes.c @@ -7,6 +7,7 @@ #include #include #include +#include /* * Emit the sbox as volatile const to prevent the compiler from doing @@ -189,6 +190,13 @@ int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, u32 rc, i, j; int err; +#ifndef __DISABLE_EXPORTS + err = -(MAX_ERRNO + 1); + trace_android_vh_aes_expandkey(ctx, in_key, key_len, &err); + if (err != -(MAX_ERRNO + 1)) + return err; +#endif + err = aes_check_keylen(key_len); if (err) return err; @@ -261,6 +269,13 @@ void aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in) int rounds = 6 + ctx->key_length / 4; u32 st0[4], st1[4]; int round; +#ifndef __DISABLE_EXPORTS + int hook_inuse = 0; + + trace_android_vh_aes_encrypt(ctx, out, in, &hook_inuse); + if (hook_inuse) + return; +#endif st0[0] = ctx->key_enc[0] ^ get_unaligned_le32(in); st0[1] = ctx->key_enc[1] ^ get_unaligned_le32(in + 4); @@ -312,6 +327,13 @@ void aes_decrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in) int rounds = 6 + ctx->key_length / 4; u32 st0[4], st1[4]; int round; +#ifndef __DISABLE_EXPORTS + int hook_inuse = 0; + + trace_android_vh_aes_decrypt(ctx, out, in, &hook_inuse); + if (hook_inuse) + return; +#endif st0[0] = ctx->key_dec[0] ^ get_unaligned_le32(in); st0[1] = ctx->key_dec[1] ^ get_unaligned_le32(in + 4);