Hello,
I've got a question about the "num" parameter of the cipher context
(EVP_CIPHER_CTX_get_num [0]). The documentation states:
Gets or sets the cipher specific "num" parameter for the associated ctx. Built-in ciphers typically use this to track how much of the current underlying block has been "used" already.
I'd like to use this parameter to check in advance how big should the
output buffer passed to EVP_CipherUpdate be. My understanding of it was
that "num" would be incremented if I feed partial block to
EVP_CipherUpdate but I've failed to observe any other values of "num"
than 0.
My two questions:
- what is the "num" parameter used for? is it only for internal use?
and, more importantly,
- given EVP_CIPHER_CTX object and the length of the input buffer, is
it possible to calculate the needed output buffer size without
explicitly keeping external state?
The manual algorithm on how it is handled has been excellently described
by Matt here [1]. I'm wondering if it's possible to calculate that in
code (from OpenSSL client's perspective).
Thank you in advance for your time!
Kind regards,
Wiktor
[0]: https://www.openssl.org/docs/man3.0/man3/EVP_CIPHER_CTX_get_num.html
[1]:
https://mta.openssl.org/pipermail/openssl-users/2022-November/015623.html
Below you will find sample code that reproduces the behavior of "num"
I've seen. (Please beware that C is not my native language :))
#include <string.h>
#include <openssl/evp.h>
int main()
{
unsigned char outbuf[1024];
int outlen, tmplen;
unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned char iv[] = {1,2,3,4,5,6,7,8};
char intext[] = "1234567"; // half of block size
EVP_CIPHER_CTX *ctx;
FILE *out;
int num;
unsigned int block_size;
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex2(ctx, EVP_aes_128_cbc(), key, iv, NULL);
block_size = EVP_CIPHER_CTX_block_size(ctx);
printf("Block size: %d\n", block_size); // 16- block cipher
num = EVP_CIPHER_CTX_num(ctx);
printf("Num is: %d\n", num); // num is 0
if (!EVP_CipherUpdate(ctx, outbuf, &outlen, intext, strlen(intext))) {
EVP_CIPHER_CTX_free(ctx);
return 1;
}
printf("Out len: %d\n", outlen); // 0 - no block produced, OK
num = EVP_CIPHER_CTX_num(ctx);
printf("Num is: %d\n", num); // num is still 0
// I want to know the exact size of output buffer needed here
if (!EVP_CipherFinal(ctx, outbuf + outlen, &tmplen)) {
EVP_CIPHER_CTX_free(ctx);
return 1;
}
outlen += tmplen;
EVP_CIPHER_CTX_free(ctx);
out = fopen("outfile", "wb");
if (out == NULL) {
return 1;
}
fwrite(outbuf, 1, outlen, out);
fclose(out);
return 0;
}