From 9cbcbc183d7d620448a882ab66aa952a06452c22 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 22 Oct 2017 13:07:41 +0000 Subject: Added capability for a fall-back crypto implementation. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10874 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/include/hal_crypto.h | 67 ++++++++-- os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c | 18 +-- os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h | 25 +--- os/hal/src/hal_crypto.c | 178 ++++++++++++++++++++----- os/hal/templates/hal_crypto_lld.h | 23 +--- 5 files changed, 223 insertions(+), 88 deletions(-) diff --git a/os/hal/include/hal_crypto.h b/os/hal/include/hal_crypto.h index 091bc0829..cc2ca5fdf 100644 --- a/os/hal/include/hal_crypto.h +++ b/os/hal/include/hal_crypto.h @@ -31,14 +31,42 @@ /* Driver constants. */ /*===========================================================================*/ +/** + * #brief Maximum size of a key for all supported algorithms. + */ +#define HAL_CRY_MAX_KEY_SIZE 32 + /*===========================================================================*/ /* Driver pre-compile time settings. */ /*===========================================================================*/ +/** + * @brief Enables the SW fall-back of the cryptographic driver. + * @details When enabled, this option, activates a fall-back software + * implementation for algorithms not supported by the underlying + * hardware. + * @note Fall-back implementations may not be present for all algorithms. + */ +#if !defined(HAL_CRY_USE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_USE_FALLBACK FALSE +#endif + +/** + * @brief Makes the driver forcibly use the fall-back implementations. + */ +#if !defined(HAL_CRY_ENFORCE_FALLBACK) || defined(__DOXYGEN__) +#define HAL_CRY_ENFORCE_FALLBACK FALSE +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ +#if HAL_CRY_ENFORCE_FALLBACK == TRUE +#undef HAL_CRY_USE_FALLBACK +#define HAL_CRY_USE_FALLBACK TRUE +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -74,7 +102,33 @@ typedef enum { cry_algo_tripledes } cryalgorithm_t; +#if HAL_CRY_ENFORCE_FALLBACK == FALSE +/* Use the defined low level driver.*/ #include "hal_crypto_lld.h" +#else +/* No LLD at all, using the standalone mode.*/ + +#define CRY_LLD_SUPPORTS_AES_ECB FALSE +#define CRY_LLD_SUPPORTS_AES_CBC FALSE +#define CRY_LLD_SUPPORTS_AES_CFB FALSE +#define CRY_LLD_SUPPORTS_AES_CTR FALSE + +typedef uint_fast8_t crykey_t; + +typedef struct CRYDriver CRYDriver; + +typedef struct { + uint32_t dummy; +} CRYConfig; + +struct CRYDriver { + crystate_t state; + const CRYConfig *config; + cryalgorithm_t key0_type; + size_t key0_size; + uint8_t key0_buffer[HAL_CRY_MAX_KEY_SIZE]; +}; +#endif #if !defined(CRY_LLD_SUPPORTS_AES_ECB) || \ !defined(CRY_LLD_SUPPORTS_AES_CBC) || \ @@ -104,13 +158,10 @@ extern "C" { void cryObjectInit(CRYDriver *cryp); void cryStart(CRYDriver *cryp, const CRYConfig *config); void cryStop(CRYDriver *cryp); - cryerror_t cryLoadTransientKey(CRYDriver *cryp, cryalgorithm_t algorithm, size_t size, const uint8_t *keyp); - -#if CRY_LLD_SUPPORTS_AES_ECB == TRUE cryerror_t cryEncryptAES_ECB(CRYDriver *cryp, crykey_t key_id, size_t size, @@ -121,9 +172,6 @@ extern "C" { size_t size, const uint8_t *in, uint8_t *out); -#endif /* CRY_LLD_SUPPORTS_AES_ECB == TRUE */ - -#if CRY_LLD_SUPPORTS_AES_CBC == TRUE cryerror_t cryEncryptAES_CBC(CRYDriver *cryp, crykey_t key_id, size_t size, @@ -136,9 +184,6 @@ extern "C" { const uint8_t *in, uint8_t *out, const uint8_t *iv); -#endif /* CRY_LLD_SUPPORTS_AES_CBC == TRUE */ - -#if CRY_LLD_SUPPORTS_AES_CFB == TRUE cryerror_t cryEncryptAES_CFB(CRYDriver *cryp, crykey_t key_id, size_t size, @@ -151,9 +196,6 @@ extern "C" { const uint8_t *in, uint8_t *out, const uint8_t *iv); -#endif /* CRY_LLD_SUPPORTS_AES_CFB == TRUE */ - -#if CRY_LLD_SUPPORTS_AES_CTR == TRUE cryerror_t cryEncryptAES_CTR(CRYDriver *cryp, crykey_t key_id, size_t size, @@ -168,7 +210,6 @@ extern "C" { uint8_t *out, const uint8_t *nonce, uint8_t *cnt); -#endif /* CRY_LLD_SUPPORTS_AES_CTR == TRUE */ #ifdef __cplusplus } #endif diff --git a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c index 9268e5398..f871ff4d4 100644 --- a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c +++ b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.c @@ -35,7 +35,7 @@ /*===========================================================================*/ /** @brief CRY1 driver identifier.*/ -#if PLATFORM_CRY_USE_CRY1 || defined(__DOXYGEN__) +#if STM32_CRY_USE_CRYP1 || defined(__DOXYGEN__) CRYDriver CRYD1; #endif @@ -151,7 +151,7 @@ cryerror_t cry_lld_encrypt_AES_ECB(CRYDriver *cryp, (void)in; (void)out; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -187,7 +187,7 @@ cryerror_t cry_lld_decrypt_AES_ECB(CRYDriver *cryp, (void)in; (void)out; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -226,7 +226,7 @@ cryerror_t cry_lld_encrypt_AES_CBC(CRYDriver *cryp, (void)out; (void)iv; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -265,7 +265,7 @@ cryerror_t cry_lld_decrypt_AES_CBC(CRYDriver *cryp, (void)out; (void)iv; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -304,7 +304,7 @@ cryerror_t cry_lld_encrypt_AES_CFB(CRYDriver *cryp, (void)out; (void)iv; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -343,7 +343,7 @@ cryerror_t cry_lld_decrypt_AES_CFB(CRYDriver *cryp, (void)out; (void)iv; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -385,7 +385,7 @@ cryerror_t cry_lld_encrypt_AES_CTR(CRYDriver *cryp, (void)nonce; (void)cnt; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } /** @@ -427,7 +427,7 @@ cryerror_t cry_lld_decrypt_AES_CTR(CRYDriver *cryp, (void)nonce; (void)cnt; - return CRY_NOERROR; + return CRY_ERR_INV_ALGO; } #endif /* HAL_USE_CRY == TRUE */ diff --git a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h index 2bc94b31d..4273340ad 100644 --- a/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h +++ b/os/hal/ports/STM32/LLD/CRYPv1/hal_crypto_lld.h @@ -37,7 +37,7 @@ */ #define CRY_LLD_SUPPORTS_AES_ECB TRUE #define CRY_LLD_SUPPORTS_AES_CBC TRUE -#define CRY_LLD_SUPPORTS_AES_CFB TRUE +#define CRY_LLD_SUPPORTS_AES_CFB FALSE #define CRY_LLD_SUPPORTS_AES_CTR TRUE /** @{ */ @@ -77,23 +77,6 @@ typedef uint32_t crykey_t; */ typedef struct CRYDriver CRYDriver; -/** - * @brief CRY notification callback type. - * - * @param[in] cryp pointer to the @p CRYDriver object triggering the - * callback - */ -typedef void (*crycallback_t)(CRYDriver *cryp); - -/** - * @brief CRY error callback type. - * - * @param[in] cryp pointer to the @p CRYDriver object triggering the - * callback - * @param[in] err CRY error code - */ -typedef void (*cryerrorcallback_t)(CRYDriver *cryp, cryerror_t err); - /** * @brief Driver configuration structure. * @note It could be empty on some architectures. @@ -122,6 +105,12 @@ struct CRYDriver { * @brief Size of transient key. */ size_t key0_size; +#if (HAL_CRY_USE_FALLBACK == TRUE) || defined(__DOXYGEN__) + /** + * @brief Key buffer for the fall-back implementation. + */ + uint8_t key0_buffer[HAL_CRY_MAX_KEY_SIZE]; +#endif #if defined(CRY_DRIVER_EXT_FIELDS) CRY_DRIVER_EXT_FIELDS #endif diff --git a/os/hal/src/hal_crypto.c b/os/hal/src/hal_crypto.c index 218d013c8..de516dc72 100644 --- a/os/hal/src/hal_crypto.c +++ b/os/hal/src/hal_crypto.c @@ -22,6 +22,8 @@ * @{ */ +#include + #include "hal.h" #if (HAL_USE_CRY == TRUE) || defined(__DOXYGEN__) @@ -47,7 +49,7 @@ /*===========================================================================*/ /** - * @brief Crypto Driver initialization. + * @brief Cryptographic Driver initialization. * @note This function is implicitly invoked by @p halInit(), there is * no need to explicitly initialize the driver. * @@ -55,7 +57,9 @@ */ void cryInit(void) { +#if HAL_CRY_ENFORCE_FALLBACK == FALSE cry_lld_init(); +#endif } /** @@ -75,7 +79,7 @@ void cryObjectInit(CRYDriver *cryp) { } /** - * @brief Configures and activates the CRY peripheral. + * @brief Configures and activates the cryptographic peripheral. * * @param[in] cryp pointer to the @p CRYDriver object * @param[in] config pointer to the @p CRYConfig object. Depending on @@ -91,13 +95,15 @@ void cryStart(CRYDriver *cryp, const CRYConfig *config) { osalDbgAssert((cryp->state == CRY_STOP) || (cryp->state == CRY_READY), "invalid state"); cryp->config = config; +#if HAL_CRY_ENFORCE_FALLBACK == FALSE cry_lld_start(cryp); +#endif cryp->state = CRY_READY; osalSysUnlock(); } /** - * @brief Deactivates the CRY peripheral. + * @brief Deactivates the cryptographic peripheral. * * @param[in] cryp pointer to the @p CRYDriver object * @@ -112,7 +118,9 @@ void cryStop(CRYDriver *cryp) { osalDbgAssert((cryp->state == CRY_STOP) || (cryp->state == CRY_READY), "invalid state"); +#if HAL_CRY_ENFORCE_FALLBACK == FALSE cry_lld_stop(cryp); +#endif cryp->config = NULL; cryp->state = CRY_STOP; @@ -140,21 +148,32 @@ cryerror_t cryLoadTransientKey(CRYDriver *cryp, const uint8_t *keyp) { cryerror_t err; - /* Storing the transient key metadata.*/ - cryp->key0_type = algorithm; - cryp->key0_size = size; + osalDbgCheck((cryp != NULL) && (size <= HAL_CRY_MAX_KEY_SIZE) && + (keyp != NULL)); + +#if HAL_CRY_ENFORCE_FALLBACK == FALSE /* Key setup in the low level driver.*/ err = cry_lld_loadkey(cryp, algorithm, size, keyp); - if (err != CRY_NOERROR) { - cryp->key0_type = cry_algo_none; - cryp->key0_size = (size_t)0; +#else + err = CRY_ERR_INV_ALGO; +#endif + +#if HAL_CRY_USE_FALLBACK == TRUE + if (err == CRY_ERR_INV_ALGO) { + err = cry_fallback_loadkey(cryp, algorithm, size, keyp); + } +#endif + + if (err == CRY_NOERROR) { + /* Storing the transient key info.*/ + cryp->key0_type = algorithm; + cryp->key0_size = size; } return err; } -#if (CRY_LLD_SUPPORTS_AES_ECB == TRUE) || defined(__DOXYGEN__) /** * @brief Encryption operation using AES-ECB. * @@ -182,12 +201,24 @@ cryerror_t cryEncryptAES_ECB(CRYDriver *cryp, const uint8_t *in, uint8_t *out) { - osalDbgCheck((in != NULL) && (out != NULL) && + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); +#if CRY_LLD_SUPPORTS_AES_ECB == TRUE return cry_lld_encrypt_AES_ECB(cryp, key_id, size, in, out); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_encrypt_AES_ECB(cryp, key_id, size, in, out); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + + return CRY_ERR_INV_ALGO; +#endif } /** @@ -217,16 +248,26 @@ cryerror_t cryDecryptAES_ECB(CRYDriver *cryp, const uint8_t *in, uint8_t *out) { - osalDbgCheck((in != NULL) && (out != NULL) && + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); +#if CRY_LLD_SUPPORTS_AES_ECB == TRUE return cry_lld_decrypt_AES_ECB(cryp, key_id, size, in, out); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_decrypt_AES_ECB(cryp, key_id, size, in, out); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + + return CRY_ERR_INV_ALGO; +#endif } -#endif /* CRY_LLD_SUPPORTS_AES_ECB == TRUE */ -#if (CRY_LLD_SUPPORTS_AES_CBC == TRUE) || defined(__DOXYGEN__) /** * @brief Encryption operation using AES-CBC. * @@ -256,12 +297,25 @@ cryerror_t cryEncryptAES_CBC(CRYDriver *cryp, uint8_t *out, const uint8_t *iv) { - osalDbgCheck((in != NULL) && (out != NULL) && (iv != NULL) && - ((size & (size_t)15) == (size_t)0)); + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && + (iv != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); +#if CRY_LLD_SUPPORTS_AES_CBC == TRUE return cry_lld_encrypt_AES_CBC(cryp, key_id, size, in, out, iv); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_encrypt_AES_CBC(cryp, key_id, size, in, out, iv); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)iv; + + return CRY_ERR_INV_ALGO; +#endif } /** @@ -293,16 +347,27 @@ cryerror_t cryDecryptAES_CBC(CRYDriver *cryp, uint8_t *out, const uint8_t *iv) { - osalDbgCheck((in != NULL) && (out != NULL) && (iv != NULL) && - ((size & (size_t)15) == (size_t)0)); + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && + (iv != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); +#if CRY_LLD_SUPPORTS_AES_CBC == TRUE return cry_lld_decrypt_AES_CBC(cryp, key_id, size, in, out, iv); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_decrypt_AES_CBC(cryp, key_id, size, in, out, iv); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)iv; + + return CRY_ERR_INV_ALGO; +#endif } -#endif /* CRY_LLD_SUPPORTS_AES_CBC == TRUE */ -#if (CRY_LLD_SUPPORTS_AES_CFB == TRUE) || defined(__DOXYGEN__) /** * @brief Encryption operation using AES-CFB. * @@ -332,12 +397,25 @@ cryerror_t cryEncryptAES_CFB(CRYDriver *cryp, uint8_t *out, const uint8_t *iv) { - osalDbgCheck((in != NULL) && (out != NULL) && (iv != NULL) && - ((size & (size_t)15) == (size_t)0)); + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && + (iv != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); - return cry_lld_encrypt_AES_CBC(cryp, key_id, size, in, out, iv); +#if CRY_LLD_SUPPORTS_AES_CFB == TRUE + return cry_lld_encrypt_AES_CFB(cryp, key_id, size, in, out, iv); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_encrypt_AES_CFB(cryp, key_id, size, in, out, iv); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)iv; + + return CRY_ERR_INV_ALGO; +#endif } /** @@ -369,16 +447,27 @@ cryerror_t cryDecryptAES_CFB(CRYDriver *cryp, uint8_t *out, const uint8_t *iv) { - osalDbgCheck((in != NULL) && (out != NULL) && (iv != NULL) && - ((size & (size_t)15) == (size_t)0)); + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && + (iv != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); - return cry_lld_decrypt_AES_CBC(cryp, key_id, size, in, out, iv); +#if CRY_LLD_SUPPORTS_AES_CFB == TRUE + return cry_lld_decrypt_AES_CFB(cryp, key_id, size, in, out, iv); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_decrypt_AES_CFB(cryp, key_id, size, in, out, iv); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)iv; + + return CRY_ERR_INV_ALGO; +#endif } -#endif /* CRY_LLD_SUPPORTS_AES_CFB == TRUE */ -#if (CRY_LLD_SUPPORTS_AES_CTR == TRUE) || defined(__DOXYGEN__) /** * @brief Encryption operation using AES-CTR. * @@ -410,13 +499,27 @@ cryerror_t cryEncryptAES_CTR(CRYDriver *cryp, const uint8_t *nonce, uint8_t *cnt) { - osalDbgCheck((in != NULL) && (out != NULL) && + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && (nonce != NULL) && (cnt != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); +#if CRY_LLD_SUPPORTS_AES_CTR == TRUE return cry_lld_encrypt_AES_CTR(cryp, key_id, size, in, out, nonce, cnt); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_encrypt_AES_CTR(cryp, key_id, size, in, out, nonce, cnt); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)nonce; + (void)cnt; + + return CRY_ERR_INV_ALGO; +#endif } /** @@ -450,15 +553,28 @@ cryerror_t cryDecryptAES_CTR(CRYDriver *cryp, const uint8_t *nonce, uint8_t *cnt) { - osalDbgCheck((in != NULL) && (out != NULL) && + osalDbgCheck((cryp != NULL) && (in != NULL) && (out != NULL) && (nonce != NULL) && (cnt != NULL) && ((size & (size_t)15) == (size_t)0)); osalDbgAssert(cryp->state == CRY_READY, "not ready"); +#if CRY_LLD_SUPPORTS_AES_CTR == TRUE return cry_lld_decrypt_AES_CTR(cryp, key_id, size, in, out, nonce, cnt); +#elif HAL_CRY_USE_FALLBACK == TRUE + return cry_fallback_decrypt_AES_CTR(cryp, key_id, size, in, out, nonce, cnt); +#else + (void)cryp; + (void)key_id; + (void)size; + (void)in; + (void)out; + (void)nonce; + (void)cnt; + + return CRY_ERR_INV_ALGO; +#endif } -#endif /* CRY_LLD_SUPPORTS_AES_CTR == TRUE */ #endif /* HAL_USE_CRY == TRUE */ diff --git a/os/hal/templates/hal_crypto_lld.h b/os/hal/templates/hal_crypto_lld.h index 53046d814..05aa5566d 100644 --- a/os/hal/templates/hal_crypto_lld.h +++ b/os/hal/templates/hal_crypto_lld.h @@ -77,23 +77,6 @@ typedef uint32_t crykey_t; */ typedef struct CRYDriver CRYDriver; -/** - * @brief CRY notification callback type. - * - * @param[in] cryp pointer to the @p CRYDriver object triggering the - * callback - */ -typedef void (*crycallback_t)(CRYDriver *cryp); - -/** - * @brief CRY error callback type. - * - * @param[in] cryp pointer to the @p CRYDriver object triggering the - * callback - * @param[in] err CRY error code - */ -typedef void (*cryerrorcallback_t)(CRYDriver *cryp, cryerror_t err); - /** * @brief Driver configuration structure. * @note It could be empty on some architectures. @@ -122,6 +105,12 @@ struct CRYDriver { * @brief Size of transient key. */ size_t key0_size; +#if (HAL_CRY_USE_FALLBACK == TRUE) || defined(__DOXYGEN__) + /** + * @brief Key buffer for the fall-back implementation. + */ + uint8_t key0_buffer[HAL_CRY_MAX_KEY_SIZE]; +#endif #if defined(CRY_DRIVER_EXT_FIELDS) CRY_DRIVER_EXT_FIELDS #endif -- cgit v1.2.3