/*
 *  NIST SP800-38C compliant CCM implementation
 *
 *  Copyright The Mbed TLS Contributors
 *  SPDX-License-Identifier: Apache-2.0
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 *  not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/*
 * Definition of CCM:
 * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
 * RFC 3610 "Counter with CBC-MAC (CCM)"
 *
 * Related:
 * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
 */

#include "common.h"

#if defined(MBEDTLS_CCM_C)

#include "mbedtls/ccm.h"
#include "mbedtls/platform_util.h"
#include "mbedtls/error.h"

#include <string.h>

#if defined(MBEDTLS_PLATFORM_C)
#include "mbedtls/platform.h"
#else
#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
#include <stdio.h>
#define mbedtls_printf printf
#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */
#endif /* MBEDTLS_PLATFORM_C */

#if !defined(MBEDTLS_CCM_ALT)


/*
 * Initialize context
 */
void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
{
    memset( ctx, 0, sizeof( mbedtls_ccm_context ) );
}

int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
                        mbedtls_cipher_id_t cipher,
                        const unsigned char *key,
                        unsigned int keybits )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    const mbedtls_cipher_info_t *cipher_info;

    cipher_info = mbedtls_cipher_info_from_values( cipher, keybits,
                                                   MBEDTLS_MODE_ECB );
    if( cipher_info == NULL )
        return( MBEDTLS_ERR_CCM_BAD_INPUT );

    if( cipher_info->block_size != 16 )
        return( MBEDTLS_ERR_CCM_BAD_INPUT );

    mbedtls_cipher_free( &ctx->cipher_ctx );

    if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits,
                               MBEDTLS_ENCRYPT ) ) != 0 )
    {
        return( ret );
    }

    return( 0 );
}

/*
 * Free context
 */
void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
{
    if( ctx == NULL )
        return;
    mbedtls_cipher_free( &ctx->cipher_ctx );
    mbedtls_platform_zeroize( ctx, sizeof( mbedtls_ccm_context ) );
}

#define CCM_STATE__CLEAR                0
#define CCM_STATE__STARTED              (1 << 0)
#define CCM_STATE__LENGTHS_SET          (1 << 1)
#define CCM_STATE__AUTH_DATA_STARTED    (1 << 2)
#define CCM_STATE__AUTH_DATA_FINISHED   (1 << 3)
#define CCM_STATE__ERROR                (1 << 4)

/*
 * Encrypt or decrypt a partial block with CTR
 */
static int mbedtls_ccm_crypt( mbedtls_ccm_context *ctx,
                              size_t offset, size_t use_len,
                              const unsigned char *input,
                              unsigned char *output )
{
    size_t olen = 0;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char tmp_buf[16] = {0};

    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->ctr, 16, tmp_buf,
                                       &olen ) ) != 0 )
    {
        ctx->state |= CCM_STATE__ERROR;
        mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf));
        return ret;
    }

    mbedtls_xor( output, input, tmp_buf + offset, use_len );

    mbedtls_platform_zeroize(tmp_buf, sizeof(tmp_buf));
    return ret;
}

static void mbedtls_ccm_clear_state(mbedtls_ccm_context *ctx) {
    ctx->state = CCM_STATE__CLEAR;
    memset( ctx->y, 0, 16);
    memset( ctx->ctr, 0, 16);
}

static int ccm_calculate_first_block_if_ready(mbedtls_ccm_context *ctx)
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char i;
    size_t len_left, olen;

    /* length calculation can be done only after both
     * mbedtls_ccm_starts() and mbedtls_ccm_set_lengths() have been executed
     */
    if( !(ctx->state & CCM_STATE__STARTED) || !(ctx->state & CCM_STATE__LENGTHS_SET) )
        return 0;

    /* 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:
     * 0        .. 0        flags
     * 1        .. iv_len   nonce (aka iv)  - set by: mbedtls_ccm_starts()
     * iv_len+1 .. 15       length
     *
     * With flags as (bits):
     * 7        0
     * 6        add present?
     * 5 .. 3   (t - 2) / 2
     * 2 .. 0   q - 1
     */
    ctx->y[0] |= ( ctx->add_len > 0 ) << 6;
    ctx->y[0] |= ( ( ctx->tag_len - 2 ) / 2 ) << 3;
    ctx->y[0] |= ctx->q - 1;

    for( i = 0, len_left = ctx->plaintext_len; i < ctx->q; i++, len_left >>= 8 )
        ctx->y[15-i] = MBEDTLS_BYTE_0( len_left );

    if( len_left > 0 )
    {
        ctx->state |= CCM_STATE__ERROR;
        return( MBEDTLS_ERR_CCM_BAD_INPUT );
    }

    /* Start CBC-MAC with first block*/
    if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
    {
        ctx->state |= CCM_STATE__ERROR;
        return( ret );
    }

    return (0);
}

