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
#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);
}
_______________________________________________
openssl-dev mailing list
[email protected]
https://mta.opensslfoundation.net/mailman/listinfo/openssl-dev

Reply via email to