15

I'd like to use the OpenSSL library to decrypt some AES data. The code has access to the key. This project already uses libopenssl for something else, so I'd like to stick to this library.

I went looking directly into /usr/include/openssl/aes.h since the OpenSSL site is light on documentation. The only decrypt function is this one:

void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);

Unfortunately, this doesn't have a way to specify the length of the in pointer, so I'm not sure how that would work.

There are several other functions which I believe take a numeric parm to differentiate between encryption and decryption. For example:

void AES_ecb_encrypt(*in, *out, *key, enc);
void AES_cbc_encrypt(*in, *out, length, *key, *ivec, enc);
void AES_cfb128_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfb1_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfb8_encrypt(*in, *out, length, *key, *ivec, *num, enc);
void AES_cfbr_encrypt_block(*in, *out, nbits, *key, *ivec, enc);
void AES_ofb128_encrypt(*in, *out, length, *key, *ivec, *num);
void AES_ctr128_encrypt(*in, *out, length, *key, ivec[], ecount_buf[], *num);
void AES_ige_encrypt(*in, *out, length, *key, *ivec, enc);
void AES_bi_ige_encrypt(*in, *out, length, *key, *key2, *ivec, enc);

From what I understand using Google, the enc parm gets set to AES_ENCRYPT or AES_DECRYPT to specify which action needs to take place.

Which brings me to my 2 questions:

  1. What do these names mean? What is ecb, cbc, cfb128, etc..., and how do I decide which one I should be using?
  2. What is the unsigned char *ivec parm needed for most of these, and where do I get it from?
jww
  • 97,681
  • 90
  • 411
  • 885
Stéphane
  • 19,459
  • 24
  • 95
  • 136
  • You should *not* use `AES_encrypt` and friends. You should be using `EVP_*` functions. See [EVP Symmetric Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides *both* confidentiality and authenticity. See [EVP Authenticated Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) on the OpenSSL wiki. – jww May 15 '15 at 20:14

1 Answers1

18

There's no size given because the block sizes for AES are fixed based on the key size; you've found the ECB mode implementation, which isn't suitable for direct use (except as a teaching tool).

ECB, CBC, CFB128, etc, are all short names for the modes of operation that are in common use. They have different properties, but if you never touch ECB mode, you should be alright.

I suggest staying further away from the low-level code; use the EVP_* interfaces instead, if you can, and you can move some of these decisions into a text configuration file, so your users could easily select between the different ciphers, block sizes, and modes of operation if there should ever be a good reason to change away from the defaults.

My sympathies, OpenSSL documentation feels worse than it is, and it isn't that great. You may find Network Security with OpenSSL a useful book. I wish I had found it sooner the last time I needed to use OpenSSL. (Don't let the silly title fool you -- it should have been titled just "OpenSSL". Oh well.)

Edit I forgot to mention the initialization vectors. They are used to make sure that if you encrypt the same data using the same key, the ciphertext won't be identical. You need the IV to decrypt the data, but you don't need to keep the IV secret. You should either generate one randomly for each session (and send it along with an RSA or El Gamal or DH-encrypted session key) or generate it identically on both endpoints, or store it locally with the file, something like that.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • 4
    "There's no size given because the block sizes for AES are fixed based on the key size" -- not really; they're fixed at 16 bytes independent of key size. And the reason AES_decrypt doesn't take a size is because it only decrypts one block, so the length is fixed at 16. – Jumbogram Feb 27 '11 at 12:36
  • 1
    Note that if you're decrypting a message that is encrypted by another process outside of your control, the block cipher mode (CBC, CFB etc) will be specified by that process. The initialisation vector should be supplied along with the ciphertext. – caf Feb 28 '11 at 05:35
  • 1
    Note that Java, when told to use AES without specifying anything else, defaults to ECB mode. Once I understood that and what all these functions were for, things made much more sense. I now have my C/C++ code using OpenSSL to decrypt the payload that comes from this specific Java application. – Stéphane Mar 01 '11 at 18:49
  • 2
    @Stéphane, pity Java defaults to ECB mode, it's really not intended for 'end users', but it _is_ a lowest common denominator. – sarnold Mar 02 '11 at 09:13
  • @sarnold: How would I use the EVP_* interface to do AES encryption ? On the page you link to, I see many ciphers, but not AES. – Gene Vincent Apr 11 '12 at 16:55
  • @Gene: OpenSSL's documentation is .. uneven at best. My distribution's packaging of OpenSSL placed the `evp.h` header in `/usr/include/openssl/evp.h`, and it includes all the declarations you expect: `EVP_aes_128_ecb()`, `_cbc()`, `_cfb1()`, `_cfb8()`, `_cfb128()`, `_ofb()`. The routines are available in 128, 192, 256, bits. – sarnold Apr 12 '12 at 00:17