From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Eli Zaretskii Newsgroups: gmane.emacs.bugs Subject: bug#22202: 24.5; SECURITY ISSUE -- Emacs Server vulnerable to random number generator attack on Windows systems Date: Wed, 30 Dec 2015 17:58:14 +0200 Message-ID: <83mvssc4ix.fsf@gnu.org> References: <83lh8ddy45.fsf@gnu.org> <8760zh81oo.fsf@isaac.fritz.box> Reply-To: Eli Zaretskii NNTP-Posting-Host: plane.gmane.org X-Trace: ger.gmane.org 1451491105 20182 80.91.229.3 (30 Dec 2015 15:58:25 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 30 Dec 2015 15:58:25 +0000 (UTC) Cc: 22202@debbugs.gnu.org, demetriobenour@gmail.com, deng@randomsample.de To: Richard Copley Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Dec 30 16:58:11 2015 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1aEJ8c-000178-F3 for geb-bug-gnu-emacs@m.gmane.org; Wed, 30 Dec 2015 16:58:10 +0100 Original-Received: from localhost ([::1]:52875 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aEJ8c-0002Gd-30 for geb-bug-gnu-emacs@m.gmane.org; Wed, 30 Dec 2015 10:58:10 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:57583) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aEJ8Y-0002FR-9T for bug-gnu-emacs@gnu.org; Wed, 30 Dec 2015 10:58:07 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aEJ8U-000433-Sw for bug-gnu-emacs@gnu.org; Wed, 30 Dec 2015 10:58:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:42937) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aEJ8U-00042x-QA for bug-gnu-emacs@gnu.org; Wed, 30 Dec 2015 10:58:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84) (envelope-from ) id 1aEJ8U-00067z-KP for bug-gnu-emacs@gnu.org; Wed, 30 Dec 2015 10:58:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Eli Zaretskii Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 30 Dec 2015 15:58:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 22202 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: security Original-Received: via spool by 22202-submit@debbugs.gnu.org id=B22202.145149105223491 (code B ref 22202); Wed, 30 Dec 2015 15:58:02 +0000 Original-Received: (at 22202) by debbugs.gnu.org; 30 Dec 2015 15:57:32 +0000 Original-Received: from localhost ([127.0.0.1]:50535 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84) (envelope-from ) id 1aEJ7z-00066o-Vx for submit@debbugs.gnu.org; Wed, 30 Dec 2015 10:57:32 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:38127) by debbugs.gnu.org with esmtp (Exim 4.84) (envelope-from ) id 1aEJ7y-00066d-SW for 22202@debbugs.gnu.org; Wed, 30 Dec 2015 10:57:31 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aEJ7s-0003vX-Ci for 22202@debbugs.gnu.org; Wed, 30 Dec 2015 10:57:25 -0500 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:54915) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aEJ7o-0003vF-Fk; Wed, 30 Dec 2015 10:57:20 -0500 Original-Received: from 84.94.185.246.cable.012.net.il ([84.94.185.246]:1122 helo=HOME-C4E4A596F7) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.82) (envelope-from ) id 1aEJ7n-0007CV-ML; Wed, 30 Dec 2015 10:57:20 -0500 In-reply-to: (message from Richard Copley on Tue, 29 Dec 2015 21:22:55 +0000) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:111025 Archived-At: > Date: Tue, 29 Dec 2015 21:22:55 +0000 > From: Richard Copley > Cc: Eli Zaretskii , 22202@debbugs.gnu.org, > Demetri Obenour > > I haven't reproduced the whole attack scenario and I don't pretend > know whether it could work. I don't claim any expertise in software > security. I just wanted to help out by answering Eli's questions. > > To get back to the OP's main point, given that we already go to the > trouble of creating this secret, it wouldn't hurt to do it better (on all > systems, for preference). On Windows it really doesn't seem hard. > Sorry, no patch, for legal reasons, but there's a simple example on > the MSDN page for CryptGenRandom. Can you audit the patch below? I know next to nothing about cryptography, and I'm not sure I understood all the flags involved in these APIs. Also, generating random numbers with these APIs is significantly slower -- about 2.5 msec per number, as opposed to something like 175 microsec using 'rand'. Should we perhaps provide an option (by default off) to force using the old, weaker, but faster method? Thanks. --- src/w32.c~0 2015-11-29 06:48:07.000000000 +0200 +++ src/w32.c 2015-12-30 17:48:19.297251800 +0200 @@ -224,6 +224,8 @@ typedef struct _REPARSE_DATA_BUFFER { #include /* should be after winsock2.h */ +#include + #include #include "w32.h" @@ -2093,9 +2095,34 @@ init_user_info (void) CloseHandle (token); } +static HCRYPTPROV w32_crypto_hprov; +static int +w32_init_crypt_random (void) +{ + if (!CryptAcquireContext (&w32_crypto_hprov, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + DebPrint (("CryptAcquireContext failed with error %x\n", + GetLastError ())); + return -1; + } + return 0; +} + int random (void) { + if (w32_crypto_hprov) + w32_init_crypt_random (); + if (w32_crypto_hprov) + { + const DWORD nbytes = 4; /* see RAND_BITS in sysdep.c */ + BYTE rand_buffer[nbytes]; + + if (CryptGenRandom (w32_crypto_hprov, nbytes, rand_buffer)) + return *(int *)&rand_buffer[0]; + } + /* Else fall back on rand () */ /* rand () on NT gives us 15 random bits...hack together 30 bits. */ return ((rand () << 15) | rand ()); } @@ -2103,6 +2130,18 @@ random (void) void srandom (int seed) { + if (!w32_crypto_hprov) + w32_init_crypt_random (); + if (w32_crypto_hprov) + { + const DWORD nbytes = 4; /* see RAND_BITS in sysdep.c */ + BYTE buf[nbytes]; + + memcpy (buf, &seed, sizeof buf); + CryptGenRandom (w32_crypto_hprov, nbytes, buf); + } + /* Always seed rand () as well, in case some future call to + CryptGenRandom fails and we need to fall back to rand () */ srand (seed); } @@ -9386,6 +9425,8 @@ globals_of_w32 (void) extern void dynlib_reset_last_error (void); dynlib_reset_last_error (); #endif + + w32_crypto_hprov = (HCRYPTPROV)0; } /* For make-serial-process */