9fad15674d960e5b0fa56f94678d1b470c214090
[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 "polarssl/config.h"
31 #include "polarssl/sha1.h"
32
33 #define CLS(a) a.cmd_apdu_head[0]
34 #define INS(a) a.cmd_apdu_head[1]
35 #define P1(a) a.cmd_apdu_head[2]
36 #define P2(a) a.cmd_apdu_head[3]
37
38 #define INS_VERIFY                              0x20
39 #define INS_CHANGE_REFERENCE_DATA               0x24
40 #define INS_PSO                                 0x2a
41 #define INS_RESET_RETRY_COUNTER                 0x2c
42 #define INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR    0x47
43 #define INS_EXTERNAL_AUTHENTICATE               0x82
44 #define INS_GET_CHALLENGE                       0x84
45 #define INS_INTERNAL_AUTHENTICATE               0x88
46 #define INS_SELECT_FILE                         0xa4
47 #define INS_READ_BINARY                         0xb0
48 #define INS_GET_DATA                            0xca
49 #define INS_WRITE_BINARY                        0xd0
50 #define INS_UPDATE_BINARY                       0xd6
51 #define INS_PUT_DATA                            0xda
52 #define INS_PUT_DATA_ODD                        0xdb    /* For key import */
53
54 #define CHALLENGE_LEN   16
55 static const uint8_t *challenge; /* Random bytes */
56
57 static const uint8_t
58 select_file_TOP_result[] __attribute__ ((aligned (1))) = {
59   0x00, 0x00,        /* unused */
60   0x00, 0x00,        /* number of bytes in this directory: to be filled */
61   0x3f, 0x00,        /* field of selected file: MF, 3f00 */
62   0x38,                 /* it's DF */
63   0xff,                 /* unused */
64   0xff, 0x44, 0x44,     /* access conditions */
65   0x01,                 /* status of the selected file (OK, unblocked) */
66   0x05,                 /* number of bytes of data follow */
67     0x03,                       /* Features: unused */
68     0x01,                       /* number of subdirectories (OpenPGP) */
69     0x01,                       /* number of elementary files (SerialNo) */
70     0x00,                       /* number of secret codes */
71     0x00,                       /* Unused */
72   0x00, 0x00            /* PIN status: OK, PIN blocked?: No */
73 };
74
75 void
76 set_res_sw (uint8_t sw1, uint8_t sw2)
77 {
78   apdu.sw = (sw1 << 8) | sw2;
79 }
80
81 #define FILE_NONE       0
82 #define FILE_DF_OPENPGP 1
83 #define FILE_MF         2
84 #define FILE_EF_DIR     3
85 #define FILE_EF_SERIAL_NO       4
86 #define FILE_EF_UPDATE_KEY_0    5
87 #define FILE_EF_UPDATE_KEY_1    6
88 #define FILE_EF_UPDATE_KEY_2    7
89 #define FILE_EF_UPDATE_KEY_3    8
90 #define FILE_EF_CH_CERTIFICATE  9
91
92 static uint8_t file_selection;
93
94 static void
95 gpg_init (void)
96 {
97   const uint8_t *flash_data_start;
98
99   file_selection = FILE_NONE;
100   flash_data_start = flash_init ();
101   gpg_data_scan (flash_data_start);
102 }
103
104 static void
105 gpg_fini (void)
106 {
107   ac_fini ();
108 }
109
110 #if defined(PINPAD_SUPPORT)
111 /* 
112  * Let user input PIN string.
113  * Return length of the string.
114  * The string itself is in PIN_INPUT_BUFFER.
115  */
116 static int
117 get_pinpad_input (int msg_code)
118 {
119   int r;
120
121   chEvtSignal (main_thread, LED_WAIT_MODE);
122   r = pinpad_getline (msg_code, MS2ST (8000));
123   chEvtSignal (main_thread, LED_STATUS_MODE);
124   return r;
125 }
126 #endif
127
128 static void
129 cmd_verify (void)
130 {
131   int len;
132   uint8_t p2 = P2 (apdu);
133   int r;
134   const uint8_t *pw;
135
136   DEBUG_INFO (" - VERIFY\r\n");
137   DEBUG_BYTE (p2);
138
139   len = apdu.cmd_apdu_data_len;
140   pw = apdu.cmd_apdu_data;
141
142   if (p2 == 0x81)
143     r = verify_pso_cds (pw, len);
144   else if (p2 == 0x82)
145     r = verify_other (pw, len);
146   else
147     r = verify_admin (pw, len);
148
149   if (r < 0)
150     {
151       DEBUG_INFO ("failed\r\n");
152       GPG_SECURITY_FAILURE ();
153     }
154   else if (r == 0)
155     {
156       DEBUG_INFO ("blocked\r\n");
157       GPG_SECURITY_AUTH_BLOCKED ();
158     }
159   else
160     {
161       DEBUG_INFO ("good\r\n");
162       GPG_SUCCESS ();
163     }
164 }
165
166 int
167 gpg_change_keystring (int who_old, const uint8_t *old_ks,
168                       int who_new, const uint8_t *new_ks)
169 {
170   int r;
171   int prv_keys_exist = 0;
172
173   r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, who_old, old_ks);
174   if (r < 0)
175     return r;
176
177   if (r > 0)
178     prv_keys_exist++;
179
180   r = gpg_do_chks_prvkey (GPG_KEY_FOR_SIGNING, who_old, old_ks,
181                           who_new, new_ks);
182   if (r < 0)
183     return -2;
184
185   r = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, who_old, old_ks);
186   if (r < 0)
187     return r;
188
189   if (r > 0)
190     prv_keys_exist++;
191
192   r = gpg_do_chks_prvkey (GPG_KEY_FOR_DECRYPTION, who_old, old_ks,
193                           who_new, new_ks);
194   if (r < 0)
195     return -2;
196
197   r = gpg_do_load_prvkey (GPG_KEY_FOR_AUTHENTICATION, who_old, old_ks);
198   if (r < 0)
199     return r;
200
201   if (r > 0)
202     prv_keys_exist++;
203
204   r = gpg_do_chks_prvkey (GPG_KEY_FOR_AUTHENTICATION, who_old, old_ks,
205                           who_new, new_ks);
206   if (r < 0)
207     return -2;
208
209   if (prv_keys_exist)
210     return 1;
211   else
212     return 0;
213 }
214
215 static void
216 cmd_change_password (void)
217 {
218   uint8_t old_ks[KEYSTRING_MD_SIZE];
219   uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
220   uint8_t *new_ks = &new_ks0[1];
221   uint8_t p1 = P1 (apdu);       /* 0: change (old+new), 1: exchange (new) */
222   uint8_t p2 = P2 (apdu);
223   int len;
224   const uint8_t *pw;
225   const uint8_t *newpw;
226   int pw_len, newpw_len;
227   int who = p2 - 0x80;
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
248       if (pw_len < 0)
249         {
250           DEBUG_INFO ("permission denied.\r\n");
251           GPG_SECURITY_FAILURE ();
252           return;
253         }
254       else if (pw_len == 0)
255         {
256           DEBUG_INFO ("blocked.\r\n");
257           GPG_SECURITY_AUTH_BLOCKED ();
258           return;
259         }
260       else
261         {
262           newpw = pw + pw_len;
263           newpw_len = len - pw_len;
264         }
265     }
266   else                          /* PW3 (0x83) */
267     {
268       pw_len = verify_admin_0 (pw, len, -1);
269
270       if (pw_len < 0)
271         {
272           DEBUG_INFO ("permission denied.\r\n");
273           GPG_SECURITY_FAILURE ();
274           return;
275         }
276       else if (pw_len == 0)
277         {
278           DEBUG_INFO ("blocked.\r\n");
279           GPG_SECURITY_AUTH_BLOCKED ();
280           return;
281         }
282       else
283         {
284           newpw = pw + pw_len;
285           newpw_len = len - pw_len;
286           gpg_set_pw3 (newpw, newpw_len);
287         }
288     }
289
290   sha1 (pw, pw_len, old_ks);
291   sha1 (newpw, newpw_len, new_ks);
292   new_ks0[0] = newpw_len;
293
294   r = gpg_change_keystring (who, old_ks, who, new_ks);
295   if (r <= -2)
296     {
297       DEBUG_INFO ("memory error.\r\n");
298       GPG_MEMORY_FAILURE ();
299     }
300   else if (r < 0)
301     {
302       DEBUG_INFO ("security error.\r\n");
303       GPG_SECURITY_FAILURE ();
304     }
305   else if (r == 0 && who == BY_USER)    /* no prvkey */
306     {
307       gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, KEYSTRING_SIZE_PW1);
308       ac_reset_pso_cds ();
309       ac_reset_other ();
310       DEBUG_INFO ("Changed DO_KEYSTRING_PW1.\r\n");
311       GPG_SUCCESS ();
312     }
313   else if (r > 0 && who == BY_USER)
314     {
315       gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0, 1);
316       ac_reset_pso_cds ();
317       ac_reset_other ();
318       DEBUG_INFO ("Changed length of DO_KEYSTRING_PW1.\r\n");
319       GPG_SUCCESS ();
320     }
321   else                          /* r >= 0 && who == BY_ADMIN */
322     {
323       DEBUG_INFO ("done.\r\n");
324       ac_reset_admin ();
325       GPG_SUCCESS ();
326     }
327 }
328
329 static void
330 cmd_reset_user_password (void)
331 {
332   uint8_t p1 = P1 (apdu);
333   int len;
334   const uint8_t *pw;
335   const uint8_t *newpw;
336   int pw_len, newpw_len;
337   int r;
338   uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
339   uint8_t *new_ks = &new_ks0[1];
340
341   DEBUG_INFO ("Reset PW1\r\n");
342   DEBUG_BYTE (p1);
343
344   len = apdu.cmd_apdu_data_len;
345   pw = apdu.cmd_apdu_data;
346
347   if (p1 == 0x00)               /* by User with Reseting Code */
348     {
349       const uint8_t *ks_rc = gpg_do_read_simple (NR_DO_KEYSTRING_RC);
350       uint8_t old_ks[KEYSTRING_MD_SIZE];
351
352       if (gpg_pw_locked (PW_ERR_RC))
353         {
354           DEBUG_INFO ("blocked.\r\n");
355           GPG_SECURITY_AUTH_BLOCKED ();
356           return;
357         }
358
359       if (ks_rc == NULL)
360         {
361           DEBUG_INFO ("security error.\r\n");
362           GPG_SECURITY_FAILURE ();
363           return;
364         }
365
366       pw_len = ks_rc[0];
367       newpw = pw + pw_len;
368       newpw_len = len - pw_len;
369       sha1 (pw, pw_len, old_ks);
370       sha1 (newpw, newpw_len, new_ks);
371       new_ks0[0] = newpw_len;
372       r = gpg_change_keystring (BY_RESETCODE, old_ks, BY_USER, new_ks);
373       if (r <= -2)
374         {
375           DEBUG_INFO ("memory error.\r\n");
376           GPG_MEMORY_FAILURE ();
377         }
378       else if (r < 0)
379         {
380         sec_fail:
381           DEBUG_INFO ("failed.\r\n");
382           gpg_pw_increment_err_counter (PW_ERR_RC);
383           GPG_SECURITY_FAILURE ();
384         }
385       else if (r == 0)
386         {
387           if (memcmp (ks_rc+1, old_ks, KEYSTRING_MD_SIZE) != 0)
388             goto sec_fail;
389           DEBUG_INFO ("done (no prvkey).\r\n");
390           gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
391                                KEYSTRING_SIZE_PW1);
392           ac_reset_pso_cds ();
393           ac_reset_other ();
394           gpg_pw_reset_err_counter (PW_ERR_RC);
395           gpg_pw_reset_err_counter (PW_ERR_PW1);
396           GPG_SUCCESS ();
397         }
398       else
399         {
400           DEBUG_INFO ("done.\r\n");
401           ac_reset_pso_cds ();
402           ac_reset_other ();
403           gpg_pw_reset_err_counter (PW_ERR_RC);
404           gpg_pw_reset_err_counter (PW_ERR_PW1);
405           GPG_SUCCESS ();
406         }
407     }
408   else                          /* by Admin (p1 == 0x02) */
409     {
410       const uint8_t *old_ks = keystring_md_pw3;
411
412       if (!ac_check_status (AC_ADMIN_AUTHORIZED))
413         {
414           DEBUG_INFO ("permission denied.\r\n");
415           GPG_SECURITY_FAILURE ();
416           return;
417         }
418
419       newpw_len = len;
420       newpw = pw;
421       sha1 (newpw, newpw_len, new_ks);
422       new_ks0[0] = newpw_len;
423       r = gpg_change_keystring (admin_authorized, old_ks, BY_USER, new_ks);
424       if (r <= -2)
425         {
426           DEBUG_INFO ("memory error.\r\n");
427           GPG_MEMORY_FAILURE ();
428         }
429       else if (r < 0)
430         {
431           DEBUG_INFO ("security error.\r\n");
432           GPG_SECURITY_FAILURE ();
433         }
434       else if (r == 0)
435         {
436           DEBUG_INFO ("done (no privkey).\r\n");
437           gpg_do_write_simple (NR_DO_KEYSTRING_PW1, new_ks0,
438                                KEYSTRING_SIZE_PW1);
439           ac_reset_pso_cds ();
440           ac_reset_other ();
441           gpg_pw_reset_err_counter (PW_ERR_PW1);
442           GPG_SUCCESS ();
443         }
444       else
445         {
446           DEBUG_INFO ("done.\r\n");
447           ac_reset_pso_cds ();
448           ac_reset_other ();
449           gpg_pw_reset_err_counter (PW_ERR_PW1);
450           GPG_SUCCESS ();
451         }
452     }
453 }
454
455 static void
456 cmd_put_data (void)
457 {
458   uint8_t *data;
459   uint16_t tag;
460   int len;
461
462   DEBUG_INFO (" - PUT DATA\r\n");
463
464   if (file_selection != FILE_DF_OPENPGP)
465     GPG_NO_RECORD();
466
467   tag = ((P1 (apdu)<<8) | P2 (apdu));
468   len = apdu.cmd_apdu_data_len;
469   data = apdu.cmd_apdu_data;
470   gpg_do_put_data (tag, data, len);
471 }
472
473 static void
474 cmd_pgp_gakp (void)
475 {
476   DEBUG_INFO (" - Generate Asymmetric Key Pair\r\n");
477   DEBUG_BYTE (P1 (apdu));
478
479   if (P1 (apdu) == 0x81)
480     /* Get public key */
481     gpg_do_public_key (apdu.cmd_apdu_data[0]);
482   else
483     {
484       if (!ac_check_status (AC_ADMIN_AUTHORIZED))
485         GPG_SECURITY_FAILURE ();
486       /* Generate key pair */
487       gpg_do_keygen (apdu.cmd_apdu_data[0]);
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           chEvtSignal (main_thread, LED_WAIT_MODE);
705           r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
706                         &kd[GPG_KEY_FOR_SIGNING]);
707           chEvtSignal (main_thread, LED_STATUS_MODE);
708           if (r < 0)
709             {
710               ac_reset_pso_cds ();
711               GPG_ERROR ();
712             }
713           else
714             /* Success */
715             gpg_increment_digital_signature_counter ();
716         }
717     }
718   else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
719     {
720       DEBUG_SHORT (len);
721       DEBUG_BINARY (&kd[GPG_KEY_FOR_DECRYPTION], KEY_CONTENT_LEN);
722
723       if (!ac_check_status (AC_OTHER_AUTHORIZED))
724         {
725           DEBUG_INFO ("security error.");
726           GPG_SECURITY_FAILURE ();
727           return;
728         }
729
730       /* Skip padding 0x00 */
731       len--;
732       chEvtSignal (main_thread, LED_WAIT_MODE);
733       r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
734                        &kd[GPG_KEY_FOR_DECRYPTION]);
735       chEvtSignal (main_thread, LED_STATUS_MODE);
736       if (r < 0)
737         GPG_ERROR ();
738     }
739   else
740     {
741       DEBUG_INFO (" - ??");
742       DEBUG_BYTE (P1 (apdu));
743       DEBUG_INFO (" - ??");
744       DEBUG_BYTE (P2 (apdu));
745       GPG_ERROR ();
746     }
747
748   DEBUG_INFO ("PSO done.\r\n");
749 }
750
751
752 #define MAX_DIGEST_INFO_LEN 102 /* 40% */
753 static void
754 cmd_internal_authenticate (void)
755 {
756   int len = apdu.cmd_apdu_data_len;
757   int r;
758
759   DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
760
761   if (P1 (apdu) == 0x00 && P2 (apdu) == 0x00)
762     {
763       DEBUG_SHORT (len);
764
765       if (!ac_check_status (AC_OTHER_AUTHORIZED))
766         {
767           DEBUG_INFO ("security error.");
768           GPG_SECURITY_FAILURE ();
769           return;
770         }
771
772       if (len > MAX_DIGEST_INFO_LEN)
773         {
774           DEBUG_INFO ("input is too long.");
775           GPG_CONDITION_NOT_SATISFIED ();
776           return;
777         }
778
779       chEvtSignal (main_thread, LED_WAIT_MODE);
780       r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
781                     &kd[GPG_KEY_FOR_AUTHENTICATION]);
782       chEvtSignal (main_thread, LED_STATUS_MODE);
783       if (r < 0)
784         GPG_ERROR ();
785     }
786   else
787     {
788       DEBUG_INFO (" - ??");
789       DEBUG_BYTE (P1 (apdu));
790       DEBUG_INFO (" - ??");
791       DEBUG_BYTE (P2 (apdu));
792       GPG_ERROR ();
793     }
794
795   DEBUG_INFO ("INTERNAL AUTHENTICATE done.\r\n");
796 }
797
798 #define MBD_OPRATION_WRITE  0
799 #define MBD_OPRATION_UPDATE 1
800
801 static void
802 modify_binary (uint8_t op, uint8_t p1, uint8_t p2, int len)
803 {
804   uint8_t file_id;
805   uint16_t offset;
806   int is_short_EF = (p1 & 0x80) != 0;
807   int r;
808
809   if (!ac_check_status (AC_ADMIN_AUTHORIZED))
810     {
811       DEBUG_INFO ("security error.");
812       GPG_SECURITY_FAILURE ();
813       return;
814     }
815
816   if (is_short_EF)
817     file_id = (p1 & 0x1f);
818   else
819     file_id = file_selection - FILE_EF_SERIAL_NO + FILEID_SERIAL_NO;
820
821   if (!FILEID_CH_CERTIFICATE_IS_VALID && file_id == FILEID_CH_CERTIFICATE)
822     {
823       GPG_NO_FILE ();
824       return;
825     }
826
827   if (op == MBD_OPRATION_UPDATE && file_id != FILEID_CH_CERTIFICATE)
828     {
829       GPG_CONDITION_NOT_SATISFIED ();
830       return;
831     }
832
833   if (file_id > FILEID_CH_CERTIFICATE)
834     {
835       GPG_NO_FILE ();
836       return;
837     }
838
839   if (is_short_EF)
840     {
841       file_selection = file_id - FILEID_SERIAL_NO + FILE_EF_SERIAL_NO;
842       offset = p2;
843
844       if (op == MBD_OPRATION_UPDATE)
845         {
846           r = flash_erase_binary (file_id);
847           if (r < 0)
848             {
849               DEBUG_INFO ("memory error.\r\n");
850               GPG_MEMORY_FAILURE ();
851               return;
852             }
853         }
854     }
855   else
856     offset = (p1 << 8) | p2;
857
858   DEBUG_SHORT (len);
859   DEBUG_SHORT (offset);
860
861   r = flash_write_binary (file_id, apdu.cmd_apdu_data, len, offset);
862   if (r < 0)
863     {
864       DEBUG_INFO ("memory error.\r\n");
865       GPG_MEMORY_FAILURE ();
866       return;
867     }
868
869   GPG_SUCCESS ();
870 }
871
872
873 #if defined(CERTDO_SUPPORT)
874 static void
875 cmd_update_binary (void)
876 {
877   int len = apdu.cmd_apdu_data_len;
878
879   DEBUG_INFO (" - UPDATE BINARY\r\n");
880   modify_binary (MBD_OPRATION_UPDATE, P1 (apdu), P2 (apdu), len);
881   DEBUG_INFO ("UPDATE BINARY done.\r\n");
882 }
883 #endif
884
885
886 static void
887 cmd_write_binary (void)
888 {
889   int len = apdu.cmd_apdu_data_len;
890   int i;
891   const uint8_t *p;
892
893   DEBUG_INFO (" - WRITE BINARY\r\n");
894   modify_binary (MBD_OPRATION_WRITE, P1 (apdu), P2 (apdu), len);
895
896   for (i = 0; i < 4; i++)
897     {
898       p = gpg_get_firmware_update_key (i);
899       if (p[0] != 0x00 || p[1] != 0x00) /* still valid */
900         break;
901     }
902
903   if (i == 4)                   /* all update keys are removed */
904     {
905       p = gpg_get_firmware_update_key (0);
906       flash_erase_page ((uint32_t)p);
907     }
908
909   DEBUG_INFO ("WRITE BINARY done.\r\n");
910 }
911
912
913 static void
914 cmd_external_authenticate (void)
915 {
916   const uint8_t *pubkey;
917   const uint8_t *signature = apdu.cmd_apdu_data;
918   uint8_t *hash = apdu.cmd_apdu_data + 256;
919   int len = apdu.cmd_apdu_data_len;
920   uint8_t keyno = P2 (apdu);
921
922   DEBUG_INFO (" - EXTERNAL AUTHENTICATE\r\n");
923
924   if (keyno > 4)
925     {
926       GPG_CONDITION_NOT_SATISFIED ();
927       return;
928     }
929
930   pubkey = gpg_get_firmware_update_key (keyno);
931   if (len != 256
932       || (pubkey[0] == 0xff && pubkey[1] == 0xff) /* not registered */
933       || (pubkey[0] == 0x00 && pubkey[1] == 0x00) /* removed */)
934     {
935       GPG_CONDITION_NOT_SATISFIED ();
936       return;
937     }
938   
939   memcpy (hash, unique_device_id (), 4);
940   memcpy (hash+4, challenge, CHALLENGE_LEN);
941   random_bytes_free (challenge);
942   challenge = NULL;
943
944   if (rsa_verify (pubkey, hash, signature) < 0)
945     {
946       GPG_SECURITY_FAILURE ();
947       return;
948     }
949
950   chThdTerminate (chThdSelf ());
951   set_res_sw (0xff, 0xff);
952   DEBUG_INFO ("EXTERNAL AUTHENTICATE done.\r\n");
953 }
954
955 static void
956 cmd_get_challenge (void)
957 {
958   DEBUG_INFO (" - GET CHALLENGE\r\n");
959
960   if (challenge)
961     random_bytes_free (challenge);
962
963   challenge = random_bytes_get ();
964   memcpy (res_APDU, unique_device_id (), 4);
965   memcpy (res_APDU+4, challenge, CHALLENGE_LEN);
966   res_APDU_size = CHALLENGE_LEN + 4;
967   GPG_SUCCESS ();
968   DEBUG_INFO ("GET CHALLENGE done.\r\n");
969 }
970
971
972 struct command
973 {
974   uint8_t command;
975   void (*cmd_handler) (void);
976 };
977
978 const struct command cmds[] = {
979   { INS_VERIFY, cmd_verify },
980   { INS_CHANGE_REFERENCE_DATA, cmd_change_password },
981   { INS_PSO, cmd_pso },
982   { INS_RESET_RETRY_COUNTER, cmd_reset_user_password },
983   { INS_PGP_GENERATE_ASYMMETRIC_KEY_PAIR, cmd_pgp_gakp },
984   { INS_EXTERNAL_AUTHENTICATE,              /* Not in OpenPGP card protocol */
985     cmd_external_authenticate },
986   { INS_GET_CHALLENGE, cmd_get_challenge }, /* Not in OpenPGP card protocol */
987   { INS_INTERNAL_AUTHENTICATE, cmd_internal_authenticate },
988   { INS_SELECT_FILE, cmd_select_file },
989   { INS_READ_BINARY, cmd_read_binary },
990   { INS_GET_DATA, cmd_get_data },
991   { INS_WRITE_BINARY, cmd_write_binary},    /* Not in OpenPGP card protocol */
992 #if defined(CERTDO_SUPPORT)
993   { INS_UPDATE_BINARY, cmd_update_binary }, /* Not in OpenPGP card protocol */
994 #endif
995   { INS_PUT_DATA, cmd_put_data },
996   { INS_PUT_DATA_ODD, cmd_put_data },
997 };
998 #define NUM_CMDS ((int)(sizeof (cmds) / sizeof (struct command)))
999
1000 static void
1001 process_command_apdu (void)
1002 {
1003   int i;
1004   uint8_t cmd = INS (apdu);
1005
1006   for (i = 0; i < NUM_CMDS; i++)
1007     if (cmds[i].command == cmd)
1008       break;
1009
1010   if (i < NUM_CMDS)
1011     cmds[i].cmd_handler ();
1012   else
1013     {
1014       DEBUG_INFO (" - ??");
1015       DEBUG_BYTE (cmd);
1016       GPG_NO_INS ();
1017     }
1018 }
1019
1020 msg_t
1021 GPGthread (void *arg)
1022 {
1023   Thread *icc_thread = (Thread *)arg;
1024
1025   gpg_init ();
1026
1027   chEvtClear (ALL_EVENTS);
1028
1029   while (!chThdShouldTerminate ())
1030     {
1031       eventmask_t m = chEvtWaitOne (ALL_EVENTS);
1032 #if defined(PINPAD_SUPPORT)
1033       int len, pw_len, newpw_len;
1034 #endif
1035
1036       DEBUG_INFO ("GPG!: ");
1037
1038       if (m == EV_VERIFY_CMD_AVAILABLE)
1039         {
1040 #if defined(PINPAD_SUPPORT)
1041           if (INS (apdu) != INS_VERIFY)
1042             {
1043               GPG_CONDITION_NOT_SATISFIED ();
1044               goto done;
1045             }
1046
1047           pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
1048           if (pw_len < 0)
1049             {
1050               GPG_ERROR ();
1051               goto done;
1052             }
1053           memcpy (apdu.cmd_apdu_data, pin_input_buffer, pw_len);
1054           apdu.cmd_apdu_data_len = pw_len;
1055 #else
1056           GPG_ERROR ();
1057           goto done;
1058 #endif
1059         }
1060       else if (m == EV_MODIFY_CMD_AVAILABLE)
1061         {
1062 #if defined(PINPAD_SUPPORT)
1063           uint8_t bConfirmPIN = apdu.cmd_apdu_data[5];
1064           uint8_t *p = apdu.cmd_apdu_data;
1065
1066           if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
1067               && INS (apdu) != INS_RESET_RETRY_COUNTER
1068               && INS (apdu) != INS_PUT_DATA)
1069             {
1070               GPG_CONDITION_NOT_SATISFIED ();
1071               goto done;
1072             }
1073
1074           if ((bConfirmPIN & 2))        /* Require old PIN */
1075             {
1076               pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
1077               if (pw_len < 0)
1078                 {
1079                   GPG_ERROR ();
1080                   goto done;
1081                 }
1082               memcpy (p, pin_input_buffer, pw_len);
1083               p += pw_len;
1084             }
1085           else
1086             pw_len = 0;
1087
1088           newpw_len = get_pinpad_input (PIN_INPUT_NEW);
1089           if (newpw_len < 0)
1090             {
1091               GPG_ERROR ();
1092               goto done;
1093             }
1094           memcpy (p, pin_input_buffer, newpw_len);
1095
1096           if ((bConfirmPIN & 1))        /* New PIN twice */
1097             {
1098               len = get_pinpad_input (PIN_INPUT_CONFIRM);
1099               if (len < 0)
1100                 {
1101                   GPG_ERROR ();
1102                   goto done;
1103                 }
1104
1105               if (len != newpw_len || memcmp (p, pin_input_buffer, len) != 0)
1106                 {
1107                   GPG_SECURITY_FAILURE ();
1108                   goto done;
1109                 }
1110             }
1111
1112           apdu.cmd_apdu_data_len = pw_len + newpw_len;
1113 #else
1114           GPG_ERROR ();
1115           goto done;
1116 #endif
1117         }
1118       else if (m == EV_NOP)
1119         continue;
1120
1121       process_command_apdu ();
1122     done:
1123       chEvtSignal (icc_thread, EV_EXEC_FINISHED);
1124     }
1125
1126   gpg_fini ();
1127   return 0;
1128 }