Skip to content

Commit

Permalink
Merge pull request #8124 from yanrayw/support_cipher_encrypt_only
Browse files Browse the repository at this point in the history
Support the negative option MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
  • Loading branch information
daverodgman authored Nov 23, 2023
2 parents e490475 + 18040ed commit 8cd4bc4
Show file tree
Hide file tree
Showing 27 changed files with 495 additions and 122 deletions.
6 changes: 6 additions & 0 deletions ChangeLog.d/add-block-cipher-no-decrypt.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Features
* Enable the new option MBEDTLS_BLOCK_CIPHER_NO_DECRYPT to omit
the decryption direction of block ciphers (AES, ARIA, Camellia).
This affects both the low-level modules and the high-level APIs
(the cipher and PSA interfaces). This option is incompatible with modes
that use the decryption direction (ECB in PSA, CBC, XTS, KW) and with DES.
4 changes: 4 additions & 0 deletions include/mbedtls/aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits);

#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
/**
* \brief This function sets the decryption key.
*
Expand All @@ -173,6 +174,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits);
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

#if defined(MBEDTLS_CIPHER_MODE_XTS)
/**
Expand Down Expand Up @@ -592,6 +594,7 @@ int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16]);

#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
/**
* \brief Internal AES block decryption function. This is only
* exposed to allow overriding it using see
Expand All @@ -607,6 +610,7 @@ MBEDTLS_CHECK_RETURN_TYPICAL
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16]);
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

#if defined(MBEDTLS_SELF_TEST)
/**
Expand Down
2 changes: 2 additions & 0 deletions include/mbedtls/aria.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits);

#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
/**
* \brief This function sets the decryption key.
*
Expand All @@ -116,6 +117,7 @@ int mbedtls_aria_setkey_enc(mbedtls_aria_context *ctx,
int mbedtls_aria_setkey_dec(mbedtls_aria_context *ctx,
const unsigned char *key,
unsigned int keybits);
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

/**
* \brief This function performs an ARIA single-block encryption or
Expand Down
2 changes: 2 additions & 0 deletions include/mbedtls/camellia.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
const unsigned char *key,
unsigned int keybits);

#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
/**
* \brief Perform a CAMELLIA key schedule operation for decryption.
*
Expand All @@ -96,6 +97,7 @@ int mbedtls_camellia_setkey_enc(mbedtls_camellia_context *ctx,
int mbedtls_camellia_setkey_dec(mbedtls_camellia_context *ctx,
const unsigned char *key,
unsigned int keybits);
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

/**
* \brief Perform a CAMELLIA-ECB block encryption/decryption operation.
Expand Down
30 changes: 30 additions & 0 deletions include/mbedtls/check_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,36 @@
#error "MBEDTLS_NIST_KW_C defined, but not all prerequisites"
#endif

#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT) && defined(MBEDTLS_PSA_CRYPTO_CONFIG)
#if defined(PSA_WANT_ALG_CBC_NO_PADDING)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_NO_PADDING cannot be defined simultaneously"
#endif
#if defined(PSA_WANT_ALG_CBC_PKCS7)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_CBC_PKCS7 cannot be defined simultaneously"
#endif
#if defined(PSA_WANT_ALG_ECB_NO_PADDING)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_ALG_ECB_NO_PADDING cannot be defined simultaneously"
#endif
#if defined(PSA_WANT_KEY_TYPE_DES)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and PSA_WANT_KEY_TYPE_DES cannot be defined simultaneously"
#endif
#endif

#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_CBC cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_CIPHER_MODE_XTS)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_CIPHER_MODE_XTS cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_DES_C)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_DES_C cannot be defined simultaneously"
#endif
#if defined(MBEDTLS_NIST_KW_C)
#error "MBEDTLS_BLOCK_CIPHER_NO_DECRYPT and MBEDTLS_NIST_KW_C cannot be defined simultaneously"
#endif
#endif

#if defined(MBEDTLS_ECDH_C) && !defined(MBEDTLS_ECP_C)
#error "MBEDTLS_ECDH_C defined, but not all prerequisites"
#endif
Expand Down
19 changes: 19 additions & 0 deletions include/mbedtls/mbedtls_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -2374,6 +2374,25 @@
*/
#define MBEDTLS_BASE64_C

