On Fri, Nov 27, 2009 at 10:31 AM, Nick via RT <[email protected]> wrote:
> As you understand now, troubles in key generation. It's time to dip into 
> sources.

Most probably troubles in correct usage of APIs. Read on.

> Cipher context initialization (and simultaneous key definition) perform in
> call of EVP_EncryptInit() (in consideration code of crypto_test.cpp).
[...]
> We see initial initialization of `key' with predefined `bf_init' values and
> next computing over `data' (range: {0 - len}, len - cipher key length).
> Cipher key length set to 16 bytes (initialization vector length 8 bytes).
> `Human' key (asciiz-string password) is barely 3 byte length. Computing
> key material over next 12 bytes is wrong, because it contain undefined
> data (it was not zero-filled under win32).

Which is, unless I'm gravely mistaken, case in point of wrong usage of APIs.

Let me elaborate:

 man blowfish
says:
"Blowfish is a block cipher that operates on 64 bit (8 byte) blocks of
data.  It uses a variable size key, but typically, 128 bit (16 byte)
keys are considered good for strong encryption.[...]"

two important things to note here: 'bytes' (not: characters, not:
strings), second: "variable size key, but typically 16 bytes." With
the 16 memorized, we check the EVP layer documentation which one
should use for all things crypto (unless you have a /very/ specific
need which is not served through EVP).

 man EVP
leads us to
 man EVP_EncryptInit
which says:
"EVP_EncryptInit_ex() sets up cipher context ctx for encryption [...]
key is the symmetric key to use and iv is the IV to use (if
necessary), the actual number of bytes used for the key and IV depends
on the cipher.[...]"

Note here the mention of 'bytes' again and the part where it says:
"the actual number of bytes used for the key and IV depends on the
cipher."
With regular BF, we already know that would be 16 bytes each.

The cryptographic routines (and their published mathematical
specifications) do not mention 'passwords' or 'strings' anywhere; it
is an unwritten assumption in the crypto world that you operate on
bytes (or words, or quadwords, ...) and where this is not the case,
such will be documented and specifically mentioned as part of the
cipher design whitepapers/specifications.

I assume you have a thorough understanding of the difference between
bytes, byte arrays, characters and strings in the 'C' programming
language.

Side note: using Blowfish with non-regular sized keys of 16 bytes is
for (very) special circumstances. It can be used that way, but no
matter which key size you are using even then, it's always a fixed
number of bytes.


If, on the other hand, you have strings (often containing passwords)
which carry your key material, you either

1) have to stick to the key size mentioned above and should know how
your strings must be converted to the afore-mentioned defined, fixed
size, key byte sequences, before feeding this to any of the regular
crypto API methods (any method which mentions 'bytes' as input, does
not expect 'strings' instead - a common misconception).

This can be a simple case of hex2bin, base64 decoding or another which
all serve only under quite particular conditions, or a more elaborate
scheme: there are several transformation schemes for passwords to key
material around. Have a look at the

 man EVP_BytesToKey

documentation, where you will find one possible (and advised) way to
transform password strings and other string-based key material into
suitable key byte sequences. This API is particularly useful as it
will help you ensure the produced key sequences match your selected
cipher's requirements, as per previously indicated/quoted documentation.

To see this at work, you may grep for this API in the openssl source
code, where you will find that the
 openssl enc
tool enploys this API to do exactly that: convert key strings to key
byte sequences. The code is available in
 apps/enc.c


There are other roads which lead to Rome, but going through
EVP_BytesToKey() would be advised.


In closing: A lot of the cross-platform and cross-execution-run issues
regarding encrypting/decrypting content are due to erroneously
treating key byte sequences as strings. There is a very subtle
difference between strings, characters, bytes and byte sequences (byte
arrays) in the 'C' programming language, which is often glossed over
in regular programming text books, yet the difference is quite
important, not only when using any cryptographic library API out
there.

--
Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
       http://www.hebbut.net/
mail:   [email protected]
mobile: +31-6-11 120 978
--------------------------------------------------


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to