/*
 *  \brief  Generic file encryption program using generic wrappers for configured
 *          security.
 *
 *  Copyright (C) 2006-2011, ARM Limited, All Rights Reserved
 *
 *  This file is part of mbed TLS (https://tls.mbed.org)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#if !defined(POLARSSL_CONFIG_FILE)
#include "polarssl/config.h"
#else
#include POLARSSL_CONFIG_FILE
#endif

#if defined(POLARSSL_PLATFORM_C)
#include "polarssl/platform.h"
#else
#include <stdio.h>
#define polarssl_fprintf    fprintf
#define polarssl_printf     printf
#endif

#if defined(POLARSSL_CIPHER_C) && defined(POLARSSL_MD_C) && \
 defined(POLARSSL_FS_IO)
#include "polarssl/cipher.h"
#include "polarssl/md.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif

#if defined(_WIN32)
#include <windows.h>
#if !defined(_WIN32_WCE)
#include <io.h>
#endif
#else
#include <sys/types.h>
#include <unistd.h>
#endif

#define MODE_ENCRYPT    0
#define MODE_DECRYPT    1

#define USAGE   \
    "\n  crypt_and_hash <mode> <input filename> <output filename> <cipher> <md> <key>\n" \
    "\n   <mode>: 0 = encrypt, 1 = decrypt\n" \
    "\n  example: crypt_and_hash 0 file file.aes AES-128-CBC SHA1 hex:E76B2413958B00E193\n" \
    "\n"

#if !defined(POLARSSL_CIPHER_C) || !defined(POLARSSL_MD_C) || \
    !defined(POLARSSL_FS_IO)
int main( void )
{
    polarssl_printf("POLARSSL_CIPHER_C and/or POLARSSL_MD_C and/or POLARSSL_FS_IO not defined.\n");
    return( 0 );
}
#else
int main( int argc, char *argv[] )
{
    int ret = 1, i, n;
    int mode, lastn;
    size_t keylen, ilen, olen;
    FILE *fkey, *fin = NULL, *fout = NULL;

    char *p;
    unsigned char IV[16];
    unsigned char key[512];
    unsigned char digest[POLARSSL_MD_MAX_SIZE];
    unsigned char buffer[1024];
    unsigned char output[1024];
    unsigned char diff;

    const cipher_info_t *cipher_info;
    const md_info_t *md_info;
    cipher_context_t cipher_ctx;
    md_context_t md_ctx;
#if defined(_WIN32_WCE)
    long filesize, offset;
#elif defined(_WIN32)
       LARGE_INTEGER li_size;
    __int64 filesize, offset;
#else
      off_t filesize, offset;
#endif

    cipher_init( &cipher_ctx );
    md_init( &md_ctx );

    /*
     * Parse the command-line arguments.
     */
    if( argc != 7 )
    {
        const int *list;

        polarssl_printf( USAGE );

        polarssl_printf( "Available ciphers:\n" );
        list = cipher_list();
        while( *list )
        {
            cipher_info = cipher_info_from_type( *list );
            polarssl_printf( "  %s\n", cipher_info->name );
            list++;
        }

        polarssl_printf( "\nAvailable message digests:\n" );
        list = md_list();
        while( *list )
        {
            md_info = md_info_from_type( *list );
            polarssl_printf( "  %s\n", md_info->name );
            list++;
        }

#if defined(_WIN32)
        polarssl_printf( "\n  Press Enter to exit this program.\n" );
        fflush( stdout ); getchar();
#endif

        goto exit;
    }

    mode = atoi( argv[1] );

    if( mode != MODE_ENCRYPT && mode != MODE_DECRYPT )
    {
        polarssl_fprintf( stderr, "invalid operation mode\n" );
        goto exit;
    }

    if( strcmp( argv[2], argv[3] ) == 0 )
    {
        polarssl_fprintf( stderr, "input and output filenames must differ\n" );
        goto exit;
    }

    if( ( fin = fopen( argv[2], "rb" ) ) == NULL )
    {
        polarssl_fprintf( stderr, "fopen(%s,rb) failed\n", argv[2] );
        goto exit;
    }

    if( ( fout = fopen( argv[3], "wb+" ) ) == NULL )
    {
        polarssl_fprintf( stderr, "fopen(%s,wb+) failed\n", argv[3] );
        goto exit;
    }

    /*
     * Read the Cipher and MD from the command line
     */
    cipher_info = cipher_info_from_string( argv[4] );
    if( cipher_info == NULL )
    {
        polarssl_fprintf( stderr, "Cipher '%s' not found\n", argv[4] );
        goto exit;
    }
    if( ( ret = cipher_init_ctx( &cipher_ctx, cipher_info) ) != 0 )
    {
        polarssl_fprintf( stderr, "cipher_init_ctx failed\n" );
        goto exit;
    }

    md_info = md_info_from_string( argv[5] );
    if( md_info == NULL )
    {
        polarssl_fprintf( stderr, "Message Digest '%s' not found\n", argv[5] );
        goto exit;
    }
    md_init_ctx( &md_ctx, md_info);

    /*
     * Read the secret key and clean the command line.
     */
    if( ( fkey = fopen( argv[6], "rb" ) ) != NULL )
    {
        keylen = fread( key, 1, sizeof( key ), fkey );
        fclose( fkey );
    }
    else
    {
        if( memcmp( argv[6], "hex:", 4 ) == 0 )
        {
            p = &argv[6][4];
            keylen = 0;

            while( sscanf( p, "%02X", &n ) > 0 &&
                   keylen < (int) sizeof( key ) )
            {
                key[keylen++] = (unsigned char) n;
                p += 2;
            }
        }
        else
        {
            keylen = strlen( argv[6] );

            if( keylen > (int) sizeof( key ) )
                keylen = (int) sizeof( key );

            memcpy( key, argv[6], keylen );
        }
    }

    memset( argv[6], 0, strlen( argv[6] ) );

