Fix EdDSA signature counter
authorNIIBE Yutaka <gniibe@fsij.org>
Tue, 10 Feb 2015 00:58:45 +0000 (09:58 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Tue, 10 Feb 2015 00:58:45 +0000 (09:58 +0900)
ChangeLog
src/call-rsa.c
src/gnuk.h
src/openpgp.c

index f9d1b37..b0aac5c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,14 @@
+2015-02-10  Niibe Yutaka  <gniibe@fsij.org>
+
+       * src/openpgp.c (cmd_pso): Fix counter update for EdDSA.  Thanks
+       to Jonathan Schleifer.
+
+       * src/call-rsa.c (rsa_sign): Don't set res_APDU_len.
+       (rsa_decrypt): Likewise, but get OUTPUT_LEN_P as an argument.
+
 2015-02-09  Niibe Yutaka  <gniibe@fsij.org>
 
-       * src/openpgp.c (cmd_pso): Fix eddsa. Use GPG_KEY_FOR_SIGNING.
+       * src/openpgp.c (cmd_pso): Fix EdDSA. Use GPG_KEY_FOR_SIGNING.
 
 2014-12-15  Niibe Yutaka  <gniibe@fsij.org>
 
index c494156..6632c07 100644 (file)
@@ -83,7 +83,6 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
     }
   else
     {
-      res_APDU_size = pubkey_len;
       DEBUG_INFO ("done.\r\n");
       GPG_SUCCESS ();
       return 0;
@@ -120,14 +119,13 @@ modulus_calc (const uint8_t *p, int len)
 
 int
 rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
-            struct key_data *kd)
+            struct key_data *kd, unsigned int *output_len_p)
 {
   mpi P1, Q1, H;
   int ret;
-  unsigned int output_len;
 
   DEBUG_INFO ("RSA decrypt:");
-  DEBUG_WORD ((uint32_t)&output_len);
+  DEBUG_WORD ((uint32_t)&ret);
 
   rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
   mpi_init (&P1);  mpi_init (&Q1);  mpi_init (&H);
@@ -154,7 +152,7 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
     {
       DEBUG_INFO ("RSA decrypt ...");
       ret = rsa_rsaes_pkcs1_v15_decrypt (&rsa_ctx, NULL, NULL,
-                                        RSA_PRIVATE, &output_len, input,
+                                        RSA_PRIVATE, output_len_p, input,
                                         output, MAX_RES_APDU_DATA_SIZE);
     }
 
@@ -167,7 +165,6 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
     }
   else
     {
-      res_APDU_size = output_len;
       DEBUG_INFO ("done.\r\n");
       GPG_SUCCESS ();
       return 0;
index 63b4a76..cb58636 100644 (file)
@@ -256,7 +256,8 @@ void put_binary (const char *s, int len);
 
 int rsa_sign (const uint8_t *, uint8_t *, int, struct key_data *, int);
 uint8_t *modulus_calc (const uint8_t *, int);
-int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *);
+int rsa_decrypt (const uint8_t *, uint8_t *, int, struct key_data *,
+                unsigned int *);
 int rsa_verify (const uint8_t *, int, const uint8_t *, const uint8_t *);
 uint8_t *rsa_genkey (int);
 
index 5976255..c3107a0 100644 (file)
@@ -819,6 +819,7 @@ cmd_pso (void)
   int r = -1;
   int attr;
   int pubkey_len;
+  unsigned int result_len = 0;
 
   DEBUG_INFO (" - PSO: ");
   DEBUG_WORD ((uint32_t)&r);
@@ -855,13 +856,9 @@ cmd_pso (void)
 
          DEBUG_BINARY (kd[GPG_KEY_FOR_SIGNING].data, pubkey_len);
 
+         result_len = pubkey_len;
          r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
                        &kd[GPG_KEY_FOR_SIGNING], pubkey_len);
-         if (r < 0)
-           ac_reset_pso_cds ();
-         else
-           /* Success */
-           gpg_increment_digital_signature_counter ();
        }
       else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
        {
@@ -873,19 +870,13 @@ cmd_pso (void)
              return;
            }
 
+         result_len = ECDSA_SIGNATURE_LENGTH;
          if (attr == ALGO_NISTP256R1)
            r = ecdsa_sign_p256r1 (apdu.cmd_apdu_data, res_APDU,
                                   kd[GPG_KEY_FOR_SIGNING].data);
          else                  /* ALGO_SECP256K1 */
            r = ecdsa_sign_p256k1 (apdu.cmd_apdu_data, res_APDU,
                                   kd[GPG_KEY_FOR_SIGNING].data);
-         if (r < 0)
-           ac_reset_pso_cds ();
-         else
-           {                   /* Success */
-             gpg_increment_digital_signature_counter ();
-             res_APDU_size = ECDSA_SIGNATURE_LENGTH;
-           }
        }
       else if (attr == ALGO_ED25519)
        {
@@ -898,13 +889,27 @@ cmd_pso (void)
              return;
            }
 
-         res_APDU_size = EDDSA_SIGNATURE_LENGTH;
+         result_len = EDDSA_SIGNATURE_LENGTH;
          r = eddsa_sign_25519 (apdu.cmd_apdu_data, len, output,
                                kd[GPG_KEY_FOR_SIGNING].data,
                                kd[GPG_KEY_FOR_SIGNING].data+32,
                                kd[GPG_KEY_FOR_SIGNING].pubkey);
          memcpy (res_APDU, output, EDDSA_SIGNATURE_LENGTH);
        }
+      else
+       {
+         DEBUG_INFO ("unknown algo.");
+         GPG_FUNCTION_NOT_SUPPORTED ();
+         return;
+       }
+
+      if (r == 0)
+       {
+         res_APDU_size = result_len;
+         gpg_increment_digital_signature_counter ();
+       }
+      else   /* Failure */
+       ac_reset_pso_cds ();
     }
   else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
     {
@@ -931,7 +936,7 @@ cmd_pso (void)
              return;
            }
          r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
-                          &kd[GPG_KEY_FOR_DECRYPTION]);
+                          &kd[GPG_KEY_FOR_DECRYPTION], &result_len);
        }
       else if (attr == ALGO_NISTP256R1 || attr == ALGO_SECP256K1)
        {
@@ -942,16 +947,23 @@ cmd_pso (void)
              return;
            }
 
+         result_len = 65;
          if (attr == ALGO_NISTP256R1)
            r = ecdh_decrypt_p256r1 (apdu.cmd_apdu_data, res_APDU,
                                     kd[GPG_KEY_FOR_DECRYPTION].data);
          else
            r = ecdh_decrypt_p256k1 (apdu.cmd_apdu_data, res_APDU,
                                     kd[GPG_KEY_FOR_DECRYPTION].data);
-
-         if (r == 0)
-           res_APDU_size = 65;
        }
+      else
+       {
+         DEBUG_INFO ("unknown algo.");
+         GPG_FUNCTION_NOT_SUPPORTED ();
+         return;
+       }
+
+      if (r == 0)
+       res_APDU_size = result_len;
     }
 
   if (r < 0)