Reputation: 17117
I'm trying to implement a hybrid cryptosystem (RSA for key envelope, and DES3 (with two-key option) for data envelope). Thus, I'm trying first to implement DES3 with Openssl's EVP
functions. Because it seems I can easily use EVP to combine RSA and DES3 encryption.
I've got this example code (changed data types to fix gcc warnings and put snippets in one file) from the Openssl book:
#include <stdio.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
unsigned char *encrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *data, int inl, int *rb);
unsigned char *decrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *ct, int inl);
void select_random_key(unsigned char *key, int b);
void select_random_iv(unsigned char *iv, int b);
int seed_prng(int bytes);
int main(int argc, char *argv[])
{
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH];
unsigned char *ct, *out;
unsigned char final[EVP_MAX_BLOCK_LENGTH];
unsigned char str[] = "123456789abcdef";
int i = 0;
if (!seed_prng(16))
{
printf("Fatal Error! Unable to seed the PRNG!\n");
abort();
}
select_random_key(key, EVP_MAX_KEY_LENGTH);
select_random_iv(iv, EVP_MAX_IV_LENGTH);
/* EVP_des_ede3() :three-key DES3 with ECB
* EVP_des_ede() :two-key DES3 with ECB
* EVP_des_ede_cbc() :two-key DES3 with CBC
* EVP_des_ede3_cbc() :three-key DES3 with CBC */
EVP_EncryptInit(&ctx, EVP_des_ede_cbc(), key, NULL);
ct = encrypt_example(&ctx, str, strlen((const char*)str), &i);
printf("Ciphertext is %d bytes.\n", i);
EVP_DecryptInit(&ctx, EVP_des_ede_cbc(), key, NULL);
out = decrypt_example(&ctx, ct, 8);
printf("Decrypted: >>%s<<\n", out);
out = decrypt_example(&ctx, ct + 8, 8);
printf("Decrypted: >>%s<<\n", out);
if (!EVP_DecryptFinal(&ctx, final, &i))
{
printf("Padding incorrect.\n");
abort();
}
final[i] = 0;
printf("Decrypted: >>%s<<\n", final);
return 0;
}
int seed_prng(int bytes)
{
if (!RAND_load_file("/dev/random", bytes))
return 0;
return 1;
}
void select_random_key(unsigned char *key, int b)
{
int i;
RAND_bytes(key, b);
for (i = 0; i < b - 1; i++)
printf("%02X:",key[i]);
printf("%02X\n\n", key[b - 1]);
}
void select_random_iv (unsigned char *iv, int b)
{
RAND_pseudo_bytes (iv, b);
}
unsigned char *encrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *data, int inl, int *rb)
{
unsigned char *ret = (unsigned char *)malloc(inl + EVP_CIPHER_CTX_block_size(ctx));
int i, tmp, ol;
ol = 0;
for (i = 0; i < inl /100; i++)
{
EVP_EncryptUpdate(ctx, &ret[ol], &tmp, &data[ol], 100);
ol += tmp;
}
if (inl % 100)
{
EVP_EncryptUpdate(ctx, &ret[ol], &tmp, &data[ol], inl%100);
ol += tmp;
}
EVP_EncryptFinal(ctx, &ret[ol], &tmp);
*rb = ol + tmp;
return ret;
}
unsigned char *decrypt_example(EVP_CIPHER_CTX *ctx, unsigned char *ct, int inl)
{
/* We're going to null-terminate the plaintext under the assumption it's
* non-null terminated ASCII text. The null can be ignored otherwise.
*/
unsigned char *pt = (unsigned char *)malloc(inl + EVP_CIPHER_CTX_block_size(ctx) + 1);
int ol;
EVP_DecryptUpdate(ctx, pt, &ol, ct, inl);
if (!ol) /* there's no block to decrypt */
{
free(pt);
return NULL;
}
pt[ol] = 0;
return pt;
}
I'm compiling it with this
gcc -g -O0 -Wall evp_encrypt_decrypt.c -o evp_encrypt_decrypt -lssl -lcrypto
Now if I execute this i get this output:
13:98:EB:64:D5:8B:1E:0A:70:1D:28:9D:25:3A:13:40:FE:C1:81:3C:C5:8F:4B:F6:66:1A:07:F8:17:D6:10:B6:4E:BC:45:96:00:A1:9F:59:44:A0:43:D9:9D:DD:C8:A9:0B:22:EC:7B:F2:5F:78:01:D1:58:6D:0B:B4:CB:5F:CD
Ciphertext is 16 bytes.
Decrypted: >>(null)<<
Decrypted: >>12345678<<
Decrypted: >>9abcdef<<
Here it says that the the chipertext is 16 bytes (which is ok). But the key itself(hex code printed above) is 64 bytes long!
However, DES3 with two-key options should have key length with 128 bits (including parity bits). However the EVP_MAX_KEY_LENGTH definition is by default 64. Also I've tried to print the chiper key length, the size of variable key
and the ctx key size as seen below:
printf("Key length DES3: %d\n", EVP_CIPHER_key_length(EVP_des_ede3_cbc()));
printf("Key size: %d\n", sizeof(key));
printf("Cipher CTX key length: %d\n\n", EVP_CIPHER_CTX_key_length(&ctx));
This will output:
Key length DES3: 24
Key size: 64
Cipher CTX key length: 16
I'm a little bit confused here. Shouldn't be the DES3(two-key) key size 128 bits? Why is the length of DES3 key printed as 24(is this bit,byte,etc..)? Why are all these key lengths and sizes different?
Upvotes: 1
Views: 5965
Reputation: 102205
However, DES3 with two-key options should have key length with 128 bits (including parity bits)
Yes. 2-key 3DES has a key size of 64x2 = 128-bits; and 3-key 3DES has a key size of 64x3 = 192-bits (as Greg S stated).
However the EVP_MAX_KEY_LENGTH definition is by default 64
That's the maximum it can be (for all EVP symmetric ciphers), and not just DES/3DES/AES, etc. That value might even change in the future.
Shouldn't be the DES3 (two-key) key size 128 bits?
Yes.
Why is the length of DES3 key printed as 24 (is this bit, byte, etc..)?
Who knows.... but its in bytes, not bits.
Why are all these key lengths and sizes different?
The size is based on the algorithm or cryptosystem.
2-key 3DES performs Encrypt-Decrypt-Encrypt and uses two keys. So one of the keys is used twice. 3-key 3DES performs Encrypt-Decrypt-Encrypt and uses three independent keys. That's how they were designed.
Upvotes: 0