/**
* \def MBEDTLS_BLOCK_CIPHER_NO_DECRYPT
*
* Remove decryption operation for AES, ARIA and Camellia block cipher.
*
* \note This feature is incompatible with insecure block cipher,
* MBEDTLS_DES_C, and cipher modes which always require decryption
* operation, MBEDTLS_CIPHER_MODE_CBC, MBEDTLS_CIPHER_MODE_XTS and
* MBEDTLS_NIST_KW_C.
*
* Module: library/aes.c
* library/aesce.c
* library/aesni.c
* library/aria.c
* library/camellia.c
* library/cipher.c
*/
//#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT

/**
* \def MBEDTLS_BIGNUM_C
*
Expand Down
57 changes: 42 additions & 15 deletions library/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@

#include "mbedtls/platform.h"

/*
* This is a convenience shorthand macro to check if we need reverse S-box and
* reverse tables. It's private and only defined in this file.
*/
#if (!defined(MBEDTLS_AES_DECRYPT_ALT) || \
(!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))) && \
!defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
#define MBEDTLS_AES_NEED_REVERSE_TABLES
#endif

#if !defined(MBEDTLS_AES_ALT)

#if defined(MBEDTLS_VIA_PADLOCK_HAVE_CODE)
Expand Down Expand Up @@ -389,7 +399,9 @@ MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
* generate the forward and reverse S-boxes
*/
FSb[0x00] = 0x63;
#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
RSb[0x63] = 0x00;
#endif

for (i = 1; i < 256; i++) {
x = pow[255 - log[i]];
Expand All @@ -401,7 +413,9 @@ MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
x ^= y ^ 0x63;

FSb[i] = x;
#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
RSb[x] = (unsigned char) i;
#endif
}

/*
Expand All @@ -423,10 +437,9 @@ MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
FT3[i] = ROTL8(FT2[i]);
#endif /* !MBEDTLS_AES_FEWER_TABLES */

#if defined(MBEDTLS_AES_NEED_REVERSE_TABLES)
x = RSb[i];

#if !defined(MBEDTLS_AES_DECRYPT_ALT) || \
(!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY))
RT0[i] = ((uint32_t) MUL(0x0E, x)) ^
((uint32_t) MUL(0x09, x) << 8) ^
((uint32_t) MUL(0x0D, x) << 16) ^
Expand All @@ -437,8 +450,7 @@ MBEDTLS_MAYBE_UNUSED static void aes_gen_tables(void)
RT2[i] = ROTL8(RT1[i]);
RT3[i] = ROTL8(RT2[i]);
#endif /* !MBEDTLS_AES_FEWER_TABLES */
#endif \
/* !defined(MBEDTLS_AES_DECRYPT_ALT) || (!defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)) */
#endif /* MBEDTLS_AES_NEED_REVERSE_TABLES */
}
}

Expand Down Expand Up @@ -670,7 +682,7 @@ int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
/*
* AES key schedule (decryption)
*/
#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT)
#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
unsigned int keybits)
{
Expand Down Expand Up @@ -739,7 +751,7 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,

return ret;
}
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */
#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

#if defined(MBEDTLS_CIPHER_MODE_XTS)
static int mbedtls_aes_xts_decode_keys(const unsigned char *key,
Expand Down Expand Up @@ -928,7 +940,7 @@ int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
/*
* AES-ECB block decryption
*/
#if !defined(MBEDTLS_AES_DECRYPT_ALT)
#if !defined(MBEDTLS_AES_DECRYPT_ALT) && !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
const unsigned char input[16],
unsigned char output[16])
Expand Down Expand Up @@ -985,7 +997,7 @@ int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,

return 0;
}
#endif /* !MBEDTLS_AES_DECRYPT_ALT */
#endif /* !MBEDTLS_AES_DECRYPT_ALT && !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

/* VIA Padlock and our intrinsics-based implementation of AESNI require
* the round keys to be aligned on a 16-byte boundary. We take care of this
Expand Down Expand Up @@ -1040,13 +1052,15 @@ int mbedtls_aes_crypt_ecb(mbedtls_aes_context *ctx,
#endif

#if !defined(MBEDTLS_AES_USE_HARDWARE_ONLY)
if (mode == MBEDTLS_AES_ENCRYPT) {
return mbedtls_internal_aes_encrypt(ctx, input, output);
} else {
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
if (mode == MBEDTLS_AES_DECRYPT) {
return mbedtls_internal_aes_decrypt(ctx, input, output);
}
} else
#endif

{
return mbedtls_internal_aes_encrypt(ctx, input, output);
}
#endif /* !MBEDTLS_AES_USE_HARDWARE_ONLY */
}

