Thread: How to decrypt / encrypt using libgcrypt ? (ARC4)

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    111

    How to decrypt / encrypt using libgcrypt ? (ARC4)

    Howdy ,..

    I'm reaading libgcrypt manual but
    I cannot understand what values i should use in encrypt /decrypt when using gcry_cipher_encrypt :

    for example when i run this code :
    Code:
    #include <stdio.h>
    #include <gcrypt.h>
    #include <assert.h>
    
    int main()
    {
    
      gcry_cipher_hd_t handle;
      gcry_error_t err = 0;
      char * plain_text ;
      char * out ;
      char * deout ;
    
      size_t size_of_plain = sizeof(char) * 6;
      size_t size_of_crypt = sizeof(char) * 601;
      plain_text = malloc (size_of_plain);
      out =  malloc (size_of_crypt);
      deout = malloc (size_of_crypt);
      assert(plain_text);
      assert(out);
      assert(deout);
    
      strcpy(plain_text , "Secret");
      
    
      gcry_check_version (NULL);
      gcry_control( GCRYCTL_DISABLE_SECMEM_WARN );
      gcry_control( GCRYCTL_INIT_SECMEM, 16384, 0 );
    
    
           {
    
    
           err = gcry_cipher_open (&handle, GCRY_CIPHER_ARCFOUR,GCRY_CIPHER_MODE_STREAM,0);
     
           if (err)
             {
               fprintf (stderr, "Failure: &#37;s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
               fprintf (stdout, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
    
             }
    	err = gcry_cipher_setkey (handle, "This is really strange , i read the documentation i googled for two days and nothing , i can't encrypt && decrypt",128);
    	if (err)
             {
               fprintf (stderr, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
               fprintf (stdout, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
    
             }
         }
      err =  gcry_cipher_encrypt (handle,
              (unsigned char *)out, sizeof(out), (const unsigned char *)plain_text,sizeof plain_text);
    if (err)
             {
               fprintf (stderr, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
               fprintf (stdout, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
    
             }
      printf(" out :%s ||| plain text %s\n",out, plain_text);
    err =  gcry_cipher_encrypt (handle,
              (unsigned char *)deout, sizeof deout, (const unsigned char *)out,sizeof out);
    if (err)
             {
               fprintf (stderr, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
               fprintf (stdout, "Failure: %s/%s\n",
                        gcry_strsource (err),
                        gcry_strerror (err));
    
             }
      printf("deout: %s ||| out: %s ||| plain text: %s\n",deout, out,plain_text);
      
      free(plain_text);
      free(out);
      free(deout);
      gcry_cipher_close(handle);
      return 0;
    
    }
    i get the next output :

    Code:
    ��g�zB�QK]o
    ��A�R����       2�9�

    while i should get according to wikipedia :

    Code:
    45A01F645FC35B383552544B9BF5
    Attack at down
    What should i do to fix it ?
    Last edited by jabka; 07-30-2008 at 01:30 PM.
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  2. #2
    Registered User
    Join Date
    Mar 2006
    Posts
    725
    Don't cast malloc.
    Malloc can fail.
    sizeof(char) is 1.
    You're not doing any error checking at all for any of the libgcrypt functions you are calling.
    The encrypted bytes do not transform into human-readable pairs of hexadecimal characters magically.
    Code:
    #include <stdio.h>
    
    void J(char*a){int f,i=0,c='1';for(;a[i]!='0';++i)if(i==81){
    puts(a);return;}for(;c<='9';++c){for(f=0;f<9;++f)if(a[i-i%27+i%9
    /3*3+f/3*9+f%3]==c||a[i%9+f*9]==c||a[i-i%9+f]==c)goto e;a[i]=c;J(a);a[i]
    ='0';e:;}}int main(int c,char**v){int t=0;if(c>1){for(;v[1][
    t];++t);if(t==81){J(v[1]);return 0;}}puts("sudoku [0-9]{81}");return 1;}

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    111
    I edited the code and added error checks ,
    But the problem isn't in error check or malloc casting .
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  4. #4
    Registered User
    Join Date
    Apr 2007
    Posts
    111

    Got the Ans

    Sorry for my math newness ...

    I got an answer that ARCFOUR changes it self on each run so sorry .
    Working ugly unindented , posibly with momery leeks etc ...
    code is brought here under public domain :

    Code:
    #include <stdio.h>
    #include <gcrypt.h>
    #include <assert.h>
    
    int main()
    {
    
    	gcry_cipher_hd_t handle;
    	gcry_cipher_hd_t handle2;
    	gcry_error_t err = 0;
    	char * plain_text ;
    	char * out ;
    	char * deout ;
    
    	plain_text = ( char * ) malloc ( sizeof ( char ) * ( 6 ) );
    	out = ( char * ) malloc ( sizeof ( char ) * ( 60 + 1 ) );
    	deout = ( char * ) malloc ( sizeof ( char ) * ( 60 + 1 ) );
    	assert ( plain_text );
    	assert ( out );
    	assert ( deout );
    
    	strcpy ( plain_text , "Secret" );
    
    	printf ( "%d %d \n", ( int ) sizeof ( plain_text ), strlen ( plain_text ) );
    	gcry_check_version ( NULL );
    	gcry_control ( GCRYCTL_DISABLE_SECMEM_WARN );
    	gcry_control ( GCRYCTL_INIT_SECMEM, 16384, 0 );
    
    
    	{
    
    		err = gcry_cipher_open ( &handle2, GCRY_CIPHER_ARCFOUR,GCRY_CIPHER_MODE_STREAM,0 );
    		err = gcry_cipher_open ( &handle, GCRY_CIPHER_ARCFOUR,GCRY_CIPHER_MODE_STREAM,0 );
    
    		if ( err )
    		{
    			fprintf ( stderr, "Failure: %s/%s\n",
    			          gcry_strsource ( err ),
    			          gcry_strerror ( err ) );
    			fprintf ( stdout, "Failure: %s/%s\n",
    			          gcry_strsource ( err ),
    			          gcry_strerror ( err ) );
    
    		}
    		err = gcry_cipher_setkey ( handle, "This is really strange , i read the documentation i googled for two days and nothing , i can't encrypt && decrypt",256 );
    		err = gcry_cipher_setkey ( handle2, "This is really strange , i read the documentation i googled for two days and nothing , i can't encrypt && decrypt",256 );
    		if ( err )
    		{
    			fprintf ( stderr, "Failure: %s/%s\n",
    			          gcry_strsource ( err ),
    			          gcry_strerror ( err ) );
    			fprintf ( stdout, "Failure: %s/%s\n",
    			          gcry_strsource ( err ),
    			          gcry_strerror ( err ) );
    
    		}
    	}
    	err =  gcry_cipher_encrypt ( handle,
    	                             ( unsigned char * ) out, sizeof ( out ), ( const unsigned char * ) plain_text,sizeof plain_text );
    	if ( err )
    	{
    		fprintf ( stderr, "Failure: %s/%s\n",
    		          gcry_strsource ( err ),
    		          gcry_strerror ( err ) );
    		fprintf ( stdout, "Failure: %s/%s\n",
    		          gcry_strsource ( err ),
    		          gcry_strerror ( err ) );
    
    	}
    	printf ( " out :%s ||| plain text %s\n",out, plain_text );
    	err =  gcry_cipher_encrypt ( handle2,
    	                             ( unsigned char * ) deout, sizeof deout, ( const unsigned char * ) out,sizeof out );
    	if ( err )
    	{
    		fprintf ( stderr, "Failure: %s/%s\n",
    		          gcry_strsource ( err ),
    		          gcry_strerror ( err ) );
    		fprintf ( stdout, "Failure: %s/%s\n",
    		          gcry_strsource ( err ),
    		          gcry_strerror ( err ) );
    
    	}
    	printf ( "deout: %s ||| out: %s ||| plain text: %s\n",deout, out,plain_text );
    
    	free ( plain_text );
    	free ( out );
    	free ( deout );
    	gcry_cipher_close ( handle );
    	gcry_cipher_close ( handle2 );
    	return 0;
    
    }
    Special thanks to Adam Langle the man who gave me the ans (The reason is that RC4 mutates itself as it processe)
    why Gaos didn't had a wife ?
    http://bsh83.blogspot.com

  5. #5
    Registered User
    Join Date
    Apr 2010
    Location
    Boulder, CO
    Posts
    2

    Example AES gcrypt gcry_cipher_encrypt code

    I was searching for a simple AES encryption example using the gcrypt library and surprisingly this is the only page I found. The example code given here was totally inadequate for my needs so I had to write my own. It would have been nice if I could have found a good example so I thought others may like to see my example now that it is done. The output in CBC mode is:

    Code:
    gcry_cipher_open    worked
    gcry_cipher_setkey  worked
    gcry_cipher_setiv   worked
    gcry_cipher_encrypt worked
    gcry_cipher_setiv   worked
    gcry_cipher_decrypt worked
    keyLength = 16
    blkLength = 16
    txtLength = 64
    aesSymKey = one test AES key
    iniVector = a test ini value
    txtBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    encBuffer = A2096693C727CB6114907E15F1C2CA66A77D482DA6191C5DACB57F77DE10B65
                CC53F7FF2AB1C9F665B5722789DD57416C9B6105E67C32EFA9F02C9E1D7747F87
    outBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    The output in ECB mode is:

    Code:
    gcry_cipher_open    worked
    gcry_cipher_setkey  worked
    gcry_cipher_setiv   worked
    gcry_cipher_encrypt worked
    gcry_cipher_setiv   worked
    gcry_cipher_decrypt worked
    keyLength = 16
    blkLength = 16
    txtLength = 64
    aesSymKey = one test AES key
    iniVector = a test ini value
    txtBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    encBuffer = 72DE8D0017E14AA35C8716B33355925CAC22D29373B01A64FED5D7D0D3F07CD
                227CE13D4E2400948CAB715ABA86ECF9FA5F71131A95F72167D3BCAD9892A051A
    outBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    And here is the simple test code:

    Code:
    static void aesTest(void)
    {
        #define GCRY_CIPHER GCRY_CIPHER_AES128   // Pick the cipher here
        #define GCRY_C_MODE GCRY_CIPHER_MODE_ECB // Pick the cipher mode here
    
        gcry_error_t     gcryError;
        gcry_cipher_hd_t gcryCipherHd;
        size_t           index;
    
        size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
        size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
        char * txtBuffer = "123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ";
        size_t txtLength = strlen(txtBuffer)+1; // string plus termination
        char * encBuffer = malloc(txtLength);
        char * outBuffer = malloc(txtLength);
        char * aesSymKey = "one test AES key"; // 16 bytes
        char * iniVector = "a test ini value"; // 16 bytes
    
        gcryError = gcry_cipher_open(
            &gcryCipherHd, // gcry_cipher_hd_t *
            GCRY_CIPHER,   // int
            GCRY_C_MODE,   // int
            0);            // unsigned int
        if (gcryError)
        {
            printf("gcry_cipher_open failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
        printf("gcry_cipher_open    worked\n");
    
        gcryError = gcry_cipher_setkey(gcryCipherHd, aesSymKey, keyLength);
        if (gcryError)
        {
            printf("gcry_cipher_setkey failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
        printf("gcry_cipher_setkey  worked\n");
    
        gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
        if (gcryError)
        {
            printf("gcry_cipher_setiv failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
        printf("gcry_cipher_setiv   worked\n");
    
        gcryError = gcry_cipher_encrypt(
            gcryCipherHd, // gcry_cipher_hd_t
            encBuffer,    // void *
            txtLength,    // size_t
            txtBuffer,    // const void *
            txtLength);   // size_t
        if (gcryError)
        {
            printf("gcry_cipher_encrypt failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
        printf("gcry_cipher_encrypt worked\n");
    
        gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
        if (gcryError)
        {
            printf("gcry_cipher_setiv failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
        printf("gcry_cipher_setiv   worked\n");
    
        gcryError = gcry_cipher_decrypt(
            gcryCipherHd, // gcry_cipher_hd_t
            outBuffer,    // void *
            txtLength,    // size_t
            encBuffer,    // const void *
            txtLength);   // size_t
        if (gcryError)
        {
            printf("gcry_cipher_decrypt failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
        printf("gcry_cipher_decrypt worked\n");
    
        printf("keyLength = %d\n", keyLength);
        printf("blkLength = %d\n", blkLength);
        printf("txtLength = %d\n", txtLength);
        printf("aesSymKey = %s\n", aesSymKey);
        printf("iniVector = %s\n", iniVector);
        printf("txtBuffer = %s\n", txtBuffer);
    
        printf("encBuffer = ");
        for (index = 0; index<txtLength; index++)
            printf("%02X", (unsigned char)encBuffer[index]);
        printf("\n");
    
        printf("outBuffer = %s\n", outBuffer);
    
        // clean up after ourselves
        gcry_cipher_close(gcryCipherHd);
        free(encBuffer);
        free(outBuffer);
    }
    Burt Wagner - LinkedIn
    Senior Firmware Engineer
    Deadline Specialists, Inc.
    Post Office Box 18985
    Boulder, CO 80308 USA
    Last edited by BurtWagner; 04-13-2010 at 10:24 AM. Reason: Add signature

  6. #6
    Registered User
    Join Date
    Apr 2010
    Location
    Boulder, CO
    Posts
    2

    CBC versus ECB

    Next I wanted to prove to myself that the initialization vector was being used in CBC mode but not in ECB mode. Here is the output showing that the initialization vector had no effect on the encrypted value in ECB mode but it did have an effect on the encrypted value in CBC mode:

    Code:
    gcry_mode = ECB
    keyLength = 16
    blkLength = 16
    txtLength = 64
    aesSymKey = one test AES key
    iniVector = a test ini value
    txtBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    encBuffer = 72DE8D0017E14AA35C8716B33355925CAC22D29373B01A64FED5D7D0D3F07CD
                227CE13D4E2400948CAB715ABA86ECF9FA5F71131A95F72167D3BCAD9892A051A
    outBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    gcry_mode = ECB
    keyLength = 16
    blkLength = 16
    txtLength = 64
    aesSymKey = one test AES key
    iniVector = different value!
    txtBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    encBuffer = 72DE8D0017E14AA35C8716B33355925CAC22D29373B01A64FED5D7D0D3F07CD
                227CE13D4E2400948CAB715ABA86ECF9FA5F71131A95F72167D3BCAD9892A051A
    outBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    gcry_mode = CBC
    keyLength = 16
    blkLength = 16
    txtLength = 64
    aesSymKey = one test AES key
    iniVector = a test ini value
    txtBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    encBuffer = A2096693C727CB6114907E15F1C2CA66A77D482DA6191C5DACB57F77DE10B65
                CC53F7FF2AB1C9F665B5722789DD57416C9B6105E67C32EFA9F02C9E1D7747F87
    outBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    gcry_mode = CBC
    keyLength = 16
    blkLength = 16
    txtLength = 64
    aesSymKey = one test AES key
    iniVector = different value!
    txtBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    encBuffer = 28371488E2A4C0706E3F5EB8172CE0E5C75C73ABE3E6F45DFF108D6FA6B4C6E
                C5EACF255B5F703D4479B361A4024C0F6B67010A040C221FF3E6F5BBE39AE223D
    outBuffer = 123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ
    And here is the "improved" code:

    Code:
    static void aesTest(int gcry_mode, char * iniVector)
    {
        #define GCRY_CIPHER GCRY_CIPHER_AES128   // Pick the cipher here
    
        gcry_error_t     gcryError;
        gcry_cipher_hd_t gcryCipherHd;
        size_t           index;
    
        size_t keyLength = gcry_cipher_get_algo_keylen(GCRY_CIPHER);
        size_t blkLength = gcry_cipher_get_algo_blklen(GCRY_CIPHER);
        char * txtBuffer = "123456789 abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWZYZ";
        size_t txtLength = strlen(txtBuffer)+1; // string plus termination
        char * encBuffer = malloc(txtLength);
        char * outBuffer = malloc(txtLength);
        char * aesSymKey = "one test AES key"; // 16 bytes
    
        gcryError = gcry_cipher_open(
            &gcryCipherHd, // gcry_cipher_hd_t *
            GCRY_CIPHER,   // int
            gcry_mode,     // int
            0);            // unsigned int
        if (gcryError)
        {
            printf("gcry_cipher_open failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
    
        gcryError = gcry_cipher_setkey(gcryCipherHd, aesSymKey, keyLength);
        if (gcryError)
        {
            printf("gcry_cipher_setkey failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
    
        gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
        if (gcryError)
        {
            printf("gcry_cipher_setiv failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
    
        gcryError = gcry_cipher_encrypt(
            gcryCipherHd, // gcry_cipher_hd_t
            encBuffer,    // void *
            txtLength,    // size_t
            txtBuffer,    // const void *
            txtLength);   // size_t
        if (gcryError)
        {
            printf("gcry_cipher_encrypt failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
    
        gcryError = gcry_cipher_setiv(gcryCipherHd, iniVector, blkLength);
        if (gcryError)
        {
            printf("gcry_cipher_setiv failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
    
        gcryError = gcry_cipher_decrypt(
            gcryCipherHd, // gcry_cipher_hd_t
            outBuffer,    // void *
            txtLength,    // size_t
            encBuffer,    // const void *
            txtLength);   // size_t
        if (gcryError)
        {
            printf("gcry_cipher_decrypt failed:  %s/%s\n",
                   gcry_strsource(gcryError),
                   gcry_strerror(gcryError));
            return;
        }
    
        printf("gcry_mode = %s\n", gcry_mode == GCRY_CIPHER_MODE_ECB ? "ECB" : "CBC");
        printf("keyLength = %d\n", keyLength);
        printf("blkLength = %d\n", blkLength);
        printf("txtLength = %d\n", txtLength);
        printf("aesSymKey = %s\n", aesSymKey);
        printf("iniVector = %s\n", iniVector);
        printf("txtBuffer = %s\n", txtBuffer);
    
        printf("encBuffer = ");
        for (index = 0; index<txtLength; index++)
            printf("%02X", (unsigned char)encBuffer[index]);
        printf("\n");
    
        printf("outBuffer = %s\n", outBuffer);
    
        // clean up after ourselves
        gcry_cipher_close(gcryCipherHd);
        free(encBuffer);
        free(outBuffer);
    }
    
    Called from my main function:
    
        aesTest(GCRY_CIPHER_MODE_ECB, "a test ini value");
        aesTest(GCRY_CIPHER_MODE_ECB, "different value!");
        aesTest(GCRY_CIPHER_MODE_CBC, "a test ini value");
        aesTest(GCRY_CIPHER_MODE_CBC, "different value!");
    Burt Wagner - LinkedIn
    Senior Firmware Engineer
    Deadline Specialists, Inc.
    Post Office Box 18985
    Boulder, CO 80308 USA

  7. #7
    Registered User
    Join Date
    Apr 2010
    Posts
    1
    Hi Burt,

    The post is indeed very useful for first time users of libgcrypt library. Me included, many thanks.

    To add on, there are restrictions on the size of key, initialization vector and plain text buffer. We cannot expect to use the code correctly without understanding how the encryption works. gcrypt.info file provided the rest of the info though!


    Handi

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange issue utilizing encrypt() in libcrypt
    By TheComedian in forum C Programming
    Replies: 8
    Last Post: 01-18-2009, 07:14 AM
  2. Encrypt text using a Digital Certififcate
    By magic.mike in forum Windows Programming
    Replies: 0
    Last Post: 01-11-2009, 03:53 AM
  3. dll to encrypt packet sends
    By splintter in forum C++ Programming
    Replies: 22
    Last Post: 04-20-2008, 09:00 PM
  4. encrypt input message
    By axedia in forum C Programming
    Replies: 1
    Last Post: 05-30-2005, 12:48 AM
  5. Ask about Encrypt data 2 times.
    By ooosawaddee3 in forum C++ Programming
    Replies: 1
    Last Post: 07-16-2002, 03:28 AM