title: SIGSEGV error when using AES_ctr128_encrypt for sockets
body: <p>When i am trying to encrypt the data of the file using AES_ctr128_encrypt i am getting SIGBUS error. Here, I am using <code>read()</code> function to read the data from the file to the <code>bufptr[32k]</code>  in 32k chunks each time. For each chunk i want to encrypt only the part of data using <code>AES_ctr128_encrypt(bufptr+200, outdata, bytes_encrypt, &amp;key, state.ivec, state.ecount, &amp;state.num);</code> encrypt only the data desired and again send it to the server and there again decrypt it and add to the buffer. Can some one help me how to overcome this issue? Thanks in advance. </p>
  
  <p>First client is able to send the file size to the server and when it has come to the <code>AES_ctr128_encrypt()</code> i am getting the the <strong>Segmentation fault (core dumped)</strong> and gdb says it is a SIGSEGV.</p>
  
  <p>My header file</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;malloc.h&gt;
  #include &lt;string.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;resolv.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;sys/stat.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;fcntl.h&gt;
  #include &lt;sys/sendfile.h&gt;
  #include &lt;pthread.h&gt;
  #include &lt;sys/syscall.h&gt;
  #include &lt;openssl/ssl.h&gt;
  #include &lt;openssl/err.h&gt;
  #include &lt;sys/time.h&gt;
  #include &lt;openssl/aes.h&gt;
  #include &lt;openssl/rand.h&gt;
  #include &lt;openssl/modes.h&gt;
  #include &lt;openssl/crypto.h&gt;
  #define FAIL    -1
  #define SEGMENT_SIZE 32768
  #define j 10
  #define OUT1 AES_BLOCK_SIZE
  #define BYTES_ENCRYPT AES_BLOCK_SIZE
  </code></pre>
  
  <p>my client program   </p>
  
  <pre><code>#include "headers.h"
  #define FILE "/tmp/book"
  
  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[8])
  {
      /* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the
       * first call. */
      state-&gt;num = 0;
      memset(state-&gt;ecount, 0, 16);
  
      /* Initialise counter in 'ivec' to 0 */
      memset(state-&gt;ivec + 16, 0, 16);
  
      /* Copy IV into 'ivec' */
      memcpy(state-&gt;ivec, iv, 16);
  }
  
  int main(int argc, char* argv[])
  {
  size_t count;   
  AES_KEY key;
  unsigned char ckey[] =  "/home/nandan/aes.key"; 
  unsigned char iv[AES_BLOCK_SIZE];
  struct ctr_state state;   
  
  // validate proper usage
  if (argc != 3)
  {
      fprintf(stderr, "Usage: %s &lt;serverIP&gt; &lt;serverPort&gt;\n", argv[0]);
      exit(-1);
  }
  
  // store the command line arguments 
  char *server_ip = argv[1];
  int server_port = htons(atoi(argv[2]));
  // stores address of remote server to connect
  struct sockaddr_in server_addr;
  int fd, option;
  
  fd = socket(AF_INET, SOCK_STREAM, 0);
  if (fd == -1)
  {
      fprintf(stderr, "Error creating socket\n");
      exit(-1);
  }
  
  memset(&amp;server_addr, 0, sizeof(server_addr));
  
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = inet_addr(server_ip);
  server_addr.sin_port = server_port;
  
  if (connect(fd, (struct sockaddr *)&amp;server_addr, sizeof(server_addr)) == -1)
  {
      fprintf(stderr, "Error connecting to server\n");
      exit(-1);
  }
  
  struct stat stats;
  stat("/tmp/book", &amp;stats);
  int size = stats.st_size;
  // send size of file to the client
  send(fd, &amp;size, sizeof(int),0);
  printf("Written \n");
  unsigned char outdata[OUT1];
  in = open (FILE, O_RDONLY);
  to_read = size;
  char *bufptr = malloc(SEGMENT_SIZE);
    do
    {
     n = read (in, bufptr, SEGMENT_SIZE);
     if(n &lt; 0)
     {  
      perror("Read Error:");
     }
     init_ctr(&amp;state, iv);
     AES_ctr128_encrypt(bufptr+200, outdata, BYTES_ENCRYPT, &amp;key, state.ivec, state.ecount, &amp;state.num);
     memcpy(bufptr+200,outdata,BYTES_ENCRYPT);
     sending = send(fd, bufptr, n,0);
     to_read = to_read-n;
     } while (to_read != 0);  
  close(fd);
  }
  </code></pre>
  
  <p>my server program</p>
  
  <pre><code>#include "headers.h"
  struct ctr_state {
      unsigned char ivec[16]; 
      unsigned int num;
      unsigned char ecount[16];
  };
  int init_ctr(struct ctr_state *state, const unsigned char iv[8])
  {
      /* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the
       * first call. */
      state-&gt;num = 0;
      memset(state-&gt;ecount, 0, 16);
  
      /* Initialise counter in 'ivec' to 0 */
      memset(state-&gt;ivec + 8, 0, 8);
  
      /* Copy IV into 'ivec' */
      memcpy(state-&gt;ivec, iv, 8);
  }
  
  int main(int argc, char* argv[])
  {
  
  size_t count;    
  AES_KEY key;   
  unsigned char ckey[] =  "/home/nandan/aes.key";
  unsigned char iv[AES_BLOCK_SIZE];
  struct ctr_state state;   
  // validate proper usage
  if (argc != 4)
  {
      fprintf(stderr, "Usage %s &lt;serverBindIP&gt; &lt;serverBindPort&gt; &lt;CredentialsFilePath&gt;\n", argv[0]);
      exit(-1);
  }
  
  int server;
  char* ip = argv[1];
  int port = htons(atoi(argv[2]));
  char* passwd_file = argv[3];
  struct sockaddr_in server_addr, client_addr;
  clock_t start, end;
  double cpu_time_used, timer = 0;
  int server_fd, client_fd, result;
  socklen_t length;
  
  // Create an internet domain TCP socket
  server_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (server_fd == -1)
  {
      fprintf(stderr, "Unable to create socket\n");
      exit(-1);
  }
  
  server_addr.sin_family = AF_INET;
  server_addr.sin_port = port;
  server_addr.sin_addr.s_addr = inet_addr(ip);
  
  // bind socket to an network interface
  result = bind(server_fd, (struct sockaddr*) &amp;server_addr, sizeof(server_addr));
  if (result == -1)
  {
      fprintf(stderr, "Unable to bind socket\n");
      exit(-1);
  }
  
  // mark the socket used for incoming requests
  listen(server_fd, 5);
  
  // accept an incoming connection
  printf("Waiting for incoming connection\n");
  length = sizeof(client_addr);
  client_fd = accept(server_fd, (struct sockaddr*) &amp;client_addr, &amp;length);/* accept connection as usual */
  if (client_fd == -1)
  {
  fprintf(stderr, "Unable to accept peer connection\n");
  exit(-1);
  }  
  printf("Connection: %s:%d\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    int tmp = 0,i,size = 0;  // read file size first
    unsigned char outdata[OUT1]; 
    recv(client_fd, &amp;size, sizeof(int),0);
    printf("%d \n", size);
    int bytes_read = 0;
    int to_read = size;
    printf("%d \n", size);
    FILE* out = fopen("/tmp/x1.pdf", "wb");
    char *buffer = malloc(SEGMENT_SIZE);
     do 
     {
       bytes_read = recv(client_fd, buffer, sizeof(buffer),0);
       init_ctr(&amp;state, iv);
       AES_ctr128_encrypt(buffer+200, outdata, BYTES_ENCRYPT, &amp;key, state.ivec, state.ecount, &amp;state.num);
       memcpy(buffer+200, outdata, BYTES_ENCRYPT);
       tmp = tmp + bytes_read;
      // save content to disk
       fwrite(buffer, 1, bytes_read, out);
     } while (tmp != size);
  close(client_fd);         /* close socket */
  return 0;
  }
  </code></pre>
  
  <p><strong>edit1:</strong> I don't want to encrypt all the data, i want to encrypt only the part of data in each chunk and see how useful it is.</p>