0

I have a 1MB size data and want to use aes_128_ctr to encrypt. I found the source code in openssl as follow.

/* The input encrypted as though 128bit counter mode is being
 * used.  The extra state information to record how much of the
 * 128bit block we have used is contained in *num, and the
 * encrypted counter is kept in ecount_buf.  Both *num and
 * ecount_buf must be initialised with zeros before the first
 * call to AES_ctr128_encrypt().
 */
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
    const unsigned long length, const AES_KEY *key,
    unsigned char counter[AES_BLOCK_SIZE],
    unsigned char ecount_buf[AES_BLOCK_SIZE],
    unsigned int *num) {

    unsigned int n;
    unsigned long l=length;

    assert(in && out && key && counter && num);
    assert(*num < AES_BLOCK_SIZE);

    n = *num;

    while (l--) {
        if (n == 0) {
            AES_encrypt(counter, ecount_buf, key);
            AES_ctr128_inc(counter);
        }
        *(out++) = *(in++) ^ ecount_buf[n];
        n = (n+1) % AES_BLOCK_SIZE;
    }

    *num=n;
}

My question is: In order to encrypt the entire 1MB data, do I need to use a while loop to encrypt every 128-bit? Can I just call this function once by setting length as (1024 * 1024 / 16)? And I don't understand what this *num do. Anybody can explain this for me?

Luke
  • 281
  • 2
  • 7
  • 19
  • You have to call the encrypt function multiple times to encrypt all data, but you must initialize ctr_state struct only once, which will be used by the encrypt function. The num parameter is a pointer, which will be pointing to the ctr_state struct's num element: &state->num. Maybe [this](http://stackoverflow.com/questions/3141860/aes-ctr-256-encryption-mode-of-operation-on-openssl/3146214#3146214) answer will help you. – Linus May 28 '16 at 12:38
  • You should *not* use `AES_encrypt` and friends. That's a software-only implementation, so you will not enjoy hardware support, like AES-NI. You should be using `EVP_*` functions. See [EVP Symmetric Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides *both* confidentiality and authenticity. See [EVP Authenticated Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) on the OpenSSL wiki. – jww May 28 '16 at 13:19
  • Possibly related: [AES CTR 256 Encryption Mode of operation on OpenSSL](http://stackoverflow.com/q/3141860/608639) (or at least a reference already provided on Stack Overflow). Also see [Is it possible to use AES CTR mode encryption using the EVP API](http://stackoverflow.com/q/3783311). – jww May 28 '16 at 13:30

1 Answers1

1

You can do it in one go. So first initialise the AES_KEY key (for encryption) and before the encryption do memset(ecount_buf,0,AES_BLOCK_SIZE);unsigned int num=0; and fill the counter buffer with the counter value for your file.

Then call AES_ctr128_encrypt(in,out,length, &key,counter,ecount_buf,&num); where length is the length in bytes so 1024 * 1024.

If you append data to the file later you can go on with the counter, ecount_buf value and num value from after this call. These values are all modified during the function's inner working.

They are needed because if you would encrypt 15 bytes in counter mode and want to add another 15 later, immediately after, you still need the encrypted counter value used for the first 15 bytes to encrypt the 16th byte as well (the block is not used up yet), so after the first encryption num would be 15, to keep track of this. Then the counter gets updated, encrypted to a new value, and used for the next 14 bytes, and num becomes 14, etc. If you're never going to append any data to the file, so out is ready, then just zeroise num, count_buffer and counter after the encrypt call, and forget about them.

It might be less confusing to use the EVP interface to the algorithms instead, which keeps track of this stuff in its own context (look in evp.h).

Henno Brandsma
  • 2,116
  • 11
  • 12