## Encryption Modes

Tonight were going discuss encryption modes.  Encryption modes solve a number of problems with encryption – and the Wikipedia reference does a good job introducing the subject; it’s a good starting location for anyone wishing to learn.  I’ll provide more examples and references to try to help further an understanding.

The example image used in the examples is famous for image processing, and other reasons, its Lenna.  There is an entertaining story behind the image and I encourage the reader to check it out at the link above.

The new Matlab code “ImEnc.m” developed for this discussion is available here.  If you have not read about my OpenSSL for Matlab toolbox I encourage you to check out the post and download the code here.

Note: I had difficulties getting the IDEA Algorithm working on OS X with OpenSSL 1.0.0a – but it did work with a slightly older version OpenSSL on Windows.

First and foremost lets look at a good result.

The above graphic shows the IDEA algorithm with the Outback FeedBack (OFB) mode.  OFB is a fast mode, much of the work can be done before encryption is performed; the algorithm encrypts the Initilization Vector with the key creating a hash which is XORs against the data.  The graphic above makes two interesting points:

1)   There is no discernable pattern in the encrypted image.  While this is a good start is it by no means an end all.

2)   There are no modes in the encrypted data histogram.

This is a good start – the encrypted data image and histogram both look good.

Unfortunately not all examples are this well behaved.

Continuing with the OFB mode lets look at an example of what not to do.  The results aren’t nearly as positive if the key is weak – in this case all zeros.

This is a most interesting example – the data is exactly the same!  The idea algorithm doesn’t do anything to the data when the key and IV are all zeros.

Unlike the first and second example there is a mode similarity with the original data.  This tells us, when looked at in a big picture that a strong key should always be verified when using the OFB mode (or any other mode for that matter). I should also mention that other algorithms produce results that look much better under the same circumstances, but don’t take my work for it – try it for yourself.

The Wikipedia article above also mentions that the Electronic Code Book (ECB) mode is weak – so lets look at it.  This mode is the most basic available – the raw data is pushed through the algorithm against a key and there are no IVs or XOR operations afterwards – nice and simple.  There are a few drawbacks since the same data will encrypt exactly the same way – certainly providing an astute mathematician an advantage.

Again if the key is weak (all zeros in this case) the data will look poor, although not as bad as above:

But, if the key is strong the result looks good regardless of the IV pushed through (makes a lot of sense since ECB ignores the IV):

At this point there is an interesting opportunity for the reader to experiment and to look at error correction and recovery or each mode and algorithm.  I’m going to leave it the reader to experiment, but while experimenting be sure to compare the differences between dropped data and bits and bad data.  The two are vastly different cases and should provide interesting experimentation.

Other Reference:

## Cryptography: A few fundamentals

Thus far we have discussed one cryptographic implementation – OpenSSL.  We have looked at that implementation through the command line and through a toolbox for Matlab.  Tonight I’m going to point out a few links that will help with the fundamentals of Cryptography.  The breadth of this material is non-trivial and a few readings may be needed to fully understand the details.

Some of the links to follow are better than others and I’m working to supplement some of the weaker ones with demonstration code to either better prove or point.

First we will discuss Symmetric-key cryptography – which consists of two core concepts Block Ciphers and Stream Ciphers.

With the tool I have released, which cover Symmetric-key cryptography, there are two main types of ciphers:

Block Ciphers

Stream Ciphers

So, what’s the difference?

A stream cipher varies it transformation as a function of the number of digits being encoded where as block ciphers transform groups of digits at a given time.

After reading that material it may not surprise you to hear that Symmetric-key cryptography can be a bit slow.  Various modes have been developed to help speed the process up.  Although the modes are specific to block ciphers operation.

The other end of the spectrum (from Symmetric-key) is Public-key Cryptography.

Other Reference:

Handbook of Applied Cryptography (free)

## OpenSSL for Matlab

Tonight I’m going to discuss OpenSSL for Matlab – which has been tested against Matlab for Windows and Mac OS X.

This code was written strictly to make it easier to look at various algorithms and modes under different circumstances.  However, its a neat tool and has many uses beyond its original intentions.

