1
0
mirror of https://github.com/ARMmbed/mbedtls.git synced 2025-05-09 16:41:19 +08:00

Merge pull request #8540 from valeriosetti/issue8060

[G2] Make CCM and GCM work with the new block_cipher module
This commit is contained in:
Manuel Pégourié-Gonnard 2023-11-28 08:18:45 +00:00 committed by GitHub
commit 294f5d7ea9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 134 additions and 35 deletions

4
ChangeLog.d/8060.txt Normal file
View File

@ -0,0 +1,4 @@
Features
* The CCM and GCM modules no longer depend on MBEDTLS_CIPHER_C. People who
use CCM and GCM but don't need the Cipher API can now disable
MBEDTLS_CIPHER_C in order to save code size.

View File

@ -40,6 +40,10 @@
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#if !defined(MBEDTLS_CIPHER_C)
#include "mbedtls/block_cipher.h"
#endif
#define MBEDTLS_CCM_DECRYPT 0 #define MBEDTLS_CCM_DECRYPT 0
#define MBEDTLS_CCM_ENCRYPT 1 #define MBEDTLS_CCM_ENCRYPT 1
#define MBEDTLS_CCM_STAR_DECRYPT 2 #define MBEDTLS_CCM_STAR_DECRYPT 2
@ -80,7 +84,11 @@ typedef struct mbedtls_ccm_context {
#MBEDTLS_CCM_DECRYPT or #MBEDTLS_CCM_DECRYPT or
#MBEDTLS_CCM_STAR_ENCRYPT or #MBEDTLS_CCM_STAR_ENCRYPT or
#MBEDTLS_CCM_STAR_DECRYPT. */ #MBEDTLS_CCM_STAR_DECRYPT. */
#if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
#else
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
#endif
int MBEDTLS_PRIVATE(state); /*!< Working value holding context's int MBEDTLS_PRIVATE(state); /*!< Working value holding context's
state. Used for chunked data input */ state. Used for chunked data input */
} }

View File

@ -336,19 +336,11 @@
#error "MBEDTLS_CCM_C defined, but not all prerequisites" #error "MBEDTLS_CCM_C defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_CCM_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_CCM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_GCM_C) && ( \ #if defined(MBEDTLS_GCM_C) && ( \
!defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) ) !defined(MBEDTLS_AES_C) && !defined(MBEDTLS_CAMELLIA_C) && !defined(MBEDTLS_ARIA_C) )
#error "MBEDTLS_GCM_C defined, but not all prerequisites" #error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif #endif
#if defined(MBEDTLS_GCM_C) && !defined(MBEDTLS_CIPHER_C)
#error "MBEDTLS_GCM_C defined, but not all prerequisites"
#endif
#if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C) #if defined(MBEDTLS_CHACHAPOLY_C) && !defined(MBEDTLS_CHACHA20_C)
#error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites" #error "MBEDTLS_CHACHAPOLY_C defined, but not all prerequisites"
#endif #endif

View File

@ -22,8 +22,8 @@
#ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H #ifndef MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
#define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H #define MBEDTLS_CONFIG_ADJUST_LEGACY_CRYPTO_H
/* Temporary hack to pacify check_names.py. /* GCM_C and CCM_C can either depend on (in order of preference) CIPHER_C or
* (GCM and CCM still hard-depend on CIPHER_C for now.) */ * BLOCK_CIPHER_C. If the former is not defined, auto-enable the latter. */
#if (defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)) && \ #if (defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C)) && \
!defined(MBEDTLS_CIPHER_C) !defined(MBEDTLS_CIPHER_C)
#define MBEDTLS_BLOCK_CIPHER_C #define MBEDTLS_BLOCK_CIPHER_C

View File

