pspp-convert: Support decrypting encrypted SPSS syntax files.
[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
21 #include <errno.h>
22 #include <stdlib.h>
23
24 #include "data/file-name.h"
25 #include "libpspp/assertion.h"
26 #include "libpspp/cast.h"
27 #include "libpspp/cmac-aes256.h"
28 #include "libpspp/message.h"
29
30 #include "gl/minmax.h"
31 #include "gl/rijndael-alg-fst.h"
32 #include "gl/xalloc.h"
33
34 #include "gettext.h"
35 #define _(msgid) gettext (msgid)
36
37 struct encrypted_file
38   {
39     FILE *file;
40     enum { SYSTEM, SYNTAX } type;
41     int error;
42
43     uint8_t ciphertext[16];
44     uint8_t plaintext[16];
45     unsigned int ofs, n;
46
47     uint32_t rk[4 * (RIJNDAEL_MAXNR + 1)];
48     int Nr;
49   };
50
51 static bool try_password(struct encrypted_file *, const char *password);
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 char *filename)
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 (filename, "rb");
73   if (f->file == NULL)
74     {
75       msg (ME, _("An error occurred while opening `%s': %s."),
76            filename, 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              filename, 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 (filename, 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 (try_password (f, password)
125           || (decode_password (password, decoded_password)
126               && try_password (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 /* If CIPHERTEXT is the first ciphertext block in an encrypted .sav file for
290    PASSWORD, initializes rk[] and returns an nonzero Nr value.
291
292    Otherwise, returns zero. */
293 static bool
294 try_password(struct encrypted_file *f, const char *password)
295 {
296   /* NIST SP 800-108 fixed data. */
297   static const uint8_t fixed[] = {
298     /* i */
299     0x00, 0x00, 0x00, 0x01,
300
301     /* label */
302     0x35, 0x27, 0x13, 0xcc, 0x53, 0xa7, 0x78, 0x89,
303     0x87, 0x53, 0x22, 0x11, 0xd6, 0x5b, 0x31, 0x58,
304     0xdc, 0xfe, 0x2e, 0x7e, 0x94, 0xda, 0x2f, 0x00,
305     0xcc, 0x15, 0x71, 0x80, 0x0a, 0x6c, 0x63, 0x53,
306
307     /* delimiter */
308     0x00,
309
310     /* context */
311     0x38, 0xc3, 0x38, 0xac, 0x22, 0xf3, 0x63, 0x62,
312     0x0e, 0xce, 0x85, 0x3f, 0xb8, 0x07, 0x4c, 0x4e,
313     0x2b, 0x77, 0xc7, 0x21, 0xf5, 0x1a, 0x80, 0x1d,
314     0x67, 0xfb, 0xe1, 0xe1, 0x83, 0x07, 0xd8, 0x0d,
315
316     /* L */
317     0x00, 0x00, 0x01, 0x00,
318   };
319
320   char padded_password[32];
321   size_t password_len;
322   uint8_t cmac[16];
323   uint8_t key[32];
324
325   /* Truncate password to at most 10 bytes. */
326   password_len = strlen (password);
327   if (password_len > 10)
328     password_len = 10;
329
330   /* padded_password = password padded with zeros to 32 bytes. */
331   memset (padded_password, 0, sizeof padded_password);
332   memcpy (padded_password, password, password_len);
333
334   /* cmac = CMAC(padded_password, fixed). */
335   cmac_aes256 (CHAR_CAST (const uint8_t *, padded_password),
336                fixed, sizeof fixed, cmac);
337
338   /* The key is the cmac repeated twice. */
339   memcpy(key, cmac, 16);
340   memcpy(key + 16, cmac, 16);
341
342   /* Use key to initialize AES. */
343   assert (sizeof key == 32);
344   f->Nr = rijndaelKeySetupDec (f->rk, CHAR_CAST (const char *, key), 256);
345
346   /* Check for magic number at beginning of plaintext. */
347   rijndaelDecrypt (f->rk, f->Nr,
348                    CHAR_CAST (const char *, f->ciphertext),
349                    CHAR_CAST (char *, f->plaintext));
350   return !memcmp (f->plaintext, f->type == SYSTEM ? "$FL" : "* E", 3);
351 }
352
353 static bool
354 fill_buffer (struct encrypted_file *f)
355 {
356   f->n = fread (f->ciphertext, 1, sizeof f->ciphertext, f->file);
357   f->ofs = 0;
358   if (f->n == sizeof f->ciphertext)
359     {
360       rijndaelDecrypt (f->rk, f->Nr,
361                        CHAR_CAST (const char *, f->ciphertext),
362                        CHAR_CAST (char *, f->plaintext));
363       if (f->type == SYNTAX)
364         {
365           const char *eof = memchr (f->plaintext, '\04', sizeof f->plaintext);
366           if (eof)
367             f->n = CHAR_CAST (const uint8_t *, eof) - f->plaintext;
368         }
369       return true;
370     }
371   else
372     {
373       if (ferror (f->file))
374         f->error = errno;
375       return false;
376     }
377 }