Add two latest security advisories:

Fix NFS server deadlock vulnerability. [SA-14:05]

Fix OpenSSL multiple vulnerabilities. [SA-14:06]
This commit is contained in:
Xin LI 2014-04-08 23:27:31 +00:00
parent 56edf86dc7
commit dd97bfc0fc
Notes: svn2git 2020-12-08 03:00:23 +00:00
svn path=/head/; revision=44494
9 changed files with 859 additions and 0 deletions

View file

@ -0,0 +1,165 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-14:05.nfsserver Security Advisory
The FreeBSD Project
Topic: Deadlock in the NFS server
Category: core
Module: nfsserver
Announced: 2014-04-08
Credits: Rick Macklem
Affects: All supported versions of FreeBSD.
Corrected: 2014-04-08 18:27:39 UTC (stable/10, 10.0-STABLE)
2014-04-08 18:27:46 UTC (releng/10.0, 10.0-RELEASE-p1)
2014-04-08 23:16:19 UTC (stable/9, 9.2-STABLE)
2014-04-08 23:16:05 UTC (releng/9.2, 9.2-RELEASE-p4)
2014-04-08 23:16:05 UTC (releng/9.1, 9.1-RELEASE-p11)
2014-04-08 23:16:19 UTC (stable/8, 8.4-STABLE)
2014-04-08 23:16:05 UTC (releng/8.4, 8.4-RELEASE-p8)
2014-04-08 23:16:05 UTC (releng/8.3, 8.3-RELEASE-p15)
CVE Name: CVE-2014-1453
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:http://security.FreeBSD.org/>.
I. Background
The Network File System (NFS) allows a host to export some or all of its
file systems so that other hosts can access them over the network and mount
them as if they were on local disks. FreeBSD includes both server and client
implementations of NFS.
II. Problem Description
The kernel holds a lock over the source directory vnode while trying to
convert the target directory file handle to a vnode, which needs to be
returned with the lock held, too. This order may be in violation of normal
lock order, which in conjunction with other threads that grab locks in the
right order, constitutes a deadlock condition because no thread can proceed.
III. Impact
An attacker on a trusted client could cause the NFS server become deadlocked,
resulting in a denial of service.
IV. Workaround
Systems that do not provide NFS services are not vulnerable. Neither
are systems that do but use the old NFS implementation, which is the
default in FreeBSD 8.x.
To determine which implementation an NFS server is running, run the
following command:
# kldstat -v | grep -cw nfsd
This will print 1 if the system is running the new NFS implementation,
and 0 otherwise.
To switch to the old NFS implementation:
1) Append the following lines to /etc/rc.conf:
nfsv4_server_enable="no"
oldnfs_server_enable="yes"
2) If the NFS server is compiled into the kernel (which is the case
for the stock GENERIC kernel), replace the NFSD option with the
NFSSERVER option, then recompile your kernel as described in
<URL:http://www.FreeBSD.org/handbook/kernelconfig.html>.
If the NFS server is not compiled into the kernel, the correct
module will be loaded at boot time.
3) Finally, reboot the system.
V. Solution
Perform one of the following:
1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
# fetch http://security.FreeBSD.org/patches/SA-14:05/nfsserver.patch
# fetch http://security.FreeBSD.org/patches/SA-14:05/nfsserver.patch.asc
# gpg --verify nfsserver.patch.asc
b) Apply the patch.
# cd /usr/src
# patch < /path/to/patch
c) Recompile your kernel as described in
<URL:http://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
system.
3) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/8/ r264285
releng/8.3/ r264284
releng/8.4/ r264284
stable/9/ r264285
releng/9.1/ r264284
releng/9.2/ r264284
stable/10/ r264266
releng/10.0/ r264267
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:http://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1453>
The latest revision of this advisory is available at
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-14:05.nfsserver.asc>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAEBCgAGBQJTRISyAAoJEO1n7NZdz2rnOvoQAJoxWjKV1UACccAi4Z/ChESU
rSi2NrW6ZixCmSzbPxAcz9Qv7vaQVSywfG5Zy1JddNh1aVy4ExUsd/FZcRr92Cz2
ujprve/JBMc0YOsND7KIna9Rk7Ryj0IchRXquN5SyDhZbvWwnDNatQWID5awzgYM
aX+48WUFk/oFX009JCR2LO3u3GqOZN6fJhLSQs+Yj+CuxQO9XlQSSUK+lTDO/2ig
snT7j52eCJhsMNn1QcdMGx1Y+NdfIEDfinioAPKLUfWCXWwNRAhTD5scasHDQWV4
60kVXZzl/CNOD7awOXwIrx3GRPQSwsg2YUqGP+jXlEdIA+MNE5+vUijDcLI/cTBj
WSApShrdybIyOyPzczDKmLae9NUeKspUoZTwwwSJ6p8Zr6m0/dBzKbk7TB+XFn17
Q1FVDkpq7pJUzPQxNfB9Z6wwRXeZgaJBEck/P0DvHZwJDq1mZLbcPFap91I4p471
iBVhSHHP466pj0EUuCjNrld7BgVj/iCrCO7LZr4L9t/7sDAIE+CYqv5eR7byUIOO
WoMs3zplSR1XgTk5c9p6XQifv3dtRGyJicfjtKdNFxYjeokIhXxdAjWjQmwC2XoG
PK7enzV2MHWg3nCpdCztD+4ZjHqdwOq/o2g0rVrum7SfOeZXyqr+YB58rpd6uR11
8z8hxDfKCzc/Lo1/T+EO
=xBcd
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,169 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
=============================================================================
FreeBSD-SA-14:06.openssl Security Advisory
The FreeBSD Project
Topic: OpenSSL multiple vulnerabilities
Category: contrib
Module: openssl
Announced: 2014-04-08
Affects: All supported versions of FreeBSD.
Corrected: 2014-04-08 18:27:39 UTC (stable/10, 10.0-STABLE)
2014-04-08 18:27:46 UTC (releng/10.0, 10.0-RELEASE-p1)
2014-04-08 23:16:19 UTC (stable/9, 9.2-STABLE)
2014-04-08 23:16:05 UTC (releng/9.2, 9.2-RELEASE-p4)
2014-04-08 23:16:05 UTC (releng/9.1, 9.1-RELEASE-p11)
2014-04-08 23:16:19 UTC (stable/8, 8.4-STABLE)
2014-04-08 23:16:05 UTC (releng/8.4, 8.4-RELEASE-p8)
2014-04-08 23:16:05 UTC (releng/8.3, 8.3-RELEASE-p15)
CVE Name: CVE-2014-0076, CVE-2014-0160
For general information regarding FreeBSD Security Advisories,
including descriptions of the fields above, security branches, and the
following sections, please visit <URL:http://security.FreeBSD.org/>.
I. Background
FreeBSD includes software from the OpenSSL Project. The OpenSSL Project is
a collaborative effort to develop a robust, commercial-grade, full-featured
Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3)
and Transport Layer Security (TLS v1) protocols as well as a full-strength
general purpose cryptography library.
The Heartbeat Extension provides a new protocol for TLS/DTLS allowing the
usage of keep-alive functionality without performing a renegotiation and a
basis for path MTU (PMTU) discovery for DTLS.
Elliptic Curve Digital Signature Algorithm (ECDSA) is a variant of the
Digital Signature Algorithm (DSA) which uses Elliptic Curve Cryptography.
OpenSSL uses the Montgomery Ladder Approach to compute scalar multiplication
in a fixed amount of time, which does not leak any information through timing
or power.
II. Problem Description
The code used to handle the Heartbeat Extension does not do sufficient boundary
checks on record length, which allows reading beyond the actual payload.
[CVE-2014-0160]. Affects FreeBSD 10.0 only.
A flaw in the implementation of Montgomery Ladder Approach would create a
side-channel that leaks sensitive timing information. [CVE-2014-0076]
III. Impact
An attacker who can send a specifically crafted packet to TLS server or client
with an established connection can reveal up to 64k of memory of the remote
system. Such memory might contain sensitive information, including key
material, protected content, etc. which could be directly useful, or might
be leveraged to obtain elevated privileges. [CVE-2014-0160]
A local attacker might be able to snoop a signing process and might recover
the signing key from it. [CVE-2014-0076]
IV. Workaround
No workaround is available, but systems that do not use OpenSSL to implement
the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1)
protocols implementation and do not use the ECDSA implementation from OpenSSL
are not vulnerable.
V. Solution
Perform one of the following:
1) Upgrade your vulnerable system to a supported FreeBSD stable or
release / security branch (releng) dated after the correction date.
2) To update your vulnerable system via a source code patch:
The following patches have been verified to apply to the applicable
FreeBSD release branches.
a) Download the relevant patch from the location below, and verify the
detached PGP signature using your PGP utility.
[FreeBSD 8.x and FreeBSD 9.x]
# fetch http://security.FreeBSD.org/patches/SA-14:06/openssl.patch
# fetch http://security.FreeBSD.org/patches/SA-14:06/openssl.patch.asc
# gpg --verify openssl.patch.asc
[FreeBSD 10.0]
# fetch http://security.FreeBSD.org/patches/SA-14:06/openssl-10.patch
# fetch http://security.FreeBSD.org/patches/SA-14:06/openssl-10.patch.asc
# gpg --verify openssl-10.patch.asc
Recompile the operating system using buildworld and installworld as
described in <URL:http://www.FreeBSD.org/handbook/makeworld.html>.
Restart all deamons using the library, or reboot the system.
3) To update your vulnerable system via a binary patch:
Systems running a RELEASE version of FreeBSD on the i386 or amd64
platforms can be updated via the freebsd-update(8) utility:
# freebsd-update fetch
# freebsd-update install
IMPORTANT: the update procedure above does not update OpenSSL from the
Ports Collection or from a package, known as security/openssl, which
has to be updated separately via ports or package. Users who have
installed security/openssl should update to at least version 1.0.1_10.
VI. Correction details
The following list contains the correction revision numbers for each
affected branch.
Branch/path Revision
- -------------------------------------------------------------------------
stable/8/ r264285
releng/8.3/ r264284
releng/8.4/ r264284
stable/9/ r264285
releng/9.1/ r264284
releng/9.2/ r264284
stable/10/ r264266
releng/10.0/ r264267
- -------------------------------------------------------------------------
To see which files were modified by a particular revision, run the
following command, replacing NNNNNN with the revision number, on a
machine with Subversion installed:
# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
Or visit the following URL, replacing NNNNNN with the revision number:
<URL:http://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
VII. References
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0076>
<URL:http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0160>
<URL:http://www.openssl.org/news/secadv_20140407.txt>
<URL:http://eprint.iacr.org/2014/140.pdf>
The latest revision of this advisory is available at
<URL:http://security.FreeBSD.org/advisories/FreeBSD-SA-14:06.openssl.asc>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAEBCgAGBQJTRISyAAoJEO1n7NZdz2rnwdgP/RFT6HsugPJZeIKX2Rn36Mat
qgAET7gotiU1Y7G/647BiSCOn/BQs9Z1yTLE7wKdgiVDDTZOHJCJxssXav/+Cqli
G1Cyoi2Rv9R77sno0wdj62YguTg0EKnU52CYpHVmF2NA0H/zexXDrCgiQtyvnU62
ZtM2TO76qhKFXwNtIQ1EQYmu+qsxLbp65ryyu9Tq7rXlc52JYTa0QdWDcKoPtcBO
U85HzJwQglX2lEmipv63s0vwur5eSTtlWSmUSpFzE1jsjYiRl7xFHQKdXxA5Ifw0
qO7LYrYK7b4EyEq9TcQQKvh05IgorjRcA4i0mSQFpc0HINtgv3bYlHyQL+tyN1+k
/4uzdDFB27j8EuKZzEg6aF1JLNq9/zMvx+E0iykPodb5i+n5BzPzWc4rogHvj7rU
mfSeABG3m/SifTewy1258V3TRfTKLNU8EPX2CTnJI9WjYX83GO7sM1vtaGQUOAFK
gff2tFfeSmDpyCmp+RwnmIr5IefIG2y8s/0iJM/wLF3rW8ZrwP1zX+cot5KRCWfT
FpdhHHLRcsCLM7frxmSgRdN+iuXIAcdfbj1EN7z1ryHLk2vRsm2n66kojt4BCnig
7JcStOjMSz843+1L3eCZubHIxVxxjKBGwqVfQ9OWbgeIro0+bapYLJIavuAa9BM6
1T0hWKFh59zAxyGPqX49
=X7Qk
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,70 @@
Index: sys/fs/nfsserver/nfs_nfsdserv.c
===================================================================
--- sys/fs/nfsserver/nfs_nfsdserv.c (revision 264251)
+++ sys/fs/nfsserver/nfs_nfsdserv.c (working copy)
@@ -1457,10 +1457,23 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr
nfsvno_relpathbuf(&fromnd);
goto out;
}
+ /*
+ * Unlock dp in this code section, so it is unlocked before
+ * tdp gets locked. This avoids a potential LOR if tdp is the
+ * parent directory of dp.
+ */
if (nd->nd_flag & ND_NFSV4) {
tdp = todp;
tnes = *toexp;
- tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0);
+ if (dp != tdp) {
+ NFSVOPUNLOCK(dp, 0);
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
+ p, 0); /* Might lock tdp. */
+ } else {
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
+ p, 1);
+ NFSVOPUNLOCK(dp, 0);
+ }
} else {
tfh.nfsrvfh_len = 0;
error = nfsrv_mtofh(nd, &tfh);
@@ -1481,10 +1494,12 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr
tnes = *exp;
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
p, 1);
+ NFSVOPUNLOCK(dp, 0);
} else {
+ NFSVOPUNLOCK(dp, 0);
nd->nd_cred->cr_uid = nd->nd_saveduid;
nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL,
- 0, p);
+ 0, p); /* Locks tdp. */
if (tdp) {
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor,
nd->nd_cred, p, 1);
@@ -1499,7 +1514,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr
if (error) {
if (tdp)
vrele(tdp);
- vput(dp);
+ vrele(dp);
nfsvno_relpathbuf(&fromnd);
nfsvno_relpathbuf(&tond);
goto out;
@@ -1514,7 +1529,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr
}
if (tdp)
vrele(tdp);
- vput(dp);
+ vrele(dp);
nfsvno_relpathbuf(&fromnd);
nfsvno_relpathbuf(&tond);
goto out;
@@ -1523,7 +1538,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgr
/*
* Done parsing, now down to business.
*/
- nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 1, exp, p, &fdirp);
+ nd->nd_repstat = nfsvno_namei(nd, &fromnd, dp, 0, exp, p, &fdirp);
if (nd->nd_repstat) {
if (nd->nd_flag & ND_NFSV3) {
nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret,

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAABCgAGBQJTRISyAAoJEO1n7NZdz2rnpjwP/1IqQ6BYvuyc5s5PZe27pJaX
R5gOEq72RxI1mFEhV+6H0Sfk8YD7KjO74YxF9jsCyqbRJJNF08v1rik4sCBjjyWg
+kk58H5xrGFFXMx1A4xiBwXBZzgnzc2g/18IV3x2+YvjmZFzldSp7HOzOouKNBh0
kRN8gisceYsNdbj0nUkp9ztJbrPID+A2e5GWtu/b9fYCMoD20ng6jO1tOQ8ZQ/MY
v0uEQvZH8Nx05525a1LCxKYb5EfbXSQp2kg7UeUmCJ/2XNf6kFydrR9xeuy4Bf9w
nSd/aVm+3alJEPvogH0RwZyZOXaEG2BibLhs6TzVRpbLYA1KoVgREeFYKbR8swhz
omZJq2wrXctHR+5HejNHbzCfD3i8EvIx5RJuFikX2MqHpFiiBZwAcjwQ8+zv3cGw
n5PpkvmIc5DhCvcAgLdD8yfY/BgYaRSjDkNh/gXMlM14RtT9/8+SAfaVdArHLM4a
Vn+7YEE3BKQQqI77vJNwjlMQoiaX4kYSB+PfQm67I4cO2d2s+KcxYuCuGaIDUKzl
viUE0HjQqDiA7zyfm0efXug6ezmmuEX3+vkTe42kA9BLrBh5EQnW18UR1RCr4rMw
I/bXDLsiPoAyVd+6DJ1RgZK+1TLP6p6SBlE4TUA7IDzartIBWkL/LgWjvXeD+zNc
EvHJWTOgfiFtbaPjrZf2
=ud+9
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,241 @@
Index: crypto/openssl/crypto/bn/bn.h
===================================================================
--- crypto/openssl/crypto/bn/bn.h (revision 264251)
+++ crypto/openssl/crypto/bn/bn.h (working copy)
@@ -538,6 +538,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret,
BIGNUM *BN_mod_sqrt(BIGNUM *ret,
const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
/* Deprecated versions */
#ifndef OPENSSL_NO_DEPRECATED
BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
@@ -774,11 +776,20 @@ int RAND_pseudo_bytes(unsigned char *buf,int num);
#define bn_fix_top(a) bn_check_top(a)
+#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
+#define bn_wcheck_size(bn, words) \
+ do { \
+ const BIGNUM *_bnum2 = (bn); \
+ assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \
+ } while(0)
+
#else /* !BN_DEBUG */
#define bn_pollute(a)
#define bn_check_top(a)
#define bn_fix_top(a) bn_correct_top(a)
+#define bn_check_size(bn, bits)
+#define bn_wcheck_size(bn, words)
#endif
Index: crypto/openssl/crypto/bn/bn_lib.c
===================================================================
--- crypto/openssl/crypto/bn/bn_lib.c (revision 264251)
+++ crypto/openssl/crypto/bn/bn_lib.c (working copy)
@@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_
}
return bn_cmp_words(a,b,cl);
}
+
+/*
+ * Constant-time conditional swap of a and b.
+ * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+ {
+ BN_ULONG t;
+ int i;
+
+ bn_wcheck_size(a, nwords);
+ bn_wcheck_size(b, nwords);
+
+ assert(a != b);
+ assert((condition & (condition - 1)) == 0);
+ assert(sizeof(BN_ULONG) >= sizeof(int));
+
+ condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+ t = (a->top^b->top) & condition;
+ a->top ^= t;
+ b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+ do { \
+ t = (a->d[ind] ^ b->d[ind]) & condition; \
+ a->d[ind] ^= t; \
+ b->d[ind] ^= t; \
+ } while (0)
+
+
+ switch (nwords) {
+ default:
+ for (i = 10; i < nwords; i++)
+ BN_CONSTTIME_SWAP(i);
+ /* Fallthrough */
+ case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
+ case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
+ case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
+ case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
+ case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
+ case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
+ case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
+ case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
+ case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
+ case 1: BN_CONSTTIME_SWAP(0);
+ }
+#undef BN_CONSTTIME_SWAP
+}
Index: crypto/openssl/crypto/ec/ec2_mult.c
===================================================================
--- crypto/openssl/crypto/ec/ec2_mult.c (revision 264251)
+++ crypto/openssl/crypto/ec/ec2_mult.c (working copy)
@@ -208,11 +208,15 @@ static int gf2m_Mxy(const EC_GROUP *group, const B
return ret;
}
+
/* Computes scalar*point and stores the result in r.
* point can not equal r.
- * Uses algorithm 2P of
+ * Uses a modified algorithm 2P of
* Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation" (CHES '99, LNCS 1717).
+ *
+ * To protect against side-channel attack the function uses constant time swap,
+ * avoiding conditional branches.
*/
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
const EC_POINT *point, BN_CTX *ctx)
@@ -246,6 +250,11 @@ static int ec_GF2m_montgomery_point_multiply(const
x2 = &r->X;
z2 = &r->Y;
+ bn_wexpand(x1, group->field.top);
+ bn_wexpand(z1, group->field.top);
+ bn_wexpand(x2, group->field.top);
+ bn_wexpand(z2, group->field.top);
+
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
if (!BN_one(z1)) goto err; /* z1 = 1 */
if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
@@ -270,16 +279,12 @@ static int ec_GF2m_montgomery_point_multiply(const
word = scalar->d[i];
while (mask)
{
- if (word & mask)
- {
- if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
- if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
- }
- else
- {
- if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
- if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
- }
+ BN_consttime_swap(word & mask, x1, x2, group->field.top);
+ BN_consttime_swap(word & mask, z1, z2, group->field.top);
+ if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
+ if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
+ BN_consttime_swap(word & mask, x1, x2, group->field.top);
+ BN_consttime_swap(word & mask, z1, z2, group->field.top);
mask >>= 1;
}
mask = BN_TBIT;
Index: crypto/openssl/ssl/d1_both.c
===================================================================
--- crypto/openssl/ssl/d1_both.c (revision 264251)
+++ crypto/openssl/ssl/d1_both.c (working copy)
@@ -1458,26 +1458,36 @@ dtls1_process_heartbeat(SSL *s)
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
+ &s->s3->rrec.data[0], s->s3->rrec.length,
+ s, s->msg_callback_arg);
+
/* Read type and payload length first */
+ if (1 + 2 + 16 > s->s3->rrec.length)
+ return 0; /* silently discard */
hbtype = *p++;
n2s(p, payload);
+ if (1 + 2 + payload + 16 > s->s3->rrec.length)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;
- if (s->msg_callback)
- s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
- &s->s3->rrec.data[0], s->s3->rrec.length,
- s, s->msg_callback_arg);
-
if (hbtype == TLS1_HB_REQUEST)
{
unsigned char *buffer, *bp;
+ unsigned int write_length = 1 /* heartbeat type */ +
+ 2 /* heartbeat length */ +
+ payload + padding;
int r;
+ if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+ return 0;
+
/* Allocate memory for the response, size is 1 byte
* message type, plus 2 bytes payload length, plus
* payload, plus padding
*/
- buffer = OPENSSL_malloc(1 + 2 + payload + padding);
+ buffer = OPENSSL_malloc(write_length);
bp = buffer;
/* Enter response type, length and copy payload */
@@ -1488,11 +1498,11 @@ dtls1_process_heartbeat(SSL *s)
/* Random padding */
RAND_pseudo_bytes(bp, padding);
- r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, 3 + payload + padding);
+ r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
if (r >= 0 && s->msg_callback)
s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
- buffer, 3 + payload + padding,
+ buffer, write_length,
s, s->msg_callback_arg);
OPENSSL_free(buffer);
Index: crypto/openssl/ssl/t1_lib.c
===================================================================
--- crypto/openssl/ssl/t1_lib.c (revision 264251)
+++ crypto/openssl/ssl/t1_lib.c (working copy)
@@ -2486,16 +2486,20 @@ tls1_process_heartbeat(SSL *s)
unsigned int payload;
unsigned int padding = 16; /* Use minimum padding */
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
+ &s->s3->rrec.data[0], s->s3->rrec.length,
+ s, s->msg_callback_arg);
+
/* Read type and payload length first */
+ if (1 + 2 + 16 > s->s3->rrec.length)
+ return 0; /* silently discard */
hbtype = *p++;
n2s(p, payload);
+ if (1 + 2 + payload + 16 > s->s3->rrec.length)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
pl = p;
- if (s->msg_callback)
- s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
- &s->s3->rrec.data[0], s->s3->rrec.length,
- s, s->msg_callback_arg);
-
if (hbtype == TLS1_HB_REQUEST)
{
unsigned char *buffer, *bp;

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAABCgAGBQJTRISyAAoJEO1n7NZdz2rnH4MQAN2LbMPf1MKwtVJPT9r1qDwh
RXxn23yAPwnGh4Y4YkG+lWl2rq4QK3smKgsYwl45D9TJyK+5xjzRjT34nqmfPaKl
lyQU/LtlxwxsUVrDx/12eaQgRZWcK3NWI65hJGu2kgNRT5g1mSLeTh0EBYDTp0A5
JF2RuL8hVir3JiDKkbQf/lLfkfpKq8P1Y24ha1W0GJameh+dFFmnjv9WPTBiQvBQ
9HV/8RIT88TJtS0PVtKtX2Inr7Xb2Dl4lvHS+graI+zsLKWSCQmG/Lt/cDfcuyKe
CKjnXESlGwD4joNmZLz49G4BtVyDrXJXV3np98mCkt4VA8baRJn/tMerOyIiRA1Z
PruJETeQRxnvdnLetODmgxObkOqdEHk6tYTpTUGSeLQQih3iGSxXuSC9LBx7u2jY
soyB7NT59NbReIhVLCtPn6Ww9xd1HmpYEOd8yfklKOuNdchK1l89RX668lmqblAb
EtOxe9+cDjyrggKFS4OeJTOiciJBlln7YTgpLQbxXQU2DEjGemMD20W06ZVO3ku8
OYH+8IVT+WWslteifp2UhW+Sh43qLy/49ahM2SOpD/Cjuf4p/r1OFgYXIZcW59q0
eroE9cUXWV1lAvaYKR1P5nBO/FWl3uVPSx0aFvmlGACR4nULKlwRLWcKrYz+nftV
KIonztokb/H3JnITL+A8
=kE9T
-----END PGP SIGNATURE-----

View file

@ -0,0 +1,147 @@
Index: crypto/openssl/crypto/bn/bn.h
===================================================================
--- crypto/openssl/crypto/bn/bn.h (revision 264251)
+++ crypto/openssl/crypto/bn/bn.h (working copy)
@@ -511,6 +511,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *ret,
BIGNUM *BN_mod_sqrt(BIGNUM *ret,
const BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords);
+
/* Deprecated versions */
#ifndef OPENSSL_NO_DEPRECATED
BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,
@@ -740,11 +742,20 @@ int RAND_pseudo_bytes(unsigned char *buf,int num);
#define bn_fix_top(a) bn_check_top(a)
+#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2)
+#define bn_wcheck_size(bn, words) \
+ do { \
+ const BIGNUM *_bnum2 = (bn); \
+ assert(words <= (_bnum2)->dmax && words >= (_bnum2)->top); \
+ } while(0)
+
#else /* !BN_DEBUG */
#define bn_pollute(a)
#define bn_check_top(a)
#define bn_fix_top(a) bn_correct_top(a)
+#define bn_check_size(bn, bits)
+#define bn_wcheck_size(bn, words)
#endif
Index: crypto/openssl/crypto/bn/bn_lib.c
===================================================================
--- crypto/openssl/crypto/bn/bn_lib.c (revision 264251)
+++ crypto/openssl/crypto/bn/bn_lib.c (working copy)
@@ -824,3 +824,55 @@ int bn_cmp_part_words(const BN_ULONG *a, const BN_
}
return bn_cmp_words(a,b,cl);
}
+
+/*
+ * Constant-time conditional swap of a and b.
+ * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set.
+ * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b,
+ * and that no more than nwords are used by either a or b.
+ * a and b cannot be the same number
+ */
+void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
+ {
+ BN_ULONG t;
+ int i;
+
+ bn_wcheck_size(a, nwords);
+ bn_wcheck_size(b, nwords);
+
+ assert(a != b);
+ assert((condition & (condition - 1)) == 0);
+ assert(sizeof(BN_ULONG) >= sizeof(int));
+
+ condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
+
+ t = (a->top^b->top) & condition;
+ a->top ^= t;
+ b->top ^= t;
+
+#define BN_CONSTTIME_SWAP(ind) \
+ do { \
+ t = (a->d[ind] ^ b->d[ind]) & condition; \
+ a->d[ind] ^= t; \
+ b->d[ind] ^= t; \
+ } while (0)
+
+
+ switch (nwords) {
+ default:
+ for (i = 10; i < nwords; i++)
+ BN_CONSTTIME_SWAP(i);
+ /* Fallthrough */
+ case 10: BN_CONSTTIME_SWAP(9); /* Fallthrough */
+ case 9: BN_CONSTTIME_SWAP(8); /* Fallthrough */
+ case 8: BN_CONSTTIME_SWAP(7); /* Fallthrough */
+ case 7: BN_CONSTTIME_SWAP(6); /* Fallthrough */
+ case 6: BN_CONSTTIME_SWAP(5); /* Fallthrough */
+ case 5: BN_CONSTTIME_SWAP(4); /* Fallthrough */
+ case 4: BN_CONSTTIME_SWAP(3); /* Fallthrough */
+ case 3: BN_CONSTTIME_SWAP(2); /* Fallthrough */
+ case 2: BN_CONSTTIME_SWAP(1); /* Fallthrough */
+ case 1: BN_CONSTTIME_SWAP(0);
+ }
+#undef BN_CONSTTIME_SWAP
+}
Index: crypto/openssl/crypto/ec/ec2_mult.c
===================================================================
--- crypto/openssl/crypto/ec/ec2_mult.c (revision 264251)
+++ crypto/openssl/crypto/ec/ec2_mult.c (working copy)
@@ -208,9 +208,12 @@ static int gf2m_Mxy(const EC_GROUP *group, const B
/* Computes scalar*point and stores the result in r.
* point can not equal r.
- * Uses algorithm 2P of
+ * Uses a modified algorithm 2P of
* Lopex, J. and Dahab, R. "Fast multiplication on elliptic curves over
* GF(2^m) without precomputation".
+ *
+ * To protect against side-channel attack the function uses constant time
+ * swap avoiding conditional branches.
*/
static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
const EC_POINT *point, BN_CTX *ctx)
@@ -244,6 +247,11 @@ static int ec_GF2m_montgomery_point_multiply(const
x2 = &r->X;
z2 = &r->Y;
+ bn_wexpand(x1, group->field.top);
+ bn_wexpand(z1, group->field.top);
+ bn_wexpand(x2, group->field.top);
+ bn_wexpand(z2, group->field.top);
+
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) goto err; /* x1 = x */
if (!BN_one(z1)) goto err; /* z1 = 1 */
if (!group->meth->field_sqr(group, z2, x1, ctx)) goto err; /* z2 = x1^2 = x^2 */
@@ -266,16 +274,12 @@ static int ec_GF2m_montgomery_point_multiply(const
{
for (; j >= 0; j--)
{
- if (scalar->d[i] & mask)
- {
- if (!gf2m_Madd(group, &point->X, x1, z1, x2, z2, ctx)) goto err;
- if (!gf2m_Mdouble(group, x2, z2, ctx)) goto err;
- }
- else
- {
- if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
- if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
- }
+ BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top);
+ BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top);
+ if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) goto err;
+ if (!gf2m_Mdouble(group, x1, z1, ctx)) goto err;
+ BN_consttime_swap(scalar->d[i] & mask, x1, x2, group->field.top);
+ BN_consttime_swap(scalar->d[i] & mask, z1, z2, group->field.top);
mask >>= 1;
}
j = BN_BITS2 - 1;

