protection improvement (1): different S2K for PW1 and Reset-code
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 14 Jun 2012 00:13:59 +0000 (09:13 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 14 Jun 2012 00:13:59 +0000 (09:13 +0900)
ChangeLog
NEWS
src/gnuk.h
src/openpgp-do.c
src/openpgp.c
src/sha256.c

index bd16ada..20f4403 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2012-06-14  Niibe Yutaka  <gniibe@fsij.org>
 
+       * src/openpgp.c (resetcode_s2k): New.
+       (cmd_reset_user_password): Use resetcode_s2k.
+       * src/openpgp-do.c (proc_resetting_code): Likewise.
+
+       * src/sha256.c (sha256_finish): Clear out CTX at the end.
+
        * src/call-rsa.c (rsa_sign, rsa_decrypt, rsa_verify): Use
        mpi_lset (was: mpi_read_string).
        * polarssl-0.14.0/library/bignum.c (mpi_get_digit)
diff --git a/NEWS b/NEWS
index 971e952..6b6a4e8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,10 @@ Data encryption key for private keys are computed by KDF (Key
 Derivation Function, sometimes also is refered as string to key
 function, S2K).  It was SHA1 before, but it is replaced by SHA-256.
 
+** Protection improvement (even when data is disclosed)
+Even if PW1 and Reset-code is same, content of encripted DEK is
+different now.
+
 
 * Major changes in Gnuk 0.19
 
index 30cb99e..c0fed78 100644 (file)
@@ -193,6 +193,9 @@ struct prvkey_data {
 #define BY_RESETCODE   2
 #define BY_ADMIN       3
 
+extern void resetcode_s2k (const unsigned char *input, unsigned int ilen,
+                          unsigned char output[32]);
+
 extern int flash_key_write (uint8_t *key_addr, const uint8_t *key_data, const uint8_t *modulus);
 
 #define KEYSTRING_PASSLEN_SIZE  1
index c333234..07c564a 100644 (file)
@@ -543,7 +543,7 @@ proc_resetting_code (const uint8_t *data, int len)
 
   newpw_len = len;
   newpw = data;
-  sha256 (newpw, newpw_len, new_ks);
+  resetcode_s2k (newpw, newpw_len, new_ks);
   new_ks0[0] = newpw_len;
   r = gpg_change_keystring (admin_authorized, old_ks, BY_RESETCODE, new_ks);
   if (r <= -2)
index 2fa8f0a..43c089c 100644 (file)
@@ -328,6 +328,23 @@ cmd_change_password (void)
     }
 }
 
+
+#define RESETCODE_S2K_MAGIC "\xffRESET\r\n"
+
+void
+resetcode_s2k (const unsigned char *input, unsigned int ilen,
+              unsigned char output[32])
+{
+  sha256_context ctx;
+
+  sha256_start (&ctx);
+  sha256_update (&ctx, input, ilen);
+  sha256_update (&ctx, (unsigned char *)RESETCODE_S2K_MAGIC,
+                sizeof (RESETCODE_S2K_MAGIC));
+  sha256_finish (&ctx, output);
+}
+
+
 static void
 cmd_reset_user_password (void)
 {
@@ -368,7 +385,7 @@ cmd_reset_user_password (void)
       pw_len = ks_rc[0];
       newpw = pw + pw_len;
       newpw_len = len - pw_len;
-      sha256 (pw, pw_len, old_ks);
+      resetcode_s2k (pw, pw_len, old_ks);
       sha256 (newpw, newpw_len, new_ks);
       new_ks0[0] = newpw_len;
       r = gpg_change_keystring (BY_RESETCODE, old_ks, BY_USER, new_ks);
index d896296..a91abe4 100644 (file)
@@ -194,6 +194,7 @@ sha256_finish (sha256_context *ctx, unsigned char output[32])
 
   bswap32_buf (ctx->state, SHA256_DIGEST_SIZE >> 2);
   memcpy (output, ctx->state, SHA256_DIGEST_SIZE);
+  memset (&ctx, 0, sizeof (sha256_context));
 }
 
 const uint32_t initial_state[8] =
@@ -218,6 +219,4 @@ sha256 (const unsigned char *input, unsigned int ilen,
   sha256_start (&ctx);
   sha256_update (&ctx, input, ilen);
   sha256_finish (&ctx, output);
-
-  memset (&ctx, 0, sizeof (sha256_context));
 }