A.Kryeem
A.Kryeem

Reputation: 56

OpenSSL EVP_CIPHER_CTX get updated IV

I'm using OpenSSL EVP_Encrypt APIs, with AES_ctr_128 mode. I'm trying to retrieve the updated (incremented counter) In OpenSSL 1.1.0 we CANNOT simply do:

    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    /*
    EVP_EncryptInit(ctx, ...);
    EVP_EncryptUpdate(ctx, ...);
    EVP_EncryptFinal(ctx, ...);
    */
    memcpy(iv, ctx->iv, sizeof(ctx->iv);

since the ctx structure is hidden (getting incomplete type error with the above code).

Also there is no any get API for this field.

Is there any way to get the updated IV buffer stored in EVP_CIPHER_ctx structure (Incremented IV)?

Upvotes: 3

Views: 1598

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94048

The IV alone is only enough if you write a fixed number of blocks (with block size 16 for AES) to the cipher. So you need to keep track of the amount of data written anyway.

To retrieve the counter value it is therefore easier if you simply calculate it yourself. Then you can restart the cipher stream for a specific IV. Note that you may still have to skip an amount of plain or ciphertext, for instance by encrypting zero valued bytes, before you can continue the operation.

So to calculate the counter value simply perform addition of the IV with the number of complete blocks processed: len(pt) / n where len is the length in bytes and n = 16 using integer division. The IV consists of the nonce and the initial counter value as a fixed size big endian number. So you can just add each byte of the IV with each byte of the integer, taking the possible carry from right to left (high index for the least significant byte, to low index with the most significant byte).

To calculate how many bytes you need to skip (i.e. encrypt/decrypt before the key stream is again synchronized you simply calculate len(pt) % n where % is the remainder or modulus operator.

Upvotes: 1

Related Questions