Guest User

crypto.c

a guest
Mar 30th, 2013
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.06 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5. #include <unistd.h>
  6. #include <math.h>
  7. #include <openssl/aes.h>
  8. #include <openssl/evp.h>
  9.  
  10. #include <assert.h>
  11. static const char BASE64_CHARS[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  12.  
  13. void base64_encode_triple(const unsigned char *src, char *dest)
  14. {
  15.     int i, v;
  16.  
  17.     v = (((src[0] << 8) + src[1]) << 8) + src[2];
  18.     for (i = 0; i < 4; ++i)
  19.     {
  20.         dest[3 - i] = BASE64_CHARS[v%64];
  21.         v /= 64;
  22.     }
  23. }
  24.  
  25. int base64_encode(const unsigned char *src, unsigned int src_len, char *dest, size_t dest_len)
  26. {
  27.     unsigned char tmp[3];
  28.  
  29.     if (4*(src_len + 2)/3 >= dest_len)
  30.     {
  31.         return 0;
  32.     }
  33.     while (src_len >= 3)
  34.     {
  35.         base64_encode_triple(src, dest);
  36.         src     += 3;
  37.         src_len -= 3;
  38.         dest    += 4;
  39.     }
  40.     if (src_len > 0)
  41.     {
  42.         memset(tmp, 0, sizeof(tmp));
  43.         memcpy(tmp, src, src_len);
  44.         base64_encode_triple(tmp, dest);
  45.         dest[3] = '=';
  46.         if (src_len == 1)
  47.         {
  48.             dest[2] = '=';
  49.         }
  50.         dest += 4;
  51.     }
  52.     *dest = '\0';
  53.     return 1;
  54. }
  55.  
  56. int base64_char_value(char ch)
  57. {
  58.     return  (ch >= 'A' && ch <= 'Z') ? ch - 'A'      :
  59.             (ch >= 'a' && ch <= 'z') ? ch - 'a' + 26 :
  60.             (ch >= '0' && ch <= '9') ? ch - '0' + 52 :
  61.             (ch == '+')              ?            62 :
  62.             (ch == '/')              ?            63 : -1;
  63. }
  64.  
  65. int base64_decode_triple(const char *src, unsigned char *dest)
  66. {
  67.     int digits[4], dest_len, junk, i, v;
  68.  
  69.     dest_len = 3;
  70.     junk = 1;
  71.     for (i = 0; i < 4; ++i)
  72.     {
  73.         digits[i] = base64_char_value(src[i]);
  74.     }
  75.     for (i = 3; i >= 0; --i)
  76.     {
  77.         if (digits[i] >= 0)
  78.         {
  79.             junk = 0;
  80.         }
  81.         else
  82.         {
  83.             if (!junk || src[i] != '=')
  84.             {
  85.                 return 0;
  86.             }
  87.             digits[i] = 0;
  88.             --dest_len;
  89.         }
  90.     }
  91.     if (dest_len < 0)
  92.     {
  93.         dest_len = 0;
  94.     }
  95.     v = (((((digits[0] << 6) + digits[1]) << 6) + digits[2]) << 6) + digits[3];
  96.     for (i = dest_len; i < 3; ++i)
  97.     {
  98.         v >>= 8;
  99.     }
  100.     for (i = dest_len - 1; i >= 0; --i)
  101.     {
  102.         dest[i] = v;
  103.         v >>= 8;
  104.     }
  105.     return dest_len;
  106. }
  107.  
  108. int base64_decode(const char *src, unsigned char *dest, size_t dest_len)
  109. {
  110.     int i, decoded, total_decoded;
  111.     char temp_src[4], *copy, *p;
  112.     unsigned char temp_dest[3];
  113.  
  114.     decoded = 3;
  115.     total_decoded = 0;
  116.     copy = malloc(strlen(src) + 5);
  117.     if (copy == NULL)
  118.     {
  119.         return -1;
  120.     }
  121.     strcpy(copy, src);
  122.     strcat(copy, "====");
  123.     p = copy;
  124.     while (decoded == 3)
  125.     {
  126.         for (i = 0; i < 4; ++i)
  127.         {
  128.             while (*p != '=' && base64_char_value(*p) < 0)
  129.             {
  130.                 ++p;
  131.             }
  132.             temp_src[i] = *p++;
  133.         }
  134.         decoded = base64_decode_triple(temp_src, temp_dest);
  135.         if ((size_t)decoded > dest_len)
  136.         {
  137.             free(copy);
  138.             return -1;
  139.         }
  140.         memcpy(dest, temp_dest, decoded);
  141.         dest          += decoded;
  142.         dest_len      -= decoded;
  143.         total_decoded += decoded;
  144.     }
  145.     free(copy);
  146.     return total_decoded;
  147. }
  148.  
  149. void encrypt(const unsigned char key[32], const char *src)
  150. {
  151.     AES_KEY aes_key;
  152.     unsigned char temp[1024], ivec[16];
  153.     char buf[1024];
  154.  
  155.     memset(temp, 0, sizeof(temp));
  156.     memset(temp, 0, sizeof(temp));  /* intended to zero `buf' here? */
  157.     memset(ivec, 0, sizeof(ivec));
  158.     AES_set_encrypt_key(key, 256, &aes_key);
  159.     AES_cbc_encrypt((const unsigned char*)src, temp, strlen(src), &aes_key, ivec, 1);
  160.     base64_encode(temp, (int)(ceil(strlen(src) / 16.0) * 16.0), buf, sizeof(buf));
  161.     printf("encrypted: %s\n", buf);
  162. }
  163.  
  164. void decrypt(const unsigned char key[32], const char *src)
  165. {
  166.     AES_KEY aes_key;
  167.     unsigned char temp[1024], ivec[16];
  168.     char buf[1024];
  169.  
  170.     memset(temp, 0, sizeof(temp));
  171.     memset(buf, 0, sizeof(buf));
  172.     memset(ivec, 0, sizeof(ivec));
  173.     base64_decode(src, temp, sizeof(temp));
  174.     AES_set_decrypt_key(key, 256, &aes_key);
  175.     AES_cbc_encrypt(temp, (unsigned char*)buf, sizeof(buf), &aes_key, ivec, 0);
  176.     printf("decrypted: %s\n", buf);
  177. }
  178.  
  179. void menu(const unsigned char key[32])
  180. {
  181.     char ch, tmp, buf[256];
  182.  
  183.     do {
  184.         puts("\n1. encrypt");
  185.         puts("2. decrypt");
  186.         puts("0. quit\n");
  187.         fwrite("menu: ", 1, 6, stdout);
  188.         fflush(stdout);
  189.         tmp = ch = getchar();
  190.         while (tmp != '\n' && tmp != EOF)
  191.         {
  192.             tmp = getchar();
  193.         }
  194.         if (ch == '1'|| ch == '2')
  195.         {
  196.             memset(buf, 0, sizeof(buf));
  197.             fwrite("\nmsg: ", 1, 6, stdout);
  198.             fflush(stdout);
  199.             fgets(buf, sizeof(buf), stdin);
  200.             if (ch == '1')
  201.             {
  202.                 encrypt(key, buf);
  203.             }
  204.             else
  205.             if (ch == '2')
  206.             {
  207.                 decrypt(key, buf);
  208.             }
  209.         }
  210.     } while (ch != '0');
  211. }
  212.  
  213. int fill_buffer_with_random_data(char *buf, int len)
  214. {
  215.     int i;
  216.  
  217.     for (i = 0; i < len; ++i)
  218.     {
  219.         buf[i] = rand()%90 + 33;
  220.     }
  221.     return i;
  222. }
  223.  
  224. void crypto()
  225. {
  226.     static char *salt = "Ohroowie2eisieQuojiaBoop1chi0wu";
  227.     char *p, pass[128], user[64], prefix[16];
  228.     unsigned char key[32];
  229.  
  230.     fill_buffer_with_random_data(pass, 128);
  231.     fill_buffer_with_random_data(user, 64);
  232.     base64_encode("q1ePg3J1", 8, prefix, 16);  /* "cTFlUGczSjE=" */
  233.     p = getpass("password: ");
  234.     memcpy(user, p, strlen(p));
  235.     memcpy(pass, prefix, strlen(prefix));
  236.     memcpy(pass + strlen(prefix), user, strlen(p));
  237.     PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(prefix) + strlen(p), salt, strlen(salt), 1000, 32, key);
  238.     fill_buffer_with_random_data(p, 4);         /* (intentional) bug? */
  239.     fill_buffer_with_random_data(pass, 128);
  240.     menu(key);
  241. }
  242.  
  243. int main()
  244. {
  245.     srandom(time(NULL));
  246.     crypto();
  247.     return 0;
  248. }
Advertisement
Add Comment
Please, Sign In to add comment