3

I am trying to understand the parameters of the following function in openSSL crypto library.

void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
    size_t length, const AES_KEY *key,
    unsigned char ivec[AES_BLOCK_SIZE],
    unsigned char ecount_buf[AES_BLOCK_SIZE],
    unsigned int *num);

By working through the suggestions given here I was able to figure out:

*in - is the buffer in.
*out - is the buffer out.
length - is the the length of the *in buffer.
*key - is the private key.
ivec[0-7] - is the random IV
ivec[8-15] - is the counter thats incremented for every block that's encrypted.

I am not certain about the ecount_buf and num parameters.

I see that num is set to length % AES_BLOCK_SIZE after the call returns.

Any pointers to what the ecount_buf parameter is for ?

Community
  • 1
  • 1
kupamanduka
  • 33
  • 1
  • 4
  • 1
    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 Jul 07 '16 at 22:58

1 Answers1

1

If you look at the implementation code taken from here:

/* 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;
}

you can deduce that it is an intermediate buffer for holding the encrypted counter. num holds the state information (in case of subsequent calls that we might make in order to chain extra data) in a form of the number of bytes used out of the total block size.

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61