[openssl-dev] [openssl.org #3636] BIO_read() (enc_read()) with 0 length

Istvan Noszticzius via RT rt at openssl.org
Sat Dec 13 07:14:31 UTC 2014


Dear Openssl-bugs,

According to the BIO_read() documentation [1]: "All these functions return either the amount of data successfully read or written (if the return value is positive) or that no data was successfully read or written if the result is 0 or -1.". However if there is a decryption BIO in the chain, requesting the reading of 0 bytes (by setting the "len" parameter to 0) results in a return value of 1, indicating that 1 byte was actually read, but - upon checking the passed in buffer's contents - turns not to be the case (as it should be).

Now it is not documented whether passing 0 to as the value for "len" is legal and what the defined behavior (if any) should be in that case, but (looking at the code) if a NULL "buf" value is passed to enc_read() (thus BIO_read()) it will always return 0 (including when "len" is 0), see [2]. It seems to me that enc_read() (thus BIO_read()) should always return 0 if the value of "len" is 0 (regardless of whether "buf" is NULL or not), and in fact that seems to be the behavior for enc_write() [3].

Attached is a small test program demonstrating the issue (tested against the latest 1.x OpenSSL).

Sincerely,
Istvan Noszticzius
RightNow/Oracle development

[1] "int BIO_read(BIO *b, void *buf, int len)": https://www.openssl.org/docs/crypto/BIO_read.html
[2] line 148 of https://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=crypto/evp/bio_enc.c
[3] line 258 of https://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=crypto/evp/bio_enc.c
-------------- next part --------------
#include <stdio.h>

#include <openssl/evp.h>
#include <openssl/bio.h>

int main(int argc, char** argv)
{
    unsigned char encrypted_buffer[16+1] = "\xea\xde\x4d\xb3\xaf\xa2\x03\x20\x0b\x45\xdd\x82\x0e\xa9\x38\x26";
    unsigned char read_buffer[16+1] = { 0 };
    unsigned char key[] ="\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
    unsigned char iv[] = "\x00\x00\x00\x00\x00\x00\x00\x00";
    int read_bytes;

    ERR_load_crypto_strings();
    OpenSSL_add_all_algorithms();

    BIO* bio_mem = BIO_new_mem_buf(encrypted_buffer, sizeof(encrypted_buffer)-1);
    BIO* bio_dec = BIO_new(BIO_f_cipher());
    BIO_set_cipher(bio_dec, EVP_get_cipherbyname("des-ede3-cbc"), key, iv, 0);
    bio_dec = BIO_push(bio_dec, bio_mem);
    read_bytes = BIO_read(bio_dec, read_buffer, 0); // Reading 0 bytes
    printf("read bytes: %d (data: \"%s\")\n", read_bytes, read_buffer); // read_bytes is 1 (but no bytes were actually read)

    return(0);
}


More information about the openssl-dev mailing list