changeset 1512:dcc8abbc6dfd

Change cookie signature comparison to resist timing attacks (based on code suggested by Robin Green and Austin Seipp)
author Adam Chlipala <adam@chlipala.net>
date Tue, 19 Jul 2011 09:18:50 -0400 (2011-07-19)
parents e717e2b56b21
children 5616b2cbdcdb
files include/urweb.h src/c/urweb.c src/cjr_print.sml
diffstat 3 files changed, 19 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/include/urweb.h	Sun Jul 17 14:49:52 2011 -0400
+++ b/include/urweb.h	Tue Jul 19 09:18:50 2011 -0400
@@ -230,6 +230,7 @@
 
 uw_Basis_string uw_unnull(uw_Basis_string);
 uw_Basis_string uw_Basis_makeSigString(uw_context, uw_Basis_string);
+int uw_streq(uw_Basis_string, uw_Basis_string);
 uw_Basis_string uw_Basis_sigString(uw_context, uw_unit);
 
 uw_Basis_string uw_Basis_fileName(uw_context, uw_Basis_file);
--- a/src/c/urweb.c	Sun Jul 17 14:49:52 2011 -0400
+++ b/src/c/urweb.c	Tue Jul 19 09:18:50 2011 -0400
@@ -3455,6 +3455,23 @@
   return r;
 }
 
+/* This bit of crafty code is intended to prevent GCC from performing
+ * optimizations that would enable timing attacks.  See:
+ *   http://www.impredicative.com/pipermail/ur/2011-July/000659.html
+ */
+int uw_streq(uw_Basis_string s1, uw_Basis_string s2) {
+  int i, x = 0, len1 = strlen(s1);
+
+  if (len1 != strlen(s2)) return 0;
+
+  for (i = 0; i < len1; ++i) {
+        __asm__ __volatile__ ("");
+        x |= s1[i] ^ s2[i];
+  }
+
+  return x == 0;
+}
+
 uw_Basis_string uw_Basis_sigString(uw_context ctx, uw_unit u) {
   return ctx->app->cookie_sig(ctx);
 }
--- a/src/cjr_print.sml	Sun Jul 17 14:49:52 2011 -0400
+++ b/src/cjr_print.sml	Tue Jul 19 09:18:50 2011 -0400
@@ -2634,7 +2634,7 @@
                               newline,
                               string "if (sig == NULL) uw_error(ctx, FATAL, \"Missing cookie signature\");",
                               newline,
-                              string "if (strcmp(sig, uw_cookie_sig(ctx)))",
+                              string "if (!uw_streq(sig, uw_cookie_sig(ctx)))",
                               newline,
                               box [string "uw_error(ctx, FATAL, \"Wrong cookie signature\");",
                                    newline],