title: AES CTR encryption and decryption
body: <p>So I have this code, which basically, encrypts two plain text messages and then try to decrypt them, and print. The problem is that first message is recovered fine but the second is garbage. I downloaded this code from <a href="http://www.gurutechnologies.net/blog/aes-ctr-encryption-in-c/" rel="nofollow">this tutorial</a> and then modified it to work with strings instead of files as <strong>I need it for sending encrypted text over sockets.</strong> So length of the plaintext won't be known to other endpoint, is there a way to find the length or will I have to send the length of plaintext along with the cipher somehow?</p>
  
  <p>Now, I think there is a problem in the break condition of decrypt. </p>
  
  <p>Also, is the main() code right conceptually: encrypt messages with updating state and then reset state and decrypt messages with updating state?</p>
  
  <p>And is there a way to find out the actual length of cipher text (not the buffer)?</p>
  
  <p><strong>This is just a dummy program that I was trying out to understand how AES CTR will work.</strong></p>
  
  <pre><code>#include &lt;openssl/aes.h&gt;
  #include &lt;openssl/rand.h&gt; 
  #include &lt;openssl/hmac.h&gt;
  #include &lt;openssl/buffer.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;math.h&gt;
  
  // Code example uses partail code from: http://stackoverflow.com/questions/3141860/aes-ctr-256-encryption-mode-of-operation-on-openssl
  // Mostly in the ctr_ state, and init_ctr functions. 
  
  struct ctr_state 
  { 
      unsigned char ivec[AES_BLOCK_SIZE];  
      unsigned int num; 
      unsigned char ecount[AES_BLOCK_SIZE]; 
  }; 
  
  int init_ctr(struct ctr_state *state, const unsigned char iv[16])
  {        
      /* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the
       * first call. */
      state-&gt;num = 0;
      memset(state-&gt;ecount, 0, AES_BLOCK_SIZE);
  
      /* Initialise counter in 'ivec' to 0 */
      memset(state-&gt;ivec + 8, 0, 8);
  
      /* Copy IV into 'ivec' */
      memcpy(state-&gt;ivec, iv, 8);
  }
  
  void fencrypt(char* text, char* cipher, const unsigned char* enc_key, struct ctr_state* state)
  { 
      AES_KEY key;
      unsigned char indata[AES_BLOCK_SIZE]; 
      unsigned char outdata[AES_BLOCK_SIZE];
      int offset=0;
      //Initializing the encryption KEY
      if (AES_set_encrypt_key(enc_key, 128, &amp;key) &lt; 0)
      {
          fprintf(stderr, "Could not set encryption key.");
          exit(1); 
      }
  
      //Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext  
      while(1)    
      {
          printf("while going\n");
          memcpy(indata, text+offset, AES_BLOCK_SIZE); 
          AES_ctr128_encrypt(indata, outdata, AES_BLOCK_SIZE, &amp;key, state-&gt;ivec, state-&gt;ecount, &amp;state-&gt;num);
  
          memcpy(cipher+offset, outdata, AES_BLOCK_SIZE);
          offset=offset+AES_BLOCK_SIZE;
          if (offset &gt; strlen(text))
          {
              break;
          }
      }
  }
  
  void fdecrypt(char* cipher, char* text, const unsigned char* enc_key, struct ctr_state* state)
  {   
      AES_KEY key;
      unsigned char indata[AES_BLOCK_SIZE]; 
      unsigned char outdata[AES_BLOCK_SIZE];
      int offset=0;
      //Initializing the encryption KEY
      if (AES_set_encrypt_key(enc_key, 128, &amp;key) &lt; 0)
      {
          fprintf(stderr, "Could not set decryption key.");
          exit(1);
      }
  
      //Encrypting Blocks of 16 bytes and writing the output.txt with ciphertext       
      while(1)    
      {
          memcpy(indata, cipher+offset, AES_BLOCK_SIZE);  
          //printf("%i\n", state.num);
          AES_ctr128_encrypt(indata, outdata, AES_BLOCK_SIZE, &amp;key, state-&gt;ivec, state-&gt;ecount, &amp;state-&gt;num);
  
          memcpy(text+offset, outdata, AES_BLOCK_SIZE); 
          offset=offset+AES_BLOCK_SIZE;
          if (offset &gt; strlen(cipher))
          {
              break;
          }
      }
  }
  
  int main(int argc, char *argv[])
  {
      unsigned char iv[AES_BLOCK_SIZE];
      struct ctr_state state;
      char* plain="quick brown fox jumped over the lazy dog what ";
      char* plain2="a dog he is idiot who is the genius ";
      char cipher[128];
      char cipher2[128];
      char recovered[128];
      char recovered2[128];
      const unsigned char* enc_key="123456789abcdef0";
  
      if(!RAND_bytes(iv, AES_BLOCK_SIZE))
      {
          fprintf(stderr, "Could not create random bytes.");
          exit(1);    
      }
      init_ctr(&amp;state, iv); //Counter call
      printf("Plain text length:%lu\n",strlen(plain));
      // BIO_dump_fp(stdout, plain, strlen(plain));
      // printf("Plain text:%s\n",plain);
      fencrypt(plain, cipher,enc_key,&amp;state);
      fencrypt(plain2, cipher2,enc_key,&amp;state);
      // cipher[strlen(plain)]='\0';
      // BIO_dump_fp(stdout, cipher, strlen(plain));
      init_ctr(&amp;state, iv); //Counter call
      fdecrypt(cipher,recovered,enc_key,&amp;state);
      fdecrypt(cipher2,recovered2,enc_key,&amp;state);
      // printf("Cipher text length:%lu\n",strlen(cipher));
      printf("Recovered text:%s\n",recovered);
      printf("Recovered text:%s\n",recovered2);
      return 0;
  }
  </code></pre>