pspp-convert: Add -a and -l options to search for a password.
[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 decode_password (const char *input, char output[11]);
53 static bool fill_buffer (struct encrypted_file *);
54
55 /* If FILENAME names an encrypted SPSS file, returns 1 and initializes *FP
56    for further use by the caller.
57
58    If FILENAME can be opened and read, but is not an encrypted SPSS file,
59    returns 0.
60
61    If FILENAME cannot be open or read, returns a negative errno value. */
62 int
63 encrypted_file_open (struct encrypted_file **fp, const struct file_handle *fh)
64 {
65   struct encrypted_file *f;
66   char header[36 + 16];
67   int retval;
68   int n;
69
70   f = xmalloc (sizeof *f);
71   f->error = 0;
72   f->file = fn_open (fh, "rb");
73   if (f->file == NULL)
74     {
75       msg (ME, _("An error occurred while opening `%s': %s."),
76            fh_get_file_name (fh), strerror (errno));
77       retval = -errno;
78       goto error;
79     }
80
81   n = fread (header, 1, sizeof header, f->file);
82   if (n != sizeof header)
83     {
84       int error = feof (f->file) ? 0 : errno;
85       if (error)
86         msg (ME, _("An error occurred while reading `%s': %s."),
87              fh_get_file_name (fh), strerror (error));
88       retval = -error;
89       goto error;
90     }
91
92   if (!memcmp (header + 8, "ENCRYPTEDSAV", 12))
93     f->type = SYSTEM;
94   else if (!memcmp (header + 8, "ENCRYPTEDSPS", 12))
95     f->type = SYNTAX;
96   else
97     {
98       retval = 0;
99       goto error;
100     }
101
102   memcpy (f->ciphertext, header + 36, 16);
103   f->n = 16;
104   f->ofs = 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   if (f->error)
142     return 0;
143
144   while (ofs < n)
145     {
146       unsigned int chunk = MIN (n - ofs, f->n - f->ofs);
147       if (chunk > 0)
148         {
149           memcpy (buf + ofs, &f->plaintext[f->ofs], chunk);
150           ofs += chunk;
151           f->ofs += chunk;
152         }
153       else
154         {
155           if (!fill_buffer (f))
156             return ofs;
157         }
158     }
159
160   return ofs;
161 }
162
163 /* Closes F.  Returns 0 if no read errors occurred, otherwise a positive errno
164    value. */
165 int
166 encrypted_file_close (struct encrypted_file *f)
167 {
168   int error = f->error;
169   if (fclose (f->file) == EOF && !error)
170     error = errno;
171   free (f);
172
173   return error;
174 }
175
176 /* Returns true if F is an encrypted system file,
177    false if it is an encrypted syntax file. */
178 bool
179 encrypted_file_is_sav (const struct encrypted_file *f)
180 {
181   return f->type == SYSTEM;
182 }
183 \f
184 #define b(x) (1 << (x))
185
186 static const uint16_t m0[4][2] = {
187   { b(2),                         b(2) | b(3) | b(6) | b(7) },
188   { b(3),                         b(0) | b(1) | b(4) | b(5) },
189   { b(4) | b(7),                  b(8) | b(9) | b(12) | b(14) },
190   { b(5) | b(6),                  b(10) | b(11) | b(14) | b(15) },
191 };
192
193 static const uint16_t m1[4][2] = {
194   { b(0) | b(3) | b(12) | b(15),  b(0) | b(1) | b(4) | b(5) },
195   { b(1) | b(2) | b(13) | b(14),  b(2) | b(3) | b(6) | b(7) },
196   { b(4) | b(7) | b(8) | b(11),   b(8) | b(9) | b(12) | b(13) },
197   { b(5) | b(6) | b(9) | b(10),   b(10) | b(11) | b(14) | b(15) },
198 };
199
200 static const uint16_t m2[4][2] = {
201   { b(2),                         b(1) | b(3) | b(9) | b(11) },
202   { b(3),                         b(0) | b(2) | b(8) | b(10) },
203   { b(4) | b(7),                  b(4) | b(6) | b(12) | b(14) },
204   { b(5) | b(6),                  b(5) | b(7) | b(13) | b(15) },
205 };
206
207 static const uint16_t m3[4][2] = {
208   { b(0) | b(3) | b(12) | b(15),  b(0) | b(2) | b(8) | b(10) },
209   { b(1) | b(2) | b(13) | b(14),  b(1) | b(3) | b(9) | b(11) },
210   { b(4) | b(7) | b(8) | b(11),   b(4) | b(6) | b(12) | b(14) },
211   { b(5) | b(6) | b(9) | b(10),   b(5) | b(7) | b(13) | b(15) },
212 };
213
214 static int
215 decode_nibble (const uint16_t table[4][2], int nibble)
216 {
217   int i;
218
219   for (i = 0; i < 4; i++)
220     if (table[i][0] & (1 << nibble))
221       return table[i][1];
222
223   return 0;
224 }
225
226 /* Returns true if X has exactly one 1-bit, false otherwise. */
227 static bool
228 is_pow2 (int x)
229 {
230   return x && (x & (x - 1)) == 0;
231 }
232
233 /* If X has exactly one 1-bit, returns its index, where bit 0 is the LSB.
234    Otherwise, returns 0. */
235 static int
236 find_1bit (uint16_t x)
237 {
238   int i;
239
240   if (!is_pow2 (x))
241     return -1;
242
243   for (i = 0; i < 16; i++)
244     if (x & (1u << i))
245       return i;
246
247   abort ();
248 }
249
250 /* Attempts to decode a pair of encoded password characters A and B into a
251    single byte of the plaintext password.  Returns 0 if A and B are not a valid
252    encoded password pair, otherwise a byte of the plaintext password. */
253 static int
254 decode_password_2bytes (uint8_t a, uint8_t b)
255 {
256   int x = find_1bit (decode_nibble (m0, a >> 4) & decode_nibble (m2, b >> 4));
257   int y = find_1bit (decode_nibble (m1, a & 15) & decode_nibble (m3, b & 15));
258   return x < 0 || y < 0 ? 0 : (x << 4) | y;
259 }
260
261 /* Decodes an SPSS so-called "encrypted" password INPUT into OUTPUT.
262
263    An encoded password is always an even number of bytes long and no longer
264    than 20 bytes.  A decoded password is never longer than 10 bytes plus a null
265    terminator.
266
267    Returns true if successful, otherwise false. */
268 static bool
269 decode_password (const char *input, char output[11])
270 {
271   size_t len;
272
273   len = strlen (input);
274   if (len > 20 || len % 2)
275     return false;
276
277   for (; *input; input += 2)
278     {
279       int c = decode_password_2bytes (input[0], input[1]);
280       if (!c)
281         return false;
282       *output++ = c;
283     }
284   *output = '\0';
285
286   return true;
287 }
288
289 /* Attempts to use plaintext password PASSWORD to unlock F.  Returns true if
290    successful, otherwise false. */
291 bool
292 encrypted_file_unlock__ (struct encrypted_file *f, const char *password)
293 {
294   /* NIST SP 800-108 fixed data. */
295   static const uint8_t fixed[] = {
296     /* i */
297     0x00, 0x00, 0x00, 0x01,
298
299     /* label */
300     0x35, 0x27, 0x13, 0xcc, 0x53, 0xa7, 0x78, 0x89,
301     0x87, 0x53, 0x22, 0x11, 0xd6, 0x5b, 0x31, 0x58,
302     0xdc, 0xfe, 0x2e, 0x7e, 0x94, 0xda, 0x2f, 0x00,
303     0xcc, 0x15, 0x71, 0x80, 0x0a, 0x6c, 0x63, 0x53,
304
305     /* delimiter */
306     0x00,
307
308     /* context */
309     0x38, 0xc3, 0x38, 0xac, 0x22, 0xf3, 0x63, 0x62,
310     0x0e, 0xce, 0x85, 0x3f, 0xb8, 0x07, 0x4c, 0x4e,
311     0x2b, 0x77, 0xc7, 0x21, 0xf5, 0x1a, 0x80, 0x1d,
312     0x67, 0xfb, 0xe1, 0xe1, 0x83, 0x07, 0xd8, 0x0d,
313
314     /* L */
315     0x00, 0x00, 0x01, 0x00,
316   };
317
318   char padded_password[32];
319   size_t password_len;
320   uint8_t cmac[16];
321   uint8_t key[32];
322
323   /* Truncate password to at most 10 bytes. */
324   password_len = strlen (password);
325   if (password_len > 10)
326     password_len = 10;
327
328   /* padded_password = password padded with zeros to 32 bytes. */
329   memset (padded_password, 0, sizeof padded_password);
330   memcpy (padded_password, password, password_len);
331
332   /* cmac = CMAC(padded_password, fixed). */
333   cmac_aes256 (CHAR_CAST (const uint8_t *, padded_password),
334                fixed, sizeof fixed, cmac);
335
336   /* The key is the cmac repeated twice. */
337   memcpy(key, cmac, 16);
338   memcpy(key + 16, cmac, 16);
339
340   /* Use key to initialize AES. */
341   assert (sizeof key == 32);
342   f->Nr = rijndaelKeySetupDec (f->rk, CHAR_CAST (const char *, key), 256);
343
344   /* Check for magic number at beginning of plaintext. */
345   rijndaelDecrypt (f->rk, f->Nr,
346                    CHAR_CAST (const char *, f->ciphertext),
347                    CHAR_CAST (char *, f->plaintext));
348
349   const char *magic = f->type == SYSTEM ? "$FL?@(#)" : "* Encoding";
350   for (int i = 0; magic[i]; i++)
351     if (magic[i] != '?' && f->plaintext[i] != magic[i])
352       return false;
353   return true;
354 }
355
356 static bool
357 fill_buffer (struct encrypted_file *f)
358 {
359   f->n = fread (f->ciphertext, 1, sizeof f->ciphertext, f->file);
360   f->ofs = 0;
361   if (f->n == sizeof f->ciphertext)
362     {
363       rijndaelDecrypt (f->rk, f->Nr,
364                        CHAR_CAST (const char *, f->ciphertext),
365                        CHAR_CAST (char *, f->plaintext));
366       if (f->type == SYNTAX)
367         {
368           const char *eof = memchr (f->plaintext, '\04', sizeof f->plaintext);
369           if (eof)
370             f->n = CHAR_CAST (const uint8_t *, eof) - f->plaintext;
371         }
372       return true;
373     }
374   else
375     {
376       if (ferror (f->file))
377         f->error = errno;
378       return false;
379     }
380 }