drivers: crypto: Add authenticated decryption framework

Add framework for autheticated decryption of data. Currently this
patch optionally imports mbedtls library as a backend if build option
"DECRYPTION_SUPPORT = aes_gcm" is set to perform authenticated decryption
using AES-GCM algorithm.

Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Change-Id: I2966f0e79033151012bf4ffc66f484cd949e7271
This commit is contained in:
Sumit Garg 2019-11-15 10:43:00 +05:30
parent d95f7a7287
commit 7cda17bb0f
10 changed files with 223 additions and 9 deletions

View File

@ -623,7 +623,7 @@ endif
ifeq ($(MEASURED_BOOT),1) ifeq ($(MEASURED_BOOT),1)
ifneq (${TRUSTED_BOARD_BOOT},1) ifneq (${TRUSTED_BOARD_BOOT},1)
$(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1") $(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1)
else else
$(info MEASURED_BOOT is an experimental feature) $(info MEASURED_BOOT is an experimental feature)
endif endif
@ -635,6 +635,14 @@ ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
endif endif
endif endif
ifneq (${DECRYPTION_SUPPORT},none)
ifeq (${TRUSTED_BOARD_BOOT}, 0)
$(error TRUSTED_BOARD_BOOT must be enabled for DECRYPTION_SUPPORT to be set)
else
$(info DECRYPTION_SUPPORT is an experimental feature)
endif
endif
################################################################################ ################################################################################
# Process platform overrideable behaviour # Process platform overrideable behaviour
################################################################################ ################################################################################
@ -843,6 +851,7 @@ $(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS))
$(eval $(call add_define,EL3_EXCEPTION_HANDLING)) $(eval $(call add_define,EL3_EXCEPTION_HANDLING))
$(eval $(call add_define,CTX_INCLUDE_MTE_REGS)) $(eval $(call add_define,CTX_INCLUDE_MTE_REGS))
$(eval $(call add_define,CTX_INCLUDE_EL2_REGS)) $(eval $(call add_define,CTX_INCLUDE_EL2_REGS))
$(eval $(call add_define,DECRYPTION_SUPPORT_${DECRYPTION_SUPPORT}))
$(eval $(call add_define,ENABLE_AMU)) $(eval $(call add_define,ENABLE_AMU))
$(eval $(call add_define,ENABLE_ASSERTIONS)) $(eval $(call add_define,ENABLE_ASSERTIONS))
$(eval $(call add_define,ENABLE_BTI)) $(eval $(call add_define,ENABLE_BTI))

View File

@ -160,6 +160,12 @@ Common build options
- ``DEBUG``: Chooses between a debug and release build. It can take either 0 - ``DEBUG``: Chooses between a debug and release build. It can take either 0
(release) or 1 (debug) as values. 0 is the default. (release) or 1 (debug) as values. 0 is the default.
- ``DECRYPTION_SUPPORT``: This build flag enables the user to select the
authenticated decryption algorithm to be used to decrypt firmware/s during
boot. It accepts 2 values: ``aes_gcm`` and ``none``. The default value of
this flag is ``none`` to disable firmware decryption which is an optional
feature as per TBBR. Also, it is an experimental feature.
- ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation - ``DISABLE_BIN_GENERATION``: Boolean option to disable the generation
of the binary image. If set to 1, then only the ELF image is built. of the binary image. If set to 1, then only the ELF image is built.
0 is the default. 0 is the default.

View File

@ -124,3 +124,35 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output); return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output);
} }
#endif /* MEASURED_BOOT */ #endif /* MEASURED_BOOT */
/*
* Authenticated decryption of data
*
* Parameters:
*
* dec_algo: authenticated decryption algorithm
* data_ptr, len: data to be decrypted (inout param)
* key, key_len, key_flags: symmetric decryption key
* iv, iv_len: initialization vector
* tag, tag_len: authentication tag
*/
int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
size_t len, const void *key, unsigned int key_len,
unsigned int key_flags, const void *iv,
unsigned int iv_len, const void *tag,
unsigned int tag_len)
{
assert(crypto_lib_desc.auth_decrypt != NULL);
assert(data_ptr != NULL);
assert(len != 0U);
assert(key != NULL);
assert(key_len != 0U);
assert(iv != NULL);
assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE));
assert(tag != NULL);
assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE));
return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key,
key_len, key_flags, iv, iv_len, tag,
tag_len);
}

View File

@ -301,5 +301,5 @@ static int verify_hash(void *data_ptr, unsigned int data_len,
/* /*
* Register crypto library descriptor * Register crypto library descriptor
*/ */
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);

View File

