mirror of
https://github.com/CTCaer/switch-l4t-atf.git
synced 2024-11-24 02:09:46 +00:00
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:
parent
d95f7a7287
commit
7cda17bb0f
11
Makefile
11
Makefile
@ -623,7 +623,7 @@ endif
|
||||
|
||||
ifeq ($(MEASURED_BOOT),1)
|
||||
ifneq (${TRUSTED_BOARD_BOOT},1)
|
||||
$(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1")
|
||||
$(error MEASURED_BOOT requires TRUSTED_BOARD_BOOT=1)
|
||||
else
|
||||
$(info MEASURED_BOOT is an experimental feature)
|
||||
endif
|
||||
@ -635,6 +635,14 @@ ifeq (${ARM_XLAT_TABLES_LIB_V1}, 1)
|
||||
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
|
||||
################################################################################
|
||||
@ -843,6 +851,7 @@ $(eval $(call add_define,CTX_INCLUDE_PAUTH_REGS))
|
||||
$(eval $(call add_define,EL3_EXCEPTION_HANDLING))
|
||||
$(eval $(call add_define,CTX_INCLUDE_MTE_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_ASSERTIONS))
|
||||
$(eval $(call add_define,ENABLE_BTI))
|
||||
|
@ -160,6 +160,12 @@ Common build options
|
||||
- ``DEBUG``: Chooses between a debug and release build. It can take either 0
|
||||
(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
|
||||
of the binary image. If set to 1, then only the ELF image is built.
|
||||
0 is the default.
|
||||
|
@ -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);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
@ -301,5 +301,5 @@ static int verify_hash(void *data_ptr, unsigned int data_len,
|
||||
/*
|
||||
* 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);
|
||||
|
||||
|
@ -23,13 +23,17 @@ MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c
|
||||
|
||||
|
||||
LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \
|
||||
aes.c \
|
||||
asn1parse.c \
|
||||
asn1write.c \
|
||||
cipher.c \
|
||||
cipher_wrap.c \
|
||||
memory_buffer_alloc.c \
|
||||
oid.c \
|
||||
platform.c \
|
||||
platform_util.c \
|
||||
bignum.c \
|
||||
gcm.c \
|
||||
md.c \
|
||||
md_wrap.c \
|
||||
pk.c \
|
||||
@ -87,11 +91,17 @@ else
|
||||
$(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS")
|
||||
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
|
||||
$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
|
||||
$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE))
|
||||
$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
|
||||
|
||||
$(eval $(call add_define,TF_MBEDTLS_USE_AES_GCM))
|
||||
|
||||
$(eval $(call MAKE_LIB,mbedtls))
|
||||
|
||||
|
@ -4,10 +4,12 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/* mbed TLS headers */
|
||||
#include <mbedtls/gcm.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/memory_buffer_alloc.h>
|
||||
#include <mbedtls/oid.h>
|
||||
@ -17,6 +19,7 @@
|
||||
#include <drivers/auth/crypto_mod.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_common.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_config.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#define LIB_NAME "mbed TLS"
|
||||
|
||||
@ -226,11 +229,121 @@ int calc_hash(unsigned int alg, void *data_ptr,
|
||||
}
|
||||
#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
|
||||
*/
|
||||
#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
|
||||
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 */
|
||||
|
@ -13,9 +13,18 @@ enum crypto_ret_value {
|
||||
CRYPTO_ERR_INIT,
|
||||
CRYPTO_ERR_HASH,
|
||||
CRYPTO_ERR_SIGNATURE,
|
||||
CRYPTO_ERR_DECRYPTION,
|
||||
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
|
||||
*/
|
||||
@ -44,6 +53,15 @@ typedef struct crypto_lib_desc_s {
|
||||
unsigned int data_len, unsigned char *output);
|
||||
#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;
|
||||
|
||||
/* 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);
|
||||
int crypto_mod_verify_hash(void *data_ptr, unsigned int data_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
|
||||
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 */
|
||||
#define REGISTER_CRYPTO_LIB(_name, _init, _verify_signature, _verify_hash, \
|
||||
_calc_hash) \
|
||||
_calc_hash, _auth_decrypt) \
|
||||
const crypto_lib_desc_t crypto_lib_desc = { \
|
||||
.name = _name, \
|
||||
.init = _init, \
|
||||
.verify_signature = _verify_signature, \
|
||||
.verify_hash = _verify_hash, \
|
||||
.calc_hash = _calc_hash \
|
||||
.calc_hash = _calc_hash, \
|
||||
.auth_decrypt = _auth_decrypt \
|
||||
}
|
||||
#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 = { \
|
||||
.name = _name, \
|
||||
.init = _init, \
|
||||
.verify_signature = _verify_signature, \
|
||||
.verify_hash = _verify_hash \
|
||||
.verify_hash = _verify_hash, \
|
||||
.auth_decrypt = _auth_decrypt \
|
||||
}
|
||||
#endif /* MEASURED_BOOT */
|
||||
|
||||
|
@ -79,6 +79,12 @@
|
||||
#define MBEDTLS_X509_USE_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 */
|
||||
#define MBEDTLS_MPI_WINDOW_SIZE 2
|
||||
|
||||
|
@ -36,6 +36,15 @@ struct sp_res_desc;
|
||||
ROTPK is not deployed */
|
||||
#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
|
||||
******************************************************************************/
|
||||
|
@ -65,6 +65,9 @@ CTX_INCLUDE_PAUTH_REGS := 0
|
||||
# Debug build
|
||||
DEBUG := 0
|
||||
|
||||
# By default disable authenticated decryption support.
|
||||
DECRYPTION_SUPPORT := none
|
||||
|
||||
# Build platform
|
||||
DEFAULT_PLAT := fvp
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user