Ignore plaintext length for CCM*-no-tag.
Signed-off-by: Mateusz Starzyk <mateusz.starzyk@mobica.com>
diff --git a/include/mbedtls/ccm.h b/include/mbedtls/ccm.h
index 6f991fe..0dc5b59 100644
--- a/include/mbedtls/ccm.h
+++ b/include/mbedtls/ccm.h
@@ -198,6 +198,7 @@
* \param ctx The CCM context to use for encryption. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
+ * For tag length = 0, input length is ignored.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
@@ -207,6 +208,7 @@
* at least \p ad_len Bytes.
* \param ad_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
+ * For tag length = 0, AD length can be 0.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
@@ -279,6 +281,7 @@
* \param ctx The CCM context to use for decryption. This must be
* initialized and bound to a key.
* \param length The length of the input data in Bytes.
+ * For tag length = 0, input length is ignored.
* \param iv The initialization vector (nonce). This must be a readable
* buffer of at least \p iv_len Bytes.
* \param iv_len The length of the nonce in Bytes: 7, 8, 9, 10, 11, 12,
@@ -288,6 +291,7 @@
* at least that \p ad_len Bytes.
* \param ad_len The length of additional data in Bytes.
* This must be less than 2^16 - 2^8.
+ * For tag length = 0, AD length can be 0.
* \param input The buffer holding the input data. If \p length is greater
* than zero, \p input must be a readable buffer of at least
* that length.
diff --git a/library/ccm.c b/library/ccm.c
index 15efff7..e062678 100644
--- a/library/ccm.c
+++ b/library/ccm.c
@@ -150,9 +150,20 @@
if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGHTS_SET) )
return 0;
- if( ctx->tag_len == 0 && \
- ( ctx->mode == MBEDTLS_CCM_ENCRYPT || ctx->mode == MBEDTLS_CCM_DECRYPT ) )
- return( MBEDTLS_ERR_CCM_BAD_INPUT );
+ /* CCM expects non-empty tag.
+ * CCM* allows empty tag. For CCM* without tag, ignore plaintext length.
+ */
+ if( ctx->tag_len == 0 )
+ {
+ if( ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT || ctx->mode == MBEDTLS_CCM_STAR_DECRYPT )
+ {
+ ctx->plaintext_len = 0;
+ }
+ else
+ {
+ return( MBEDTLS_ERR_CCM_BAD_INPUT );
+ }
+ }
/*
* First block:
@@ -342,7 +353,10 @@
return MBEDTLS_ERR_CCM_BAD_INPUT;
}
- if( ctx->processed + input_len > ctx->plaintext_len )
+ /* Check against plaintext length only if performing operation with
+ * authentication
+ */
+ if( ctx->tag_len != 0 && ctx->processed + input_len > ctx->plaintext_len )
{
return MBEDTLS_ERR_CCM_BAD_INPUT;
}