@ -23,13 +23,17 @@ MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c
LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \ LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \
aes.c \
asn1parse.c \ asn1parse.c \
asn1write.c \ asn1write.c \
cipher.c \
cipher_wrap.c \
memory_buffer_alloc.c \ memory_buffer_alloc.c \
oid.c \ oid.c \
platform.c \ platform.c \
platform_util.c \ platform_util.c \
bignum.c \ bignum.c \
gcm.c \
md.c \ md.c \
md_wrap.c \ md_wrap.c \
pk.c \ pk.c \
@ -87,11 +91,17 @@ else
$(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS") $(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS")
endif endif
ifeq (${DECRYPTION_SUPPORT}, aes_gcm)
TF_MBEDTLS_USE_AES_GCM := 1
else
TF_MBEDTLS_USE_AES_GCM := 0
endif
# Needs to be set to drive mbed TLS configuration correctly # Needs to be set to drive mbed TLS configuration correctly
$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID)) $(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) $(eval $(call add_define,TF_MBEDTLS_KEY_SIZE))
$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) $(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM))
$(eval $(call MAKE_LIB,mbedtls)) $(eval $(call MAKE_LIB,mbedtls))

View File

@ -4,10 +4,12 @@
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <assert.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
/* mbed TLS headers */ /* mbed TLS headers */
#include <mbedtls/gcm.h>
#include <mbedtls/md.h> #include <mbedtls/md.h>
#include <mbedtls/memory_buffer_alloc.h> #include <mbedtls/memory_buffer_alloc.h>
#include <mbedtls/oid.h> #include <mbedtls/oid.h>
@ -17,6 +19,7 @@
#include <drivers/auth/crypto_mod.h> #include <drivers/auth/crypto_mod.h>
#include <drivers/auth/mbedtls/mbedtls_common.h> #include <drivers/auth/mbedtls/mbedtls_common.h>
#include <drivers/auth/mbedtls/mbedtls_config.h> #include <drivers/auth/mbedtls/mbedtls_config.h>
#include <plat/common/platform.h>
#define LIB_NAME "mbed TLS" #define LIB_NAME "mbed TLS"
@ -226,11 +229,121 @@ int calc_hash(unsigned int alg, void *data_ptr,
} }
#endif /* MEASURED_BOOT */ #endif /* MEASURED_BOOT */
#if TF_MBEDTLS_USE_AES_GCM
/*
* Stack based buffer allocation for decryption operation. It could
* be configured to balance stack usage vs execution speed.
*/
#define DEC_OP_BUF_SIZE 128
static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
unsigned int key_len, const void *iv,
unsigned int iv_len, const void *tag,
unsigned int tag_len)
{
mbedtls_gcm_context ctx;
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
unsigned char buf[DEC_OP_BUF_SIZE];
unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
unsigned char *pt = data_ptr;
size_t dec_len;
int diff, i, rc;
mbedtls_gcm_init(&ctx);
rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
if (rc != 0) {
rc = CRYPTO_ERR_DECRYPTION;
goto exit_gcm;
}
rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
if (rc != 0) {
rc = CRYPTO_ERR_DECRYPTION;
goto exit_gcm;
}
while (len > 0) {
dec_len = MIN(sizeof(buf), len);
rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
if (rc != 0) {
rc = CRYPTO_ERR_DECRYPTION;
goto exit_gcm;
}
memcpy(pt, buf, dec_len);
pt += dec_len;
len -= dec_len;
}
rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
if (rc != 0) {
rc = CRYPTO_ERR_DECRYPTION;
goto exit_gcm;
}
/* Check tag in "constant-time" */
for (diff = 0, i = 0; i < tag_len; i++)
diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
if (diff != 0) {
rc = CRYPTO_ERR_DECRYPTION;
goto exit_gcm;
}
/* GCM decryption success */
rc = CRYPTO_SUCCESS;
exit_gcm:
mbedtls_gcm_free(&ctx);
return rc;
}
/*
* Authenticated decryption of an image
*/
static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
size_t len, const void *key, unsigned int key_len,
unsigned int key_flags, const void *iv,
unsigned int iv_len, const void *tag,
unsigned int tag_len)
{
int rc;
assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
switch (dec_algo) {
case CRYPTO_GCM_DECRYPT:
rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
tag, tag_len);
if (rc != 0)
return rc;
break;
default:
return CRYPTO_ERR_DECRYPTION;
}
return CRYPTO_SUCCESS;
}
#endif /* TF_MBEDTLS_USE_AES_GCM */
/* /*
* Register crypto library descriptor * Register crypto library descriptor
*/ */
#if MEASURED_BOOT #if MEASURED_BOOT
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash); #if TF_MBEDTLS_USE_AES_GCM
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
auth_decrypt);
#else #else
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash); REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
NULL);
#endif
#else /* MEASURED_BOOT */
#if TF_MBEDTLS_USE_AES_GCM
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash,
auth_decrypt);
#else
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
#endif
#endif /* MEASURED_BOOT */ #endif /* MEASURED_BOOT */

View File

