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