View file

@ -0,0 +1,17 @@
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (FreeBSD)
iQIcBAABCgAGBQJTRISyAAoJEO1n7NZdz2rnhZIP/0Y8pnBr0lwVcN9qvtZUmFNn
Xg74WoB4CcpHKfDMSct2Rcn++Ezx3BferOQ0TLQdLhoIoZQiQIvtiXL87Xie9Abg
jD1enNYn1tw5jb5rwbRrTamo/Sfwgnsnasy/mg+ZJSGRvTmcsQXVousUvEe68IHM
zO0AcM6QsS4YU5agwS+0ICCkfQFY29JlizJ/uABXq5gasiTdslm8g18kcUB8VIp6
G7TL0hhqDnh2C1K49YSQVtkDZkSfWJfjthl0tv/hpL7X6JPhUFDChFGCrJAdB0fm
sDAzOd+4fPBbtjhwhibZz8LnzfsDQ8jeU+hnoO+lVqJ8U61OZgWv7zyWV2EVfjlt
hmhBadR8RjIPM8uZ4C3TTjcJt0uhrr6lEJ0omvt/TIloS7tFbub24/oMN3Vw6DxY
qLh6G6tZ1B5nRMqnqboQWJKOhdXiyd2ZnVjUDx/gyLLBRbXpQakUKyrDJoMelMEv
qKBf2SKm1yMWSwLrNQ526HEvaDmgPH2YDnQOG+MgNVn4w+A3zXapXtZiu7TV4z3z
rpiQU6QHrv+g41Jkh0TZJUavoWHxM7mpt9otmEg4uC7KlfVe0mrpu+OCTr+1nlSR
g0AubXbvRW5YaLoGGZpOw80YoRa3GybMdhB1tXDV2Bv5+yNczS+DmlN4WKaG2rvc
NJtlEfF4UvAMSv6AI9V/
=FeFQ
-----END PGP SIGNATURE-----

View file

@ -7,6 +7,22 @@
<year>
<name>2014</name>
<month>
<name>4</name>
<day>
<name>08</name>
<advisory>
<name>FreeBSD-SA-14:06.openssl</name>
</advisory>
<advisory>
<name>FreeBSD-SA-14:05.nfsserver</name>
</advisory>
</day>
</month>
<month>
<name>1</name>