Hi Ali,

Thus wrote Ali Sydney (asyd...@k-state.edu):

> Thanks for the speedy response.  I have been attempting to use the EVP
> interface, but the cipher text produced is wrong (and I am fairly new
> to this). As a simple test, I have hard-coded an 8 byte block for the
> key (in hexadecimal), and also an 8 byte block (also in hex) for the
> plaintext. Can you kindly take a look and provide feedback? 

> int main()
> {

>    EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX));
>    EVP_CIPHER_CTX_init(ctx);

>    unsigned char key[]={0x01, 0x91, 0xd0, 0xad, 0x79, 0x4c, 0xae, 0x9b};  
> //64-bit KEY
>    unsigned char plaintext[]={0x61, 0x62, 0x63, 0x64, 0x61, 0x62, 0x63, 
> 0x64}; //64-bit Plaintext to be encrypted

>    int ret;
>    ret = EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, key, NULL); //USE DES 
> ECB mode
>    assert(ret == 1);

>    ret = EVP_CIPHER_CTX_set_padding(ctx, 0); //No padding
>    assert(ret == 1);

>    int val, num_bytes_in(8),num_bytes_out(8); //8 bytes of plaintext, 8 bytes 
> of ciphertext

>    unsigned char out[8]; //Store ciphertext in "out"
>    val=EVP_EncryptUpdate(ctx, out, &num_bytes_out, plaintext, num_bytes_in ); 
> //Encrypt plaintext

>     for (int i=0; i<8; i++) //Print ciphertext
>     {
>         printf("%02x",out[i]);
>     }
>     cout<<endl;

> }

EVP_EncryptFinal() is missing.

The attached example works ok for me

Best regards,

   Martin
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include <openssl/objects.h>
#include <openssl/evp.h>




unsigned char K[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7 };


int main(void)
{
   int ret;
   EVP_CIPHER_CTX ctx;

   char in[] = "abcdefgh";
   int inl;
   char out[500];
   int outl;
   char back[500];
   int backl;
   int tmp;


   inl = strlen(in);
   
   /* ATTENTION: the _ex routines require an initialized context, i.e.
    * EVP_CIPHER_CTX_init() must be called before Init_ex,
    * it's enough to do this once before encryption, no need to call it a
    * second time before decryption */
   EVP_CIPHER_CTX_init(&ctx);


   /* ----- encryption ----- */

   /* EVP_EncryptInit_ex() cleans up the context, it doesn't initialize it */
   ret = EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, K, NULL);
   assert(ret == 1);

   /* this must be called after EVP_EncryptInit() because EVP_EncryptInit()
    * reinitialises the ctx !!!
    * 0 turns padding off, i.e. the input string must be exactly N blocks */
   ret = EVP_CIPHER_CTX_set_padding(&ctx, 0);
   assert(ret == 1);

   ret = EVP_EncryptUpdate(&ctx, out, &outl, in, inl);
   assert(ret == 1);
   assert(outl == inl);    /* input must be exactly N blocks */
   tmp = outl;

   ret = EVP_EncryptFinal_ex(&ctx, &out[outl], &outl);
   assert(ret == 1);
   assert(outl == 0);   /* no remaining incomplete blocks */
   outl += tmp;

   /* is this really necessary? -> it seems so*/
   ret = EVP_CIPHER_CTX_cleanup(&ctx);
   assert(ret == 1);


   /* ----- decryption ----- */

   /* EVP_DecryptInit_ex() cleans up the context, it doesn't initialize it
      -> no need to call EVP_CIPHER_CTX_init(&ctx) here,
         but padding setting must be renewed */
   ret = EVP_DecryptInit_ex(&ctx, EVP_des_ecb(), NULL, K, NULL);
   assert(ret == 1);

   ret = EVP_CIPHER_CTX_set_padding(&ctx, 0);
   assert(ret == 1);

   /* out, outl == input data, back, backl == output data */
   ret = EVP_DecryptUpdate(&ctx, back, &backl, out, outl);
   assert(ret == 1);
   assert(backl == outl);  /* input to decryption must be exactly N blocks */
   tmp = backl;

   ret = EVP_DecryptFinal_ex(&ctx, &back[backl], &backl);
   assert(ret == 1);
   assert(backl == 0);  /* no remaining incomplete blocks */
   backl += tmp;

   ret = EVP_CIPHER_CTX_cleanup(&ctx);
   assert(ret == 1);

   back[backl+1] = 0x0;

   printf("%s\n", back);
   return 0;
}

Reply via email to