RE: Is it not possible to decrypt partial AES messages?

2010-05-07 Thread Dave Thompson
 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 vectorunsigned 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 Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


is it not possible to decrypt partial AES messages?

2010-05-05 Thread Christina Penn
Hello,



Here is some example code of me trying to decrypt a partial AES message. It
doesn't work.. is there a way I can do something like this? It only works if
I call DecryptMessage() with the entire encrypted string. Why?



Thanks!!



#include openssl/evp.h
#include iostream
#include string
using namespace std;
#pragma comment (lib, libeay32MDd.lib)

EVP_CIPHER_CTX enCTX, deCTX;
int blockSize=128;

string DecryptMessage(const string message)
{
try
{
int p_len = message.length(), f_len = 0;
unsigned char* plaintext = (unsigned char*)malloc(p_len);
if(!EVP_DecryptInit_ex(deCTX, NULL, NULL, NULL, NULL))
cerr  ERROR in EVP_DecryptInit_ex  endl;
if(!EVP_DecryptUpdate(deCTX, plaintext, p_len, (unsigned
char*)message.data(),
message.length()))
cerr  ERROR in EVP_DecryptUpdate  endl;
if(!EVP_DecryptFinal_ex(deCTX, plaintext+p_len, f_len))
cerr  ERROR in EVP_DecryptFinal_ex  endl;

return string((char*)plaintext, p_len + f_len-1);
}
catch(...)
{
return message;
}
}

string EncryptMessage(const string message)
{
try
{
// max ciphertext len for a n bytes of plaintext is n +
AES_BLOCK_SIZE bytes
int c_len = message.length() + blockSize;
unsigned char *ciphertext = (unsigned char*)malloc(c_len);
if(!EVP_EncryptInit_ex(enCTX, NULL, NULL, NULL, NULL))
cerr  ERROR in EVP_EncryptInit_ex  endl;
// update ciphertext, c_len is filled with the length of ciphertext
generated
if(!EVP_EncryptUpdate(enCTX, ciphertext, c_len, (unsigned
char*)message.data(),
message.length()+1))
cerr  ERROR in EVP_EncryptUpdate  endl;
// update ciphertext with the final remaining bytes
int f_len = 0;
if(!EVP_EncryptFinal_ex(enCTX, ciphertext+c_len, f_len))
cerr  ERROR in EVP_EncryptFinal_ex  endl;

return string((char*)ciphertext, c_len + f_len);
}
catch(...)
{
return message;
}
}

int main()
{
// ssl init
const EVP_CIPHER* c = EVP_aes_128_cbc();
unsigned char key[32], iv[32];
string passphrase=test;
string salt=12345678;
int rounds=5;
EVP_BytesToKey(c, EVP_sha1(), (unsigned char*)salt.data(), (unsigned
char*)passphrase.data(), passphrase.length(), rounds, key, iv);
EVP_CIPHER_CTX_init(deCTX);
EVP_DecryptInit_ex(deCTX, c, NULL, key, iv);
EVP_CIPHER_CTX_init(enCTX);
EVP_EncryptInit_ex(enCTX, c, NULL, key, iv);

// trying to encrypt and decrypt
string plaintext = 015this is a test!;
cout  plaintext:   plaintext  endl;
string ciphertext = EncryptMessage(plaintext);
cout  ciphertext:   ciphertext  endl;
string header = ciphertext.substr(0, 7);
cout  header:   header  endl;
string decrypted_header = DecryptMessage(header);
cout  decrypted header:   decrypted_header  endl;
}


Re: Is it not possible to decrypt partial AES messages?

2010-05-05 Thread Christina Penn
Hello David,

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, but it got thrown into my catch statement. I am really confused.

Thanks,
Christina Penn

On Tue, May 4, 2010 at 6:42 PM, David Schwartz dav...@webmaster.com wrote:


 Christina Penn wrote:

  Here is some example code of me trying to decrypt a partial AES message.
  It doesn't work.. is there a way I can do something like this? It only
 works
  if I call DecryptMessage() with the entire encrypted string. Why?

 Your DecryptMessage function is specifically designed to require the entire
 encrypted string:

if(!EVP_DecryptFinal_ex(deCTX, plaintext+p_len, f_len))
cerr  ERROR in EVP_DecryptFinal_ex  endl;

 See how it calls EVP_DecryptFinal_ex?

 As EVP_DecryptInit should only be called at the very start to initialize a
 message, so EVP_DecryptFinal_ex should only be called at the very end to
 finish a complete message. In the middle, you should only be using
 EVP_DecryptUpdate.

 DS

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



Re: Is it not possible to decrypt partial AES messages?

2010-05-05 Thread Dr. Stephen Henson
On Wed, May 05, 2010, Christina Penn wrote:

 Hello David,
 
 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, but it got thrown into my catch statement. I am really confused.
 

In that mode (CBC) you can decrypt partial messages but only in multiples
of the block size: 16 bytes for AES.

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


Re: Is it not possible to decrypt partial AES messages?

2010-05-05 Thread Steffen DETTMER
* 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...).
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.

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 :)).

but it got thrown into my catch statement.
I am really confused.

(I'm also confused, because there is no `throw' anywhere...)

oki,

Steffen


 
About Ingenico: Ingenico is a leading provider of payment solutions, with over 
15 million terminals deployed in more than 125 countries. Its 2,850 employees 
worldwide support retailers, banks and service providers to optimize and secure 
their electronic payments solutions, develop their offer of services and 
increase their point of sales revenue. More information on 
http://www.ingenico.com/.
 This message may contain confidential and/or privileged information. If you 
