Laboratorul 09 - OpenSSL MACs, Hashes and AEAD

Exercise 1

In this exercise we'll use the command line to compute an HMAC, with SHA-1 as the hashing algorithm.

Recall from the lecture that for HMAC to be secure, we need to sample a random key $k \gets \mathcal{K}$.

We can generate random bytes using openssl rand. To compute HMACs, check the documentation for openssl dgst.

For this exercise, use OpenSSL commands to:

  1. generate a 16 byte random key;
  2. use the key to compute the SHA-1 HMAC of the following message: “Laborator IC”;
  3. use the same key to compute the SHA-1 HMAC of the following message: “Laborator IC!”. Notice the difference between the messages - a single character (e.g ”!”). Observe that the message authentication codes are completely different.

Exercise 2

In this exercise you will implement the Birthday attack on SHA-1 from the previous lab using OpenSSL. The goal is to obtain a collision in the first four bytes of the hash.

In contrast to previous labs, this time we'll use C. You can implement the attack from scratch, or start from our archive here.

To compute a digest, you might find the code below useful:

    SHA_CTX context;
    SHA1_Init(&context);
    SHA1_Update(&context, buffer, length);
    SHA1_Final(md, &context); /* md must point to at least 20 bytes of valid memory */

You may compile and install OpenSSL from sources.

Download the library from https://www.openssl.org/source/openssl-1.1.1d.tar.gz, and unpack it.

Open the unpacked folder from bash, and run the following commands:

$ ./config --prefix=your_working_dir --openssldir=your_working_dir/openssl
$ make
$ make install_sw

To fix the makefile using the new paths, change the variables at the start with the ones below:

LDFLAGS=-Lyour_working_dir/lib -lcrypto
CFLAGS=-Wall -g -Iyour_working_dir/include

Exercise 3

Before you start solving the exercises below, download the lab archive from here.

The archive contains the source code for Exercise 4, but sadly it is encrypted. Luckily, we forgot to remove the password file from the archive.

Use openssl commands to decrypt the source file.

The file is encrypted using AES-256 in CBC mode.

Exercise 4

In this exercise we'll use OpenSSL to encrypt and decrypt with AES-128-GCM. Unfortunately, AES-GCM is not supported by the command line utilities of OpenSSL so we'll have to implement it ourselves.

Open the file you decrypted in the previous exercise and inspect the code. There are two functions that need to be implemented: aes_gcm_encrypt and aes_gcm_decrypt. We have included hints to guide you through the code.

The main program initializes a dummy key and a dummy IV; a long message is then encrypted and decrypted. The encryption should automatically include the authentication tag at the end, and the decryption should return an error if the verification of the tag fails.

If you do not change keys and the implementation is ok, the ciphertext you obtain should be equal to our own. Otherwise, some of the tests will fail.

Below we have included an example of encryption with RC2 (taken from the OpenSSL man pages). The AES-GCM encryption implementation is quite similar - the authentication tag is automatically appended when finalizing the encryption context.

int do_crypt(FILE *in, FILE *out, int do_encrypt) {
    /* Allow enough space in output buffer for additional block */
    inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH];
    int inlen, outlen;
    /* Bogus key and IV: we'd normally set these from
     * another source.
     */
    unsigned char key[] = "0123456789";
    unsigned char iv[] = "12345678";
    /* Don't set key or IV because we will modify the parameters */
    EVP_CIPHER_CTX_init(&ctx);
    EVP_CipherInit_ex(&ctx, EVP_rc2(), NULL, NULL, NULL, do_encrypt);
    EVP_CIPHER_CTX_set_key_length(&ctx, 10);
    /* We finished modifying parameters so now we can set key and IV */
    EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt);
 
    for(;;) {
        inlen = fread(inbuf, 1, 1024, in);
        if(inlen <= 0) break;
        if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) {
            /* Error */
            EVP_CIPHER_CTX_cleanup(&ctx);
            return 0;
        }
        fwrite(outbuf, 1, outlen, out);
    }
    if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) {
        /* Error */
        EVP_CIPHER_CTX_cleanup(&ctx);
        return 0;
    }
    fwrite(outbuf, 1, outlen, out);
    EVP_CIPHER_CTX_cleanup(&ctx);
    return 1;
}

You may need to change the the LDFLAGS in Makefile: LDFLAGS=-lcrypto -ldl

See the open ssl manual here page for EVP encrypt to see the usage of the EVP functions and an example similar to the one above.

ic/laboratoare/09.txt · Last modified: 2020/11/05 17:54 by acosmin.maria
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0