SHA1 for external authentication
[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 "openpgp.h"
29 #include "polarssl/config.h"
30 #include "polarssl/sha1.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_INPUT_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 r;
228
229   DEBUG_INFO ("Change PW\r\n");
230   DEBUG_BYTE (who);
231
232   len = apdu.cmd_apdu_data_len;
233   pw = apdu.cmd_apdu_data;
234
235   if (p1 != 0)
236     {
237       GPG_FUNCTION_NOT_SUPPORTED();
238       return;
239     }
240
241   if (who == BY_USER)                   /* PW1 */
242     {
243       const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
244
245       pw_len = verify_user_0 (AC_PSO_CDS_AUTHORIZED, pw, len, -1, ks_pw1);
246
247       if (pw_len < 0)
248         {
249           DEBUG_INFO ("permission denied.\r\n");
250           GPG_SECURITY_FAILURE ();
251           return;
252         }
253       else if (pw_len == 0)
254         {
255           DEBUG_INFO ("blocked.\r\n");
256           GPG_SECURITY_AUTH_BLOCKED ();
257           return;
258         }
259       else
260         {
261           newpw = pw + pw_len;
262           newpw_len = len - pw_len;
263         }
264     }
265   else                          /* PW3 (0x83) */
266     {
267       pw_len = verify_admin_0 (pw, len, -1);
268
269       if (pw_len < 0)
270         {
271           DEBUG_INFO ("permission denied.\r\n");
272           GPG_SECURITY_FAILURE ();
273           return;
274         }
275       else if (pw_len == 0)
276         {
277           DEBUG_INFO ("blocked.\r\n");
278           GPG_SECURITY_AUTH_BLOCKED ();
279           return;
280         }
281       else
282         {
283           newpw = pw + pw_len;
284           newpw_len = len - pw_len;
285           gpg_set_pw3 (newpw, newpw_len);
286         }
287     }
288
289   sha1 (pw, pw_len, old_ks);
290   sha1 (newpw, newpw_len, new_ks);
291   new_ks0[0] = newpw_len;
292
293   r = gpg_change_keystring (who, old_ks, who, new_ks);
294   if (r <= -2)
295     {
296       DEBUG_INFO ("memory error.\r\n");
297       GPG_MEMORY_FAILURE ();
298     }
299   else if (r < 0)
300     {
301       DEBUG_INFO ("security error.\r\n");
302       GPG_SECURITY_FAILURE ();
303     }
304   else if (r == 0 && who == BY_USER)    /* no prvkey */
305     {
306       gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1);
307       ac_reset_pso_cds ();
308       ac_reset_other ();
309       DEBUG_INFO ("Changed DO_KEYSTRING_PW1.\r\n");
310       GPG_SUCCESS ();
311     }
312   else if (r > 0 && who == BY_USER)
313     {
314       gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, 1);
315       ac_reset_pso_cds ();
316       ac_reset_other ();
317       DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
318       GPG_SUCCESS ();
319     }
320   else                          /* r >= 0 && who == BY_ADMIN */
321     {
322       DEBUG_INFO ("done.\r\n");
323       ac_reset_admin ();
324       GPG_SUCCESS ();
325     }
326 }
327
328 static void
329 cmd_reset_user_password (void)
330 {
331   uint8_t p1 = P1 (apdu);
332   int len;
333   const uint8_t *pw;
334   const uint8_t *newpw;
335   int pw_len, newpw_len;
336   int r;
337   uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
338   uint8_t *new_ks = &new_ks0[1];
339
340   DEBUG_INFO ("Reset PW1\r\n");
341   DEBUG_BYTE (p1);
342
343   len = apdu.cmd_apdu_data_len;
344   pw = apdu.cmd_apdu_data;
345
346   if (p1 == 0x00)               /* by User with Reseting Code */
347     {
348       const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
349       uint8_t old_ks[KEYSTRING_MD_SIZE];
350
351       if (gpg_pw_locked (PW_ERR_RC))
352         {
353           DEBUG_INFO ("blocked.\r\n");
354           GPG_SECURITY_AUTH_BLOCKED ();
355           return;
356         }
357
358       if (ks_rc == NULL)
359         {
360           DEBUG_INFO ("security error.\r\n");
361           GPG_SECURITY_FAILURE ();
362           return;
363         }
364
365       pw_len = ks_rc[0];
366       newpw = pw + pw_len;
367       newpw_len = len - pw_len;
368       sha1 (pw, pw_len, old_ks);
369       sha1 (newpw, newpw_len, new_ks);
370       new_ks0[0] = newpw_len;
371       r = gpg_change_keystring (BY_RESETCODE, old_ks, BY_USER, new_ks);
372       if (r <= -2)
373         {
374           DEBUG_INFO ("memory error.\r\n");
375           GPG_MEMORY_FAILURE ();
376         }
377       else if (r < 0)
378         {
379         sec_fail:
380           DEBUG_INFO ("failed.\r\n");
381           gpg_pw_increment_err_counter (PW_ERR_RC);
382           GPG_SECURITY_FAILURE ();
383         }
384       else if (r == 0)
385         {
386           if (memcmp (ks_rc+1, old_ks, KEYSTRING_MD_SIZE) != 0)
387             goto sec_fail;
388           DEBUG_INFO ("done (no prvkey).\r\n");
389           gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
390                                KEYSTRING_SIZE_PW1);
391           ac_reset_pso_cds ();
392           ac_reset_other ();
393           gpg_pw_reset_err_counter (PW_ERR_RC);
394           gpg_pw_reset_err_counter (PW_ERR_PW1);
395           GPG_SUCCESS ();
396         }
397       else
398         {
399           DEBUG_INFO ("done.\r\n");
400           ac_reset_pso_cds ();
401           ac_reset_other ();
402           gpg_pw_reset_err_counter (PW_ERR_RC);
403           gpg_pw_reset_err_counter (PW_ERR_PW1);
404           GPG_SUCCESS ();
405         }
406     }
407   else                          /* by Admin (p1 == 0x02) */
408     {
409       const uint8_t *old_ks = keystring_md_pw3;
410
411       if (!ac_check_status (AC_ADMIN_AUTHORIZED))
412         {
413           DEBUG_INFO ("permission denied.\r\n");
414           GPG_SECURITY_FAILURE ();
415           return;
416         }
417
418       newpw_len = len;
419       newpw = pw;
420       sha1 (newpw, newpw_len, new_ks);
421       new_ks0[0] = newpw_len;
422       r = gpg_change_keystring (admin_authorized, old_ks, BY_USER, new_ks);
423       if (r <= -2)
424         {
425           DEBUG_INFO ("memory error.\r\n");
426           GPG_MEMORY_FAILURE ();
427         }
428       else if (r < 0)
429         {
430           DEBUG_INFO ("security error.\r\n");
431           GPG_SECURITY_FAILURE ();
432         }
433       else if (r == 0)
434         {
435           DEBUG_INFO ("done (no privkey).\r\n");
436           gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
437                                KEYSTRING_SIZE_PW1);
438           ac_reset_pso_cds ();
439           ac_reset_other ();
440           gpg_pw_reset_err_counter (PW_ERR_PW1);
441           GPG_SUCCESS ();
442         }
443       else
444         {
445           DEBUG_INFO ("done.\r\n");
446           ac_reset_pso_cds ();
447           ac_reset_other ();
448           gpg_pw_reset_err_counter (PW_ERR_PW1);
449           GPG_SUCCESS ();
450         }
451     }
452 }
453
454 static void
455 cmd_put_data (void)
456 {
457   uint8_t *data;
458   uint16_t tag;
459   int len;
460
461   DEBUG_INFO (" - PUT DATA\r\n");
462
463   if (file_selection != FILE_DF_OPENPGP)
464     GPG_NO_RECORD();
465
466   tag = ((P1 (apdu)<<8) | P2 (apdu));
467   len = apdu.cmd_apdu_data_len;
468   data = apdu.cmd_apdu_data;
469   gpg_do_put_data (tag, data, len);
470 }
471
472 static void
473 cmd_pgp_gakp (void)
474 {
475   DEBUG_INFO (" - Generate Asymmetric Key Pair\r\n");
476   DEBUG_BYTE (P1 (apdu));
477
478   if (P1 (apdu) == 0x81)
479     /* Get public key */
480     gpg_do_public_key (apdu.cmd_apdu_data[0]);
481   else
482     {                                   /* Generate key pair */
483       if (!ac_check_status (AC_ADMIN_AUTHORIZED))
484         GPG_SECURITY_FAILURE ();
485
486       /* XXX: Not yet supported */
487       GPG_ERROR ();
488     }
489 }
490
491 const uint8_t *
492 gpg_get_firmware_update_key (uint8_t keyno)
493 {
494   extern uint8_t _updatekey_store;
495   const uint8_t *p;
496
497   p = &_updatekey_store + keyno * KEY_CONTENT_LEN;
498   return p;
499 }
500
501 #ifdef CERTDO_SUPPORT
502 #define FILEID_CH_CERTIFICATE_IS_VALID 1
503 #else
504 #define FILEID_CH_CERTIFICATE_IS_VALID 0
505 #endif
506
507 static void
508 cmd_read_binary (void)
509 {
510   int is_short_EF = (P1 (apdu) & 0x80) != 0;
511   uint8_t file_id;
512   const uint8_t *p;
513   uint16_t offset;
514
515   DEBUG_INFO (" - Read binary\r\n");
516
517   if (is_short_EF)
518     file_id = (P1 (apdu) & 0x1f);
519   else
520     file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
521
522   if ((!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
523       || file_id > FILEID_CH_CERTIFICATE)
524     {
525       GPG_NO_FILE ();
526       return;
527     }
528
529   if (is_short_EF)
530     {
531       file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
532       offset = P2 (apdu);
533     }
534   else
535     offset = (P1 (apdu) << 8) | P2 (apdu);
536
537   if (file_id == FILEID_SERIAL_NO)
538     {
539       if (offset != 0)
540         GPG_BAD_P1_P2 ();
541       else
542         {
543           gpg_do_get_data (0x004f, 1); /* Get AID... */
544           res_APDU[0] = 0x5a; /* ... and overwrite the first byte of data. */
545         }
546       return;
547     }
548
549   if (file_id >= FILEID_UPDATE_KEY_0 && file_id <= FILEID_UPDATE_KEY_3)
550     {
551       if (offset != 0)
552         GPG_MEMORY_FAILURE ();
553       else
554         {
555           p = gpg_get_firmware_update_key (file_id - FILEID_UPDATE_KEY_0);
556           res_APDU_size = KEY_CONTENT_LEN;
557           memcpy (res_APDU, p, KEY_CONTENT_LEN);
558           GPG_SUCCESS ();
559         }
560     }
561 #if defined(CERTDO_SUPPORT)
562   else /* file_id == FILEID_CH_CERTIFICATE */
563     {
564       uint16_t len = 256;
565
566       p = &ch_certificate_start;
567       if (offset >= FLASH_CH_CERTIFICATE_SIZE)
568         GPG_MEMORY_FAILURE ();
569       else
570         {
571           if (offset + len >= FLASH_CH_CERTIFICATE_SIZE)
572             len = FLASH_CH_CERTIFICATE_SIZE - offset;
573
574           res_APDU_size = len;
575           memcpy (res_APDU, p + offset, len);
576           GPG_SUCCESS ();
577         }
578     }
579 #endif
580 }
581
582 static void
583 cmd_select_file (void)
584 {
585   if (P1 (apdu) == 4)   /* Selection by DF name */
586     {
587       DEBUG_INFO (" - select DF by name\r\n");
588
589       /* name = D2 76 00 01 24 01 */
590       if (apdu.cmd_apdu_data_len != 6
591           || memcmp (openpgpcard_aid, apdu.cmd_apdu_data, 6) != 0)
592         {
593           DEBUG_SHORT (apdu.cmd_apdu_data_len);
594           DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
595
596           GPG_NO_FILE ();
597           return;
598         }
599
600       file_selection = FILE_DF_OPENPGP;
601       if ((P2 (apdu) & 0x0c) == 0x0c)   /* No FCI */
602         GPG_SUCCESS ();
603       else
604         {
605           gpg_do_get_data (0x004f, 1); /* AID */
606           memmove (res_APDU+2, res_APDU, res_APDU_size);
607           res_APDU[0] = 0x6f;
608           res_APDU[1] = 0x12;
609           res_APDU[2] = 0x84;   /* overwrite: DF name */
610           res_APDU_size += 2;
611           GPG_SUCCESS ();
612         }
613     }
614   else if (apdu.cmd_apdu_data_len == 2
615            && apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
616     {
617       DEBUG_INFO (" - select 0x2f02 EF\r\n");
618       /*
619        * MF.EF-GDO -- Serial number of the card and name of the owner
620        */
621       GPG_SUCCESS ();
622       file_selection = FILE_EF_SERIAL_NO;
623     }
624   else if (apdu.cmd_apdu_data_len == 2
625            && apdu.cmd_apdu_data[0] == 0x3f && apdu.cmd_apdu_data[1] == 0x00)
626     {
627       DEBUG_INFO (" - select ROOT MF\r\n");
628       if (P2 (apdu) == 0x0c)
629         {
630           GPG_SUCCESS ();
631         }
632       else
633         {
634           int len = sizeof (select_file_TOP_result);
635
636           res_APDU_size = len;
637           memcpy (res_APDU, select_file_TOP_result, len);
638           res_APDU[2] = (data_objects_number_of_bytes & 0xff);
639           res_APDU[3] = (data_objects_number_of_bytes >> 8);
640           GPG_SUCCESS ();
641         }
642
643       file_selection = FILE_MF;
644       ac_fini ();               /* Reset authentication */
645     }
646   else
647     {
648       DEBUG_INFO (" - select ?? \r\n");
649
650       file_selection = FILE_NONE;
651       GPG_NO_FILE ();
652     }
653 }
654
655 static void
656 cmd_get_data (void)
657 {
658   uint16_t tag = ((P1 (apdu)<<8) | P2 (apdu));
659
660   DEBUG_INFO (" - Get Data\r\n");
661
662   if (file_selection != FILE_DF_OPENPGP)
663     GPG_NO_RECORD ();
664
665   gpg_do_get_data (tag, 0);
666 }
667
668 static void
669 cmd_pso (void)
670 {
671   int len = apdu.cmd_apdu_data_len;
672   int r;
673
674   DEBUG_INFO (" - PSO: ");
675   DEBUG_WORD ((uint32_t)&r);
676   DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
677
678   if (P1 (apdu) == 0x9e && P2 (apdu) == 0x9a)
679     {
680       if (!ac_check_status (AC_PSO_CDS_AUTHORIZED))
681         {
682           DEBUG_INFO ("security error.");
683           GPG_SECURITY_FAILURE ();
684           return;
685         }
686
687       /* Check size of digestInfo */
688       if (len != 34             /* MD5 */
689           && len != 35          /* SHA1 / RIPEMD-160 */
690           && len != 47          /* SHA224 */
691           && len != 51          /* SHA256 */
692           && len != 67          /* SHA384 */
693           && len != 83)         /* SHA512 */
694         {
695           DEBUG_INFO (" wrong length: ");
696           DEBUG_SHORT (len);
697           GPG_ERROR ();
698         }
699       else
700         {
701           DEBUG_SHORT (len);
702           DEBUG_BINARY (&kd[GPG_KEY_FOR_SIGNING], KEY_CONTENT_LEN);
703
704           r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
705                         &kd[GPG_KEY_FOR_SIGNING]);
706           if (r < 0)
707             {
708               ac_reset_pso_cds ();
709               GPG_ERROR ();
710             }
711           else
712             /* Success */
713             gpg_increment_digital_signature_counter ();
714         }
715     }
716   else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
717     {
718       DEBUG_SHORT (len);
719       DEBUG_BINARY (&kd[GPG_KEY_FOR_DECRYPTION], KEY_CONTENT_LEN);
720
721       if (!ac_check_status (AC_OTHER_AUTHORIZED))
722         {
723           DEBUG_INFO ("security error.");
724           GPG_SECURITY_FAILURE ();
725           return;
726         }
727
728       /* Skip padding 0x00 */
729       len--;
730       r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
731                        &kd[GPG_KEY_FOR_DECRYPTION]);
732       if (r < 0)
733         GPG_ERROR ();
734     }
735   else
736     {
737       DEBUG_INFO (" - ??");
738       DEBUG_BYTE (P1 (apdu));
739       DEBUG_INFO (" - ??");
740       DEBUG_BYTE (P2 (apdu));
741       GPG_ERROR ();
742     }
743
744   DEBUG_INFO ("PSO done.\r\n");
745 }
746
747 static void
748 cmd_internal_authenticate (void)
749 {
750   int len = apdu.cmd_apdu_data_len;
751   int r;
752
753   DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
754
755   if (P1 (apdu) == 0x00 && P2 (apdu) == 0x00)
756     {
757       DEBUG_SHORT (len);
758
759       if (!ac_check_status (AC_OTHER_AUTHORIZED))
760         {
761           DEBUG_INFO ("security error.");
762           GPG_SECURITY_FAILURE ();
763           return;
764         }
765
766       r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
767                     &kd[GPG_KEY_FOR_AUTHENTICATION]);
768       if (r < 0)
769         GPG_ERROR ();
770     }
771   else
772     {
773       DEBUG_INFO (" - ??");
774       DEBUG_BYTE (P1 (apdu));
775       DEBUG_INFO (" - ??");
776       DEBUG_BYTE (P2 (apdu));
777       GPG_ERROR ();
778     }
779
780   DEBUG_INFO ("INTERNAL AUTHENTICATE done.\r\n");
781 }
782
783 #define MBD_OPRATION_WRITE  0
784 #define MBD_OPRATION_UPDATE 1
785
786 static void
787 modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
788 {
789   uint8_t file_id;
790   uint16_t offset;
791   int is_short_EF = (p1 & 0x80) != 0;
792   int r;
793
794   if (!ac_check_status (AC_ADMIN_AUTHORIZED))
795     {
796       DEBUG_INFO ("security error.");
797       GPG_SECURITY_FAILURE ();
798       return;
799     }
800
801   if (is_short_EF)
802     file_id = (p1 & 0x1f);
803   else
804     file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
805
806   if (!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
807     {
808       GPG_NO_FILE ();
809       return;
810     }
811
812   if (op == MBD_OPRATION_UPDATE && file_id != FILEID_CH_CERTIFICATE)
813     {
814       GPG_CONDITION_NOT_SATISFIED ();
815       return;
816     }
817
818   if (file_id > FILEID_CH_CERTIFICATE)
819     {
820       GPG_NO_FILE ();
821       return;
822     }
823
824   if (is_short_EF)
825     {
826       file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
827       offset = p2;
828
829       if (op == MBD_OPRATION_UPDATE)
830         {
831           r = flash_erase_binary (file_id);
832           if (r < 0)
833             {
834               DEBUG_INFO ("memory error.\r\n");
835               GPG_MEMORY_FAILURE ();
836               return;
837             }
838         }
839     }
840   else
841     offset = (p1 << 8) | p2;
842
843   DEBUG_SHORT (len);
844   DEBUG_SHORT (offset);
845
846   r = flash_write_binary (file_id, apdu.cmd_apdu_data, len, offset);
847   if (r < 0)
848     {
849       DEBUG_INFO ("memory error.\r\n");
850       GPG_MEMORY_FAILURE ();
851       return;
852     }
853
854   GPG_SUCCESS ();
855 }
856
857
858 #if defined(CERTDO_SUPPORT)
859 static void
860 cmd_update_binary (void)
861 {
862   int len = apdu.cmd_apdu_data_len;
863
864   DEBUG_INFO (" - UPDATE BINARY\r\n");
865   modify_binary (MBD_OPRATION_UPDATE, P1 (apdu), P2 (apdu), len);
866   DEBUG_INFO ("UPDATE BINARY done.\r\n");
867 }
868 #endif
869
870
871 static void
872 cmd_write_binary (void)
873 {
874   int len = apdu.cmd_apdu_data_len;
875   int i;
876   const uint8_t *p;
877
878   DEBUG_INFO (" - WRITE BINARY\r\n");
879   modify_binary (MBD_OPRATION_WRITE, P1 (apdu), P2 (apdu), len);
880
881   for (i = 0; i < 4; i++)
882     {
883       p = gpg_get_firmware_update_key (i);
884       if (p[0] != 0x00 || p[1] != 0x00) /* still valid */
885         break;
886     }
887
888   if (i == 4)                   /* all update keys are removed */
889     {
890       p = gpg_get_firmware_update_key (0);
891       flash_erase_page ((uint32_t)p);
892     }
893
894   DEBUG_INFO ("WRITE BINARY done.\r\n");
895 }
896
897
898 static void
899 cmd_external_authenticate (void)
900 {
901   const uint8_t *pubkey;
902   const uint8_t *signature = apdu.cmd_apdu_data;
903   const uint8_t *hash = apdu.cmd_apdu_data + 256;
904   int len = apdu.cmd_apdu_data_len;
905   uint8_t keyno = P2 (apdu);
906
907   DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
908
909   if (keyno > 4)
910     {
911       GPG_CONDITION_NOT_SATISFIED ();
912       return;
913     }
914
915   pubkey = gpg_get_firmware_update_key (keyno);
916   if (len != 256
917       || (pubkey[0] == 0xff && pubkey[1] == 0xff) /* not registered */
918       || (pubkey[0] == 0x00 && pubkey[1] == 0x00) /* removed */)
919     {
920       GPG_CONDITION_NOT_SATISFIED ();
921       return;
922     }
923   
924   memcpy (hash, unique_device_id (), 4);
925   memcpy (hash+4, challenge, CHALLENGE_LEN);
926   random_bytes_free (challenge);
927   challenge = NULL;
928
929   if (rsa_verify (pubkey, hash, signature) < 0)
930     {
931       GPG_SECURITY_FAILURE ();
932       return;
933     }
934
935   chThdTerminate (chThdSelf ());
936   set_res_sw (0xff, 0xff);
937   DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
938 }
939
940 static void
941 cmd_get_challenge (void)
942 {
943   DEBUG_INFO (" - GET CHALLENGE\r\n");
944
945   if (challenge)
946     random_bytes_free (challenge);
947
948   challenge = random_bytes_get ();
949   memcpy (res_APDU, unique_device_id (), 4);
950   memcpy (res_APDU+4, challenge, CHALLENGE_LEN);
951   res_APDU_size = CHALLENGE_LEN + 4;
952   GPG_SUCCESS ();
953   DEBUG_INFO ("GET CHALLENGE done.\r\n");
954 }
955
956
957 struct command
958 {
959   uint8_t command;
960   void (*cmd_handler) (void);
961 };
962
963 const struct command cmds[] = {
964   { INS_VERIFY, cmd_verify },
965   { INS_CHANGE_REFERENCE_DATA, cmd_change_password },
966   { INS_PSO, cmd_pso },
967   { INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
968   { INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
969   { INS_EXTERNAL_AUTHENTICATE,              /* Not in OpenPGP card protocol */
970     cmd_external_authenticate },
971   { INS_GET_CHALLENGE, cmd_get_challenge }, /* Not in OpenPGP card protocol */
972   { INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
973   { INS_SELECT_FILE, cmd_select_file },
974   { INS_READ_BINARY, cmd_read_binary },
975   { INS_GET_DATA, cmd_get_data },
976   { INS_WRITE_BINARY, cmd_write_binary},    /* Not in OpenPGP card protocol */
977 #if defined(CERTDO_SUPPORT)
978   { INS_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
979 #endif
980   { INS_PUT_DATA, cmd_put_data },
981   { INS_PUT_DATA_ODD, cmd_put_data },
982 };
983 #define NUM_CMDS ((int)(sizeof (cmds) / sizeof (struct command)))
984
985 static void
986 process_command_apdu (void)
987 {
988   int i;
989   uint8_t cmd = INS (apdu);
990
991   for (i = 0; i < NUM_CMDS; i++)
992     if (cmds[i].command == cmd)
993       break;
994
995   if (i < NUM_CMDS)
996     cmds[i].cmd_handler ();
997   else
998     {
999       DEBUG_INFO (" - ??");
1000       DEBUG_BYTE (cmd);
1001       GPG_NO_INS ();
1002     }
1003 }
1004
1005 msg_t
1006 GPGthread (void *arg)
1007 {
1008   Thread *icc_thread = (Thread *)arg;
1009
1010   gpg_init ();
1011
1012   chEvtClear (ALL_EVENTS);
1013
1014   while (!chThdShouldTerminate ())
1015     {
1016       eventmask_t m = chEvtWaitOne (ALL_EVENTS);
1017 #if defined(PINPAD_SUPPORT)
1018       int len, pw_len, newpw_len;
1019 #endif
1020
1021       DEBUG_INFO ("GPG!: ");
1022
1023       if (m == EV_VERIFY_CMD_AVAILABLE)
1024         {
1025 #if defined(PINPAD_SUPPORT)
1026           if (INS (apdu) != INS_VERIFY)
1027             {
1028               GPG_CONDITION_NOT_SATISFIED ();
1029               goto done;
1030             }
1031
1032           pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
1033           if (pw_len < 0)
1034             {
1035               GPG_ERROR ();
1036               goto done;
1037             }
1038           memcpy (apdu.cmd_apdu_data, pin_input_buffer, pw_len);
1039           apdu.cmd_apdu_data_len = pw_len;
1040 #else
1041           GPG_ERROR ();
1042           goto done;
1043 #endif
1044         }
1045       else if (m == EV_MODIFY_CMD_AVAILABLE)
1046         {
1047 #if defined(PINPAD_SUPPORT)
1048           uint8_t bConfirmPIN = apdu.cmd_apdu_data[5];
1049           uint8_t *p = apdu.cmd_apdu_data;
1050
1051           if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
1052               && INS (apdu) != INS_RESET_RETRY_COUNTER
1053               && INS (apdu) != INS_PUT_DATA)
1054             {
1055               GPG_CONDITION_NOT_SATISFIED ();
1056               goto done;
1057             }
1058
1059           if ((bConfirmPIN & 2))        /* Require old PIN */
1060             {
1061               pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
1062               if (pw_len < 0)
1063                 {
1064                   GPG_ERROR ();
1065                   goto done;
1066                 }
1067               memcpy (p, pin_input_buffer, pw_len);
1068               p += pw_len;
1069             }
1070           else
1071             pw_len = 0;
1072
1073           newpw_len = get_pinpad_input (PIN_INPUT_NEW);
1074           if (newpw_len < 0)
1075             {
1076               GPG_ERROR ();
1077               goto done;
1078             }
1079           memcpy (p, pin_input_buffer, newpw_len);
1080
1081           if ((bConfirmPIN & 1))        /* New PIN twice */
1082             {
1083               len = get_pinpad_input (PIN_INPUT_CONFIRM);
1084               if (len < 0)
1085                 {
1086                   GPG_ERROR ();
1087                   goto done;
1088                 }
1089
1090               if (len != newpw_len || memcmp (p, pin_input_buffer, len) != 0)
1091                 {
1092                   GPG_SECURITY_FAILURE ();
1093                   goto done;
1094                 }
1095             }
1096
1097           apdu.cmd_apdu_data_len = pw_len + newpw_len;
1098 #else
1099           GPG_ERROR ();
1100           goto done;
1101 #endif
1102         }
1103       else if (m == EV_NOP)
1104         continue;
1105
1106       process_command_apdu ();
1107     done:
1108       chEvtSignal (icc_thread, EV_EXEC_FINISHED);
1109     }
1110
1111   gpg_fini ();
1112   return 0;
1113 }