From e4daf77c2e050617ecba19351a2284c3b70547ca Mon Sep 17 00:00:00 2001 From: Jaeden Amero Date: Mon, 30 Apr 2018 17:17:41 +0100 Subject: [PATCH] cipher: Add wrappers for AES-XTS AES-XTS does not support multipart use as it can only operate on an entire sector at a time. --- include/mbedtls/cipher.h | 6 +- include/mbedtls/cipher_internal.h | 7 ++ library/cipher.c | 22 ++++ library/cipher_wrap.c | 150 ++++++++++++++++++++++++ tests/suites/test_suite_cipher.aes.data | 64 ++++++++++ 5 files changed, 248 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/cipher.h b/include/mbedtls/cipher.h index 3ee2ab7db..278939361 100644 --- a/include/mbedtls/cipher.h +++ b/include/mbedtls/cipher.h @@ -145,6 +145,8 @@ typedef enum { MBEDTLS_CIPHER_CAMELLIA_128_CCM, /**< Camellia cipher with 128-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_192_CCM, /**< Camellia cipher with 192-bit CCM mode. */ MBEDTLS_CIPHER_CAMELLIA_256_CCM, /**< Camellia cipher with 256-bit CCM mode. */ + MBEDTLS_CIPHER_AES_128_XTS, /**< AES 128-bit cipher in XTS block mode. */ + MBEDTLS_CIPHER_AES_256_XTS, /**< AES 256-bit cipher in XTS block mode. */ } mbedtls_cipher_type_t; /** Supported cipher modes. */ @@ -158,6 +160,7 @@ typedef enum { MBEDTLS_MODE_GCM, /**< The GCM cipher mode. */ MBEDTLS_MODE_STREAM, /**< The stream cipher mode. */ MBEDTLS_MODE_CCM, /**< The CCM cipher mode. */ + MBEDTLS_MODE_XTS, /**< The XTS cipher mode. */ } mbedtls_cipher_mode_t; /** Supported cipher padding types. */ @@ -273,7 +276,8 @@ typedef struct { /** Number of Bytes that have not been processed yet. */ size_t unprocessed_len; - /** Current IV or NONCE_COUNTER for CTR-mode. */ + /** Current IV or NONCE_COUNTER for CTR-mode, data unit (or sector) number + * for XTS-mode. */ unsigned char iv[MBEDTLS_MAX_IV_LENGTH]; /** IV size in Bytes, for ciphers with variable-length IVs. */ diff --git a/include/mbedtls/cipher_internal.h b/include/mbedtls/cipher_internal.h index 969ff9ccb..d4c7a596c 100644 --- a/include/mbedtls/cipher_internal.h +++ b/include/mbedtls/cipher_internal.h @@ -71,6 +71,13 @@ struct mbedtls_cipher_base_t const unsigned char *input, unsigned char *output ); #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + /** Encrypt using XTS */ + int (*xts_func)( void *ctx, mbedtls_operation_t mode, size_t length, + const unsigned char data_unit[16], + const unsigned char *input, unsigned char *output ); +#endif + #if defined(MBEDTLS_CIPHER_MODE_STREAM) /** Encrypt using STREAM */ int (*stream_func)( void *ctx, size_t length, diff --git a/library/cipher.c b/library/cipher.c index a5cd61cdf..4f12b72ee 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -440,6 +440,27 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i } #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) + if( ctx->cipher_info->mode == MBEDTLS_MODE_XTS ) + { + if ( ctx->unprocessed_len ) { + /* We can only process an entire sector at a time. */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + ret = ctx->cipher_info->base->xts_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ); + if( ret != 0 ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #if defined(MBEDTLS_CIPHER_MODE_STREAM) if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) { @@ -641,6 +662,7 @@ int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || MBEDTLS_MODE_CTR == ctx->cipher_info->mode || MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_XTS == ctx->cipher_info->mode || MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) { return( 0 ); diff --git a/library/cipher_wrap.c b/library/cipher_wrap.c index dc76af8ff..070f1d820 100644 --- a/library/cipher_wrap.c +++ b/library/cipher_wrap.c @@ -148,6 +148,33 @@ static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, } #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int aes_crypt_xts_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, + const unsigned char data_unit[16], + const unsigned char *input, + unsigned char *output ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + int mode; + + switch (operation) + { + case MBEDTLS_ENCRYPT: + mode = MBEDTLS_AES_ENCRYPT; + break; + case MBEDTLS_DECRYPT: + mode = MBEDTLS_AES_DECRYPT; + break; + default: + return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA; + } + + return mbedtls_aes_crypt_xts( xts_ctx, mode, length, + data_unit, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, unsigned int key_bitlen ) { @@ -190,6 +217,9 @@ static const mbedtls_cipher_base_t aes_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) aes_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -337,6 +367,89 @@ static const mbedtls_cipher_info_t aes_256_ctr_info = { }; #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_MODE_XTS) +static int xts_aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return( mbedtls_aes_xts_setkey_enc( xts_ctx, key, key_bitlen ) ); +} + +static int xts_aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + return( mbedtls_aes_xts_setkey_dec( xts_ctx, key, key_bitlen ) ); +} + +static void *xts_aes_ctx_alloc( void ) +{ + mbedtls_aes_xts_context *xts_ctx = mbedtls_calloc( 1, sizeof( *xts_ctx ) ); + + if( xts_ctx ) + mbedtls_aes_xts_init( xts_ctx ); + + return( xts_ctx ); +} + +static void xts_aes_ctx_free( void *ctx ) +{ + mbedtls_aes_xts_context *xts_ctx = ctx; + + if ( !xts_ctx ) + return; + + mbedtls_aes_xts_free( xts_ctx ); + mbedtls_free( xts_ctx ); +} + +static const mbedtls_cipher_base_t xts_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + aes_crypt_xts_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + xts_aes_setkey_enc_wrap, + xts_aes_setkey_dec_wrap, + xts_aes_ctx_alloc, + xts_aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_xts_info = { + MBEDTLS_CIPHER_AES_128_XTS, + MBEDTLS_MODE_XTS, + 256, + "AES-128-XTS", + 16, + 0, + 16, + &xts_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_xts_info = { + MBEDTLS_CIPHER_AES_256_XTS, + MBEDTLS_MODE_XTS, + 512, + "AES-256-XTS", + 16, + 0, + 16, + &xts_aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_XTS */ + #if defined(MBEDTLS_GCM_C) static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, unsigned int key_bitlen ) @@ -357,6 +470,9 @@ static const mbedtls_cipher_base_t gcm_aes_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -420,6 +536,9 @@ static const mbedtls_cipher_base_t ccm_aes_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -547,6 +666,9 @@ static const mbedtls_cipher_base_t camellia_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) camellia_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -714,6 +836,9 @@ static const mbedtls_cipher_base_t gcm_camellia_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -777,6 +902,9 @@ static const mbedtls_cipher_base_t ccm_camellia_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -953,6 +1081,9 @@ static const mbedtls_cipher_base_t des_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -998,6 +1129,9 @@ static const mbedtls_cipher_base_t des_ede_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -1043,6 +1177,9 @@ static const mbedtls_cipher_base_t des_ede3_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -1152,6 +1289,9 @@ static const mbedtls_cipher_base_t blowfish_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) blowfish_crypt_ctr_wrap, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) NULL, #endif @@ -1262,6 +1402,9 @@ static const mbedtls_cipher_base_t arc4_base_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) arc4_crypt_stream_wrap, #endif @@ -1325,6 +1468,9 @@ static const mbedtls_cipher_base_t null_base_info = { #if defined(MBEDTLS_CIPHER_MODE_CTR) NULL, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + NULL, +#endif #if defined(MBEDTLS_CIPHER_MODE_STREAM) null_crypt_stream, #endif @@ -1367,6 +1513,10 @@ const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, #endif +#if defined(MBEDTLS_CIPHER_MODE_XTS) + { MBEDTLS_CIPHER_AES_128_XTS, &aes_128_xts_info }, + { MBEDTLS_CIPHER_AES_256_XTS, &aes_256_xts_info }, +#endif #if defined(MBEDTLS_GCM_C) { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, diff --git a/tests/suites/test_suite_cipher.aes.data b/tests/suites/test_suite_cipher.aes.data index 6e15be2a7..4742251d6 100644 --- a/tests/suites/test_suite_cipher.aes.data +++ b/tests/suites/test_suite_cipher.aes.data @@ -474,6 +474,70 @@ AES-128 CFB - Encrypt and decrypt 32 bytes in multiple parts 1 depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CFB enc_dec_buf_multipart:MBEDTLS_CIPHER_AES_128_CFB128:128:16:16:-1:16:16:16:16 +AES-128 XTS - Encrypt and decrypt 16 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:16:-1 + +AES-128 XTS - Encrypt and decrypt 17 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:17:-1 + +AES-128 XTS - Encrypt and decrypt 31 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:31:-1 + +AES-128 XTS - Encrypt and decrypt 32 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:32:-1 + +AES-128 XTS - Encrypt and decrypt 33 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:33:-1 + +AES-128 XTS - Encrypt and decrypt 47 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:47:-1 + +AES-128 XTS - Encrypt and decrypt 48 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:48:-1 + +AES-128 XTS - Encrypt and decrypt 49 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_128_XTS:"AES-128-XTS":256:49:-1 + +AES-256 XTS - Encrypt and decrypt 16 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:16:-1 + +AES-256 XTS - Encrypt and decrypt 17 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:17:-1 + +AES-256 XTS - Encrypt and decrypt 31 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:31:-1 + +AES-256 XTS - Encrypt and decrypt 32 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:32:-1 + +AES-256 XTS - Encrypt and decrypt 33 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:33:-1 + +AES-256 XTS - Encrypt and decrypt 47 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:47:-1 + +AES-256 XTS - Encrypt and decrypt 48 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:48:-1 + +AES-256 XTS - Encrypt and decrypt 49 bytes +depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_XTS +enc_dec_buf:MBEDTLS_CIPHER_AES_256_XTS:"AES-256-XTS":512:49:-1 + AES-128 CTR - Encrypt and decrypt 0 bytes depends_on:MBEDTLS_AES_C:MBEDTLS_CIPHER_MODE_CTR enc_dec_buf:MBEDTLS_CIPHER_AES_128_CTR:"AES-128-CTR":128:0:-1