better tests
[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 #include "libpspp/str.h"
31
32 #include "gl/minmax.h"
33 #include "gl/rijndael-alg-fst.h"
34 #include "gl/xalloc.h"
35
36 #include "gettext.h"
37 #define _(msgid) gettext (msgid)
38
39 struct encrypted_file
40   {
41     const struct file_handle *fh;
42     FILE *file;
43     int error;
44
45     uint8_t ciphertext[256];
46     uint8_t plaintext[256];
47     unsigned int ofs, n, readable;
48
49     uint32_t rk[4 * (RIJNDAEL_MAXNR + 1)];
50     int Nr;
51   };
52
53 static bool decode_password (const char *input, char output[11]);
54 static void 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   enum { HEADER_SIZE = 36 };
68   char data[HEADER_SIZE + sizeof f->ciphertext];
69   int retval;
70   int n;
71
72   f = xmalloc (sizeof *f);
73   f->error = 0;
74   f->fh = fh;
75   f->file = fn_open (fh, "rb");
76   if (f->file == NULL)
77     {
78       msg (ME, _("An error occurred while opening `%s': %s."),
79            fh_get_file_name (fh), strerror (errno));
80       retval = -errno;
81       goto error;
82     }
83
84   n = fread (data, 1, sizeof data, f->file);
85   if (n < HEADER_SIZE + 2 * 16)
86     {
87       int error = feof (f->file) ? 0 : errno;
88       if (error)
89         msg (ME, _("An error occurred while reading `%s': %s."),
90              fh_get_file_name (fh), strerror (error));
91       retval = -error;
92       goto error;
93     }
94
95   if (memcmp (data + 8, "ENCRYPTED", 9))
96     {
97       retval = 0;
98       goto error;
99     }
100
101   f->n = n - HEADER_SIZE;
102   memcpy (f->ciphertext, data + HEADER_SIZE, f->n);
103   f->ofs = 0;
104   f->readable = 0;
105   *fp = f;
106   return 1;
107
108 error:
109   if (f->file)
110     fn_close (fh, f->file);
111   free (f);
112   *fp = NULL;
113
114   return retval;
115 }
116
117 /* Attempts to use PASSWORD, which may be a plaintext or "encrypted" password,
118    to unlock F.  Returns true if successful, otherwise false. */
119 bool
120 encrypted_file_unlock (struct encrypted_file *f, const char *password)
121 {
122   char decoded_password[11];
123
124   return (encrypted_file_unlock__ (f, password)
125           || (decode_password (password, decoded_password)
126               && encrypted_file_unlock__ (f, decoded_password)));
127 }
128
129 /* Attempts to read N bytes of plaintext from F into BUF.  Returns the number
130    of bytes successfully read.  A return value less than N may indicate end of
131    file or an error; use encrypted_file_close() to distinguish.
132
133    This function can only be used after encrypted_file_unlock() returns
134    true. */
135 size_t
136 encrypted_file_read (struct encrypted_file *f, void *buf_, size_t n)
137 {
138   uint8_t *buf = buf_;
139   size_t ofs = 0;
140
141   while (ofs < n)
142     {
143       unsigned int chunk = MIN (n - ofs, f->readable - f->ofs);
144       if (chunk > 0)
145         {
146           memcpy (buf + ofs, &f->plaintext[f->ofs], chunk);
147           ofs += chunk;
148           f->ofs += chunk;
149         }
150       else
151         {
152           fill_buffer (f);
153           if (!f->readable)
154             break;
155         }
156     }
157
158   return ofs;
159 }
160
161 /* Closes F.  Returns 0 if no read errors occurred, otherwise a positive errno
162    value. */
163 int
164 encrypted_file_close (struct encrypted_file *f)
165 {
166   int error = f->error > 0 ? f->error : 0;
167   if (fclose (f->file) == EOF && !error)
168     error = errno;
169   free (f);
170
171   return error;
172 }
173 \f
174 #define b(x) (1 << (x))
175
176 static const uint16_t m0[4][2] = {
177   { b(2),                         b(2) | b(3) | b(6) | b(7) },
178   { b(3),                         b(0) | b(1) | b(4) | b(5) },
179   { b(4) | b(7),                  b(8) | b(9) | b(12) | b(14) },
180   { b(5) | b(6),                  b(10) | b(11) | b(14) | b(15) },
181 };
182
183 static const uint16_t m1[4][2] = {
184   { b(0) | b(3) | b(12) | b(15),  b(0) | b(1) | b(4) | b(5) },
185   { b(1) | b(2) | b(13) | b(14),  b(2) | b(3) | b(6) | b(7) },
186   { b(4) | b(7) | b(8) | b(11),   b(8) | b(9) | b(12) | b(13) },
187   { b(5) | b(6) | b(9) | b(10),   b(10) | b(11) | b(14) | b(15) },
188 };
189
190 static const uint16_t m2[4][2] = {
191   { b(2),                         b(1) | b(3) | b(9) | b(11) },
192   { b(3),                         b(0) | b(2) | b(8) | b(10) },
193   { b(4) | b(7),                  b(4) | b(6) | b(12) | b(14) },
194   { b(5) | b(6),                  b(5) | b(7) | b(13) | b(15) },
195 };
196
197 static const uint16_t m3[4][2] = {
198   { b(0) | b(3) | b(12) | b(15),  b(0) | b(2) | b(8) | b(10) },
199   { b(1) | b(2) | b(13) | b(14),  b(1) | b(3) | b(9) | b(11) },
200   { b(4) | b(7) | b(8) | b(11),   b(4) | b(6) | b(12) | b(14) },
201   { b(5) | b(6) | b(9) | b(10),   b(5) | b(7) | b(13) | b(15) },
202 };
203
204 static int
205 decode_nibble (const uint16_t table[4][2], int nibble)
206 {
207   int i;
208
209   for (i = 0; i < 4; i++)
210     if (table[i][0] & (1 << nibble))
211       return table[i][1];
212
213   return 0;
214 }
215
216 /* Returns true if X has exactly one 1-bit, false otherwise. */
217 static bool
218 is_pow2 (int x)
219 {
220   return x && (x & (x - 1)) == 0;
221 }
222
223 /* If X has exactly one 1-bit, returns its index, where bit 0 is the LSB.
224    Otherwise, returns 0. */
225 static int
226 find_1bit (uint16_t x)
227 {
228   int i;
229
230   if (!is_pow2 (x))
231     return -1;
232
233   for (i = 0; i < 16; i++)
234     if (x & (1u << i))
235       return i;
236
237   abort ();
238 }
239
240 /* Attempts to decode a pair of encoded password characters A and B into a
241    single byte of the plaintext password.  Returns 0 if A and B are not a valid
242    encoded password pair, otherwise a byte of the plaintext password. */
243 static int
244 decode_password_2bytes (uint8_t a, uint8_t b)
245 {
246   int x = find_1bit (decode_nibble (m0, a >> 4) & decode_nibble (m2, b >> 4));
247   int y = find_1bit (decode_nibble (m1, a & 15) & decode_nibble (m3, b & 15));
248   return x < 0 || y < 0 ? 0 : (x << 4) | y;
249 }
250
251 /* Decodes an SPSS so-called "encrypted" password INPUT into OUTPUT.
252
253    An encoded password is always an even number of bytes long and no longer
254    than 20 bytes.  A decoded password is never longer than 10 bytes plus a null
255    terminator.
256
257    Returns true if successful, otherwise false. */
258 static bool
259 decode_password (const char *input, char output[11])
260 {
261   size_t len;
262
263   len = strlen (input);
264   if (len > 20 || len % 2)
265     return false;
266
267   for (; *input; input += 2)
268     {
269       int c = decode_password_2bytes (input[0], input[1]);
270       if (!c)
271         return false;
272       *output++ = c;
273     }
274   *output = '\0';
275
276   return true;
277 }
278
279 /* Check for magic number at beginning of plaintext decrypted from F. */
280 static bool
281 is_good_magic (const struct encrypted_file *f)
282 {
283   char plaintext[16];
284   rijndaelDecrypt (f->rk, f->Nr, CHAR_CAST (const char *, f->ciphertext),
285                    plaintext);
286
287   const struct substring magic[] = {
288     ss_cstr ("$FL2@(#)"),
289     ss_cstr ("$FL3@(#)"),
290     ss_cstr ("* Encoding"),
291     ss_buffer ("PK\3\4\x14\0\x8", 7)
292   };
293   for (size_t i = 0; i < sizeof magic / sizeof *magic; i++)
294     if (ss_equals (ss_buffer (plaintext, magic[i].length), magic[i]))
295       return true;
296   return false;
297 }
298
299 /* Attempts to use plaintext password PASSWORD to unlock F.  Returns true if
300    successful, otherwise false. */
301 bool
302 encrypted_file_unlock__ (struct encrypted_file *f, const char *password)
303 {
304   /* NIST SP 800-108 fixed data. */
305   static const uint8_t fixed[] = {
306     /* i */
307     0x00, 0x00, 0x00, 0x01,
308
309     /* label */
310     0x35, 0x27, 0x13, 0xcc, 0x53, 0xa7, 0x78, 0x89,
311     0x87, 0x53, 0x22, 0x11, 0xd6, 0x5b, 0x31, 0x58,
312     0xdc, 0xfe, 0x2e, 0x7e, 0x94, 0xda, 0x2f, 0x00,
313     0xcc, 0x15, 0x71, 0x80, 0x0a, 0x6c, 0x63, 0x53,
314
315     /* delimiter */
316     0x00,
317
318     /* context */
319     0x38, 0xc3, 0x38, 0xac, 0x22, 0xf3, 0x63, 0x62,
320     0x0e, 0xce, 0x85, 0x3f, 0xb8, 0x07, 0x4c, 0x4e,
321     0x2b, 0x77, 0xc7, 0x21, 0xf5, 0x1a, 0x80, 0x1d,
322     0x67, 0xfb, 0xe1, 0xe1, 0x83, 0x07, 0xd8, 0x0d,
323
324     /* L */
325     0x00, 0x00, 0x01, 0x00,
326   };
327
328   char padded_password[32];
329   size_t password_len;
330   uint8_t cmac[16];
331   uint8_t key[32];
332
333   /* Truncate password to at most 10 bytes. */
334   password_len = strlen (password);
335   if (password_len > 10)
336     password_len = 10;
337
338   /* padded_password = password padded with zeros to 32 bytes. */
339   memset (padded_password, 0, sizeof padded_password);
340   memcpy (padded_password, password, password_len);
341
342   /* cmac = CMAC(padded_password, fixed). */
343   cmac_aes256 (CHAR_CAST (const uint8_t *, padded_password),
344                fixed, sizeof fixed, cmac);
345
346   /* The key is the cmac repeated twice. */
347   memcpy(key, cmac, 16);
348   memcpy(key + 16, cmac, 16);
349
350   /* Use key to initialize AES. */
351   assert (sizeof key == 32);
352   f->Nr = rijndaelKeySetupDec (f->rk, CHAR_CAST (const char *, key), 256);
353
354   if (!is_good_magic (f))
355     return false;
356
357   fill_buffer (f);
358   return true;
359 }
360
361 /* Checks the 16 bytes of PLAINTEXT for PKCS#7 padding bytes.  Returns the
362    number of padding bytes (between 1 and 16, inclusive), if well formed,
363    otherwise 0. */
364 static int
365 check_padding (const uint8_t *plaintext)
366 {
367   uint8_t pad = plaintext[15];
368   if (pad < 1 || pad > 16)
369     return 0;
370
371   for (size_t i = 1; i < pad; i++)
372     if (plaintext[15 - i] != pad)
373       return 0;
374
375   return pad;
376 }
377
378 static void
379 fill_buffer (struct encrypted_file *f)
380 {
381   /* Move bytes between f->ciphertext[f->readable] and f->ciphertext[f->n] to
382      the beginning of f->ciphertext.
383
384      The first time this is called for a given file, it does nothing because
385      f->readable is initially 0.  After that, in steady state f->readable is 16
386      less than f->n, so the final 16 bytes of ciphertext become the first 16
387      bytes.  This is necessary because we don't know until we hit end-of-file
388      whether padding in the last 16 bytes will require us to discard up to 16
389      bytes of data. */
390   memmove (f->ciphertext, f->ciphertext + f->readable, f->n - f->readable);
391   f->n -= f->readable;
392   f->readable = 0;
393   f->ofs = 0;
394
395   if (f->error)                 /* or assert(!f->error)? */
396     return;
397
398   /* Read new ciphernext, extending f->n, until we've filled up f->ciphertext
399      or until we reach end-of-file or encounter an error.
400
401      Afterward, f->error indicates what happened. */
402   while (f->n < sizeof f->ciphertext)
403     {
404       size_t retval = fread (f->ciphertext + f->n, 1,
405                              sizeof f->ciphertext - f->n, f->file);
406       if (!retval)
407         {
408           f->error = ferror (f->file) ? errno : EOF;
409           break;
410         }
411       f->n += retval;
412     }
413
414   /* Calculate the number of readable bytes.  If we're at the end of the file,
415      then we can read everything, otherwise we hold back the last 16 bytes
416      because they might be padding or not. */
417   if (!f->error)
418     {
419       assert (f->n == sizeof f->ciphertext);
420       f->readable = f->n - 16;
421     }
422   else
423     f->readable = f->n;
424
425   /* If we have an incomplete block then trim it off and complain. */
426   unsigned int overhang = f->readable % 16;
427   if (overhang)
428     {
429       assert (f->error);
430       msg (ME, _("%s: encrypted file corrupted (ends in incomplete %u-byte "
431                  "ciphertext block)"),
432            fh_get_file_name (f->fh), overhang);
433       f->error = EIO;
434       f->readable -= overhang;
435     }
436
437   /* Decrypt all the blocks we have. */
438   for (size_t ofs = 0; ofs < f->readable; ofs += 16)
439     rijndaelDecrypt (f->rk, f->Nr,
440                      CHAR_CAST (const char *, f->ciphertext + ofs),
441                      CHAR_CAST (char *, f->plaintext + ofs));
442
443   /* If we're at end of file then check the padding and trim it off. */
444   if (f->error == EOF)
445     {
446       unsigned int pad = check_padding (&f->plaintext[f->n - 16]);
447       if (!pad)
448         {
449           msg (ME, _("%s: encrypted file corrupted (ends with bad padding)"),
450                fh_get_file_name (f->fh));
451           f->error = EIO;
452           return;
453         }
454
455       f->readable -= pad;
456     }
457 }