Skip to content

Instantly share code, notes, and snippets.

@dtikhonov
Last active January 2, 2019 17:41
Show Gist options
  • Save dtikhonov/71735cb8435c81bb8afb190033314ade to your computer and use it in GitHub Desktop.
Save dtikhonov/71735cb8435c81bb8afb190033314ade to your computer and use it in GitHub Desktop.
HP mask using CTR vs ECB using stock openssl (Ubuntu 16)
/* Test whether CTR and ECB produce the same HP mask */
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
/* Set everything to zero for our test: */
static unsigned char KEY[16];
static unsigned char IV[16];
static unsigned char IN[5];
static int
generate_mask (const EVP_CIPHER *cipher, unsigned char mask[16])
{
EVP_CIPHER_CTX *hp_ctx;
int out_len, retval;
hp_ctx = EVP_CIPHER_CTX_new();
if (EVP_EncryptInit_ex(hp_ctx, cipher, NULL, KEY, IV)
&& EVP_EncryptUpdate(hp_ctx, mask, &out_len, IN, sizeof(IN))
&& EVP_EncryptFinal_ex(hp_ctx, mask + out_len, &out_len))
{
retval = 0;
}
else
{
retval = -1;
}
EVP_CIPHER_CTX_free(hp_ctx);
return retval;
}
static void
hexstr (const unsigned char *buf, size_t bufsz, char *out, size_t outsz)
{
static const char b2c[16] = "0123456789ABCDEF";
const unsigned char *const end_input = buf + bufsz;
char *const end_output = out + outsz;
while (buf < end_input && out + 2 < end_output)
{
*out++ = b2c[ *buf >> 4 ];
*out++ = b2c[ *buf & 0xF ];
++buf;
}
if (buf < end_input)
out[-1] = '!';
*out = '\0';
}
int
main (void)
{
unsigned char mask[16];
char str[sizeof(mask)* 2 + 1];
memset(mask, 0xCE, sizeof(mask));
if (0 != generate_mask(EVP_aes_128_ctr(), mask))
{
fprintf(stderr, "failed to generate CTR mask\n");
return 1;
}
hexstr(mask, sizeof(mask), str, sizeof(str));
printf("CTR mask: %s\n", str);
memset(mask, 0xCE, sizeof(mask));
if (0 != generate_mask(EVP_aes_128_ecb(), mask))
{
fprintf(stderr, "failed to generate ECB mask\n");
return 1;
}
hexstr(mask, sizeof(mask), str, sizeof(str));
printf("ECB mask: %s\n", str);
return 0;
}
__END__
Results when run:
CTR mask: 66E94BD4EF0000006D0B400000000000
ECB mask: EA301DE00E1D5CB994996F635C3B1DD8
@nibanks
Copy link

nibanks commented Jan 2, 2019

Proposed changes:

static int
generate_mask_ctr (unsigned char mask[16])
{
    onst EVP_CIPHER *cipher;
    EVP_CIPHER_CTX *hp_ctx;
    int out_len, retval;

    cipher = EVP_aes_128_ctr();
    hp_ctx = EVP_CIPHER_CTX_new();
    if (EVP_EncryptInit_ex(hp_ctx, cipher, NULL, KEY, IV)
        && EVP_EncryptUpdate(hp_ctx, mask, &out_len, IN, sizeof(IN))
        && EVP_EncryptFinal_ex(hp_ctx, mask + out_len, &out_len))
    {
        retval = 0;
    }
    else
    {
        retval = -1;
    }

    EVP_CIPHER_CTX_free(hp_ctx);
    return retval;
}

static int
generate_mask_ecb (unsigned char mask[16])
{
    onst EVP_CIPHER *cipher;
    EVP_CIPHER_CTX *hp_ctx;
    int out_len, retval;

    cipher = EVP_aes_128_ecb();
    hp_ctx = EVP_CIPHER_CTX_new();
    if (EVP_EncryptInit_ex(hp_ctx, cipher, NULL, KEY, 0)
        && EVP_EncryptUpdate(hp_ctx, mask, &out_len, IV, sizeof(IV))
        && EVP_EncryptFinal_ex(hp_ctx, mask + out_len, &out_len))
    {
        retval = 0;
    }
    else
    {
        retval = -1;
    }

    EVP_CIPHER_CTX_free(hp_ctx);
    return retval;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment