1 /*
2 
3   Copyright (c) 2010-2015 Samuel Lidén Borell <samuel@kodafritt.se>
4 
5   Permission is hereby granted, free of charge, to any person obtaining a copy
6   of this software and associated documentation files (the "Software"), to deal
7   in the Software without restriction, including without limitation the rights
8   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9   copies of the Software, and to permit persons to whom the Software is
10   furnished to do so, subject to the following conditions:
11 
12   The above copyright notice and this permission notice shall be included in
13   all copies or substantial portions of the Software.
14 
15   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21   THE SOFTWARE.
22 
23 */
24 
25 #include <stdlib.h>
26 #include <string.h>
27 #include <openssl/blowfish.h>
28 #include <openssl/bio.h>
29 #include <openssl/evp.h>
30 #include <openssl/rand.h>
31 
32 #include "keystore.h"
33 #include "fish.h"
34 #include "misc.h"
35 
36 #define IB 64
37 static const char fish_base64[64] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
38 static const signed char fish_unbase64[256] = {
39     IB,IB,IB,IB,IB,IB,IB,IB,  IB,IB,IB,IB,IB,IB,IB,IB,
40     IB,IB,IB,IB,IB,IB,IB,IB,  IB,IB,IB,IB,IB,IB,IB,IB,
41 //      !  "  #  $  %  &  '  (    )  *  +  ,  -  .  /
42     IB,IB,IB,IB,IB,IB,IB,IB,  IB,IB,IB,IB,IB,IB, 0, 1,
43 //   0  1  2  3  4  5  6  7    8  9  :  ;  <  =  >  ?
44      2, 3, 4, 5, 6, 7, 8, 9,  10,11,IB,IB,IB,IB,IB,IB,
45 //   @  A  B  C  D  E  F  G    H  I  J  K  L  M  N  O
46     IB,38,39,40,41,42,43,44,  45,46,47,48,49,50,51,52,
47 //   P  Q  R  S  T  U  V  W    X  Y  Z  [  \  ]  ^  _
48     53,54,55,56,57,58,59,60,  61,62,63,IB,IB,IB,IB,IB,
49 //   `  a  b  c  d  e  f  g    h  i  j  k  l  m  n  o
50     IB,12,13,14,15,16,17,18,  19,20,21,22,23,24,25,26,
51 //   p  q  r  s  t  u  v  w    x  y  z  {  |  }  ~  <del>
52     27,28,29,30,31,32,33,34,  35,36,37,IB,IB,IB,IB,IB,
53 };
54 
55 #define GET_BYTES(dest, source) do { \
56     *((dest)++) = ((source) >> 24) & 0xFF; \
57     *((dest)++) = ((source) >> 16) & 0xFF; \
58     *((dest)++) = ((source) >> 8) & 0xFF; \
59     *((dest)++) = (source) & 0xFF; \
60 } while (0);
61 
secure_erase_key(BF_KEY * bfkey)62 static void secure_erase_key(BF_KEY *bfkey) {
63     secure_erase(bfkey, sizeof(*bfkey));
64 }
65 
66 /**
67  * Encrypts a message in ECB mode.
68  */
fish_encrypt_ecb(const char * key,size_t keylen,const char * message)69 char *fish_encrypt_ecb(const char *key, size_t keylen, const char *message) {
70     BF_KEY bfkey;
71     size_t messagelen;
72     size_t i;
73     int j;
74     char *encrypted;
75     char *end;
76     unsigned char bit;
77     unsigned char word;
78     unsigned char d;
79 
80     messagelen = strlen(message);
81     if (messagelen == 0) return NULL;
82     encrypted = malloc(((messagelen-1)/8)*12 + 12 + 1); // each 8-byte block becomes 12 bytes
83     end = encrypted;
84     if (!encrypted) return NULL;
85 
86     BF_set_key(&bfkey, keylen, (const unsigned char*)key);
87     while (*message) {
88         // Read 8 bytes (a Blowfish block)
89         BF_LONG binary[2] = { 0, 0 };
90         unsigned char c;
91         for (i = 0; i < 8; i++) {
92             c = message[i];
93             binary[i >> 2] |= c << 8*(3 - (i&3));
94             if (c == '\0') break;
95         }
96         message += 8;
97 
98         // Encrypt block
99         BF_encrypt(binary, &bfkey);
100 
101         // Emit FiSH-BASE64
102         bit = 0;
103         word = 1;
104         for (j = 0; j < 12; j++) {
105             d = fish_base64[(binary[word] >> bit) & 63];
106             *(end++) = d;
107             bit += 6;
108             if (j == 5) {
109                 bit = 0;
110                 word = 0;
111             }
112         }
113 
114         // Stop if a null terminator was found
115         if (c == '\0') break;
116     }
117     secure_erase_key(&bfkey);
118     *end = '\0';
119     return encrypted;
120 }
121 
122 /**
123  * Encrypts a message in CBC mode.
124  */
fish_encrypt_cbc(const char * key,size_t keylen,const char * message)125 char *fish_encrypt_cbc(const char *key, size_t keylen, const char *message) {
126     BF_KEY bfkey;
127     unsigned char *encrypted = NULL;
128     BIO *b64 = NULL;
129 
130     size_t messagelen = strlen(message);
131     if (messagelen == 0) goto err;
132 
133     // Allocate structure for final encrypted data.
134     int cryptlen = 8 + ((messagelen+7)&~7);
135     encrypted = malloc(cryptlen);
136     if (!encrypted) goto err;
137 
138     // Generate IV
139     unsigned char iv[8];
140     RAND_pseudo_bytes(iv, 8);
141     memcpy(encrypted, iv, 8);
142 
143     // Encrypt in CBC mode. The IV is overwritten
144     BF_set_key(&bfkey, keylen, (const unsigned char*)key);
145     BF_cbc_encrypt((const unsigned char*)message, encrypted+8, messagelen, &bfkey, iv, BF_ENCRYPT);
146     secure_erase_key(&bfkey);
147 
148     // Base64 encode
149     b64 = BIO_new(BIO_f_base64());
150     if (!b64) goto err;
151     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
152     BIO *bmem = BIO_new(BIO_s_mem());
153     if (!bmem) goto err;
154     BIO *bio = BIO_push(b64, bmem);
155     if (cryptlen != 0) {
156         BIO_write(bio, encrypted, cryptlen);
157     }
158     free(encrypted);
159     encrypted = NULL;
160     BIO_flush(bio);
161 
162     unsigned char *b64enc;
163     int b64len = (int)BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *)&b64enc);
164     if (b64len <= 0) goto err;
165 
166     // Copy the string
167     char *encoded = malloc(b64len+2);
168     encoded[0] = '*'; // prepended to indicate CBC mode
169     memcpy(encoded+1, b64enc, b64len);
170     encoded[b64len+1] = '\0'; // null terminator
171     BIO_free_all(b64); // data has been copied now
172     return encoded;
173 
174   err:
175     free(encrypted);
176     BIO_free_all(b64);
177     return NULL;
178 }
179 
180 
181 /**
182  * Decrypts a message in CBC mode. The leading "*" should be included.
183  */
fish_decrypt_cbc(const char * key,size_t keylen,const char * data)184 static char *fish_decrypt_cbc(const char *key, size_t keylen, const char *data) {
185     BF_KEY bfkey;
186     unsigned char *decrypted, *bindata = NULL;
187     BIO *b64 = NULL;
188 
189     // Skip leading "*" that indicates that the message is using CBC byte
190     if (*data != '*') goto err;
191     data++;
192 
193     // Decode BASE64
194     b64 = BIO_new(BIO_f_base64());
195     if (!b64) goto err;
196     BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
197     BIO *bmem = BIO_new(BIO_s_mem());
198     if (!bmem) goto err;
199     BIO *bio = BIO_push(b64, bmem);
200     int datalen = strlen(data);
201     if (BIO_write(bmem, data, datalen) != datalen) goto err;
202     BIO_flush(bio);
203 
204     size_t binlen = BIO_pending(bmem);
205     bindata = malloc(binlen+1);
206     if (!bindata) goto err;
207     int outlen = BIO_read(bio, bindata, BIO_pending(bmem));
208     if (outlen < 8) goto err; // Must at least contain an IV
209     outlen -= 8;
210     outlen &= ~7;
211 
212     // Decrypt in CBC mode
213     decrypted = malloc(outlen+1);
214     if (!decrypted) goto err;
215     if (outlen) {
216         unsigned char *iv = &bindata[0];
217         unsigned char *enc = &bindata[8];
218         BF_set_key(&bfkey, keylen, (const unsigned char*)key);
219         BF_cbc_encrypt(enc, decrypted, outlen, &bfkey, iv, BF_DECRYPT);
220         secure_erase_key(&bfkey);
221     }
222     BIO_free_all(b64);
223     decrypted[outlen] = '\0';
224     return (char*)decrypted;
225 
226   err:
227     BIO_free_all(b64);
228     free(bindata);
229     return NULL;
230 }
231 
232 /**
233  * Decrypts in ECB mode.
234  */
fish_decrypt_ecb(const char * key,size_t keylen,const char * data)235 static char *fish_decrypt_ecb(const char *key, size_t keylen, const char *data) {
236     BF_KEY bfkey;
237     size_t i;
238     char *decrypted;
239     char *end;
240     unsigned char bit;
241     unsigned char word;
242     unsigned char d;
243 
244     decrypted = malloc(strlen(data)+1);
245     end = decrypted;
246     if (!decrypted) return NULL;
247 
248     BF_set_key(&bfkey, keylen, (const unsigned char*)key);
249     while (*data) {
250         // Convert from FiSH-BASE64
251         BF_LONG binary[2] = { 0, 0 };
252         bit = 0;
253         word = 1;
254         for (i = 0; i < 12; i++) {
255             d = fish_unbase64[(const unsigned char)*(data++)];
256             if (d == IB) goto decrypt_end;
257             binary[word] |= (unsigned long)d << bit;
258             bit += 6;
259             if (i == 5) {
260                 bit = 0;
261                 word = 0;
262             }
263         }
264 
265         // Decrypt block
266         BF_decrypt(binary, &bfkey);
267 
268         // Copy to buffer
269         GET_BYTES(end, binary[0]);
270         GET_BYTES(end, binary[1]);
271     }
272 
273   decrypt_end:
274     secure_erase_key(&bfkey);
275     *end = '\0';
276     return decrypted;
277 }
278 
279 /**
280  * Decrypts a message using the given key. ECB or CBC mode is autodetected.
281  */
fish_decrypt(const char * key,size_t keylen,const char * data)282 char *fish_decrypt(const char *key, size_t keylen, const char *data) {
283     if (*data == '*') return fish_decrypt_cbc(key, keylen, data);
284     else return fish_decrypt_ecb(key, keylen, data);
285 }
286 
287 
288 /**
289  * Encrypts a message (see fish_decrypt). The key is searched for in the
290  * key store.
291  */
fish_encrypt_for_nick(const char * nick,const char * data)292 char *fish_encrypt_for_nick(const char *nick, const char *data) {
293     char *key;
294     char *encrypted;
295     bool is_cbc;
296 
297     // Look for key
298     key = keystore_get_key(nick, &is_cbc);
299     if (!key) return NULL;
300 
301     // Encrypt
302     encrypted = is_cbc ?
303         fish_encrypt_cbc(key, strlen(key), data) :
304         fish_encrypt_ecb(key, strlen(key), data);
305 
306     free(key);
307     return encrypted;
308 }
309 
310 /**
311  * Decrypts a message (see fish_decrypt). The key is searched for in the
312  * key store.
313  */
fish_decrypt_from_nick(const char * nick,const char * data)314 char *fish_decrypt_from_nick(const char *nick, const char *data) {
315     char *key;
316     char *decrypted;
317     // Look for key
318     key = keystore_get_key(nick, NULL);
319     if (!key) return NULL;
320 
321     // Decrypt
322     decrypted = fish_decrypt(key, strlen(key), data);
323 
324     free(key);
325     return decrypted;
326 }
327 
328 
329