SHOW:
|
|
- or go back to the newest paste.
| 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) |
| 25 | + | int base64_encode(const unsigned char *src, size_t 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 | } |