@ -13,9 +13,18 @@ enum crypto_ret_value {
CRYPTO_ERR_INIT, CRYPTO_ERR_INIT,
CRYPTO_ERR_HASH, CRYPTO_ERR_HASH,
CRYPTO_ERR_SIGNATURE, CRYPTO_ERR_SIGNATURE,
CRYPTO_ERR_DECRYPTION,
CRYPTO_ERR_UNKNOWN CRYPTO_ERR_UNKNOWN
}; };
#define CRYPTO_MAX_IV_SIZE 16U
#define CRYPTO_MAX_TAG_SIZE 16U
/* Decryption algorithm */
enum crypto_dec_algo {
CRYPTO_GCM_DECRYPT = 0
};
/* /*
* Cryptographic library descriptor * Cryptographic library descriptor
*/ */
@ -44,6 +53,15 @@ typedef struct crypto_lib_desc_s {
unsigned int data_len, unsigned char *output); unsigned int data_len, unsigned char *output);
#endif /* MEASURED_BOOT */ #endif /* MEASURED_BOOT */
/*
* Authenticated decryption. Return one of the
* 'enum crypto_ret_value' options.
*/
int (*auth_decrypt)(enum crypto_dec_algo dec_algo, void *data_ptr,
size_t len, const void *key, unsigned int key_len,
unsigned int key_flags, const void *iv,
unsigned int iv_len, const void *tag,
unsigned int tag_len);
} crypto_lib_desc_t; } crypto_lib_desc_t;
/* Public functions */ /* Public functions */
@ -54,6 +72,11 @@ int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
void *pk_ptr, unsigned int pk_len); void *pk_ptr, unsigned int pk_len);
int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len, int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
void *digest_info_ptr, unsigned int digest_info_len); void *digest_info_ptr, unsigned int digest_info_len);
int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
size_t len, const void *key, unsigned int key_len,
unsigned int key_flags, const void *iv,
unsigned int iv_len, const void *tag,
unsigned int tag_len);
#if MEASURED_BOOT #if MEASURED_BOOT
int crypto_mod_calc_hash(unsigned int alg, void *data_ptr, int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
@ -61,21 +84,24 @@ int crypto_mod_calc_hash(unsigned int alg, void *data_ptr,
/* Macro to register a cryptographic library */ /* Macro to register a cryptographic library */
#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \ #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
_calc_hash) \ _calc_hash, _auth_decrypt) \
const crypto_lib_desc_t crypto_lib_desc = { \ const crypto_lib_desc_t crypto_lib_desc = { \
.name = _name, \ .name = _name, \
.init = _init, \ .init = _init, \
.verify_signature = _verify_signature, \ .verify_signature = _verify_signature, \
.verify_hash = _verify_hash, \ .verify_hash = _verify_hash, \
.calc_hash = _calc_hash \ .calc_hash = _calc_hash, \
.auth_decrypt = _auth_decrypt \
} }
#else #else
#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash) \ #define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
_auth_decrypt) \
const crypto_lib_desc_t crypto_lib_desc = { \ const crypto_lib_desc_t crypto_lib_desc = { \
.name = _name, \ .name = _name, \
.init = _init, \ .init = _init, \
.verify_signature = _verify_signature, \ .verify_signature = _verify_signature, \
.verify_hash = _verify_hash \ .verify_hash = _verify_hash, \
.auth_decrypt = _auth_decrypt \
} }
#endif /* MEASURED_BOOT */ #endif /* MEASURED_BOOT */

View File

@ -79,6 +79,12 @@
#define MBEDTLS_X509_USE_C #define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C #define MBEDTLS_X509_CRT_PARSE_C
#if TF_MBEDTLS_USE_AES_GCM
#define MBEDTLS_AES_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_GCM_C
#endif
/* MPI / BIGNUM options */ /* MPI / BIGNUM options */
#define MBEDTLS_MPI_WINDOW_SIZE 2 #define MBEDTLS_MPI_WINDOW_SIZE 2

View File

@ -36,6 +36,15 @@ struct sp_res_desc;
ROTPK is not deployed */ ROTPK is not deployed */
#define ROTPK_NOT_DEPLOYED (1 << 1) #define ROTPK_NOT_DEPLOYED (1 << 1)
/*******************************************************************************
* plat_get_enc_key_info() flags
******************************************************************************/
/*
* Flag used to notify caller that information provided in key buffer is an
* identifier rather than an actual key.
*/
#define ENC_KEY_IS_IDENTIFIER (1 << 0)
/******************************************************************************* /*******************************************************************************
* Function declarations * Function declarations
******************************************************************************/ ******************************************************************************/

View File

@ -65,6 +65,9 @@ CTX_INCLUDE_PAUTH_REGS := 0
# Debug build # Debug build
DEBUG := 0 DEBUG := 0
# By default disable authenticated decryption support.
DECRYPTION_SUPPORT := none
# Build platform # Build platform
DEFAULT_PLAT := fvp DEFAULT_PLAT := fvp