#if defined(MBEDTLS_CIPHER_MODE_CBC)
Expand Down Expand Up @@ -1472,6 +1486,7 @@ int mbedtls_aes_crypt_ctr(mbedtls_aes_context *ctx,
*
* http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
*/
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
static const unsigned char aes_test_ecb_dec[][16] =
{
{ 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
Expand All @@ -1483,6 +1498,7 @@ static const unsigned char aes_test_ecb_dec[][16] =
0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
#endif
};
#endif

static const unsigned char aes_test_ecb_enc[][16] =
{
Expand Down Expand Up @@ -1864,7 +1880,7 @@ int mbedtls_aes_self_test(int verbose)
*/
{
static const int num_tests =
sizeof(aes_test_ecb_dec) / sizeof(*aes_test_ecb_dec);
sizeof(aes_test_ecb_enc) / sizeof(*aes_test_ecb_enc);

for (i = 0; i < num_tests << 1; i++) {
u = i >> 1;
Expand All @@ -1875,13 +1891,24 @@ int mbedtls_aes_self_test(int verbose)
mbedtls_printf(" AES-ECB-%3u (%s): ", keybits,
(mode == MBEDTLS_AES_DECRYPT) ? "dec" : "enc");
}
#if defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
if (mode == MBEDTLS_AES_DECRYPT) {
if (verbose != 0) {
mbedtls_printf("skipped\n");
}
continue;
}
#endif

memset(buf, 0, 16);

#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
if (mode == MBEDTLS_AES_DECRYPT) {
ret = mbedtls_aes_setkey_dec(&ctx, key, keybits);
aes_tests = aes_test_ecb_dec[u];
} else {
} else
#endif
{
ret = mbedtls_aes_setkey_enc(&ctx, key, keybits);
aes_tests = aes_test_ecb_enc[u];
}
Expand Down
15 changes: 12 additions & 3 deletions library/aesce.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ static uint8x16_t aesce_encrypt_block(uint8x16_t block,
/* Two rounds of AESCE decryption */
#define AESCE_DECRYPT_ROUND_X2 AESCE_DECRYPT_ROUND; AESCE_DECRYPT_ROUND

#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
static uint8x16_t aesce_decrypt_block(uint8x16_t block,
unsigned char *keys,
int rounds)
Expand Down Expand Up @@ -218,6 +219,7 @@ static uint8x16_t aesce_decrypt_block(uint8x16_t block,

return block;
}
#endif

/*
* AES-ECB block en(de)cryption
Expand All @@ -230,10 +232,15 @@ int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
uint8x16_t block = vld1q_u8(&input[0]);
unsigned char *keys = (unsigned char *) (ctx->buf + ctx->rk_offset);

if (mode == MBEDTLS_AES_ENCRYPT) {
block = aesce_encrypt_block(block, keys, ctx->nr);
} else {
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
if (mode == MBEDTLS_AES_DECRYPT) {
block = aesce_decrypt_block(block, keys, ctx->nr);
} else
#else
(void) mode;
#endif
{
block = aesce_encrypt_block(block, keys, ctx->nr);
}
vst1q_u8(&output[0], block);

Expand All @@ -243,6 +250,7 @@ int mbedtls_aesce_crypt_ecb(mbedtls_aes_context *ctx,
/*
* Compute decryption round keys from encryption round keys
*/
#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
void mbedtls_aesce_inverse_key(unsigned char *invkey,
const unsigned char *fwdkey,
int nr)
Expand All @@ -257,6 +265,7 @@ void mbedtls_aesce_inverse_key(unsigned char *invkey,
vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16));

}
#endif

static inline uint32_t aes_rot_word(uint32_t word)
{
Expand Down
2 changes: 2 additions & 0 deletions library/aesce.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ void mbedtls_aesce_gcm_mult(unsigned char c[16],
const unsigned char b[16]);


#if !defined(MBEDTLS_BLOCK_CIPHER_NO_DECRYPT)
/**
* \brief Internal round key inversion. This function computes
* decryption round keys from the encryption round keys.
Expand All @@ -98,6 +99,7 @@ void mbedtls_aesce_gcm_mult(unsigned char c[16],
void mbedtls_aesce_inverse_key(unsigned char *invkey,
const unsigned char *fwdkey,
int nr);
#endif /* !MBEDTLS_BLOCK_CIPHER_NO_DECRYPT */

/**
* \brief Internal key expansion for encryption
Expand Down
Loading

0 comments on commit 8cd4bc4

Please sign in to comment.