/* BEGIN_HEADER */
#include "mbedtls/gcm.h"

/* Use the multipart interface to process the encrypted data in two parts
 * and check that the output matches the expected output.
 * The context must have been set up with the key. */
static int check_multipart( mbedtls_gcm_context *ctx,
                            int mode,
                            const data_t *iv,
                            const data_t *add,
                            const data_t *input,
                            const data_t *expected_output,
                            const data_t *tag,
                            size_t n1,
                            size_t n1_add)
{
    int ok = 0;
    uint8_t *output = NULL;
    size_t n2 = input->len - n1;
    size_t n2_add = add->len - n1_add;
    size_t olen;

    /* Sanity checks on the test data */
    TEST_ASSERT( n1 <= input->len );
    TEST_ASSERT( n1_add <= add->len );
    TEST_EQUAL( input->len, expected_output->len );

    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
                                         iv->x, iv->len ) );
    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, n1_add ) );
    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x + n1_add, n2_add ) );

    /* Allocate a tight buffer for each update call. This way, if the function
     * tries to write beyond the advertised required buffer size, this will
     * count as an overflow for memory sanitizers and static checkers. */
    ASSERT_ALLOC( output, n1 );
    olen = 0xdeadbeef;
    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, n1, output, n1, &olen ) );
    TEST_EQUAL( n1, olen );
    ASSERT_COMPARE( output, olen, expected_output->x, n1 );
    mbedtls_free( output );
    output = NULL;

    ASSERT_ALLOC( output, n2 );
    olen = 0xdeadbeef;
    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x + n1, n2, output, n2, &olen ) );
    TEST_EQUAL( n2, olen );
    ASSERT_COMPARE( output, olen, expected_output->x + n1, n2 );
    mbedtls_free( output );
    output = NULL;

    ASSERT_ALLOC( output, tag->len );
    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
    TEST_EQUAL( 0, olen );
    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );
    mbedtls_free( output );
    output = NULL;

    ok = 1;
exit:
    mbedtls_free( output );
    return( ok );
}

static void check_cipher_with_empty_ad( mbedtls_gcm_context *ctx,
                                        int mode,
                                        const data_t *iv,
                                        const data_t *input,
                                        const data_t *expected_output,
                                        const data_t *tag,
                                        size_t ad_update_count)
{
    size_t n;
    uint8_t *output = NULL;
    size_t olen;

    /* Sanity checks on the test data */
    TEST_EQUAL( input->len, expected_output->len );

    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
                                       iv->x, iv->len ) );

    for( n = 0; n < ad_update_count; n++ )
    {
        TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, NULL, 0 ) );
    }

    /* Allocate a tight buffer for each update call. This way, if the function
     * tries to write beyond the advertised required buffer size, this will
     * count as an overflow for memory sanitizers and static checkers. */
    ASSERT_ALLOC( output, input->len );
    olen = 0xdeadbeef;
    TEST_EQUAL( 0, mbedtls_gcm_update( ctx, input->x, input->len, output, input->len, &olen ) );
    TEST_EQUAL( input->len, olen );
    ASSERT_COMPARE( output, olen, expected_output->x, input->len );
    mbedtls_free( output );
    output = NULL;

    ASSERT_ALLOC( output, tag->len );
    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
    TEST_EQUAL( 0, olen );
    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );

exit:
    mbedtls_free( output );
}

static void check_empty_cipher_with_ad( mbedtls_gcm_context *ctx,
                                       int mode,
                                       const data_t *iv,
                                       const data_t *add,
                                       const data_t *tag,
                                       size_t cipher_update_count)
{
    size_t olen;
    size_t n;
    uint8_t* output_tag = NULL;

    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode, iv->x, iv->len ) );
    TEST_EQUAL( 0, mbedtls_gcm_update_ad( ctx, add->x, add->len ) );

    for( n = 0; n < cipher_update_count; n++ )
    {
        olen = 0xdeadbeef;
        TEST_EQUAL( 0, mbedtls_gcm_update( ctx, NULL, 0, NULL, 0, &olen ) );
        TEST_EQUAL( 0, olen );
    }

    ASSERT_ALLOC( output_tag, tag->len );
    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen,
                                       output_tag, tag->len ) );
    TEST_EQUAL( 0, olen );
    ASSERT_COMPARE( output_tag, tag->len, tag->x, tag->len );

