[racket] PLaneTs crypto lib usage question?...

From: Ryan Culpepper (ryan at cs.utah.edu)
Date: Wed Apr 18 10:14:45 EDT 2012

On 04/18/2012 07:05 AM, Rüdiger Asche wrote:
> I'm doodling around with vyzo's crypto lib from PLaneT, doing some very
> rudimentary crypting and encrypting. I'm undoubtedly doing something
> wrong, I just don't know what...
>
> Here's my code (running from a directory that contains the crypto files):
>
> (require srfi/78
> "main.ss"
> (only-in "util.ss" hex))
>
> (require file/sha1)
>
> (define devicekey (list->bytes '(#x12 #x34 #x56 #x78 #x87 #x65 #x43 #x26
> #x12 #x34 #x56 #x78 #x87 #x65 #x43 #x26))) ; must be length 16!!!
>
> (define nonce (list->bytes '(#x12 #x34 #x56 #x78 #x87 #x65 #x43 #x26
> #x12 #x34 #x56 #x78 #x87 #x65 #x43 #x27))) ; must be length 16!!!
>
> (define devicekey1 (list->bytes '(#x12 #x34 #x56 #x88 #x87 #x65 #x43
> #x26 #x12 #x34 #x56 #x78 #x87 #x65 #x43 #x26))) ; must be length 16!!!
>
> (define nonce1 (list->bytes '(#x12 #x34 #x56 #x78 #x87 #x66 #x43 #x26
> #x12 #x34 #x56 #x78 #x87 #x65 #x43 #x27))) ; must be length 16!!!
>
> (define dummy (encrypt cipher:aes-128 devicekey nonce #"1234567887654321"))
>
> (bytes->hex-string dummy)
>
> (decrypt cipher:aes-128 devicekey nonce dummy)
>
> (decrypt cipher:aes-128 devicekey1 nonce dummy)
>
> (decrypt cipher:aes-128 devicekey nonce1 dummy)
>
> In effect, I hardcode two distinct AES keys, 2 initialization vectors
> (wich I call nonce) and one piece of plain text to encrypt and decrypt.
>
> Here are the results of the last three lines when executed in Racket:
>
> (decrypt cipher:aes-128 devicekey nonce dummy)
> #"1234567887654321" <== 1
>>
> (decrypt cipher:aes-128 devicekey1 nonce dummy)
> EVP_CipherFinal_ex: libcrypto error: bad decrypt [digital envelope
> routines:EVP_
> DecryptFinal_ex:101077092] <== 2
>>
> (decrypt cipher:aes-128 devicekey nonce1 dummy)
> #"1234557887654321" <== 3
>
> So the first decryption (with the correct key and iv) yields the
> expected result. Everything fine here.

Note that the ciphertext is 32 bytes, whereas the plaintext is 16 bytes. 
I think this is because the 'encrypt' function is automatically doing 
PKCS padding to the plaintext to bring it to a full number of blocks. 
Since it starts out as a single block, the padding brings it to two 
blocks. (If you delete the last byte of the plaintext, the plaintext 
will be be padded to a single full block and the corresponding 
ciphertext will also be a single block---16 bytes.)

See also http://www.openssl.org/docs/crypto/EVP_EncryptInit.html#NOTES

> When I decrypt with the correct iv but a wrong key, the OpenSSL Crypto
> Lib raises an error. I think that is wrong; it should simply return
> garbled output?

I think the error is because it tries to reverse the PKCS padding on the 
garbled decrypted output, and it fails there.

> And when I decrypt with the correct key but an invalid init vector, I
> would expect the decryption result to be radically different from the
> original; instead, there is only one byte varying as if the iv only does
> some weak manipulation on the input before doing the encryption? Is that
> the way AES-128 works?

That's the way the cipher-block chaining (CBC) encryption mode works, 
and according to the docs for (planet vyzo/crypto), that's the mode used 
by ciphers that don't include a mode in their name (like cipher:aes-128).

The IV isn't responsible for the secrecy of the message; that's the 
key's job. The IV is there to prevent identical blocks in the plaintext 
from appearing as identical blocks in the ciphertext. (Where "plaintext" 
and "ciphertext" comprise all multiple communications conducted with the 
same key.)

BTW, I recommend "Practical Cryptography" by Niels Ferguson and Bruce 
Schneier as a good overview of modern cryptography and a guide to what 
to worry about when implementing cryptographic systems.

Ryan

Posted on the users mailing list.