/*
 *  \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://polarssl.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
#define polarssl_printf     printf
#define polarssl_fprintf    fprintf
#endif

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

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

#include "polarssl/cipher.h"
#include "polarssl/md.h"

#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)
int main( int argc, char *argv[] )
{
    ((void) argc);
    ((void) argv);

    polarssl_printf("POLARSSL_CIPHER_C and/or POLARSSL_MD_C 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 */
