Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:72314 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 18005 invoked from network); 6 Feb 2014 04:21:40 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 6 Feb 2014 04:21:40 -0000 Authentication-Results: pb1.pair.com smtp.mail=yohgaki@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=yohgaki@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.215.49 as permitted sender) X-PHP-List-Original-Sender: yohgaki@gmail.com X-Host-Fingerprint: 209.85.215.49 mail-la0-f49.google.com Received: from [209.85.215.49] ([209.85.215.49:39893] helo=mail-la0-f49.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 84/71-09398-3DD03F25 for ; Wed, 05 Feb 2014 23:21:39 -0500 Received: by mail-la0-f49.google.com with SMTP id y1so1031333lam.22 for ; Wed, 05 Feb 2014 20:21:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:sender:in-reply-to:references:from:date:message-id :subject:to:cc:content-type; bh=C2D5zs5a2RpDoG1iKdCRSz91WPiWOxRmOAul6IKg8J0=; b=Dp23ibxnQVcdNwe04DeKN/pKvAEzZCNaKjnbt1CugscqjQY8qtO9lWPtwPX7ne8GaW LTClTFU/sJQ5VKDQ16uUuuSBr/0v/JxI4E9HeT1zwxDCsmrbgjFS40zWAGCesYF9UHmA lWY7XqAc27XmSyvUYRVkLixjJ2w+Ne6MhkKSK9pg2iODOfKxwAO2KAPXAc+6srWZySU4 tfPwdPpDblabEqF2Djdx7NB6GSdddm223JrxbLyIB3WCdwl0Dnh3HuCyy/BNKg16E+ZR 3AZxfHB8/Nu7MnnfkjGCs55hKz7FY+ORR4WC3Vk2Y3trZ9CMFQkIX27GhUZkhTC2v3mq zf9Q== X-Received: by 10.153.8.225 with SMTP id dn1mr3826751lad.17.1391660495774; Wed, 05 Feb 2014 20:21:35 -0800 (PST) MIME-Version: 1.0 Sender: yohgaki@gmail.com Received: by 10.112.199.37 with HTTP; Wed, 5 Feb 2014 20:20:55 -0800 (PST) In-Reply-To: References: <9E3AA302-1EC1-4497-996F-716555CAAB64@rouvenwessling.de> <52F0139C.2060102@sugarcrm.com> Date: Thu, 6 Feb 2014 13:20:55 +0900 X-Google-Sender-Auth: QFdYamXZUeswpUYZTrHAtMZJ_GM Message-ID: To: =?UTF-8?Q?Rouven_We=C3=9Fling?= Cc: Stas Malyshev , Nikita Popov , PHP internals Content-Type: multipart/alternative; boundary=001a1136dfc67fa66304f1b535df Subject: Re: [PHP-DEV] [VOTE] Timing attack safe string comparison function From: yohgaki@ohgaki.net (Yasuo Ohgaki) --001a1136dfc67fa66304f1b535df Content-Type: text/plain; charset=UTF-8 Hi all, On Thu, Feb 6, 2014 at 12:56 PM, Yasuo Ohgaki wrote: > Padraic gave me an another idea of additional mitigation for this. > Although we cannot rely on it, randomized delay can be used > as mitigation. It would be good for length leak. > > On Thu, Feb 6, 2014 at 10:28 AM, Yasuo Ohgaki wrote: > >> Perhaps, something like this would be good enough. >> >> + /** >> + * If known_string has a length of 0 we set the length to 1, >> + * this will cause us to compare all bytes of userString with the >> null byte which fails >> + */ >> + mod_len = MAX(known_len, 1); >> len = MAX(user_len, 64); // Do not care much >> len = MAX(known_len, len); // Do not care much >> >> // These kind of operations have done somewhere anyway >> // Just don't care. >> k = (unsinged char *)emalloc(len+1) >> u = (unsinged char *)emalloc(len+1); >> memset(k, 0, len+1); >> memset(u, 0, len+1); >> strncpy(k, known_str, known_len); >> strncpy(u, user_str, user_len); >> > > // Determination of delay is tricky. Too short or too long delay does not > work. > // It depends on execution path/data. e.g. How many times > strlen/strncpy/etc is called, length of string. > // I'm not sure if this is sufficient/valid as mitigation for average > usage. Experiments are needed. > // Improvement/suggestion is appreciated. > r1 = (unsigned char)get_random_byte(); > r1 *= 2; // doubles range > for (; r1 > 0; r1--) { > r2 = (unsigned char)get_random_byte(); > for (; r2 > 0; r2--) { > if (r1 < r2) { > buf[r2] = r2 % r1; > } else { > buf[r2] = r1 % r2; > } > } > } > > + >> + /* This is security sensitive code. Do not optimize this for speed. */ >> + result = known_len - user_len; >> >> >> + for (j = 0; j < user_len; j++) { >> >> >> + result |= known_str[j % mod_len] ^ user_str[j]; >> >> for (; len > 0; len--) { >> >> result |= *k++ ^ *u++; // This must be constant. Use simpler operation and keep constant operation here is enough. >> >> >> >> >> + } >> > Since comparison of short and/or not hashed data (e.g. user supplied raw password) should not be done as the function name imply, we may better to document so that users always compare hashed values even when they store raw password/etc. So randomized delay may be overkill. Regards, -- Yasuo Ohgaki yohgaki@ohgaki.net --001a1136dfc67fa66304f1b535df--