fbuf: New data structure for buffered file I/O.
[pspp] / src / data / encrypted-file.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2013, 2015 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include "data/encrypted-file.h"
20 #include "data/file-handle-def.h"
21
22 #include <errno.h>
23 #include <stdlib.h>
24
25 #include "data/file-name.h"
26 #include "libpspp/assertion.h"
27 #include "libpspp/cast.h"
28 #include "libpspp/cmac-aes256.h"
29 #include "libpspp/message.h"
30
31 #include "gl/minmax.h"
32 #include "gl/rijndael-alg-fst.h"
33 #include "gl/xalloc.h"
34
35 #include "gettext.h"
36 #define _(msgid) gettext (msgid)
37
38 struct encrypted_file
39   {
40     FILE *file;
41     enum { SYSTEM, SYNTAX } type;
42     int error;
43
44     uint8_t ciphertext[16];
45     uint8_t plaintext[16];
46     unsigned int ofs, n;
47
48     uint32_t rk[4 * (RIJNDAEL_MAXNR + 1)];
49     int Nr;
50   };
51
52 static bool try_password(struct encrypted_file *, const char *password);
53 static bool decode_password (const char *input, char output[11]);
54 static bool fill_buffer (struct encrypted_file *);
55
56 /* If FILENAME names an encrypted SPSS file, returns 1 and initializes *FP
57    for further use by the caller.
58
59    If FILENAME can be opened and read, but is not an encrypted SPSS file,
60    returns 0.
61
62    If FILENAME cannot be open or read, returns a negative errno value. */
63 int
64 encrypted_file_open (struct encrypted_file **fp, const struct file_handle *fh)
65 {
66   struct encrypted_file *f;
67   char header[36 + 16];
68   int retval;
69   int n;
70
71   f = xmalloc (sizeof *f);
72   f->error = 0;
73   f->file = fn_fopen (fh, "rb");
74   if (f->file == NULL)
75     {
76       msg (ME, _("An error occurred while opening `%s': %s."),
77            fh_get_file_name (fh), strerror (errno));
78       retval = -errno;
79       goto error;
80     }
81
82   n = fread (header, 1, sizeof header, f->file);
83   if (n != sizeof header)
84     {
85       int error = feof (f->file) ? 0 : errno;
86       if (error)
87         msg (ME, _("An error occurred while reading `%s': %s."),
88              fh_get_file_name (fh), strerror (error));
89       retval = -error;
90       goto error;
91     }
92
93   if (!memcmp (header + 8, "ENCRYPTEDSAV", 12))
94     f->type = SYSTEM;
95   else if (!memcmp (header + 8, "ENCRYPTEDSPS", 12))
96     f->type = SYNTAX;
97   else
98     {
99       retval = 0;
100       goto error;
101     }
102
103   memcpy (f->ciphertext, header + 36, 16);
104   f->n = 16;
105   f->ofs = 0;
106   *fp = f;
107   return 1;
108
109 error:
110   if (f->file)
111     fn_close (fh, f->file);
112   free (f);
113   *fp = NULL;
114
115   return retval;
116 }
117
118 /* Attempts to use PASSWORD, which may be a plaintext or "encrypted" password,
119    to unlock F.  Returns true if successful, otherwise false. */
120 bool
121 encrypted_file_unlock (struct encrypted_file *f, const char *password)
122 {
123   char decoded_password[11];
124
125   return (try_password (f, password)
126           || (decode_password (password, decoded_password)
127               && try_password (f, decoded_password)));
128 }
129
130 /* Attempts to read N bytes of plaintext from F into BUF.  Returns the number
131    of bytes successfully read.  A return value less than N may indicate end of
132    file or an error; use encrypted_file_close() to distinguish.
133
134    This function can only be used after encrypted_file_unlock() returns
135    true. */
136 size_t
137 encrypted_file_read (struct encrypted_file *f, void *buf_, size_t n)
138 {
139   uint8_t *buf = buf_;
140   size_t ofs = 0;
141
142   if (f->error)
143     return 0;
144
145   while (ofs < n)
146     {
147       unsigned int chunk = MIN (n - ofs, f->n - f->ofs);
148       if (chunk > 0)
149         {
150           memcpy (buf + ofs, &f->plaintext[f->ofs], chunk);
151           ofs += chunk;
152           f->ofs += chunk;
153         }
154       else
155         {
156           if (!fill_buffer (f))
157             return ofs;
158         }
159     }
160
161   return ofs;
162 }
163
164 /* Closes F.  Returns 0 if no read errors occurred, otherwise a positive errno
165    value. */
166 int
167 encrypted_file_close (struct encrypted_file *f)
168 {
169   int error = f->error;
170   if (fclose (f->file) == EOF && !error)
171     error = errno;
172   free (f);
173
174   return error;
175 }
176
177 /* Returns true if F is an encrypted system file,
178    false if it is an encrypted syntax file. */
179 bool
180 encrypted_file_is_sav (const struct encrypted_file *f)
181 {
182   return f->type == SYSTEM;
183 }
184 \f
185 #define b(x) (1 << (x))
186
187 static const uint16_t m0[4][2] = {
188   { b(2),                         b(2) | b(3) | b(6) | b(7) },
189   { b(3),                         b(0) | b(1) | b(4) | b(5) },
190   { b(4) | b(7),                  b(8) | b(9) | b(12) | b(14) },
191   { b(5) | b(6),                  b(10) | b(11) | b(14) | b(15) },
192 };
193
194 static const uint16_t m1[4][2] = {
195   { b(0) | b(3) | b(12) | b(15),  b(0) | b(1) | b(4) | b(5) },
196   { b(1) | b(2) | b(13) | b(14),  b(2) | b(3) | b(6) | b(7) },
197   { b(4) | b(7) | b(8) | b(11),   b(8) | b(9) | b(12) | b(13) },
198   { b(5) | b(6) | b(9) | b(10),   b(10) | b(11) | b(14) | b(15) },
199 };
200
201 static const uint16_t m2[4][2] = {
202   { b(2),                         b(1) | b(3) | b(9) | b(11) },
203   { b(3),                         b(0) | b(2) | b(8) | b(10) },
204   { b(4) | b(7),                  b(4) | b(6) | b(12) | b(14) },
205   { b(5) | b(6),                  b(5) | b(7) | b(13) | b(15) },
206 };
207
208 static const uint16_t m3[4][2] = {
209   { b(0) | b(3) | b(12) | b(15),  b(0) | b(2) | b(8) | b(10) },
210   { b(1) | b(2) | b(13) | b(14),  b(1) | b(3) | b(9) | b(11) },
211   { b(4) | b(7) | b(8) | b(11),   b(4) | b(6) | b(12) | b(14) },
212   { b(5) | b(6) | b(9) | b(10),   b(5) | b(7) | b(13) | b(15) },
213 };
214
215 static int
216 decode_nibble (const uint16_t table[4][2], int nibble)
217 {
218   int i;
219
220   for (i = 0; i < 4; i++)
221     if (table[i][0] & (1 << nibble))
222       return table[i][1];
223
224   return 0;
225 }
226
227 /* Returns true if X has exactly one 1-bit, false otherwise. */
228 static bool
229 is_pow2 (int x)
230 {
231   return x && (x & (x - 1)) == 0;
232 }
233
234 /* If X has exactly one 1-bit, returns its index, where bit 0 is the LSB.
235    Otherwise, returns 0. */
236 static int
237 find_1bit (uint16_t x)
238 {
239   int i;
240
241   if (!is_pow2 (x))
242     return -1;
243
244   for (i = 0; i < 16; i++)
245     if (x & (1u << i))
246       return i;
247
248   abort ();
249 }
250
251 /* Attempts to decode a pair of encoded password characters A and B into a
252    single byte of the plaintext password.  Returns 0 if A and B are not a valid
253    encoded password pair, otherwise a byte of the plaintext password. */
254 static int
255 decode_password_2bytes (uint8_t a, uint8_t b)
256 {
257   int x = find_1bit (decode_nibble (m0, a >> 4) & decode_nibble (m2, b >> 4));
258   int y = find_1bit (decode_nibble (m1, a & 15) & decode_nibble (m3, b & 15));
259   return x < 0 || y < 0 ? 0 : (x << 4) | y;
260 }
261
262 /* Decodes an SPSS so-called "encrypted" password INPUT into OUTPUT.
263
264    An encoded password is always an even number of bytes long and no longer
265    than 20 bytes.  A decoded password is never longer than 10 bytes plus a null
266    terminator.
267
268    Returns true if successful, otherwise false. */
269 static bool
270 decode_password (const char *input, char output[11])
271 {
272   size_t len;
273
274   len = strlen (input);
275   if (len > 20 || len % 2)
276     return false;
277
278   for (; *input; input += 2)
279     {
280       int c = decode_password_2bytes (input[0], input[1]);
281       if (!c)
282         return false;
283       *output++ = c;
284     }
285   *output = '\0';
286
287   return true;
288 }
289
290 /* If CIPHERTEXT is the first ciphertext block in an encrypted .sav file for
291    PASSWORD, initializes rk[] and returns an nonzero Nr value.
292
293    Otherwise, returns zero. */
294 static bool
295 try_password(struct encrypted_file *f, const char *password)
296 {
297   /* NIST SP 800-108 fixed data. */
298   static const uint8_t fixed[] = {
299     /* i */
300     0x00, 0x00, 0x00, 0x01,
301
302     /* label */
303     0x35, 0x27, 0x13, 0xcc, 0x53, 0xa7, 0x78, 0x89,
304     0x87, 0x53, 0x22, 0x11, 0xd6, 0x5b, 0x31, 0x58,
305     0xdc, 0xfe, 0x2e, 0x7e, 0x94, 0xda, 0x2f, 0x00,
306     0xcc, 0x15, 0x71, 0x80, 0x0a, 0x6c, 0x63, 0x53,
307
308     /* delimiter */
309     0x00,
310
311     /* context */
312     0x38, 0xc3, 0x38, 0xac, 0x22, 0xf3, 0x63, 0x62,
313     0x0e, 0xce, 0x85, 0x3f, 0xb8, 0x07, 0x4c, 0x4e,
314     0x2b, 0x77, 0xc7, 0x21, 0xf5, 0x1a, 0x80, 0x1d,
315     0x67, 0xfb, 0xe1, 0xe1, 0x83, 0x07, 0xd8, 0x0d,
316
317     /* L */
318     0x00, 0x00, 0x01, 0x00,
319   };
320
321   char padded_password[32];
322   size_t password_len;
323   uint8_t cmac[16];
324   uint8_t key[32];
325
326   /* Truncate password to at most 10 bytes. */
327   password_len = strlen (password);
328   if (password_len > 10)
329     password_len = 10;
330
331   /* padded_password = password padded with zeros to 32 bytes. */
332   memset (padded_password, 0, sizeof padded_password);
333   memcpy (padded_password, password, password_len);
334
335   /* cmac = CMAC(padded_password, fixed). */
336   cmac_aes256 (CHAR_CAST (const uint8_t *, padded_password),
337                fixed, sizeof fixed, cmac);
338
339   /* The key is the cmac repeated twice. */
340   memcpy(key, cmac, 16);
341   memcpy(key + 16, cmac, 16);
342
343   /* Use key to initialize AES. */
344   assert (sizeof key == 32);
345   f->Nr = rijndaelKeySetupDec (f->rk, CHAR_CAST (const char *, key), 256);
346
347   /* Check for magic number at beginning of plaintext. */
348   rijndaelDecrypt (f->rk, f->Nr,
349                    CHAR_CAST (const char *, f->ciphertext),
350                    CHAR_CAST (char *, f->plaintext));
351   return !memcmp (f->plaintext, f->type == SYSTEM ? "$FL" : "* E", 3);
352 }
353
354 static bool
355 fill_buffer (struct encrypted_file *f)
356 {
357   f->n = fread (f->ciphertext, 1, sizeof f->ciphertext, f->file);
358   f->ofs = 0;
359   if (f->n == sizeof f->ciphertext)
360     {
361       rijndaelDecrypt (f->rk, f->Nr,
362                        CHAR_CAST (const char *, f->ciphertext),
363                        CHAR_CAST (char *, f->plaintext));
364       if (f->type == SYNTAX)
365         {
366           const char *eof = memchr (f->plaintext, '\04', sizeof f->plaintext);
367           if (eof)
368             f->n = CHAR_CAST (const uint8_t *, eof) - f->plaintext;
369         }
370       return true;
371     }
372   else
373     {
374       if (ferror (f->file))
375         f->error = errno;
376       return false;
377     }
378 }