protection improvement (1): different S2K for PW1 and Reset-code
[gnuk/gnuk.git] / src / openpgp.c
1 /*
2  * openpgp.c -- OpenPGP card protocol support
3  *
4  * Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
5  * Author: NIIBE Yutaka <gniibe@fsij.org>
6  *
7  * This file is a part of Gnuk, a GnuPG USB Token implementation.
8  *
9  * Gnuk is free software: you can redistribute it and/or modify it
10  * under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * Gnuk is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 #include "config.h"
25 #include "ch.h"
26 #include "hal.h"
27 #include "gnuk.h"
28 #include "sys.h"
29 #include "openpgp.h"
30 #include "sha256.h"
31
32 #define CLS(a) a.cmd_apdu_head[0]
33 #define INS(a) a.cmd_apdu_head[1]
34 #define P1(a) a.cmd_apdu_head[2]
35 #define P2(a) a.cmd_apdu_head[3]
36
37 #define INS_VERIFY                              0x20
38 #define INS_CHANGE_REFERENCE_DATA               0x24
39 #define INS_PSO                                 0x2a
40 #define INS_RESET_RETRY_COUNTER                 0x2c
41 #define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR    0x47
42 #define INS_EXTERNAL_AUTHENTICATE               0x82
43 #define INS_GET_CHALLENGE                       0x84
44 #define INS_INTERNAL_AUTHENTICATE               0x88
45 #define INS_SELECT_FILE                         0xa4
46 #define INS_READ_BINARY                         0xb0
47 #define INS_GET_DATA                            0xca
48 #define INS_WRITE_BINARY                        0xd0
49 #define INS_UPDATE_BINARY                       0xd6
50 #define INS_PUT_DATA                            0xda
51 #define INS_PUT_DATA_ODD                        0xdb    /* For key import */
52
53 #define CHALLENGE_LEN   16
54 static const uint8_t *challenge; /* Random bytes */
55
56 static const uint8_t
57 select_file_TOP_result[] __attribute__ ((aligned (1))) = {
58   0x00, 0x00,        /* unused */
59   0x00, 0x00,        /* number of bytes in this directory: to be filled */
60   0x3f, 0x00,        /* field of selected file: MF, 3f00 */
61   0x38,                 /* it's DF */
62   0xff,                 /* unused */
63   0xff, 0x44, 0x44,     /* access conditions */
64   0x01,                 /* status of the selected file (OK, unblocked) */
65   0x05,                 /* number of bytes of data follow */
66     0x03,                       /* Features: unused */
67     0x01,                       /* number of subdirectories (OpenPGP) */
68     0x01,                       /* number of elementary files (SerialNo) */
69     0x00,                       /* number of secret codes */
70     0x00,                       /* Unused */
71   0x00, 0x00            /* PIN status: OK, PIN blocked?: No */
72 };
73
74 void
75 set_res_sw (uint8_t sw1, uint8_t sw2)
76 {
77   apdu.sw = (sw1 << 8) | sw2;
78 }
79
80 #define FILE_NONE       0
81 #define FILE_DF_OPENPGP 1
82 #define FILE_MF         2
83 #define FILE_EF_DIR     3
84 #define FILE_EF_SERIAL_NO       4
85 #define FILE_EF_UPDATE_KEY_0    5
86 #define FILE_EF_UPDATE_KEY_1    6
87 #define FILE_EF_UPDATE_KEY_2    7
88 #define FILE_EF_UPDATE_KEY_3    8
89 #define FILE_EF_CH_CERTIFICATE  9
90
91 static uint8_t file_selection;
92
93 static void
94 gpg_init (void)
95 {
96   const uint8_t *flash_data_start;
97
98   file_selection = FILE_NONE;
99   flash_data_start = flash_init ();
100   gpg_data_scan (flash_data_start);
101 }
102
103 static void
104 gpg_fini (void)
105 {
106   ac_fini ();
107 }
108
109 #if defined(PINPAD_SUPPORT)
110 /* 
111  * Let user input PIN string.
112  * Return length of the string.
113  * The string itself is in PIN_INPUT_BUFFER.
114  */
115 static int
116 get_pinpad_input (int msg_code)
117 {
118   int r;
119
120   chEvtSignal (main_thread, LED_WAIT_MODE);
121   r = pinpad_getline (msg_code, MS2ST (8000));
122   chEvtSignal (main_thread, LED_STATUS_MODE);
123   return r;
124 }
125 #endif
126
127 static void
128 cmd_verify (void)
129 {
130   int len;
131   uint8_t p2 = P2 (apdu);
132   int r;
133   const uint8_t *pw;
134
135   DEBUG_INFO (" - VERIFY\r\n");
136   DEBUG_BYTE (p2);
137
138   len = apdu.cmd_apdu_data_len;
139   pw = apdu.cmd_apdu_data;
140
141   if (p2 == 0x81)
142     r = verify_pso_cds (pw, len);
143   else if (p2 == 0x82)
144     r = verify_other (pw, len);
145   else
146     r = verify_admin (pw, len);
147
148   if (r < 0)
149     {
150       DEBUG_INFO ("failed\r\n");
151       GPG_SECURITY_FAILURE ();
152     }
153   else if (r == 0)
154     {
155       DEBUG_INFO ("blocked\r\n");
156       GPG_SECURITY_AUTH_BLOCKED ();
157     }
158   else
159     {
160       DEBUG_INFO ("good\r\n");
161       GPG_SUCCESS ();
162     }
163 }
164
165 int
166 gpg_change_keystring (int who_old, const uint8_t *old_ks,
167                       int who_new, const uint8_t *new_ks)
168 {
169   int r;
170   int prv_keys_exist = 0;
171
172   r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, who_old, old_ks);
173   if (r < 0)
174     return r;
175
176   if (r > 0)
177     prv_keys_exist++;
178
179   r = gpg_do_chks_prvkey (GPG_KEY_FOR_SIGNING, who_old, old_ks,
180                           who_new, new_ks);
181   if (r < 0)
182     return -2;
183
184   r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, who_old, old_ks);
185   if (r < 0)
186     return r;
187
188   if (r > 0)
189     prv_keys_exist++;
190
191   r = gpg_do_chks_prvkey (GPG_KEY_FOR_DECRYPTION, who_old, old_ks,
192                           who_new, new_ks);
193   if (r < 0)
194     return -2;
195
196   r = gpg_do_load_prvkey (GPG_KEY_FOR_AUTHENTICATION, who_old, old_ks);
197   if (r < 0)
198     return r;
199
200   if (r > 0)
201     prv_keys_exist++;
202
203   r = gpg_do_chks_prvkey (GPG_KEY_FOR_AUTHENTICATION, who_old, old_ks,
204                           who_new, new_ks);
205   if (r < 0)
206     return -2;
207
208   if (prv_keys_exist)
209     return 1;
210   else
211     return 0;
212 }
213
214 static void
215 cmd_change_password (void)
216 {
217   uint8_t old_ks[KEYSTRING_MD_SIZE];
218   uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
219   uint8_t *new_ks = &new_ks0[1];
220   uint8_t p1 = P1 (apdu);       /* 0: change (old+new), 1: exchange (new) */
221   uint8_t p2 = P2 (apdu);
222   int len;
223   const uint8_t *pw;
224   const uint8_t *newpw;
225   int pw_len, newpw_len;
226   int who = p2 - 0x80;
227   int who_old;
228   int r;
229
230   DEBUG_INFO ("Change PW\r\n");
231   DEBUG_BYTE (who);
232
233   len = apdu.cmd_apdu_data_len;
234   pw = apdu.cmd_apdu_data;
235
236   if (p1 != 0)
237     {
238       GPG_FUNCTION_NOT_SUPPORTED();
239       return;
240     }
241
242   if (who == BY_USER)                   /* PW1 */
243     {
244       const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
245
246       pw_len = verify_user_0 (AC_PSO_CDS_AUTHORIZED, pw, len, -1, ks_pw1);
247       who_old = who;
248
249       if (pw_len < 0)
250         {
251           DEBUG_INFO ("permission denied.\r\n");
252           GPG_SECURITY_FAILURE ();
253           return;
254         }
255       else if (pw_len == 0)
256         {
257           DEBUG_INFO ("blocked.\r\n");
258           GPG_SECURITY_AUTH_BLOCKED ();
259           return;
260         }
261       else
262         {
263           newpw = pw + pw_len;
264           newpw_len = len - pw_len;
265         }
266     }
267   else                          /* PW3 (0x83) */
268     {
269       pw_len = verify_admin_0 (pw, len, -1);
270
271       if (pw_len < 0)
272         {
273           DEBUG_INFO ("permission denied.\r\n");
274           GPG_SECURITY_FAILURE ();
275           return;
276         }
277       else if (pw_len == 0)
278         {
279           DEBUG_INFO ("blocked.\r\n");
280           GPG_SECURITY_AUTH_BLOCKED ();
281           return;
282         }
283       else
284         {
285           newpw = pw + pw_len;
286           newpw_len = len - pw_len;
287           gpg_set_pw3 (newpw, newpw_len);
288           who_old = admin_authorized;
289         }
290     }
291
292   sha256 (pw, pw_len, old_ks);
293   sha256 (newpw, newpw_len, new_ks);
294   new_ks0[0] = newpw_len;
295
296   r = gpg_change_keystring (who_old, old_ks, who, new_ks);
297   if (r <= -2)
298     {
299       DEBUG_INFO ("memory error.\r\n");
300       GPG_MEMORY_FAILURE ();
301     }
302   else if (r < 0)
303     {
304       DEBUG_INFO ("security error.\r\n");
305       GPG_SECURITY_FAILURE ();
306     }
307   else if (r == 0 && who == BY_USER)    /* no prvkey */
308     {
309       gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1);
310       ac_reset_pso_cds ();
311       ac_reset_other ();
312       DEBUG_INFO ("Changed DO_KEYSTRING_PW1.\r\n");
313       GPG_SUCCESS ();
314     }
315   else if (r > 0 && who == BY_USER)
316     {
317       gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, 1);
318       ac_reset_pso_cds ();
319       ac_reset_other ();
320       DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
321       GPG_SUCCESS ();
322     }
323   else                          /* r >= 0 && who == BY_ADMIN */
324     {
325       DEBUG_INFO ("done.\r\n");
326       ac_reset_admin ();
327       GPG_SUCCESS ();
328     }
329 }
330
331
332 #define RESETCODE_S2K_MAGIC "\xffRESET\r\n"
333
334 void
335 resetcode_s2k (const unsigned char *input, unsigned int ilen,
336                unsigned char output[32])
337 {
338   sha256_context ctx;
339
340   sha256_start (&ctx);
341   sha256_update (&ctx, input, ilen);
342   sha256_update (&ctx, (unsigned char *)RESETCODE_S2K_MAGIC,
343                  sizeof (RESETCODE_S2K_MAGIC));
344   sha256_finish (&ctx, output);
345 }
346
347
348 static void
349 cmd_reset_user_password (void)
350 {
351   uint8_t p1 = P1 (apdu);
352   int len;
353   const uint8_t *pw;
354   const uint8_t *newpw;
355   int pw_len, newpw_len;
356   int r;
357   uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
358   uint8_t *new_ks = &new_ks0[1];
359
360   DEBUG_INFO ("Reset PW1\r\n");
361   DEBUG_BYTE (p1);
362
363   len = apdu.cmd_apdu_data_len;
364   pw = apdu.cmd_apdu_data;
365
366   if (p1 == 0x00)               /* by User with Reseting Code */
367     {
368       const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
369       uint8_t old_ks[KEYSTRING_MD_SIZE];
370
371       if (gpg_pw_locked (PW_ERR_RC))
372         {
373           DEBUG_INFO ("blocked.\r\n");
374           GPG_SECURITY_AUTH_BLOCKED ();
375           return;
376         }
377
378       if (ks_rc == NULL)
379         {
380           DEBUG_INFO ("security error.\r\n");
381           GPG_SECURITY_FAILURE ();
382           return;
383         }
384
385       pw_len = ks_rc[0];
386       newpw = pw + pw_len;
387       newpw_len = len - pw_len;
388       resetcode_s2k (pw, pw_len, old_ks);
389       sha256 (newpw, newpw_len, new_ks);
390       new_ks0[0] = newpw_len;
391       r = gpg_change_keystring (BY_RESETCODE, old_ks, BY_USER, new_ks);
392       if (r <= -2)
393         {
394           DEBUG_INFO ("memory error.\r\n");
395           GPG_MEMORY_FAILURE ();
396         }
397       else if (r < 0)
398         {
399         sec_fail:
400           DEBUG_INFO ("failed.\r\n");
401           gpg_pw_increment_err_counter (PW_ERR_RC);
402           GPG_SECURITY_FAILURE ();
403         }
404       else if (r == 0)
405         {
406           if (memcmp (ks_rc+1, old_ks, KEYSTRING_MD_SIZE) != 0)
407             goto sec_fail;
408           DEBUG_INFO ("done (no prvkey).\r\n");
409           gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
410                                KEYSTRING_SIZE_PW1);
411           ac_reset_pso_cds ();
412           ac_reset_other ();
413           gpg_pw_reset_err_counter (PW_ERR_RC);
414           gpg_pw_reset_err_counter (PW_ERR_PW1);
415           GPG_SUCCESS ();
416         }
417       else
418         {
419           DEBUG_INFO ("done.\r\n");
420           ac_reset_pso_cds ();
421           ac_reset_other ();
422           gpg_pw_reset_err_counter (PW_ERR_RC);
423           gpg_pw_reset_err_counter (PW_ERR_PW1);
424           GPG_SUCCESS ();
425         }
426     }
427   else                          /* by Admin (p1 == 0x02) */
428     {
429       const uint8_t *old_ks = keystring_md_pw3;
430
431       if (!ac_check_status (AC_ADMIN_AUTHORIZED))
432         {
433           DEBUG_INFO ("permission denied.\r\n");
434           GPG_SECURITY_FAILURE ();
435           return;
436         }
437
438       newpw_len = len;
439       newpw = pw;
440       sha256 (newpw, newpw_len, new_ks);
441       new_ks0[0] = newpw_len;
442       r = gpg_change_keystring (admin_authorized, old_ks, BY_USER, new_ks);
443       if (r <= -2)
444         {
445           DEBUG_INFO ("memory error.\r\n");
446           GPG_MEMORY_FAILURE ();
447         }
448       else if (r < 0)
449         {
450           DEBUG_INFO ("security error.\r\n");
451           GPG_SECURITY_FAILURE ();
452         }
453       else if (r == 0)
454         {
455           DEBUG_INFO ("done (no privkey).\r\n");
456           gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
457                                KEYSTRING_SIZE_PW1);
458           ac_reset_pso_cds ();
459           ac_reset_other ();
460           gpg_pw_reset_err_counter (PW_ERR_PW1);
461           GPG_SUCCESS ();
462         }
463       else
464         {
465           DEBUG_INFO ("done.\r\n");
466           ac_reset_pso_cds ();
467           ac_reset_other ();
468           gpg_pw_reset_err_counter (PW_ERR_PW1);
469           GPG_SUCCESS ();
470         }
471     }
472 }
473
474 static void
475 cmd_put_data (void)
476 {
477   uint8_t *data;
478   uint16_t tag;
479   int len;
480
481   DEBUG_INFO (" - PUT DATA\r\n");
482
483   if (file_selection != FILE_DF_OPENPGP)
484     GPG_NO_RECORD();
485
486   tag = ((P1 (apdu)<<8) | P2 (apdu));
487   len = apdu.cmd_apdu_data_len;
488   data = apdu.cmd_apdu_data;
489   gpg_do_put_data (tag, data, len);
490 }
491
492 static void
493 cmd_pgp_gakp (void)
494 {
495   DEBUG_INFO (" - Generate Asymmetric Key Pair\r\n");
496   DEBUG_BYTE (P1 (apdu));
497
498   if (P1 (apdu) == 0x81)
499     /* Get public key */
500     gpg_do_public_key (apdu.cmd_apdu_data[0]);
501   else
502     {
503       if (!ac_check_status (AC_ADMIN_AUTHORIZED))
504         GPG_SECURITY_FAILURE ();
505 #ifdef KEYGEN_SUPPORT
506       /* Generate key pair */
507       gpg_do_keygen (apdu.cmd_apdu_data[0]);
508 #else
509       GPG_FUNCTION_NOT_SUPPORTED ();
510 #endif
511     }
512 }
513
514 const uint8_t *
515 gpg_get_firmware_update_key (uint8_t keyno)
516 {
517   extern uint8_t _updatekey_store;
518   const uint8_t *p;
519
520   p = &_updatekey_store + keyno * KEY_CONTENT_LEN;
521   return p;
522 }
523
524 #ifdef CERTDO_SUPPORT
525 #define FILEID_CH_CERTIFICATE_IS_VALID 1
526 #else
527 #define FILEID_CH_CERTIFICATE_IS_VALID 0
528 #endif
529
530 static void
531 cmd_read_binary (void)
532 {
533   int is_short_EF = (P1 (apdu) & 0x80) != 0;
534   uint8_t file_id;
535   const uint8_t *p;
536   uint16_t offset;
537
538   DEBUG_INFO (" - Read binary\r\n");
539
540   if (is_short_EF)
541     file_id = (P1 (apdu) & 0x1f);
542   else
543     file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
544
545   if ((!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
546       || file_id > FILEID_CH_CERTIFICATE)
547     {
548       GPG_NO_FILE ();
549       return;
550     }
551
552   if (is_short_EF)
553     {
554       file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
555       offset = P2 (apdu);
556     }
557   else
558     offset = (P1 (apdu) << 8) | P2 (apdu);
559
560   if (file_id == FILEID_SERIAL_NO)
561     {
562       if (offset != 0)
563         GPG_BAD_P1_P2 ();
564       else
565         {
566           gpg_do_get_data (0x004f, 1); /* Get AID... */
567           res_APDU[0] = 0x5a; /* ... and overwrite the first byte of data. */
568         }
569       return;
570     }
571
572   if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
573     {
574       if (offset != 0)
575         GPG_MEMORY_FAILURE ();
576       else
577         {
578           p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
579           res_APDU_size = KEY_CONTENT_LEN;
580           memcpy (res_APDU, p, KEY_CONTENT_LEN);
581           GPG_SUCCESS ();
582         }
583     }
584 #if defined(CERTDO_SUPPORT)
585   else /* file_id == FILEID_CH_CERTIFICATE */
586     {
587       uint16_t len = 256;
588
589       p = &ch_certificate_start;
590       if (offset >= FLASH_CH_CERTIFICATE_SIZE)
591         GPG_MEMORY_FAILURE ();
592       else
593         {
594           if (offset + len >= FLASH_CH_CERTIFICATE_SIZE)
595             len = FLASH_CH_CERTIFICATE_SIZE - offset;
596
597           res_APDU_size = len;
598           memcpy (res_APDU, p + offset, len);
599           GPG_SUCCESS ();
600         }
601     }
602 #endif
603 }
604
605 static void
606 cmd_select_file (void)
607 {
608   if (P1 (apdu) == 4)   /* Selection by DF name */
609     {
610       DEBUG_INFO (" - select DF by name\r\n");
611
612       /* name = D2 76 00 01 24 01 */
613       if (apdu.cmd_apdu_data_len != 6
614           || memcmp (openpgpcard_aid, apdu.cmd_apdu_data, 6) != 0)
615         {
616           DEBUG_SHORT (apdu.cmd_apdu_data_len);
617           DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
618
619           GPG_NO_FILE ();
620           return;
621         }
622
623       file_selection = FILE_DF_OPENPGP;
624       if ((P2 (apdu) & 0x0c) == 0x0c)   /* No FCI */
625         GPG_SUCCESS ();
626       else
627         {
628           gpg_do_get_data (0x004f, 1); /* AID */
629           memmove (res_APDU+2, res_APDU, res_APDU_size);
630           res_APDU[0] = 0x6f;
631           res_APDU[1] = 0x12;
632           res_APDU[2] = 0x84;   /* overwrite: DF name */
633           res_APDU_size += 2;
634           GPG_SUCCESS ();
635         }
636     }
637   else if (apdu.cmd_apdu_data_len == 2
638            && apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
639     {
640       DEBUG_INFO (" - select 0x2f02 EF\r\n");
641       /*
642        * MF.EF-GDO -- Serial number of the card and name of the owner
643        */
644       GPG_SUCCESS ();
645       file_selection = FILE_EF_SERIAL_NO;
646     }
647   else if (apdu.cmd_apdu_data_len == 2
648            && apdu.cmd_apdu_data[0] == 0x3f && apdu.cmd_apdu_data[1] == 0x00)
649     {
650       DEBUG_INFO (" - select ROOT MF\r\n");
651       if (P2 (apdu) == 0x0c)
652         {
653           GPG_SUCCESS ();
654         }
655       else
656         {
657           int len = sizeof (select_file_TOP_result);
658
659           res_APDU_size = len;
660           memcpy (res_APDU, select_file_TOP_result, len);
661           res_APDU[2] = (data_objects_number_of_bytes & 0xff);
662           res_APDU[3] = (data_objects_number_of_bytes >> 8);
663           GPG_SUCCESS ();
664         }
665
666       file_selection = FILE_MF;
667       ac_fini ();               /* Reset authentication */
668     }
669   else
670     {
671       DEBUG_INFO (" - select ?? \r\n");
672
673       file_selection = FILE_NONE;
674       GPG_NO_FILE ();
675     }
676 }
677
678 static void
679 cmd_get_data (void)
680 {
681   uint16_t tag = ((P1 (apdu)<<8) | P2 (apdu));
682
683   DEBUG_INFO (" - Get Data\r\n");
684
685   if (file_selection != FILE_DF_OPENPGP)
686     GPG_NO_RECORD ();
687
688   gpg_do_get_data (tag, 0);
689 }
690
691 static void
692 cmd_pso (void)
693 {
694   int len = apdu.cmd_apdu_data_len;
695   int r;
696
697   DEBUG_INFO (" - PSO: ");
698   DEBUG_WORD ((uint32_t)&r);
699   DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
700
701   if (P1 (apdu) == 0x9e && P2 (apdu) == 0x9a)
702     {
703       if (!ac_check_status (AC_PSO_CDS_AUTHORIZED))
704         {
705           DEBUG_INFO ("security error.");
706           GPG_SECURITY_FAILURE ();
707           return;
708         }
709
710       /* Check size of digestInfo */
711       if (len != 34             /* MD5 */
712           && len != 35          /* SHA1 / RIPEMD-160 */
713           && len != 47          /* SHA224 */
714           && len != 51          /* SHA256 */
715           && len != 67          /* SHA384 */
716           && len != 83)         /* SHA512 */
717         {
718           DEBUG_INFO (" wrong length: ");
719           DEBUG_SHORT (len);
720           GPG_ERROR ();
721         }
722       else
723         {
724           DEBUG_SHORT (len);
725           DEBUG_BINARY (&kd[GPG_KEY_FOR_SIGNING], KEY_CONTENT_LEN);
726
727           chEvtSignal (main_thread, LED_WAIT_MODE);
728           r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
729                         &kd[GPG_KEY_FOR_SIGNING]);
730           chEvtSignal (main_thread, LED_STATUS_MODE);
731           if (r < 0)
732             {
733               ac_reset_pso_cds ();
734               GPG_ERROR ();
735             }
736           else
737             /* Success */
738             gpg_increment_digital_signature_counter ();
739         }
740     }
741   else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
742     {
743       DEBUG_SHORT (len);
744       DEBUG_BINARY (&kd[GPG_KEY_FOR_DECRYPTION], KEY_CONTENT_LEN);
745
746       if (!ac_check_status (AC_OTHER_AUTHORIZED))
747         {
748           DEBUG_INFO ("security error.");
749           GPG_SECURITY_FAILURE ();
750           return;
751         }
752
753       /* Skip padding 0x00 */
754       len--;
755       chEvtSignal (main_thread, LED_WAIT_MODE);
756       r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
757                        &kd[GPG_KEY_FOR_DECRYPTION]);
758       chEvtSignal (main_thread, LED_STATUS_MODE);
759       if (r < 0)
760         GPG_ERROR ();
761     }
762   else
763     {
764       DEBUG_INFO (" - ??");
765       DEBUG_BYTE (P1 (apdu));
766       DEBUG_INFO (" - ??");
767       DEBUG_BYTE (P2 (apdu));
768       GPG_ERROR ();
769     }
770
771   DEBUG_INFO ("PSO done.\r\n");
772 }
773
774
775 #define MAX_DIGEST_INFO_LEN 102 /* 40% */
776 static void
777 cmd_internal_authenticate (void)
778 {
779   int len = apdu.cmd_apdu_data_len;
780   int r;
781
782   DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
783
784   if (P1 (apdu) == 0x00 && P2 (apdu) == 0x00)
785     {
786       DEBUG_SHORT (len);
787
788       if (!ac_check_status (AC_OTHER_AUTHORIZED))
789         {
790           DEBUG_INFO ("security error.");
791           GPG_SECURITY_FAILURE ();
792           return;
793         }
794
795       if (len > MAX_DIGEST_INFO_LEN)
796         {
797           DEBUG_INFO ("input is too long.");
798           GPG_CONDITION_NOT_SATISFIED ();
799           return;
800         }
801
802       chEvtSignal (main_thread, LED_WAIT_MODE);
803       r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
804                     &kd[GPG_KEY_FOR_AUTHENTICATION]);
805       chEvtSignal (main_thread, LED_STATUS_MODE);
806       if (r < 0)
807         GPG_ERROR ();
808     }
809   else
810     {
811       DEBUG_INFO (" - ??");
812       DEBUG_BYTE (P1 (apdu));
813       DEBUG_INFO (" - ??");
814       DEBUG_BYTE (P2 (apdu));
815       GPG_ERROR ();
816     }
817
818   DEBUG_INFO ("INTERNAL AUTHENTICATE done.\r\n");
819 }
820
821 #define MBD_OPRATION_WRITE  0
822 #define MBD_OPRATION_UPDATE 1
823
824 static void
825 modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
826 {
827   uint8_t file_id;
828   uint16_t offset;
829   int is_short_EF = (p1 & 0x80) != 0;
830   int r;
831
832   if (!ac_check_status (AC_ADMIN_AUTHORIZED))
833     {
834       DEBUG_INFO ("security error.");
835       GPG_SECURITY_FAILURE ();
836       return;
837     }
838
839   if (is_short_EF)
840     file_id = (p1 & 0x1f);
841   else
842     file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
843
844   if (!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
845     {
846       GPG_NO_FILE ();
847       return;
848     }
849
850   if (op == MBD_OPRATION_UPDATE && file_id != FILEID_CH_CERTIFICATE)
851     {
852       GPG_CONDITION_NOT_SATISFIED ();
853       return;
854     }
855
856   if (file_id > FILEID_CH_CERTIFICATE)
857     {
858       GPG_NO_FILE ();
859       return;
860     }
861
862   if (is_short_EF)
863     {
864       file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
865       offset = p2;
866
867       if (op == MBD_OPRATION_UPDATE)
868         {
869           r = flash_erase_binary (file_id);
870           if (r < 0)
871             {
872               DEBUG_INFO ("memory error.\r\n");
873               GPG_MEMORY_FAILURE ();
874               return;
875             }
876         }
877     }
878   else
879     offset = (p1 << 8) | p2;
880
881   DEBUG_SHORT (len);
882   DEBUG_SHORT (offset);
883
884   r = flash_write_binary (file_id, apdu.cmd_apdu_data, len, offset);
885   if (r < 0)
886     {
887       DEBUG_INFO ("memory error.\r\n");
888       GPG_MEMORY_FAILURE ();
889       return;
890     }
891
892   GPG_SUCCESS ();
893 }
894
895
896 #if defined(CERTDO_SUPPORT)
897 static void
898 cmd_update_binary (void)
899 {
900   int len = apdu.cmd_apdu_data_len;
901
902   DEBUG_INFO (" - UPDATE BINARY\r\n");
903   modify_binary (MBD_OPRATION_UPDATE, P1 (apdu), P2 (apdu), len);
904   DEBUG_INFO ("UPDATE BINARY done.\r\n");
905 }
906 #endif
907
908
909 static void
910 cmd_write_binary (void)
911 {
912   int len = apdu.cmd_apdu_data_len;
913   int i;
914   const uint8_t *p;
915
916   DEBUG_INFO (" - WRITE BINARY\r\n");
917   modify_binary (MBD_OPRATION_WRITE, P1 (apdu), P2 (apdu), len);
918
919   for (i = 0; i < 4; i++)
920     {
921       p = gpg_get_firmware_update_key (i);
922       if (p[0] != 0x00 || p[1] != 0x00) /* still valid */
923         break;
924     }
925
926   if (i == 4)                   /* all update keys are removed */
927     {
928       p = gpg_get_firmware_update_key (0);
929       flash_erase_page ((uint32_t)p);
930     }
931
932   DEBUG_INFO ("WRITE BINARY done.\r\n");
933 }
934
935
936 static void
937 cmd_external_authenticate (void)
938 {
939   const uint8_t *pubkey;
940   const uint8_t *signature = apdu.cmd_apdu_data;
941   uint8_t *hash = apdu.cmd_apdu_data + 256;
942   int len = apdu.cmd_apdu_data_len;
943   uint8_t keyno = P2 (apdu);
944
945   DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
946
947   if (keyno > 4)
948     {
949       GPG_CONDITION_NOT_SATISFIED ();
950       return;
951     }
952
953   pubkey = gpg_get_firmware_update_key (keyno);
954   if (len != 256
955       || (pubkey[0] == 0xff && pubkey[1] == 0xff) /* not registered */
956       || (pubkey[0] == 0x00 && pubkey[1] == 0x00) /* removed */)
957     {
958       GPG_CONDITION_NOT_SATISFIED ();
959       return;
960     }
961   
962   memcpy (hash, unique_device_id (), 4);
963   memcpy (hash+4, challenge, CHALLENGE_LEN);
964   random_bytes_free (challenge);
965   challenge = NULL;
966
967   if (rsa_verify (pubkey, hash, signature) < 0)
968     {
969       GPG_SECURITY_FAILURE ();
970       return;
971     }
972
973   chThdTerminate (chThdSelf ());
974   set_res_sw (0xff, 0xff);
975   DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
976 }
977
978 static void
979 cmd_get_challenge (void)
980 {
981   DEBUG_INFO (" - GET CHALLENGE\r\n");
982
983   if (challenge)
984     random_bytes_free (challenge);
985
986   challenge = random_bytes_get ();
987   memcpy (res_APDU, unique_device_id (), 4);
988   memcpy (res_APDU+4, challenge, CHALLENGE_LEN);
989   res_APDU_size = CHALLENGE_LEN + 4;
990   GPG_SUCCESS ();
991   DEBUG_INFO ("GET CHALLENGE done.\r\n");
992 }
993
994
995 struct command
996 {
997   uint8_t command;
998   void (*cmd_handler) (void);
999 };
1000
1001 const struct command cmds[] = {
1002   { INS_VERIFY, cmd_verify },
1003   { INS_CHANGE_REFERENCE_DATA, cmd_change_password },
1004   { INS_PSO, cmd_pso },
1005   { INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
1006   { INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
1007   { INS_EXTERNAL_AUTHENTICATE,              /* Not in OpenPGP card protocol */
1008     cmd_external_authenticate },
1009   { INS_GET_CHALLENGE, cmd_get_challenge }, /* Not in OpenPGP card protocol */
1010   { INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
1011   { INS_SELECT_FILE, cmd_select_file },
1012   { INS_READ_BINARY, cmd_read_binary },
1013   { INS_GET_DATA, cmd_get_data },
1014   { INS_WRITE_BINARY, cmd_write_binary},    /* Not in OpenPGP card protocol */
1015 #if defined(CERTDO_SUPPORT)
1016   { INS_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
1017 #endif
1018   { INS_PUT_DATA, cmd_put_data },
1019   { INS_PUT_DATA_ODD, cmd_put_data },
1020 };
1021 #define NUM_CMDS ((int)(sizeof (cmds) / sizeof (struct command)))
1022
1023 static void
1024 process_command_apdu (void)
1025 {
1026   int i;
1027   uint8_t cmd = INS (apdu);
1028
1029   for (i = 0; i < NUM_CMDS; i++)
1030     if (cmds[i].command == cmd)
1031       break;
1032
1033   if (i < NUM_CMDS)
1034     cmds[i].cmd_handler ();
1035   else
1036     {
1037       DEBUG_INFO (" - ??");
1038       DEBUG_BYTE (cmd);
1039       GPG_NO_INS ();
1040     }
1041 }
1042
1043 msg_t
1044 GPGthread (void *arg)
1045 {
1046   Thread *icc_thread = (Thread *)arg;
1047
1048   gpg_init ();
1049
1050   chEvtClear (ALL_EVENTS);
1051
1052   while (!chThdShouldTerminate ())
1053     {
1054       eventmask_t m = chEvtWaitOne (ALL_EVENTS);
1055 #if defined(PINPAD_SUPPORT)
1056       int len, pw_len, newpw_len;
1057 #endif
1058
1059       DEBUG_INFO ("GPG!: ");
1060
1061       if (m == EV_VERIFY_CMD_AVAILABLE)
1062         {
1063 #if defined(PINPAD_SUPPORT)
1064           if (INS (apdu) != INS_VERIFY)
1065             {
1066               GPG_CONDITION_NOT_SATISFIED ();
1067               goto done;
1068             }
1069
1070           pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
1071           if (pw_len < 0)
1072             {
1073               GPG_ERROR ();
1074               goto done;
1075             }
1076           memcpy (apdu.cmd_apdu_data, pin_input_buffer, pw_len);
1077           apdu.cmd_apdu_data_len = pw_len;
1078 #else
1079           GPG_ERROR ();
1080           goto done;
1081 #endif
1082         }
1083       else if (m == EV_MODIFY_CMD_AVAILABLE)
1084         {
1085 #if defined(PINPAD_SUPPORT)
1086           uint8_t bConfirmPIN = apdu.cmd_apdu_data[5];
1087           uint8_t *p = apdu.cmd_apdu_data;
1088
1089           if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
1090               && INS (apdu) != INS_RESET_RETRY_COUNTER
1091               && INS (apdu) != INS_PUT_DATA)
1092             {
1093               GPG_CONDITION_NOT_SATISFIED ();
1094               goto done;
1095             }
1096
1097           if ((bConfirmPIN & 2))        /* Require old PIN */
1098             {
1099               pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
1100               if (pw_len < 0)
1101                 {
1102                   GPG_ERROR ();
1103                   goto done;
1104                 }
1105               memcpy (p, pin_input_buffer, pw_len);
1106               p += pw_len;
1107             }
1108           else
1109             pw_len = 0;
1110
1111           newpw_len = get_pinpad_input (PIN_INPUT_NEW);
1112           if (newpw_len < 0)
1113             {
1114               GPG_ERROR ();
1115               goto done;
1116             }
1117           memcpy (p, pin_input_buffer, newpw_len);
1118
1119           if ((bConfirmPIN & 1))        /* New PIN twice */
1120             {
1121               len = get_pinpad_input (PIN_INPUT_CONFIRM);
1122               if (len < 0)
1123                 {
1124                   GPG_ERROR ();
1125                   goto done;
1126                 }
1127
1128               if (len != newpw_len || memcmp (p, pin_input_buffer, len) != 0)
1129                 {
1130                   GPG_SECURITY_FAILURE ();
1131                   goto done;
1132                 }
1133             }
1134
1135           apdu.cmd_apdu_data_len = pw_len + newpw_len;
1136 #else
1137           GPG_ERROR ();
1138           goto done;
1139 #endif
1140         }
1141       else if (m == EV_NOP)
1142         continue;
1143
1144       process_command_apdu ();
1145     done:
1146       chEvtSignal (icc_thread, EV_EXEC_FINISHED);
1147     }
1148
1149   gpg_fini ();
1150   return 0;
1151 }