AltSci Concepts

SSL Blowfish Wrapper
by Joel R. Voss aka. Javantea
jvoss@altsci.com
jvoss@myuw.net
Jan 20, 2006

SSL Blowfish Wrapper 0.2 Source [sig]

DESCRIPTION

SSL Blowfish is a wrapper for the OpenSSL library that allows quick and easy integration of SSL Blowfish encryption into projects. It was specifically designed to add SSL Blowfish support for the UDP Session project. It worked quite well. It is just one C file, so it is quite small and easy to add. The two test programs are compatible with the commonly used utility: openssl enc -bf-cbc. The test programs can only work on 1024 bytes at the current time. It is a limitation of the library that you have to allocate as much memory as you plan to use in each packet. For example, if you wanted to encrypt a 600 MB file the same way that you do with openssl enc -bf-cbc, you would have to allocate 600 MB to do so with this library. Since that isn't reasonable, it is reasonable to say that the library is limited to transmitting small packets that are independent from each other. This is a good library for UDP.

One problem with the library is that it requires a new key to be generated for each packet and for Blowfish, this operation is unusually slow. This is a useful security measure, but might hinder very slow machines that require very high rate of transfer. It makes sense that the in this case, a different encryption method could be used. Since OpenSSL is very modular, this library could be switched to a different algorithm.

One vulnerability in the library is the use of the MD5 hash in creation of the key and iv. This can be changed at any time by defining the symbol: USE_SHA1, but would break compatibility with openssl enc -bf-cbc. To use the SHA1 hash instead, the following switch would need to be added to the openssl enc command: "-md sha1".

None of the versions come with integrity checking, but I expect that version 0.4 will come with cryptographic hashing. I am currently looking into HMAC.

METHOD

OpenSSL's useful utility openssl enc -bf-cbc creates interesting files. They are always between 16 and 32 bytes longer than the original, no matter how long the original is. The first 8 bytes are "Salted__". This is a magic header for the enc utility. The next 8 bytes are the salt.

The algorithm that generates the key and the iv are this:

D_1 = MD5(password + salt)
D_2 = MD5(D_1 + password + salt)
(key, iv) = D_1 + D_2
You can see that the salt is pretty useful. So the second 8 bytes are the salt. In the tarball, there is a description and a manual calculation of the key generation (key_derivation1.txt).

Blowfish's block size is 8, so the size is always a multiple of 8, no matter what length the cipher is.

USAGE

Below, you can see actual udp networking code using the ssl_bf library. It is colored in yellow. chat_main() contains all the code required for ssl_bf. It is 13 lines, a 256 byte buffer, and a 1048 byte buffer for encryption and decryption. It requires no malloc(), no free(), no calls to OpenSSL, no tty manipulation, nada. This is invaluable to the coder who needs speed and ease of development. Specifically designed for UDP, each function call is contained, so that each data retreived from the call can be decrypted given only the password.

int chat_main(int s, struct sockaddr_in *saddr, struct sockaddr_in *raddr)
{
    char password[256];
    
    if (!seed_prng(4))
    {
        fprintf(stderr, "Error: Unable to seed the PRNG.\n");
        abort();
    }
    
    // Secure password retreival algorithm from enc
    get_password(password, 256, 1);
    
    // Chat
    while(1)
    {
        // Send
        int data_size = -1;
        char data[1025];
        fgets(data, 1024, stdin);
        // fgets always puts a \0 after the last char.
        // fgets never reads more than size.
        data_size = strlen(data);
        char enc_data[1024 + 24];
        int enc_size = -1;
        encrypt_packet(data, data_size, password, enc_data, &enc_size);
        UDP_CONTROL c = send_data(enc_data, &enc_size, s, (struct sockaddr *)raddr);
        fprintf(stderr, "Sent %s (%i)\n", udp_control_str(c), enc_size);
        
        // In chat, the user initiates the /quit by typing it in.
        if(data_size <= 0 || c != UDP_SENDTO)
        {
            fprintf(stderr, "Sent %s (%i)\n", udp_control_str(c), enc_size);
            break;
        }
        
        // Receive
        int recv_size = 1024;
        c = recv_data(enc_data, &recv_size, s, (struct sockaddr *)raddr);
        fprintf(stderr, "Recv %s (%i)\n", udp_control_str(c), recv_size);
        if(recv_size <= 0 || c != UDP_RECVFROM)
        {
            fprintf(stderr, "Received %s (%i)\n", udp_control_str(c), recv_size);
            break;
        }
        // TODO: Check for Salted__ before you decrypt?
        decrypt_packet(enc_data, recv_size, password, data, &data_size);
        fprintf(stdout, "%s", data);
    }
    return 0;
}
jvoss@ASLinWs01:~$ ssl_bf2ae < data.txt > data.bf
Password:
Verifying - Password:
jvoss@ASLinWs01:~$ ssl_bf2ad < data.bf > data_dec.txt
Password:
jvoss@ASLinWs01:~$ md5sum data.txt && md5sum data_dec.txt
d7bc75303388e9136aced99cfcf009ae  data.txt
d7bc75303388e9136aced99cfcf009ae  data_dec.txt

If you are interested in developing SSL Blowfish, feel free to e-mail me.

Back