int mbedtls_ccm_starts( mbedtls_ccm_context *ctx,
                        int mode,
                        const unsigned char *iv,
                        size_t iv_len )
{
    /* Also implies q is within bounds */
    if( iv_len < 7 || iv_len > 13 )
        return( MBEDTLS_ERR_CCM_BAD_INPUT );

    ctx->mode = mode;
    ctx->q = 16 - 1 - (unsigned char) iv_len;

    /*
     * Prepare counter block for encryption:
     * 0        .. 0        flags
     * 1        .. iv_len   nonce (aka iv)
     * iv_len+1 .. 15       counter (initially 1)
     *
     * With flags as (bits):
     * 7 .. 3   0
     * 2 .. 0   q - 1
     */
    memset( ctx->ctr, 0, 16);
    ctx->ctr[0] = ctx->q - 1;
    memcpy( ctx->ctr + 1, iv, iv_len );
    memset( ctx->ctr + 1 + iv_len, 0, ctx->q );
    ctx->ctr[15] = 1;

    /*
     * See ccm_calculate_first_block_if_ready() for block layout description
     */
    memcpy( ctx->y + 1, iv, iv_len );

    ctx->state |= CCM_STATE__STARTED;
    return ccm_calculate_first_block_if_ready(ctx);
}

int mbedtls_ccm_set_lengths( mbedtls_ccm_context *ctx,
                             size_t total_ad_len,
                             size_t plaintext_len,
                             size_t tag_len )
{
    /*
     * Check length requirements: SP800-38C A.1
     * Additional requirement: a < 2^16 - 2^8 to simplify the code.
     * 'length' checked later (when writing it to the first block)
     *
     * Also, loosen the requirements to enable support for CCM* (IEEE 802.15.4).
     */
    if( tag_len == 2 || tag_len > 16 || tag_len % 2 != 0 )
        return( MBEDTLS_ERR_CCM_BAD_INPUT );

    if( total_ad_len >= 0xFF00 )
        return( MBEDTLS_ERR_CCM_BAD_INPUT );

    ctx->plaintext_len = plaintext_len;
    ctx->add_len = total_ad_len;
    ctx->tag_len = tag_len;
    ctx->processed = 0;

    ctx->state |= CCM_STATE__LENGTHS_SET;
    return ccm_calculate_first_block_if_ready(ctx);
}