exit:
    mbedtls_free( output_tag );
}

static void check_no_cipher_no_ad( mbedtls_gcm_context *ctx,
                                   int mode,
                                   const data_t *iv,
                                   const data_t *tag )
{
    uint8_t *output = NULL;
    size_t olen = 0;

    TEST_EQUAL( 0, mbedtls_gcm_starts( ctx, mode,
                                       iv->x, iv->len ) );
    ASSERT_ALLOC( output, tag->len );
    TEST_EQUAL( 0, mbedtls_gcm_finish( ctx, NULL, 0, &olen, output, tag->len ) );
    TEST_EQUAL( 0, olen );
    ASSERT_COMPARE( output, tag->len, tag->x, tag->len );

exit:
    mbedtls_free( output );
}

/* END_HEADER */

/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_GCM_C
 * END_DEPENDENCIES
 */

/* BEGIN_CASE */
void gcm_bad_parameters( int cipher_id, int direction,
                         data_t *key_str, data_t *src_str,
                         data_t *iv_str, data_t *add_str,
                         int tag_len_bits, int gcm_result )
{
    unsigned char output[128];
    unsigned char tag_output[16];
    mbedtls_gcm_context ctx;
    size_t tag_len = tag_len_bits / 8;

    mbedtls_gcm_init( &ctx );

    memset( output, 0x00, sizeof( output ) );
    memset( tag_output, 0x00, sizeof( tag_output ) );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, direction, src_str->len, iv_str->x, iv_str->len,
                 add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == gcm_result );

exit:
    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_encrypt_and_tag( int cipher_id, data_t * key_str,
                          data_t * src_str, data_t * iv_str,
                          data_t * add_str, data_t * dst,
                          int tag_len_bits, data_t * tag,
                          int init_result )
{
    unsigned char output[128];
    unsigned char tag_output[16];
    mbedtls_gcm_context ctx;
    size_t tag_len = tag_len_bits / 8;
    size_t n1;
    size_t n1_add;

    mbedtls_gcm_init( &ctx );

    memset(output, 0x00, 128);
    memset(tag_output, 0x00, 16);


    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
    if( init_result == 0 )
    {
        TEST_ASSERT( mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, src_str->x, output, tag_len, tag_output ) == 0 );

        ASSERT_COMPARE( output, src_str->len, dst->x, dst->len );
        ASSERT_COMPARE( tag_output, tag_len, tag->x, tag->len );

        for( n1 = 0; n1 <= src_str->len; n1 += 1 )
        {
            for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
            {
                mbedtls_test_set_step( n1 * 10000 + n1_add );
                if( !check_multipart( &ctx, MBEDTLS_GCM_ENCRYPT,
                                    iv_str, add_str, src_str,
                                    dst, tag,
                                    n1, n1_add ) )
                    goto exit;
            }
        }
    }

exit:
    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_decrypt_and_verify( int cipher_id, data_t * key_str,
                             data_t * src_str, data_t * iv_str,
                             data_t * add_str, int tag_len_bits,
                             data_t * tag_str, char * result,
                             data_t * pt_result, int init_result )
{
    unsigned char output[128];
    mbedtls_gcm_context ctx;
    int ret;
    size_t tag_len = tag_len_bits / 8;
    size_t n1;
    size_t n1_add;

    mbedtls_gcm_init( &ctx );

    memset(output, 0x00, 128);


    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == init_result );
    if( init_result == 0 )
    {
        ret = mbedtls_gcm_auth_decrypt( &ctx, src_str->len, iv_str->x, iv_str->len, add_str->x, add_str->len, tag_str->x, tag_len, src_str->x, output );

        if( strcmp( "FAIL", result ) == 0 )
        {
            TEST_ASSERT( ret == MBEDTLS_ERR_GCM_AUTH_FAILED );
        }
        else
        {
            TEST_ASSERT( ret == 0 );
            ASSERT_COMPARE( output, src_str->len, pt_result->x, pt_result->len );

            for( n1 = 0; n1 <= src_str->len; n1 += 1 )
            {
                for( n1_add = 0; n1_add <= add_str->len; n1_add += 1 )
                {
                    mbedtls_test_set_step( n1 * 10000 + n1_add );
                    if( !check_multipart( &ctx, MBEDTLS_GCM_DECRYPT,
                                        iv_str, add_str, src_str,
                                        pt_result, tag_str,
                                        n1, n1_add ) )
                        goto exit;
                }
            }
        }
    }