@ -24,6 +24,10 @@
#include "mbedtls/cipher.h" #include "mbedtls/cipher.h"
#if !defined(MBEDTLS_CIPHER_C)
#include "mbedtls/block_cipher.h"
#endif
#include <stdint.h> #include <stdint.h>
#define MBEDTLS_GCM_ENCRYPT 1 #define MBEDTLS_GCM_ENCRYPT 1
@ -46,7 +50,11 @@ extern "C" {
* \brief The GCM context structure. * \brief The GCM context structure.
*/ */
typedef struct mbedtls_gcm_context { typedef struct mbedtls_gcm_context {
#if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */ mbedtls_cipher_context_t MBEDTLS_PRIVATE(cipher_ctx); /*!< The cipher context used. */
#else
mbedtls_block_cipher_context_t MBEDTLS_PRIVATE(block_cipher_ctx); /*!< The cipher context used. */
#endif
uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */ uint64_t MBEDTLS_PRIVATE(HL)[16]; /*!< Precalculated HTable low. */
uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */ uint64_t MBEDTLS_PRIVATE(HH)[16]; /*!< Precalculated HTable high. */
uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */ uint64_t MBEDTLS_PRIVATE(len); /*!< The total length of the encrypted data. */

View File

@ -23,6 +23,10 @@
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbedtls/constant_time.h" #include "mbedtls/constant_time.h"
#if !defined(MBEDTLS_CIPHER_C)
#include "block_cipher_internal.h"
#endif
#include <string.h> #include <string.h>
#if defined(MBEDTLS_PLATFORM_C) #if defined(MBEDTLS_PLATFORM_C)
@ -51,6 +55,8 @@ int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx,
unsigned int keybits) unsigned int keybits)
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
#if defined(MBEDTLS_CIPHER_C)
const mbedtls_cipher_info_t *cipher_info; const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
@ -73,6 +79,17 @@ int mbedtls_ccm_setkey(mbedtls_ccm_context *ctx,
MBEDTLS_ENCRYPT)) != 0) { MBEDTLS_ENCRYPT)) != 0) {
return ret; return ret;
} }
#else
mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
return MBEDTLS_ERR_CCM_BAD_INPUT;
}
if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
return MBEDTLS_ERR_CCM_BAD_INPUT;
}
#endif
return 0; return 0;
} }
@ -85,7 +102,11 @@ void mbedtls_ccm_free(mbedtls_ccm_context *ctx)
if (ctx == NULL) { if (ctx == NULL) {
return; return;
} }
#if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_free(&ctx->cipher_ctx); mbedtls_cipher_free(&ctx->cipher_ctx);
#else
mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
#endif
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ccm_context)); mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ccm_context));
} }
@ -104,12 +125,16 @@ static int mbedtls_ccm_crypt(mbedtls_ccm_context *ctx,
const unsigned char *input, const unsigned char *input,
unsigned char *output) unsigned char *output)
{ {
size_t olen = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char tmp_buf[16] = { 0 }; unsigned char tmp_buf[16] = { 0 };
if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->ctr, 16, tmp_buf, #if defined(MBEDTLS_CIPHER_C)
&olen)) != 0) { size_t olen = 0;
ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->ctr, 16, tmp_buf, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->ctr, tmp_buf);
#endif
if (ret != 0) {
ctx->state |= CCM_STATE__ERROR; ctx->state |= CCM_STATE__ERROR;
mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf)); mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf));
return ret; return ret;
@ -132,7 +157,10 @@ static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx)
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char i; unsigned char i;
size_t len_left, olen; size_t len_left;
#if defined(MBEDTLS_CIPHER_C)
size_t olen;
#endif
/* length calculation can be done only after both /* length calculation can be done only after both
* mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed * mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed
@ -178,7 +206,12 @@ static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx)
} }
/* Start CBC-MAC with first block*/ /* Start CBC-MAC with first block*/
if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) { #if defined(MBEDTLS_CIPHER_C)
ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
#endif
if (ret != 0) {
ctx->state |= CCM_STATE__ERROR; ctx->state |= CCM_STATE__ERROR;
return ret; return ret;
} }
@ -258,7 +291,10 @@ int mbedtls_ccm_update_ad(mbedtls_ccm_context *ctx,
size_t add_len) size_t add_len)
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
size_t olen, use_len, offset; size_t use_len, offset;
#if defined(MBEDTLS_CIPHER_C)
size_t olen;
#endif
if (ctx->state & CCM_STATE__ERROR) { if (ctx->state & CCM_STATE__ERROR) {
return MBEDTLS_ERR_CCM_BAD_INPUT; return MBEDTLS_ERR_CCM_BAD_INPUT;
@ -298,8 +334,12 @@ int mbedtls_ccm_update_ad(mbedtls_ccm_context *ctx,
add += use_len; add += use_len;
if (use_len + offset == 16 || ctx->processed == ctx->add_len) { if (use_len + offset == 16 || ctx->processed == ctx->add_len) {
if ((ret = #if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) { ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
#endif
if (ret != 0) {
ctx->state |= CCM_STATE__ERROR; ctx->state |= CCM_STATE__ERROR;
return ret; return ret;
} }
@ -322,7 +362,10 @@ int mbedtls_ccm_update(mbedtls_ccm_context *ctx,
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char i; unsigned char i;
size_t use_len, offset, olen; size_t use_len, offset;
#if defined(MBEDTLS_CIPHER_C)
size_t olen;
#endif
unsigned char local_output[16]; unsigned char local_output[16];
@ -360,8 +403,12 @@ int mbedtls_ccm_update(mbedtls_ccm_context *ctx,
mbedtls_xor(ctx->y + offset, ctx->y + offset, input, use_len); mbedtls_xor(ctx->y + offset, ctx->y + offset, input, use_len);
if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) { if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) {
if ((ret = #if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) { ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
#endif
if (ret != 0) {
ctx->state |= CCM_STATE__ERROR; ctx->state |= CCM_STATE__ERROR;
goto exit; goto exit;
} }
@ -391,8 +438,12 @@ int mbedtls_ccm_update(mbedtls_ccm_context *ctx,
memcpy(output, local_output, use_len); memcpy(output, local_output, use_len);
if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) { if (use_len + offset == 16 || ctx->processed == ctx->plaintext_len) {
if ((ret = #if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen)) != 0) { ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->y);
#endif
if (ret != 0) {
ctx->state |= CCM_STATE__ERROR; ctx->state |= CCM_STATE__ERROR;
goto exit; goto exit;
} }

View File

@ -25,6 +25,10 @@
#include "mbedtls/error.h" #include "mbedtls/error.h"
#include "mbedtls/constant_time.h" #include "mbedtls/constant_time.h"
#if !defined(MBEDTLS_CIPHER_C)
#include "block_cipher_internal.h"
#endif
#include <string.h> #include <string.h>
#if defined(MBEDTLS_AESNI_C) #if defined(MBEDTLS_AESNI_C)
@ -59,10 +63,16 @@ static int gcm_gen_table(mbedtls_gcm_context *ctx)
uint64_t hi, lo; uint64_t hi, lo;
uint64_t vl, vh; uint64_t vl, vh;
unsigned char h[16]; unsigned char h[16];
size_t olen = 0;
memset(h, 0, 16); memset(h, 0, 16);
if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen)) != 0) {
#if defined(MBEDTLS_CIPHER_C)
size_t olen = 0;
ret = mbedtls_cipher_update(&ctx->cipher_ctx, h, 16, h, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, h, h);
#endif
if (ret != 0) {
return ret; return ret;
} }
@ -124,12 +134,14 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
unsigned int keybits) unsigned int keybits)
{ {
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
const mbedtls_cipher_info_t *cipher_info;
if (keybits != 128 && keybits != 192 && keybits != 256) { if (keybits != 128 && keybits != 192 && keybits != 256) {
return MBEDTLS_ERR_GCM_BAD_INPUT; return MBEDTLS_ERR_GCM_BAD_INPUT;
} }
#if defined(MBEDTLS_CIPHER_C)
const mbedtls_cipher_info_t *cipher_info;
cipher_info = mbedtls_cipher_info_from_values(cipher, keybits, cipher_info = mbedtls_cipher_info_from_values(cipher, keybits,
MBEDTLS_MODE_ECB); MBEDTLS_MODE_ECB);
if (cipher_info == NULL) { if (cipher_info == NULL) {
@ -150,6 +162,17 @@ int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
MBEDTLS_ENCRYPT)) != 0) { MBEDTLS_ENCRYPT)) != 0) {
return ret; return ret;
} }
#else
mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
if ((ret = mbedtls_block_cipher_setup(&ctx->block_cipher_ctx, cipher)) != 0) {
return ret;
}
if ((ret = mbedtls_block_cipher_setkey(&ctx->block_cipher_ctx, key, keybits)) != 0) {
return ret;
}
#endif
if ((ret = gcm_gen_table(ctx)) != 0) { if ((ret = gcm_gen_table(ctx)) != 0) {
return ret; return ret;
@ -252,8 +275,11 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
unsigned char work_buf[16]; unsigned char work_buf[16];
const unsigned char *p; const unsigned char *p;
size_t use_len, olen = 0; size_t use_len;
uint64_t iv_bits; uint64_t iv_bits;
#if defined(MBEDTLS_CIPHER_C)
size_t olen = 0;
#endif
/* IV is limited to 2^64 bits, so 2^61 bytes */ /* IV is limited to 2^64 bits, so 2^61 bytes */
/* IV is not allowed to be zero length */ /* IV is not allowed to be zero length */
@ -293,8 +319,13 @@ int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
gcm_mult(ctx, ctx->y, ctx->y); gcm_mult(ctx, ctx->y, ctx->y);
} }
if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16,
ctx->base_ectr, &olen)) != 0) { #if defined(MBEDTLS_CIPHER_C)
ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ctx->base_ectr);
#endif
if (ret != 0) {
return ret; return ret;
} }
@ -386,11 +417,15 @@ static int gcm_mask(mbedtls_gcm_context *ctx,
const unsigned char *input, const unsigned char *input,
unsigned char *output) unsigned char *output)
{ {
size_t olen = 0;
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
if ((ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, #if defined(MBEDTLS_CIPHER_C)
&olen)) != 0) { size_t olen = 0;
ret = mbedtls_cipher_update(&ctx->cipher_ctx, ctx->y, 16, ectr, &olen);
#else
ret = mbedtls_block_cipher_encrypt(&ctx->block_cipher_ctx, ctx->y, ectr);
#endif
if (ret != 0) {
mbedtls_platform_zeroize(ectr, 16); mbedtls_platform_zeroize(ectr, 16);
return ret; return ret;
} }
@ -614,7 +649,11 @@ void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
if (ctx == NULL) { if (ctx == NULL) {
return; return;
} }
#if defined(MBEDTLS_CIPHER_C)
mbedtls_cipher_free(&ctx->cipher_ctx); mbedtls_cipher_free(&ctx->cipher_ctx);
#else
mbedtls_block_cipher_free(&ctx->block_cipher_ctx);
#endif
mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context)); mbedtls_platform_zeroize(ctx, sizeof(mbedtls_gcm_context));
} }

