Mercurial > urweb
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],