– First step (assuming you already have Matlab) is to build the project.  BuildMex is a helper routine to automatically complete the process.  If you change the default install path of OpenSSL that change will need to be taken into account in buildMex.  I think the path and potential change that may be necessary is obvious (ispc() – is windows only):

if(ispc())

options = [‘ C:\openssl\lib\libeay32.lib -IC:\openssl\include ‘ options];

elseif(isunix())

options = [options ‘ -I/usr/local/ssl/lib -lssl -lcrypto ‘];

end

– Step two, now that everything is built we need to make sure everything is working, example.m will verify that.

This is the output:

>> example
Test 1a Passed
Test 1b Passed
Test 1c Passed
Test 1d Passed
Test 2 Passed
Test 3 Passed

So, now that we know everything is working lets take a look at whats going on.  I’m not going to give an overly in depth description of OpenSSL, but I will describe this tool and the inputs which feed directly into OpenSSL.  Look for a more in depth discussion on OpenSSL in the future.

I’m going to start with a simple example and work up from there.

% Test 1a: Basic Encryption / Decryption

dataToEncrypt = uint8(1:255);

encryptedData = mexEVP_Encrypt(‘data’,dataToEncrypt);

decrypted = mexEVP_Decrypt(‘data’,encryptedData);

This example starts by generating data of type UINT8.  It then encrypts it and decrypts it.  If you were to plot dataToEncrypt & encryptedData it will look like this:

While the example above is powerful, it doesn’t support doubles – the primary Matlab data type.  We need a way to convert from double to uint8 and back again with out losing data.  Which leads to example 2:

%Test 2: Data Conversion

dataStart = 1:255;

toUint8 = [];

for J=1:length(dataStart)

temp = double2uint8(dataStart(J));

toUint8 = [toUint8; temp];

end

toDouble = [];

for J=1:8:length(toUint8)

temp = uint82double(toUint8(J:J+7));

toDouble = [toDouble; temp];

end

The code above is straight forward with a basic understanding of whats happening.  Keep in mind a double is 8 bytes and a uint8 is 1 byte and there are 8 bits in 1 byte.  So each double in the dataStart array needs to be converted to a uint8 – the first loop accomplishes that.  It iterates over each element and appends it to the toUint8 array – which will have 8x more elements than the input array.  The toUint8 array could be passed in the mexEVP_Encrypt function at this point as in the first example.  The avid Matlab user will also notice the guts of each loop can be reduced to 1 line – more on that in a few minutes.

So lets assume we have just returned from the mexEVP_Decrypt function – we will need to convert the uint8 array back to doubles.  This loop looks pretty similar to the first loop with one major difference – the number of elements being passed into uint82double.  Since the are 8 bytes in a double – 8 bytes need to be passed in.  Thats why J:J+7 is passed in – 8 bytes are passed in and 1 double (8 bytes) is returned.

With any luck you know have a basic understanding of how to encrypt and decrypt data that is a uint8 or a double.  We are missing a few key things at this point like:

1. Which algorithm – with mode and size is being run?
2. What key is being used to encrypt my data?
3. What IV is being used in tandem to encrypt my data?

I’m going to point out the included help – if you run mexEVP_Encrypt with no inputs this will output:

mexEVP_Encrypt:

data: What data would you like to encrypt?  This is the only required option…

key: what key would you like the data it be encrypted with?

IV: The initialization vector used to speed some algorithms up

Supported Ciphers: (Reference OpenSSL documentation for current & complete list)

Currently Defaults to: aes-128-cbc

AES: aes-128-ecb, aes-128-cbc, aes-192-ecb, aes-192-cbc, aes-256-ecb, aes-256-cbc

Blowfish: bf-ecb, bf-cbc, bf-cfb, bf-ofb

Cast: cast-ecb, cast-cbc, cast-cfb, cast-ofb

DES: des-ecb, des-cbc, des-cfb, des-ofb

DESX: desx

3DES: des-ede3, des-ede3-cbc, des-ede3-cfb, des-ede3-ofb, des-ede, des-ede-cbc, des-ede-cfb, des-ede-ofb