int mbedtls_ccm_update_ad( mbedtls_ccm_context *ctx,
                           const unsigned char *add,
                           size_t add_len )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    size_t olen, use_len, offset;

    if( ctx->state & CCM_STATE__ERROR )
    {
        return MBEDTLS_ERR_CCM_BAD_INPUT;
    }

    if( add_len > 0 )
    {
        if( ctx->state & CCM_STATE__AUTH_DATA_FINISHED )
        {
            return MBEDTLS_ERR_CCM_BAD_INPUT;
        }

        if( !(ctx->state & CCM_STATE__AUTH_DATA_STARTED) )
        {
            if ( add_len > ctx->add_len )
            {
                return MBEDTLS_ERR_CCM_BAD_INPUT;
            }

            ctx->y[0] ^= (unsigned char)( ( ctx->add_len >> 8 ) & 0xFF );
            ctx->y[1] ^= (unsigned char)( ( ctx->add_len      ) & 0xFF );

            ctx->state |= CCM_STATE__AUTH_DATA_STARTED;
        }
        else if ( ctx->processed + add_len > ctx->add_len )
        {
            return MBEDTLS_ERR_CCM_BAD_INPUT;
        }

        while( add_len > 0 )
        {
            offset = (ctx->processed + 2) % 16; /* account for y[0] and y[1]
                                                 * holding total auth data length */
            use_len = 16 - offset;

            if( use_len > add_len )
                use_len = add_len;

            mbedtls_xor( ctx->y + offset, ctx->y + offset, add, use_len );

            ctx->processed += use_len;
            add_len -= use_len;
            add += use_len;

            if( use_len + offset == 16 || ctx->processed == ctx->add_len )
            {
                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
                {
                    ctx->state |= CCM_STATE__ERROR;
                    return( ret );
                }
            }
        }

        if( ctx->processed == ctx->add_len )
        {
            ctx->state |= CCM_STATE__AUTH_DATA_FINISHED;
            ctx->processed = 0; // prepare for mbedtls_ccm_update()
        }
    }

    return (0);
}

int mbedtls_ccm_update( mbedtls_ccm_context *ctx,
                        const unsigned char *input, size_t input_len,
                        unsigned char *output, size_t output_size,
                        size_t *output_len )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char i;
    size_t use_len, offset, olen;

    unsigned char local_output[16];

    if( ctx->state & CCM_STATE__ERROR )
    {
        return MBEDTLS_ERR_CCM_BAD_INPUT;
    }

    /* 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;
    }

    if( output_size < input_len )
        return( MBEDTLS_ERR_CCM_BAD_INPUT );
    *output_len = input_len;

    ret = 0;

    while ( input_len > 0 )
    {
        offset = ctx->processed % 16;

        use_len = 16 - offset;

        if( use_len > input_len )
            use_len = input_len;

        ctx->processed += use_len;

        if( ctx->mode == MBEDTLS_CCM_ENCRYPT || \
            ctx->mode == MBEDTLS_CCM_STAR_ENCRYPT )
        {
            mbedtls_xor( ctx->y + offset, ctx->y + offset, input, use_len );

            if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
            {
                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
                {
                    ctx->state |= CCM_STATE__ERROR;
                    goto exit;
                }
            }

            ret = mbedtls_ccm_crypt( ctx, offset, use_len, input, output );
            if( ret != 0 )
                goto exit;
        }

        if( ctx->mode == MBEDTLS_CCM_DECRYPT || \
            ctx->mode == MBEDTLS_CCM_STAR_DECRYPT )
        {
            /* Since output may be in shared memory, we cannot be sure that
             * it will contain what we wrote to it. Therefore, we should avoid using
             * it as input to any operations.
             * Write decrypted data to local_output to avoid using output variable as
             * input in the XOR operation for Y.
             */
            ret = mbedtls_ccm_crypt( ctx, offset, use_len, input, local_output );
            if( ret != 0 )
                goto exit;

            mbedtls_xor( ctx->y + offset, ctx->y + offset, local_output, use_len );

            memcpy( output, local_output, use_len );
            mbedtls_platform_zeroize( local_output, 16 );

            if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
            {
                if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->y, &olen ) ) != 0 )
                {
                    ctx->state |= CCM_STATE__ERROR;
                    goto exit;
                }
            }
        }

        if( use_len + offset == 16 || ctx->processed == ctx->plaintext_len )
        {
            for( i = 0; i < ctx->q; i++ )
            if( ++(ctx->ctr)[15-i] != 0 )
                break;
        }

        input_len -= use_len;
        input += use_len;
        output += use_len;
    }

exit:
    mbedtls_platform_zeroize( local_output, 16 );

    return ret;
}