#if defined(_WIN32_WCE)
    filesize = fseek( fin, 0L, SEEK_END );
#else
#if defined(_WIN32)
    /*
     * Support large files (> 2Gb) on Win32
     */
    li_size.QuadPart = 0;
    li_size.LowPart  =
        SetFilePointer( (HANDLE) _get_osfhandle( _fileno( fin ) ),
                        li_size.LowPart, &li_size.HighPart, FILE_END );

    if( li_size.LowPart == 0xFFFFFFFF && GetLastError() != NO_ERROR )
    {
        polarssl_fprintf( stderr, "SetFilePointer(0,FILE_END) failed\n" );
        goto exit;
    }

    filesize = li_size.QuadPart;
#else
    if( ( filesize = lseek( fileno( fin ), 0, SEEK_END ) ) < 0 )
    {
        perror( "lseek" );
        goto exit;
    }
#endif
#endif

    if( fseek( fin, 0, SEEK_SET ) < 0 )
    {
        polarssl_fprintf( stderr, "fseek(0,SEEK_SET) failed\n" );
        goto exit;
    }

    if( mode == MODE_ENCRYPT )
    {
        /*
         * Generate the initialization vector as:
         * IV = SHA-256( filesize || filename )[0..15]
         */
        for( i = 0; i < 8; i++ )
            buffer[i] = (unsigned char)( filesize >> ( i << 3 ) );

        p = argv[2];

        md_starts( &md_ctx );
        md_update( &md_ctx, buffer, 8 );
        md_update( &md_ctx, (unsigned char *) p, strlen( p ) );
        md_finish( &md_ctx, digest );

        memcpy( IV, digest, 16 );

        /*
         * The last four bits in the IV are actually used
         * to store the file size modulo the AES block size.
         */
        lastn = (int)( filesize & 0x0F );

        IV[15] = (unsigned char)
            ( ( IV[15] & 0xF0 ) | lastn );

        /*
         * Append the IV at the beginning of the output.
         */
        if( fwrite( IV, 1, 16, fout ) != 16 )
        {
            polarssl_fprintf( stderr, "fwrite(%d bytes) failed\n", 16 );
            goto exit;
        }

        /*
         * Hash the IV and the secret key together 8192 times
         * using the result to setup the AES context and HMAC.
         */
        memset( digest, 0,  32 );
        memcpy( digest, IV, 16 );

        for( i = 0; i < 8192; i++ )
        {
            md_starts( &md_ctx );
            md_update( &md_ctx, digest, 32 );
            md_update( &md_ctx, key, keylen );
            md_finish( &md_ctx, digest );

        }

        memset( key, 0, sizeof( key ) );

        if( cipher_setkey( &cipher_ctx, digest, cipher_info->key_length,
                           POLARSSL_ENCRYPT ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_setkey() returned error\n");
            goto exit;
        }
        if( cipher_set_iv( &cipher_ctx, IV, 16 ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_set_iv() returned error\n");
            goto exit;
        }
        if( cipher_reset( &cipher_ctx ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_reset() returned error\n");
            goto exit;
        }

        md_hmac_starts( &md_ctx, digest, 32 );

        /*
         * Encrypt and write the ciphertext.
         */
        for( offset = 0; offset < filesize; offset += cipher_get_block_size( &cipher_ctx ) )
        {
            ilen = ( (unsigned int) filesize - offset > cipher_get_block_size( &cipher_ctx ) ) ?
                cipher_get_block_size( &cipher_ctx ) : (unsigned int) ( filesize - offset );

            if( fread( buffer, 1, ilen, fin ) != ilen )
            {
                polarssl_fprintf( stderr, "fread(%ld bytes) failed\n", (long) ilen );
                goto exit;
            }

            if( cipher_update( &cipher_ctx, buffer, ilen, output, &olen ) != 0 )
            {
                polarssl_fprintf( stderr, "cipher_update() returned error\n");
                goto exit;
            }

            md_hmac_update( &md_ctx, output, olen );

            if( fwrite( output, 1, olen, fout ) != olen )
            {
                polarssl_fprintf( stderr, "fwrite(%ld bytes) failed\n", (long) olen );
                goto exit;
            }
        }

        if( cipher_finish( &cipher_ctx, output, &olen ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_finish() returned error\n" );
            goto exit;
        }
        md_hmac_update( &md_ctx, output, olen );

        if( fwrite( output, 1, olen, fout ) != olen )
        {
            polarssl_fprintf( stderr, "fwrite(%ld bytes) failed\n", (long) olen );
            goto exit;
        }

        /*
         * Finally write the HMAC.
         */
        md_hmac_finish( &md_ctx, digest );

        if( fwrite( digest, 1, md_get_size( md_info ), fout ) != md_get_size( md_info ) )
        {
            polarssl_fprintf( stderr, "fwrite(%d bytes) failed\n", md_get_size( md_info ) );
            goto exit;
        }
    }

    if( mode == MODE_DECRYPT )
    {
        /*
         *  The encrypted file must be structured as follows:
         *
         *        00 .. 15              Initialization Vector
         *        16 .. 31              AES Encrypted Block #1
         *           ..
         *      N*16 .. (N+1)*16 - 1    AES Encrypted Block #N
         *  (N+1)*16 .. (N+1)*16 + 32   HMAC-SHA-256(ciphertext)
         */
        if( filesize < 16 + md_get_size( md_info ) )
        {
            polarssl_fprintf( stderr, "File too short to be encrypted.\n" );
            goto exit;
        }

        if( ( ( filesize - md_get_size( md_info ) ) %
                cipher_get_block_size( &cipher_ctx ) ) != 0 )
        {
            polarssl_fprintf( stderr, "File content not a multiple of the block size (%d).\n",
                     cipher_get_block_size( &cipher_ctx ));
            goto exit;
        }

        /*
         * Subtract the IV + HMAC length.
         */
        filesize -= ( 16 + md_get_size( md_info ) );

        /*
         * Read the IV and original filesize modulo 16.
         */
        if( fread( buffer, 1, 16, fin ) != 16 )
        {
            polarssl_fprintf( stderr, "fread(%d bytes) failed\n", 16 );
            goto exit;
        }

        memcpy( IV, buffer, 16 );
        lastn = IV[15] & 0x0F;

        /*
         * Hash the IV and the secret key together 8192 times
         * using the result to setup the AES context and HMAC.
         */
        memset( digest, 0,  32 );
        memcpy( digest, IV, 16 );

        for( i = 0; i < 8192; i++ )
        {
            md_starts( &md_ctx );
            md_update( &md_ctx, digest, 32 );
            md_update( &md_ctx, key, keylen );
            md_finish( &md_ctx, digest );
        }

        memset( key, 0, sizeof( key ) );

        if( cipher_setkey( &cipher_ctx, digest, cipher_info->key_length,
                           POLARSSL_DECRYPT ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_setkey() returned error\n" );
            goto exit;
        }

        if( cipher_set_iv( &cipher_ctx, IV, 16 ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_set_iv() returned error\n" );
            goto exit;
        }

        if( cipher_reset( &cipher_ctx ) != 0 )
        {
            polarssl_fprintf( stderr, "cipher_reset() returned error\n" );
            goto exit;
        }

        md_hmac_starts( &md_ctx, digest, 32 );

        /*
         * Decrypt and write the plaintext.
         */
        for( offset = 0; offset < filesize; offset += cipher_get_block_size( &cipher_ctx ) )
        {
            if( fread( buffer, 1, cipher_get_block_size( &cipher_ctx ), fin ) !=
                (size_t) cipher_get_block_size( &cipher_ctx ) )
            {
                polarssl_fprintf( stderr, "fread(%d bytes) failed\n",
                    cipher_get_block_size( &cipher_ctx ) );
                goto exit;
            }

            md_hmac_update( &md_ctx, buffer, cipher_get_block_size( &cipher_ctx ) );
            if( cipher_update( &cipher_ctx, buffer,
                               cipher_get_block_size( &cipher_ctx ),
                               output, &olen ) != 0 )
            {
                polarssl_fprintf( stderr, "cipher_update() returned error\n" );
                goto exit;
            }

            if( fwrite( output, 1, olen, fout ) != olen )
            {
                polarssl_fprintf( stderr, "fwrite(%ld bytes) failed\n", (long) olen );
                goto exit;
            }
        }

        /*
         * Verify the message authentication code.
         */
        md_hmac_finish( &md_ctx, digest );

        if( fread( buffer, 1, md_get_size( md_info ), fin ) != md_get_size( md_info ) )
        {
            polarssl_fprintf( stderr, "fread(%d bytes) failed\n", md_get_size( md_info ) );
            goto exit;
        }

        /* Use constant-time buffer comparison */
        diff = 0;
        for( i = 0; i < md_get_size( md_info ); i++ )
            diff |= digest[i] ^ buffer[i];

        if( diff != 0 )
        {
            polarssl_fprintf( stderr, "HMAC check failed: wrong key, "
                             "or file corrupted.\n" );
            goto exit;
        }

        /*
         * Write the final block of data
         */
        cipher_finish( &cipher_ctx, output, &olen );

        if( fwrite( output, 1, olen, fout ) != olen )
        {
            polarssl_fprintf( stderr, "fwrite(%ld bytes) failed\n", (long) olen );
            goto exit;
        }
    }

    ret = 0;

exit:
    if( fin )
        fclose( fin );
    if( fout )
        fclose( fout );

    memset( buffer, 0, sizeof( buffer ) );
    memset( digest, 0, sizeof( digest ) );

    cipher_free( &cipher_ctx );
    md_free( &md_ctx );

    return( ret );
}
#endif /* POLARSSL_CIPHER_C && POLARSSL_MD_C && POLARSSL_FS_IO */