IDEA: idea-ecb, idea-cbc, idea-cfb, idea-ofb

I’m also going to point out one other functions: mexRandom

mexRandom can be used to generate a random Key & IV though the official OpenSSL mechanism.

Lets put the basic understanding together with everything else we learned so far – into one large example:

% Test (not in example.m): Encryption / Decryption – random key, iv & custom algorithm

dataToEncrypt = 1:0.25:25;

[key, iv] = mexRandom(‘key’,’iv’);

toUint8 = [];

for J=1:length(dataToEncrypt)

toUint8 = [toUint8; double2uint8(dataToEncrypt(J))];

end

encryptedData = mexEVP_Encrypt(‘data’,toUint8,’key’,key,’iv’,iv,’cipher’,’bf-cbc’);

decrypted = mexEVP_Decrypt(‘data’,encryptedData,’key’,key,’iv’,iv,’cipher’,’bf-cbc’);

toDouble = [];

for J=1:8:length(decrypted)

toDouble = [toDouble; uint82double(decrypted(J:J+7))];

end

Which can be easily verified by summing the difference of dataToEncrypt and toDouble:

>> sum(dataToEncrypt – toDouble’)

ans =

0

Now I that that we now the output is valid look at the inputs.

mexRandom is generating a key and and an iv, here is a sample key:

The cipher being passed in is ‘bf-cbc’ – blowfish with a cbc mode.
I realize at this point your probably a bit saturated and more description about is what is going on behind the curtain is needed.  I’m going to cover more about that in a later post, but in the mean time I encourage you to use this code, take a look through my first post, wikipedia, and the OpenSSL website for more details.

Posted in Uncategorized | 1 Comment

## OpenSSL: An example from the command line

This first post is going to be based on the “test_AES.c” file available here AES OpenSSL Code Sample. I wrote this short example when I was first learning and navigating my way through OpenSSL land.

At that time I couldn’t find any strong examples that demonstrated how to use OpenSSL in a general form from the command line without sockets.  My end goal was to create a Matlab Toolbox (which I completed, but more on that another time) that I could use to test various algorithms and modes.  I ended up stumbling on the EVP interface which provides a nice interface providing access to all supported algorithms (DES, AES, Blowfish, etc…),  key lengths, and mode.  More on the supported ciphers here.  In the coming weeks I plan to give a better explanation on modes, but a good introduction is already available.

Most of the examples I found had issues either in the encryption and the decryption for a few reasons.   This encryption example works:

EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), (unsigned char *)mykey, (unsigned char *)iv);

EVP_EncryptUpdate(&ctx, (unsigned char *)ciphertext, &out_len, (unsigned char *)plaintext, in_len); //Call when needed

tmp_len += out_len; //Need to keep track of how much data has been encrypted

EVP_EncryptFinal(&ctx, (unsigned char *) &ciphertext[out_len], &out_len);  //Only call once – when done with encryption

tmp_len += out_len;

The problems were hidden by not zeroing out the plaintext buffer and reinitializing the variables needed to decrypt before reading the data back into it:

memset(plaintext,0,sizeof(plaintext));

in_len = tmp_len;

out_len = tmp_len = 0;

So with that said, feel to take a look at the code, it scales up .  It builds under Windows and UNIX .

This command line example shows the code building under widows with Visual C++ Express:

This example moves on to building on UNIX – I’m using gcc with OS X:

gcc test_AES.c -L/usr/local/ssl/lib/ -lssl -lcrypto

With all of that said, what example could possible be complete without output:

_______________________________________________________________________
No encrypt: Hello World? – this is a test of AES! of which I’m curious to see if it really is working.
Encrypted: ;|?|??`A ??)?????#?’??7E??/
Hv???G????b0&?/i???Y????????O??R?l?v?W??xT?ɡzp?????<?Y?aU
Decrypted: Hello World? – this is a test of AES! of which I’m curious to see if it really is working.

_______________________________________________________________________

It should go with out saying this code is not industrial strength and is really just a fun example to have fun with.