> From: owner-openssl-us...@openssl.org On Behalf Of Steffen DETTMER
> Sent: Wednesday, 05 May, 2010 14:04

> * Christina Penn wrote on Wed, May 05, 2010 at 07:42 -0400:
> >    Can you show me exactly how to break up my example code 
> to make my
> >    example work? I tried removing the EVP_DecryptFinal_ex from my
> >    DecryptMessage function and just seeing if the first 
> part would just
> >    decrypt the first 7 bytes, 
> 
> the algorithm works on lengths with (len % blocksize) == 0, i.e. on
> lengths that are multiples of blocksize, for AES-128 that are 16
> byte (or 32, 48...).

To be exact, the cipher primitive (AES) works on a block (16 bytes) 
and the pure mode (CBC) works on integral blocks. CBC with padding
(such as PKCS5, which EVP does by default) allows any number of bytes 
plaintext but ciphertext is rounded (strictly) up to integral blocks.

*Progam* logic like the OP's with EVP_DecryptUpdate for CBC-padded 
can operate on variable bytes, but with a lag of up to a full block 
which is buffered so that _DecryptFinal can unpad (and check).

> Note that the blocksize of AES-128 is 128 bits (16 byte), but
> your `int blockSize=128;' is used as 128 bytes, which at least is
> confusing.
> 
True, though to my reading not actually harmful as posted.

> Also, note not to use `std::string message' for encrypted binary
> data because it may contain binary zeros (also note malloc() can
> fail etc, casts are ugly and C-casts in C++ are worse, etc, SCNR :)).
> 
C++ std::string (and wstring) CAN contain zero aka null bytes(chars).
Unlike C-style char* (and wchar_t*) strings, which cannot. Since the 
classes intentionally make it easy to convert to and from C-style 
(wide)strings you must be careful to not use that convenience. And 
treating it as printable, like cout << ciphertext, is a poor idea.
Another type such as unsigned char [] or vector<unsigned char>
is generally preferable for clarity, but not absolutely required.

Also OP's use of .data() for .length() PLUS ONE isn't really safe; 
IME most C++ implementations do keep a guard char after the data 
for (their) convenience, but the standard doesn't require it.
Plus there's probably no good point to including a terminator 
when using CBC-padded since that already preserves length,
and in fact the OP's code is actually just discarding it.
(Although I have seen reasonable cases of packing *several* 
delimited strings into one cipherblob, and this could be, 
or be considered, a degenerate case of that.)

C++-style allocation (new/delete not malloc/free/etc) avoids 
(all forms of) casts, and (by default) throws for alloc failure 
so you don't have to handle it explicitly in each case. 

Also: whenever a libcrypto routine returns an error indication 
(or libssl returns nonsuccess AND SSL_get_error says SSL_ERROR_SSL) 
it is best to do ERR_print_errors[_fp]; this will usually give you 
more useful info to solve the problem or at least help people here 
do so. http://www.openssl.org/support/faq.html#PROG6 and 7.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to