int mbedtls_ccm_finish( mbedtls_ccm_context *ctx,
                        unsigned char *tag, size_t tag_len )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char i;

    if( ctx->state & CCM_STATE__ERROR )
    {
        return MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    }

    if( ctx->add_len > 0 && !( ctx->state & CCM_STATE__AUTH_DATA_FINISHED ) )
    {
        return MBEDTLS_ERR_CCM_BAD_INPUT;
    }

    if( ctx->plaintext_len > 0 && ctx->processed != ctx->plaintext_len )
    {
        return MBEDTLS_ERR_CCM_BAD_INPUT;
    }

    /*
     * Authentication: reset counter and crypt/mask internal tag
     */
    for( i = 0; i < ctx->q; i++ )
        ctx->ctr[15-i] = 0;

    ret = mbedtls_ccm_crypt( ctx, 0, 16, ctx->y, ctx->y );
    if( ret != 0 )
        return ret;
    if( tag != NULL )
        memcpy( tag, ctx->y, tag_len );
    mbedtls_ccm_clear_state(ctx);

    return( 0 );
}

/*
 * Authenticated encryption or decryption
 */
static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length,
                           const unsigned char *iv, size_t iv_len,
                           const unsigned char *add, size_t add_len,
                           const unsigned char *input, unsigned char *output,
                           unsigned char *tag, size_t tag_len )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    size_t olen;

    if( ( ret = mbedtls_ccm_starts( ctx, mode, iv, iv_len ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_ccm_set_lengths( ctx, add_len, length, tag_len ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_ccm_update_ad( ctx, add, add_len ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_ccm_update( ctx, input, length,
                                    output, length, &olen ) ) != 0 )
        return( ret );

    if( ( ret = mbedtls_ccm_finish( ctx, tag, tag_len ) ) != 0 )
        return( ret );

    return( 0 );
}

/*
 * Authenticated encryption
 */
int mbedtls_ccm_star_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
                         const unsigned char *iv, size_t iv_len,
                         const unsigned char *add, size_t add_len,
                         const unsigned char *input, unsigned char *output,
                         unsigned char *tag, size_t tag_len )
{
    return( ccm_auth_crypt( ctx, MBEDTLS_CCM_STAR_ENCRYPT, length, iv, iv_len,
                            add, add_len, input, output, tag, tag_len ) );
}

int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length,
                         const unsigned char *iv, size_t iv_len,
                         const unsigned char *add, size_t add_len,
                         const unsigned char *input, unsigned char *output,
                         unsigned char *tag, size_t tag_len )
{
    return( ccm_auth_crypt( ctx, MBEDTLS_CCM_ENCRYPT, length, iv, iv_len,
                            add, add_len, input, output, tag, tag_len ) );
}

/*
 * Authenticated decryption
 */
static int mbedtls_ccm_compare_tags(const unsigned char *tag1, const unsigned char *tag2, size_t tag_len)
{
    unsigned char i;
    int diff;

    /* Check tag in "constant-time" */
    for( diff = 0, i = 0; i < tag_len; i++ )
        diff |= tag1[i] ^ tag2[i];

    if( diff != 0 )
    {
        return( MBEDTLS_ERR_CCM_AUTH_FAILED );
    }

    return( 0 );
}

static int ccm_auth_decrypt( mbedtls_ccm_context *ctx, int mode, size_t length,
                             const unsigned char *iv, size_t iv_len,
                             const unsigned char *add, size_t add_len,
                             const unsigned char *input, unsigned char *output,
                             const unsigned char *tag, size_t tag_len )
{
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    unsigned char check_tag[16];

    if( ( ret = ccm_auth_crypt( ctx, mode, length,
                                iv, iv_len, add, add_len,
                                input, output, check_tag, tag_len ) ) != 0 )
    {
        return( ret );
    }

    if( ( ret = mbedtls_ccm_compare_tags( tag, check_tag, tag_len ) ) != 0 )
    {
        mbedtls_platform_zeroize( output, length );
        return( ret );
    }

    return( 0 );
}

int mbedtls_ccm_star_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                      const unsigned char *iv, size_t iv_len,
                      const unsigned char *add, size_t add_len,
                      const unsigned char *input, unsigned char *output,
                      const unsigned char *tag, size_t tag_len )
{
    return ccm_auth_decrypt( ctx, MBEDTLS_CCM_STAR_DECRYPT, length,
                             iv, iv_len, add, add_len,
                             input, output, tag, tag_len );
}

