diff options
author | Adam Chlipala <adam@chlipala.net> | 2011-07-19 09:18:50 -0400 |
---|---|---|
committer | Adam Chlipala <adam@chlipala.net> | 2011-07-19 09:18:50 -0400 |
commit | ac6fd6218962bf60b86cdfa64b8f7110ffc35ad3 (patch) | |
tree | 5a3ddc7abde84b7531e001931b0cf158d78938b5 /src | |
parent | 0b12664f70f258a5928d051b5e71715b84dd37b6 (diff) |
Change cookie signature comparison to resist timing attacks (based on code suggested by Robin Green and Austin Seipp)
Diffstat (limited to 'src')
-rw-r--r-- | src/c/urweb.c | 17 | ||||
-rw-r--r-- | src/cjr_print.sml | 2 |
2 files changed, 18 insertions, 1 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c index 238b27e2..4d2de1dd 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -3455,6 +3455,23 @@ uw_Basis_string uw_Basis_makeSigString(uw_context ctx, uw_Basis_string sig) { 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); } diff --git a/src/cjr_print.sml b/src/cjr_print.sml index 79d7e7da..340ac9f5 100644 --- a/src/cjr_print.sml +++ b/src/cjr_print.sml @@ -2634,7 +2634,7 @@ fun p_file env (ds, ps) = 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], |