View File

@ -1545,9 +1545,7 @@ component_test_full_no_cipher () {
# (currently ignored anyway because we completely disable PSA) # (currently ignored anyway because we completely disable PSA)
scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG scripts/config.py unset MBEDTLS_PSA_CRYPTO_CONFIG
# Disable features that depend on CIPHER_C # Disable features that depend on CIPHER_C
scripts/config.py unset MBEDTLS_CCM_C
scripts/config.py unset MBEDTLS_CMAC_C scripts/config.py unset MBEDTLS_CMAC_C
scripts/config.py unset MBEDTLS_GCM_C
scripts/config.py unset MBEDTLS_NIST_KW_C scripts/config.py unset MBEDTLS_NIST_KW_C
scripts/config.py unset MBEDTLS_PKCS12_C scripts/config.py unset MBEDTLS_PKCS12_C
scripts/config.py unset MBEDTLS_PKCS5_C scripts/config.py unset MBEDTLS_PKCS5_C
@ -1560,7 +1558,6 @@ component_test_full_no_cipher () {
scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO scripts/config.py unset MBEDTLS_USE_PSA_CRYPTO
scripts/config.py unset MBEDTLS_LMS_C scripts/config.py unset MBEDTLS_LMS_C
scripts/config.py unset MBEDTLS_LMS_PRIVATE scripts/config.py unset MBEDTLS_LMS_PRIVATE
make CFLAGS='-DMBEDTLS_BLOCK_CIPHER_C'
msg "test: full no CIPHER no PSA_CRYPTO_C" msg "test: full no CIPHER no PSA_CRYPTO_C"
make test make test