int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length,
                      const unsigned char *iv, size_t iv_len,
                      const unsigned char *add, size_t add_len,
                      const unsigned char *input, unsigned char *output,
                      const unsigned char *tag, size_t tag_len )
{
    return ccm_auth_decrypt( ctx, MBEDTLS_CCM_DECRYPT, length,
                             iv, iv_len, add, add_len,
                             input, output, tag, tag_len );
}
#endif /* !MBEDTLS_CCM_ALT */

#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C)
/*
 * Examples 1 to 3 from SP800-38C Appendix C
 */

#define NB_TESTS 3
#define CCM_SELFTEST_PT_MAX_LEN 24
#define CCM_SELFTEST_CT_MAX_LEN 32
/*
 * The data is the same for all tests, only the used length changes
 */
static const unsigned char key_test_data[] = {
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
};

static const unsigned char iv_test_data[] = {
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b
};

static const unsigned char ad_test_data[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13
};

static const unsigned char msg_test_data[CCM_SELFTEST_PT_MAX_LEN] = {
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
};

static const size_t iv_len_test_data [NB_TESTS] = { 7, 8,  12 };
static const size_t add_len_test_data[NB_TESTS] = { 8, 16, 20 };
static const size_t msg_len_test_data[NB_TESTS] = { 4, 16, 24 };
static const size_t tag_len_test_data[NB_TESTS] = { 4, 6,  8  };

static const unsigned char res_test_data[NB_TESTS][CCM_SELFTEST_CT_MAX_LEN] = {
    {   0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d },
    {   0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62,
        0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d,
        0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd },
    {   0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a,
        0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b,
        0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5,
        0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 }
};

int mbedtls_ccm_self_test( int verbose )
{
    mbedtls_ccm_context ctx;
    /*
     * Some hardware accelerators require the input and output buffers
     * would be in RAM, because the flash is not accessible.
     * Use buffers on the stack to hold the test vectors data.
     */
    unsigned char plaintext[CCM_SELFTEST_PT_MAX_LEN];
    unsigned char ciphertext[CCM_SELFTEST_CT_MAX_LEN];
    size_t i;
    int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;

    mbedtls_ccm_init( &ctx );

    if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key_test_data,
                            8 * sizeof key_test_data ) != 0 )
    {
        if( verbose != 0 )
            mbedtls_printf( "  CCM: setup failed" );

        return( 1 );
    }

    for( i = 0; i < NB_TESTS; i++ )
    {
        if( verbose != 0 )
            mbedtls_printf( "  CCM-AES #%u: ", (unsigned int) i + 1 );

        memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );
        memset( ciphertext, 0, CCM_SELFTEST_CT_MAX_LEN );
        memcpy( plaintext, msg_test_data, msg_len_test_data[i] );

        ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len_test_data[i],
                                           iv_test_data, iv_len_test_data[i],
                                           ad_test_data, add_len_test_data[i],
                                           plaintext, ciphertext,
                                           ciphertext + msg_len_test_data[i],
                                           tag_len_test_data[i] );

        if( ret != 0 ||
            memcmp( ciphertext, res_test_data[i],
                    msg_len_test_data[i] + tag_len_test_data[i] ) != 0 )
        {
            if( verbose != 0 )
                mbedtls_printf( "failed\n" );

            return( 1 );
        }
        memset( plaintext, 0, CCM_SELFTEST_PT_MAX_LEN );

        ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len_test_data[i],
                                        iv_test_data, iv_len_test_data[i],
                                        ad_test_data, add_len_test_data[i],
                                        ciphertext, plaintext,
                                        ciphertext + msg_len_test_data[i],
                                        tag_len_test_data[i] );

        if( ret != 0 ||
            memcmp( plaintext, msg_test_data, msg_len_test_data[i] ) != 0 )
        {
            if( verbose != 0 )
                mbedtls_printf( "failed\n" );

            return( 1 );
        }

        if( verbose != 0 )
            mbedtls_printf( "passed\n" );
    }

    mbedtls_ccm_free( &ctx );

    if( verbose != 0 )
        mbedtls_printf( "\n" );

    return( 0 );
}

#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */

#endif /* MBEDTLS_CCM_C */
