Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:72167 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 14358 invoked from network); 4 Feb 2014 04:07:16 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 4 Feb 2014 04:07:16 -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.217.176 as permitted sender) X-PHP-List-Original-Sender: yohgaki@gmail.com X-Host-Fingerprint: 209.85.217.176 mail-lb0-f176.google.com Received: from [209.85.217.176] ([209.85.217.176:52563] helo=mail-lb0-f176.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 2B/C0-09069-27760F25 for ; Mon, 03 Feb 2014 23:07:15 -0500 Received: by mail-lb0-f176.google.com with SMTP id w7so5940134lbi.21 for ; Mon, 03 Feb 2014 20:07:11 -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=QtVyBHplGLwqEGgmjAo4wivXjhZ1omSIr/RTvDnUP9I=; b=acgx7hq5vpN3DJ03y2qapxTWyPNRbu2ssW75+kCi0bLrTwJrMP69cwbDbK3s8yKHhA p7u8H7qQ5F4IWVBU9ZfQXi3GFs83YU/W4ExqmLGoXNboU9Vf5wI29oew61KYrV3uf+cm SxZoYoxhQDYKw8tORrED3PDnRs0w+6hiMMX1tjeqlmkPoiiMxAUfitjepSzRJ1aoq3ZX TnF+eoxwDgvoAfDkUrS0/77NOZ15JDciwxjCUeUeE7Ip14G/iwtibDXdPBY7ykzbgJht yreuzhi5MZBQZp8WqQMfl7DKGgbg0/KdEQfH1x4ITykeB0GjwWSVW8vDs2AQdLohcGOK rG/g== X-Received: by 10.153.3.2 with SMTP id bs2mr27738925lad.5.1391486831090; Mon, 03 Feb 2014 20:07:11 -0800 (PST) MIME-Version: 1.0 Sender: yohgaki@gmail.com Received: by 10.112.199.37 with HTTP; Mon, 3 Feb 2014 20:06:30 -0800 (PST) In-Reply-To: <52F0139C.2060102@sugarcrm.com> References: <9E3AA302-1EC1-4497-996F-716555CAAB64@rouvenwessling.de> <52F0139C.2060102@sugarcrm.com> Date: Tue, 4 Feb 2014 13:06:30 +0900 X-Google-Sender-Auth: v4nudyAA-dTewVMUFX95PxdtHSE Message-ID: To: Stas Malyshev Cc: Nikita Popov , =?UTF-8?Q?Rouven_We=C3=9Fling?= , PHP internals Content-Type: multipart/alternative; boundary=001a1136c74246e1fa04f18cc689 Subject: Re: [PHP-DEV] [VOTE] Timing attack safe string comparison function From: yohgaki@ohgaki.net (Yasuo Ohgaki) --001a1136c74246e1fa04f18cc689 Content-Type: text/plain; charset=UTF-8 Hi Stas, On Tue, Feb 4, 2014 at 7:09 AM, Stas Malyshev wrote: > > * You are using MAX, i.e. an if-then-else branch. I'm pretty sure that > the > > if and else branches will have different instruction counts in that case. > > Simple alternative would be something fixed like mod_len = known_len+1 or > > known_len&1. > > * You leak information on mod_len / known_len, because you will have > > If it's meant to compare hashes and other such things, we can presume > the attacker already knows what your code does, and thus knows what the > expected hash length is. What he doesn't know is what that hash is. The > timing attack is based on the fact that regular comparison drops after > first mismatch, so the attacker by trying different first symbols and > using time as oracle between match and mismatch, can guess the hash. The > length of the hash however is not useful for him - for most standard > crypto protocols all lengths are already known and even if you are using > some modifications basic crypto principles tell us to assume your > algorithm is known to the attacker and thus most probably your known > hash length is too. I agree partially. Length leak would not be serious issue when length is long enough. I've already posted possible improvement that would not be affected by supplied string length. + /** + * 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(known_len, 256); + + /* This is security sensitive code. Do not optimize this for speed. */ + result = known_len - user_len; + for (j = 0; j < user_len; j++) { for (j = 0; j < len; j++) { + result |= known_str[j % mod_len] ^ user_str[j]; result |= known_str[j % known_len] ^ user_str[j % user_len]; + } It's enough for hash functions up to 1024 bits. For SHA-3, we may set larger minimum. Comments, corrections, improvements are appreciated. Regards, -- Yasuo Ohgaki yohgaki@ohgaki.net --001a1136c74246e1fa04f18cc689--