'How can I decrypt only 16 byte with AES-CBC-128 with OpenSSL@3

I'm using the EVP api to decrypt aes-128-cbc message, but when I only have 16 bytes(or maybe less), the openssl did't output the decrypted plain message for me.

here is my code

void decrypt(const uint8_t *key, const uint8_t * iv, 
             const uint8_t *source, uint8_t *target, 
             size_t offset, size_t length) 
{
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    int outl = 0;
    
    EVP_DecryptUpdate(ctx, target, &outl, source + offset, length);
    EVP_DecryptFinal(ctx, target + outl, &outl);

    EVP_CIPHER_CTX_free(ctx);
}

When I using

decrypt(key, iv, input, output, 0, 17);

It works fine, but when I change length to 16

decrypt(key, iv, input, output, 0, 16);

It outputs nothing.

edit: Reproducible example

#include "stdio.h"
#include "stdint.h"
#include "string.h"

#include <openssl/evp.h>

void decrypt(const uint8_t *key, const uint8_t * iv, 
             const uint8_t *source, uint8_t *target, 
             size_t offset, size_t length) 
{
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    int outl = 0;
    
    EVP_DecryptUpdate(ctx, target, &outl, source + offset, length);
    EVP_DecryptFinal(ctx, target + outl, &outl);

    EVP_CIPHER_CTX_free(ctx);
}

void print_result(uint8_t *mem) {
    for(size_t j = 0; j < 16; j++) {
        printf("%02x", mem[j]);
    }

    printf("\n");
}

int main() {
    // this is test data not real one
    uint8_t key[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 };
    uint8_t iv[16] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 };

    uint8_t input[16] = { 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac };
    uint8_t output[16];
    memset(output, 0, 16);

    decrypt(key, iv, input, output, 0, 16);

    // output should be 638c9ef023ae52beb73f989f24a92e3b but is all zero
    print_result(output);

    // make a extra byte here
    uint8_t input1[17] = { 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0x00 };
    uint8_t output1[17];
    memset(output1, 0, 17);

    decrypt(key, iv, input1, output1, 0, 17);
    // this is right
    print_result(output1);
}

output:

% ./a.out                                                       
00000000000000000000000000000000
638c9ef023ae52beb73f989f24a92e3b


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source