exit:
    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_decrypt_and_verify_empty_cipher( int cipher_id,
                                          data_t * key_str,
                                          data_t * iv_str,
                                          data_t * add_str,
                                          data_t * tag_str,
                                          int cipher_update_calls )
{
    mbedtls_gcm_context ctx;

    mbedtls_gcm_init( &ctx );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_DECRYPT,
                                iv_str, add_str, tag_str,
                                cipher_update_calls );

    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_decrypt_and_verify_empty_ad( int cipher_id,
                                      data_t * key_str,
                                      data_t * iv_str,
                                      data_t * src_str,
                                      data_t * tag_str,
                                      data_t * pt_result,
                                      int ad_update_calls )
{
    mbedtls_gcm_context ctx;

    mbedtls_gcm_init( &ctx );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_DECRYPT,
                                iv_str, src_str, pt_result, tag_str,
                                ad_update_calls );

    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_decrypt_and_verify_no_ad_no_cipher( int cipher_id,
                                             data_t * key_str,
                                             data_t * iv_str,
                                             data_t * tag_str )
{
    mbedtls_gcm_context ctx;

    mbedtls_gcm_init( &ctx );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    check_no_cipher_no_ad( &ctx, MBEDTLS_GCM_DECRYPT,
                           iv_str, tag_str );

    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_encrypt_and_tag_empty_cipher( int cipher_id,
                                       data_t * key_str,
                                       data_t * iv_str,
                                       data_t * add_str,
                                       data_t * tag_str,
                                       int cipher_update_calls )
{
    mbedtls_gcm_context ctx;

    mbedtls_gcm_init( &ctx );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    check_empty_cipher_with_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
                                iv_str, add_str, tag_str,
                                cipher_update_calls );

exit:
    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_encrypt_and_tag_empty_ad( int cipher_id,
                                   data_t * key_str,
                                   data_t * iv_str,
                                   data_t * src_str,
                                   data_t * dst,
                                   data_t * tag_str,
                                   int ad_update_calls )
{
    mbedtls_gcm_context ctx;

    mbedtls_gcm_init( &ctx );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    check_cipher_with_empty_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
                                iv_str, src_str, dst, tag_str,
                                ad_update_calls );

exit:
    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE */
void gcm_encrypt_and_verify_no_ad_no_cipher( int cipher_id,
                                             data_t * key_str,
                                             data_t * iv_str,
                                             data_t * tag_str )
{
    mbedtls_gcm_context ctx;

    mbedtls_gcm_init( &ctx );

    TEST_ASSERT( mbedtls_gcm_setkey( &ctx, cipher_id, key_str->x, key_str->len * 8 ) == 0 );
    check_no_cipher_no_ad( &ctx, MBEDTLS_GCM_ENCRYPT,
                           iv_str, tag_str );

    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE depends_on:NOT_DEFINED */
void gcm_invalid_param( )
{
    mbedtls_gcm_context ctx;
    unsigned char valid_buffer[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 };
    mbedtls_cipher_id_t valid_cipher = MBEDTLS_CIPHER_ID_AES;
    int invalid_bitlen = 1;

    mbedtls_gcm_init( &ctx );

    /* mbedtls_gcm_setkey */
    TEST_EQUAL(
        MBEDTLS_ERR_GCM_BAD_INPUT,
        mbedtls_gcm_setkey( &ctx, valid_cipher, valid_buffer, invalid_bitlen ) );

exit:
    mbedtls_gcm_free( &ctx );
}
/* END_CASE */

/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void gcm_selftest(  )
{
    TEST_ASSERT( mbedtls_gcm_self_test( 1 ) == 0 );
}
/* END_CASE */
