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