are not the addressee or authorized to receive this for the addressee, you must 
not use, copy, disclose or take any action based on this message or any 
information herein. If you have received this message in error, please advise 
the sender immediately by reply e-mail and delete this message. Thank you for 
your cooperation.
 P Please consider the environment before printing this e-mail
 
 
__
OpenSSL Project http://www.openssl.org
User Support Mailing Listopenssl-users@openssl.org
Automated List Manager   majord...@openssl.org


RE: Is it not possible to decrypt partial AES messages?

2010-05-05 Thread David Schwartz

Christina Penn wrote:


 Hello David,
 
 Can you show me exactly how to break up my example code to make my example
work?

It's really simple. When you want to decrypt a message, call
EVP_DecryptInit_ex. For each chunk of data you want to decrypt that is part
of the message, call EVP_DecryptUpdate. For the last block (or after it),
call EVP_DecryptFinal_ex.

 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, but it
got
 thrown into my catch statement. I am really confused.

I'm not sure what you mean. That should have worked. (Note that zero bytes
coming out *is* working. You are not guaranteed that any particular number
of input bytes will produce any particular number of output bytes except
that all of the input will, of course, produce all of the output. If you
want a stream cipher, you know where to find them.)

By the way, I strongly advise you not to use the C++ 'string' class for
arbitrary chunks of bytes. It's really not suitable.

DS

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


Is it not possible to decrypt partial AES messages?

2010-05-04 Thread Christina Penn
Hello,



Here is some example code of me trying to decrypt a partial AES message. It
doesn't work.. is there a way I can do something like this? It only works if
I call DecryptMessage() with the entire encrypted string. Why?



Thanks!!



#include openssl/evp.h
#include iostream
#include string
using namespace std;
#pragma comment (lib, libeay32MDd.lib)

EVP_CIPHER_CTX enCTX, deCTX;
int blockSize=128;

string DecryptMessage(const string message)
{
try
{
int p_len = message.length(), f_len = 0;
unsigned char* plaintext = (unsigned char*)malloc(p_len);
if(!EVP_DecryptInit_ex(deCTX, NULL, NULL, NULL, NULL))
cerr  ERROR in EVP_DecryptInit_ex  endl;
if(!EVP_DecryptUpdate(deCTX, plaintext, p_len, (unsigned
char*)message.data(),
message.length()))
cerr  ERROR in EVP_DecryptUpdate  endl;
if(!EVP_DecryptFinal_ex(deCTX, plaintext+p_len, f_len))
cerr  ERROR in EVP_DecryptFinal_ex  endl;

return string((char*)plaintext, p_len + f_len-1);
}
catch(...)
{
return message;
}
}

string EncryptMessage(const string message)
{
try
{
// max ciphertext len for a n bytes of plaintext is n +
AES_BLOCK_SIZE bytes
int c_len = message.length() + blockSize;
unsigned char *ciphertext = (unsigned char*)malloc(c_len);
if(!EVP_EncryptInit_ex(enCTX, NULL, NULL, NULL, NULL))
cerr  ERROR in EVP_EncryptInit_ex  endl;
// update ciphertext, c_len is filled with the length of ciphertext
generated
if(!EVP_EncryptUpdate(enCTX, ciphertext, c_len, (unsigned
char*)message.data(),
message.length()+1))
cerr  ERROR in EVP_EncryptUpdate  endl;
// update ciphertext with the final remaining bytes
int f_len = 0;
if(!EVP_EncryptFinal_ex(enCTX, ciphertext+c_len, f_len))
cerr  ERROR in EVP_EncryptFinal_ex  endl;

return string((char*)ciphertext, c_len + f_len);
}
catch(...)
{
return message;
}
}

int main()
{
// ssl init
const EVP_CIPHER* c = EVP_aes_128_cbc();
unsigned char key[32], iv[32];
string passphrase=test;
string salt=12345678;
int rounds=5;
EVP_BytesToKey(c, EVP_sha1(), (unsigned char*)salt.data(), (unsigned
char*)passphrase.data(), passphrase.length(), rounds, key, iv);
EVP_CIPHER_CTX_init(deCTX);
EVP_DecryptInit_ex(deCTX, c, NULL, key, iv);
EVP_CIPHER_CTX_init(enCTX);
EVP_EncryptInit_ex(enCTX, c, NULL, key, iv);

// trying to encrypt and decrypt
string plaintext = 015this is a test!;
cout  plaintext:   plaintext  endl;
string ciphertext = EncryptMessage(plaintext);
cout  ciphertext:   ciphertext  endl;
string header = ciphertext.substr(0, 7);
cout  header:   header  endl;
string decrypted_header = DecryptMessage(header);
cout  decrypted header:   decrypted_header  endl;
}


RE: Is it not possible to decrypt partial AES messages?

2010-05-04 Thread David Schwartz

Christina Penn wrote:

 Here is some example code of me trying to decrypt a partial AES message.
 It doesn't work.. is there a way I can do something like this? It only
works
 if I call DecryptMessage() with the entire encrypted string. Why?

Your DecryptMessage function is specifically designed to require the entire
encrypted string:

if(!EVP_DecryptFinal_ex(deCTX, plaintext+p_len, f_len))
cerr  ERROR in EVP_DecryptFinal_ex  endl;

See how it calls EVP_DecryptFinal_ex?

As EVP_DecryptInit should only be called at the very start to initialize a
message, so EVP_DecryptFinal_ex should only be called at the very end to
finish a complete message. In the middle, you should only be using
EVP_DecryptUpdate.

DS

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