Hi

New to OpenSSL, but designing a PC application that must encrypt a stream of 48 bytes message blocks to a USB device with aes128.The iv's gets generated and synchronized when the connection with the device is established, and I would like to keep the same cipher context going until the the device is disconnected.

I wrote some test code to simulate how I plan to use EVP:

void ssl_lib_test()
{
    int n;
    unsigned char pt[96];    // Plain text
    unsigned char ct[96];    // Cipher text
unsigned char ptrx[96]; // Decrypted cipher text (hopefully the same as plain text) const unsigned char key[] = { 0x0a, 0x12, 0x23, 0x23, 0xff, 0xde, 0x00, 0x80, 0x45, 0x12, 0x33, 0xf0, 0x02, 0x3f, 0xcb, 0x00 }; const unsigned char iv[] = { 0xbb, 0x00, 0x40, 0x3c, 0xff, 0x00, 0x00, 0x10, 0x20, 0x01, 0x01, 0xa7, 0xa8, 0xa9, 0xaa, 0xab };

    // Create and initialize cipher contexts
EVP_CIPHER_CTX *encrCtx = ( EVP_CIPHER_CTX * )malloc( sizeof( EVP_CIPHER_CTX ));
    EVP_CIPHER_CTX_init( encrCtx );
EVP_CIPHER_CTX *decrCtx = ( EVP_CIPHER_CTX * )malloc( sizeof( EVP_CIPHER_CTX ));
    EVP_CIPHER_CTX_init( decrCtx );

    EVP_EncryptInit_ex( encrCtx, EVP_aes_128_cbc(), NULL, key, iv );
    EVP_DecryptInit_ex( decrCtx, EVP_aes_128_cbc(), NULL, key, iv );
//    EVP_EncryptInit_ex( encrCtx, EVP_rc4(), NULL, key, iv );
//    EVP_DecryptInit_ex( decrCtx, EVP_rc4(), NULL, key, iv );

    printf( "\nBlock size is multiple of block size test" );
    printf( "\n=========================================" );

    // Make a simple plain text buffer
    for( n = 0; n < 48; n++ )
        pt[n] = n;

    printf( "\nPlain text: " );
    hexOut( pt, 48 );

    int outlc;
    int outlp;
    int p;
    int encr;
    int decr;

    // "Stream" some messages...
    for( p = 0; p < 3; p++ )
    {
        memset( ct, 0, sizeof( ct ));
        memset( ptrx, 0, sizeof( ptrx ));

        encr = EVP_EncryptUpdate( encrCtx, ct, &outlc, pt, 48 );
        printf( "\nEnc %d: ", outlc, encr );
        hexOut( ct, 48 );

        decr = EVP_DecryptUpdate( decrCtx, ptrx, &outlp, ct, 48 );
        printf( "\nDec %d: ", outlp, decr );
        hexOut( ptrx, 48 );
    }


    // Odd block length buffer test
    int odd_length = 37;
    int outlc1 = 0;
    int outlc2 = 0;
    int outlp1 = 0;
    int outlp2 = 0;

    printf( "\n\nOdd buffer length test" );
    printf( "\n========================" );

    printf( "\nPt: " );
    hexOut( pt, odd_length );

    //for( p = 0; p < 3; p++ )
    {
        memset( ct, 0, sizeof( ct ));
        memset( ptrx, 0, sizeof( ptrx ));

        EVP_EncryptUpdate( encrCtx, ct, &outlc1, pt, odd_length );
        EVP_EncryptFinal( encrCtx, &ct[outlc1], &outlc2 );
        printf( "\nEnc %d: ", outlc1 + outlc2 );
        hexOut( ct, odd_length );

        EVP_DecryptUpdate( decrCtx, ptrx, &outlp1, ct, odd_length );
        EVP_DecryptFinal( decrCtx, &ptrx[outlp1], &outlp2 );
        printf( "\nDec %d: ", outlp1 + outlp2 );
        hexOut( ptrx, odd_length );
    }

    EVP_CIPHER_CTX_cleanup( encrCtx );
    EVP_CIPHER_CTX_cleanup( decrCtx );

    free( encrCtx );
    free( decrCtx );
}

The output of this code is:

Block size is multiple of block size test
=========================================
Plain text: { 00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f, }

Enc 48: { 94,25,01,44,12,75,5d,37,15,bc,66,16,3e,ff,e5,70,02,ba,e2,fa,62,c3,2c,be,7d,47,12,de,fa,f7,f0,b3,36,8b,96,ea,e7,d5,1d,08,b5,09,27,0a,ed,14,49,e2, }

Dec 32: { 00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f, }

Enc 48: { 57,0a,33,e2,32,53,6a,42,2b,d3,80,e2,e3,8b,34,b7,d1,fb,3f,62,aa,1b,97,52,09,69,14,34,c3,ca,1c,e7,ca,f2,9c,0f,1f,a8,1c,13,34,cb,14,42,19,76,d1,f0, }

Dec 48: { 20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f, }

Enc 48: { 99,82,14,ae,bb,a2,6c,18,05,d1,1a,ae,fe,0b,97,a7,37,a2,5b,62,49,6a,0d,f2,b2,22,14,24,d8,a2,94,20,c1,b4,3d,5c,66,c4,e1,9d,4f,c6,45,4d,94,13,97,43, }

Dec 48: { 20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f, }


Odd buffer length test
========================
Pt: { 00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14,15,16,17,18,19,1a,1b,1c,1d,1e,1f,20,21,22,23,24, }

Enc 48: { 7b,47,99,a4,10,50,a4,e0,3c,45,8a,1c,df,b1,2f,8c,85,11,55,44,92,13,4e,da,2e,40,bc,86,63,0e,7a,19,60,88,d7,a2,01, }

Dec 48: { 20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f,00,01,02,03,04,05,06,07,08,09,0a,0b,0c,0d,0e,0f,10,11,12,13,14, }


The first encryption/decryption is ok, but then it starts altering the order of the individual cipher blocks in my message, and on the first decryption it reports that only 32 bytes have been decrypted, although the entire 48 byte output buffer is correct.

I then tried with RC4, here everything was ok.

Since I need the above functionallity with AES, I did the following "hack", in evp_enc.c line 478:

    /* if we have 'decrypted' a multiple of block size, make sure
     * we have a copy of this last block */
if ( 0 ) // ( b > 1 && !ctx->buf_len) Final handling removed t...@leax.dk, 2013.02.01

Then it worked for my streamed block sized aligned messages, but of course not for the odd length test (which I will never use anyway).

Strangely (for me anyway) RC4 code still works after the hack, both block size aligned stream and odd length.

Am I seeing this because I simply use AES CBC the wrong way?

Best Regards
Tage

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to