Bug 1258375, NSS_3_24_BETA6 and required adjustments to PSM and packaging, r=martin.thomson, r=glandium

This commit is contained in:
Kai Engert 2016-04-12 14:40:44 +02:00
parent 3ce084784c
commit 70551ded71
224 changed files with 10783 additions and 71010 deletions

View File

@ -813,7 +813,11 @@
@BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
#endif
@BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
#if defined(XP_LINUX) && !defined(ANDROID)
@BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@
#else
@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
#endif
#ifndef CROSS_COMPILE
@BINPATH@/@DLL_PREFIX@freebl3.chk
@BINPATH@/@DLL_PREFIX@softokn3.chk

View File

@ -753,7 +753,11 @@
; meaning their .chk files are created there directly.
;
#ifndef MOZ_SYSTEM_NSS
#if defined(XP_LINUX) && !defined(ANDROID)
@BINPATH@/@DLL_PREFIX@freeblpriv3@DLL_SUFFIX@
#else
@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
#endif
@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
#ifndef NSS_DISABLE_DBM

View File

@ -68,9 +68,18 @@ endif
endif
endif
ifeq ($(OS_TARGET),Linux)
HAVE_FREEBL_LIBS =
HAVE_FREEBL_LIBS_PRIV = 1
FREEBL_LOWHASH_FLAG = FREEBL_LOWHASH=1
endif
ifdef HAVE_FREEBL_LIBS
NSS_EXTRA_DLLS += freebl3
endif
ifdef HAVE_FREEBL_LIBS_PRIV
NSS_EXTRA_DLLS += freeblpriv3
endif
ifdef HAVE_FREEBL_LIBS_32INT32
NSS_EXTRA_DLLS += freebl_32int_3
endif
@ -229,10 +238,7 @@ DEFAULT_GMAKE_FLAGS += \
$(NULL)
endif
DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=0
ifeq ($(OS_TARGET),Linux)
DEFAULT_GMAKE_FLAGS += FREEBL_LOWHASH=1
endif
DEFAULT_GMAKE_FLAGS += FREEBL_NO_DEPEND=0 $(FREEBL_LOWHASH_FLAG)
ifdef MOZ_NO_WLZDEFS
DEFAULT_GMAKE_FLAGS += ZDEFS_FLAG=

View File

@ -452,12 +452,14 @@ PORT_ArenaStrdup_Util
PORT_ArenaUnmark_Util
PORT_ArenaZAlloc
PORT_ArenaZAlloc_Util
PORT_DestroyCheapArena
PORT_Free
PORT_FreeArena
PORT_FreeArena_Util
PORT_Free_Util
PORT_GetError
PORT_GetError_Util
PORT_InitCheapArena
PORT_NewArena
PORT_NewArena_Util
PORT_Realloc_Util

View File

@ -83,7 +83,16 @@ ifdef USE_STATIC_RTL
NSPR_CONFIGURE_OPTS += --enable-static-rtl
endif
ifdef NS_USE_GCC
NSPR_COMPILERS = CC=gcc CXX=g++
NSPR_CONFIGURE_ENV = CC=gcc CXX=g++
endif
ifdef SANITIZER_CFLAGS
ifdef BUILD_OPT
NSPR_CONFIGURE_OPTS += --enable-debug-symbols
endif
NSPR_CONFIGURE_ENV += CFLAGS='$(SANITIZER_CFLAGS)' \
CXXFLAGS='$(SANITIZER_CFLAGS)' \
LDFLAGS='$(SANITIZER_LDFLAGS)'
endif
#
@ -110,7 +119,7 @@ endif
$(NSPR_CONFIG_STATUS): $(NSPR_CONFIGURE)
mkdir -p $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME)
cd $(CORE_DEPTH)/../nspr/$(OBJDIR_NAME) ; \
$(NSPR_COMPILERS) sh ../configure \
$(NSPR_CONFIGURE_ENV) sh ../configure \
$(NSPR_CONFIGURE_OPTS) \
--with-dist-prefix='$(NSPR_PREFIX)' \
--with-dist-includedir='$(NSPR_PREFIX)/include'

View File

@ -1 +1 @@
NSS_3_23_RTM
NSS_3_24_BETA6

View File

@ -288,14 +288,19 @@ prepare()
mv ${OUTPUTDIR} ${OUTPUTDIR}.last >/dev/null 2>&1
mkdir -p ${OUTPUTDIR}
cd ${HGDIR}/nss
if [ -z "${NSS_DISABLE_ECC}" -a -n "${NSS_ECC_MORE_THAN_SUITE_B}" ]; then
cd ${HGDIR}/nss
ECF="lib/freebl/ecl/ecl-curve.h"
print_log "hg revert -r NSS_3_11_1_RTM ${ECF}"
hg revert -r NSS_3_11_1_RTM security/nss/${ECF}
cp -f security/nss/${ECF} ${ECF}
fi
if [ -n "${FEWER_STRESS_ITERATIONS}" ]; then
sed -i 's/-c_1000_/-c_500_/g' tests/ssl/sslstress.txt
fi
return 0
}

View File

@ -5,9 +5,9 @@ checkout:
test:
override:
- make nss_build_all
- cd tests; NSS_TESTS="ssl_gtests pk11_gtests der_gtests" NSS_CYCLES=standard ./all.sh
- cd tests; NSS_TESTS="ssl_gtests pk11_gtests der_gtests util_gtests" NSS_CYCLES=standard ./all.sh
- BUILD_OPT=1 make nss_build_all
- cd tests; BUILD_OPT=1 NSS_TESTS="ssl_gtests pk11_gtests der_gtests" NSS_CYCLES=standard ./all.sh
- cd tests; BUILD_OPT=1 NSS_TESTS="ssl_gtests pk11_gtests der_gtests util_gtests" NSS_CYCLES=standard ./all.sh
machine:
environment:

View File

@ -3749,7 +3749,7 @@ int main(int argc, char **argv)
/* Do FIPS self-test */
if (bltest.commands[cmd_FIPS].activated) {
CK_RV ckrv = sftk_fipsPowerUpSelfTest();
CK_RV ckrv = sftk_FIPSEntryOK();
fprintf(stdout, "CK_RV: %ld.\n", ckrv);
PORT_Free(cipherInfo);
if (ckrv == CKR_OK)

View File

@ -441,7 +441,6 @@ outputCertOrExtension(CERTCertificate *the_cert, PRBool raw, PRBool ascii,
SECU_PrintSystemError(progName, "error writing extension");
rv = SECFailure;
}
rv = SECSuccess;
break;
}
}

View File

@ -1,8 +1,9 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#
# A Bourne shell script for running the NIST AES Algorithm Validation Suite
#
@ -12,6 +13,12 @@
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/AES
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
cbc_kat_requests="
CBCGFSbox128.req
CBCGFSbox192.req
@ -66,33 +73,40 @@ ECBMMT192.req
ECBMMT256.req
"
for request in $ecb_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes kat ecb $request > $response
done
for request in $ecb_mmt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mmt ecb $request > $response
done
for request in $ecb_mct_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mct ecb $request > $response
done
if [ ${COMMAND} = "verify" ]; then
for request in $cbc_kat_requests $cbc_mct_requests $cbc_mmt_requests $ecb_kat_requests $ecb_mct_requests $ecb_mmt_requests; do
sh ./validate1.sh ${TESTDIR} $request
done
exit 0
fi
for request in $cbc_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes kat cbc $request > $response
done
for request in $cbc_mmt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mmt cbc $request > $response
fipstest aes kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $cbc_mct_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mct cbc $request > $response
fipstest aes mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $cbc_mmt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $ecb_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $ecb_mct_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $ecb_mmt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -0,0 +1,67 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST AES Algorithm Validation Suite
#
# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
# variables appropriately so that the fipstest command and the NSPR and NSS
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/AES_GCM
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
gcm_decrypt_requests="
gcmDecrypt128.req
gcmDecrypt192.req
gcmDecrypt256.req
"
gcm_encrypt_extiv_requests="
gcmEncryptExtIV128.req
gcmEncryptExtIV192.req
gcmEncryptExtIV256.req
"
gcm_encrypt_intiv_requests="
"
#gcm_encrypt_intiv_requests="
#gcmEncryptIntIV128.req
#gcmEncryptIntIV192.req
#gcmEncryptIntIV256.req
#"
if [ ${COMMAND} = "verify" ]; then
for request in $gcm_decrypt_requests $gcm_encrypt_extiv_requests; do
sh ./validate1.sh ${TESTDIR} $request ' ' '-e /Reason:/d'
done
for request in $gcm_encrypt_intiv_requests; do
name=`basename $request .req`
echo ">>>>> $name"
fipstest aes gcm decrypt ${RSPDIR}/$name.rsp | grep FAIL
done
exit 0
fi
for request in $gcm_decrypt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes gcm decrypt ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $gcm_encrypt_intiv_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes gcm encrypt_intiv ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $gcm_encrypt_extiv_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest aes gcm encrypt_extiv ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST DSA Validation System
#
@ -11,28 +11,61 @@
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/DSA2
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
#
# several of the DSA tests do use known answer tests to verify the result.
# in those cases, feed generated tests back into the fipstest tool and
# see if we can verify those value. NOTE: th PQGVer and SigVer tests verify
# the dsa pqgver and dsa sigver functions, so we know they can detect errors
# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
#
if [ ${COMMAND} = "verify" ]; then
# verify generated keys
name=KeyPair
echo ">>>>> $name"
fipstest dsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
# verify generated pqg values
name=PQGGen
echo ">>>>> $name"
fipstest dsa pqgver ${RSPDIR}/$name.rsp | grep ^Result.=.F
# verify PQGVer with known answer
# sh ./validate1.sh ${TESTDIR} PQGVer.req ' ' '-e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
# verify signatures
name=SigGen
echo ">>>>> $name"
fipstest dsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
# verify SigVer with known answer
sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);;'
exit 0
fi
request=KeyPair.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa keypair $request > $response
fipstest dsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
request=PQGGen.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa pqggen $request > $response
fipstest dsa pqggen ${REQDIR}/$request > ${RSPDIR}/$response
request=PQGVer.req
request=PQGVer1863.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa pqgver $request > $response
fipstest dsa pqgver ${REQDIR}/$request > ${RSPDIR}/$response
request=SigGen.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa siggen $request > $response
fipstest dsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
request=SigVer.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest dsa sigver $request > $response
fipstest dsa sigver ${REQDIR}/$request > ${RSPDIR}/$response

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST ECDSA Validation System
#
@ -11,23 +11,50 @@
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/ECDSA2
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
#
# several of the ECDSA tests do not use known answer tests to verify the result.
# In those cases, feed generated tests back into the fipstest tool and
# see if we can verify those value. NOTE: PQGVer and SigVer tests verify
# the dsa pqgver and dsa sigver functions, so we know they can detect errors
# in those PQGGen and SigGen. Only the KeyPair verify is potentially circular.
#
if [ ${COMMAND} = "verify" ]; then
# verify generated keys
name=KeyPair
echo ">>>>> $name"
fipstest ecdsa keyver ${RSPDIR}/$name.rsp | grep ^Result.=.F
sh ./validate1.sh ${TESTDIR} PKV.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
# verify signatures
name=SigGen
echo ">>>>> $name"
fipstest ecdsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
# verify SigVer with known answer
sh ./validate1.sh ${TESTDIR} SigVer.req ' ' '-e /^X.=/d -e /^Result.=.F/s;.(.*);; -e /^Result.=.P/s;.(.*);;'
exit 0
fi
request=KeyPair.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest ecdsa keypair $request > $response
fipstest ecdsa keypair ${REQDIR}/$request > ${RSPDIR}/$response
request=PKV.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest ecdsa pkv $request > $response
fipstest ecdsa pkv ${REQDIR}/$request > ${RSPDIR}/$response
request=SigGen.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest ecdsa siggen $request > $response
fipstest ecdsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
request=SigVer.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest ecdsa sigver $request > $response
fipstest ecdsa sigver ${REQDIR}/$request > ${RSPDIR}/$response

View File

@ -3368,6 +3368,24 @@ drbg(char *reqfn)
}
}
loser:
if (predictedreturn_bytes) {
PORT_Free(predictedreturn_bytes);
}
if (return_bytes) {
PORT_Free(return_bytes);
}
if (additionalInput) {
PORT_Free(additionalInput);
}
if (personalizationString) {
PORT_Free(personalizationString);
}
if (nonce) {
PORT_Free(nonce);
}
if (entropyInput) {
PORT_Free(entropyInput);
}
fclose(rngreq);
}
@ -5132,7 +5150,7 @@ rsa_keypair_test(char *reqfn)
FILE *rsaresp; /* output stream to the RESPONSE file */
int count;
int i;
int keySize; /* key size in bits*/
int keySize = 1; /* key size in bits*/
int len = 0; /* key size in bytes */
int len2 = 0; /* key size in bytes/2 (prime size) */
SECItem e;

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST HMAC Algorithm Validation Suite
#
@ -11,14 +11,26 @@
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/HMAC
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
hmac_requests="
HMAC.req
"
if [ ${COMMAND} = "verify" ]; then
for request in $hmac_requests; do
sh ./validate1.sh ${TESTDIR} $request
done
exit 0
fi
for request in $hmac_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest hmac $request > $response
fipstest hmac ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST RNG Validation Suite
#
@ -11,13 +11,24 @@
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/DRBG800-90A
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
drbg_requests="
SHA256_DRBG.req
Hash_DRBG.req
"
if [ ${COMMAND} = "verify" ]; then
for request in $drbg_requests; do
sh ./validate1.sh ${TESTDIR} $request
done
exit 0
fi
for request in $drbg_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest drbg $request > $response
fipstest drbg ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST RSA Validation System
#
@ -11,14 +11,40 @@
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/RSA2
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
if [ ${COMMAND} = "verify" ]; then
#verify the signatures. The fax file does not have any known answers, so
#use our own verify function.
name=SigGen15_186-3
echo ">>>>> $name"
fipstest rsa sigver ${RSPDIR}/$name.rsp | grep ^Result.=.F
# fipstest rsa sigver ${REQDIR}/SigVer15_186-3.req | grep ^Result.=.F
#The Fax file has the private exponent and the salt value, remove it
#also remove the false reason
sh ./validate1.sh ${TESTDIR} SigVer15_186-3.req ' ' '-e /^SaltVal/d -e/^d.=/d -e /^p.=/d -e /^q.=/d -e /^EM.with/d -e /^Result.=.F/s;.(.*);;'
#
# currently don't have a way to verify the RSA keygen
#
exit 0
fi
request=SigGen15.req
request=SigGen15_186-3.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest rsa siggen $request > $response
fipstest rsa siggen ${REQDIR}/$request > ${RSPDIR}/$response
request=SigVer15.req
request=SigVer15_186-3.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest rsa sigver $request > $response
fipstest rsa sigver ${REQDIR}/$request > ${RSPDIR}/$response
#request=KeyGen_186-3.req
request=KeyGen_RandomProbablyPrime3_3.req
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest rsa keypair ${REQDIR}/$request > ${RSPDIR}/$response

View File

@ -0,0 +1,17 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
TESTDIR=${1-.}
COMMAND=${2-run}
TESTS="aes aesgcm dsa ecdsa hmac tls rng rsa sha tdea"
if [ ${NSS_ENABLE_ECC}x = 1x ]; then
TESTS=${TESTS} ecdsa
fi
for i in $TESTS
do
echo "********************Running $i tests"
sh ./${i}.sh ${TESTDIR} ${COMMAND}
done

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST SHA Algorithm Validation Suite
#
@ -11,9 +11,15 @@
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/SHA
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
sha_ShortMsg_requests="
SHA1ShortMsg.req
SHA224ShortMsg.req
SHA256ShortMsg.req
SHA384ShortMsg.req
SHA512ShortMsg.req
@ -21,6 +27,7 @@ SHA512ShortMsg.req
sha_LongMsg_requests="
SHA1LongMsg.req
SHA224LongMsg.req
SHA256LongMsg.req
SHA384LongMsg.req
SHA512LongMsg.req
@ -28,23 +35,32 @@ SHA512LongMsg.req
sha_Monte_requests="
SHA1Monte.req
SHA224Monte.req
SHA256Monte.req
SHA384Monte.req
SHA512Monte.req
"
if [ ${COMMAND} = "verify" ]; then
for request in $sha_ShortMsg_requests $sha_LongMsg_requests $sha_Monte_requests; do
sh ./validate1.sh ${TESTDIR} $request
done
exit 0
fi
for request in $sha_ShortMsg_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest sha $request > $response
fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $sha_LongMsg_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest sha $request > $response
fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $sha_Monte_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest sha $request > $response
fipstest sha ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -1,8 +1,8 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST tdea Algorithm Validation Suite
#
@ -12,6 +12,12 @@
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/TDES
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
#CBC_Known_Answer_tests
#Initial Permutation KAT
#Permutation Operation KAT
@ -59,33 +65,42 @@ TECBMMT2.req
TECBMMT3.req
"
for request in $ecb_mmt_requests; do
if [ ${COMMAND} = "verify" ]; then
for request in $cbc_kat_requests $cbc_monte_requests $cbc_mmt_requests $ecb_kat_requests $ecb_monte_requests $ecb_mmt_requests
do
sh ./validate1.sh ${TESTDIR} $request "-e /^NumKeys/d"
done
exit 0
fi
for request in $cbc_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea mmt ecb $request > $response
done
for request in $ecb_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea kat ecb $request > $response
done
for request in $ecb_monte_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea mct ecb $request > $response
fipstest tdea kat cbc ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $cbc_mmt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea mmt cbc $request > $response
done
for request in $cbc_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea kat cbc $request > $response
fipstest tdea mmt cbc ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $cbc_monte_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea mct cbc $request > $response
fipstest tdea mct cbc ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $ecb_kat_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea kat ecb ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $ecb_mmt_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea mmt ecb ${REQDIR}/$request > ${RSPDIR}/$response
done
for request in $ecb_monte_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tdea mct ecb ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -0,0 +1,34 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# A Bourne shell script for running the NIST RNG Validation Suite
#
# Before you run the script, set your PATH, LD_LIBRARY_PATH, ... environment
# variables appropriately so that the fipstest command and the NSPR and NSS
# shared libraries/DLLs are on the search path. Then run this script in the
# directory where the REQUEST (.req) files reside. The script generates the
# RESPONSE (.rsp) files in the same directory.
BASEDIR=${1-.}
TESTDIR=${BASEDIR}/KDF135
COMMAND=${2-run}
REQDIR=${TESTDIR}/req
RSPDIR=${TESTDIR}/resp
drbg_requests="
tls.req
"
if [ ${COMMAND} = "verify" ]; then
for request in $drbg_requests; do
sh ./validate1.sh ${TESTDIR} $request
done
exit 0
fi
for request in $drbg_requests; do
response=`echo $request | sed -e "s/req/rsp/"`
echo $request $response
fipstest tls ${REQDIR}/$request > ${RSPDIR}/$response
done

View File

@ -1,6 +1,7 @@
#
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
pk11test.c: pk11test.h pkcs11.h
#
sh ./runtest.sh ${1-.} verify

View File

@ -0,0 +1,30 @@
#!/bin/sh
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# Validate1.sh is a helper shell script that each of the base test shell
# scripts call to help validate that the generated response (response)
# matches the known answer response (fax). Sometimes (depending on the
# individual tests) there are extraneous output in either or both response
# and fax files. These allow the caller to pass in additional sed commands
# to clear out those extraneous outputs before we compare the two files.
# The sed line always clears out Windows line endings, replaces tabs with
# spaces, and removed comments.
#
TESTDIR=${1-.}
request=${2}
extraneous_response=${3}
extraneous_fax=${4}
name=`basename $request .req`
echo ">>>>> $name"
sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_response ${TESTDIR}/resp/${name}.rsp > /tmp/y1
# if we didn't generate any output, flag that as an error
size=`sum /tmp/y1 | awk '{ print $NF }'`
if [ $size -eq 0 ]; then
echo "${TESTDIR}/resp/${name}.rsp: empty"
exit 1;
fi
sed -e 's; ;;g' -e 's; ; ;g' -e '/^#/d' $extraneous_fax ${TESTDIR}/fax/${name}.fax > /tmp/y2
diff -i -w -B /tmp/y1 /tmp/y2

View File

@ -3697,10 +3697,6 @@ SECU_GetSSLVersionFromName(const char *buf, size_t bufLen, PRUint16 *version)
return SECFailure;
}
if (!PL_strncasecmp(buf, "ssl2", bufLen)) {
*version = SSL_LIBRARY_VERSION_2;
return SECSuccess;
}
if (!PL_strncasecmp(buf, "ssl3", bufLen)) {
*version = SSL_LIBRARY_VERSION_3_0;
return SECSuccess;
@ -3730,21 +3726,26 @@ SECU_GetSSLVersionFromName(const char *buf, size_t bufLen, PRUint16 *version)
SECStatus
SECU_ParseSSLVersionRangeString(const char *input,
const SSLVersionRange defaultVersionRange,
const PRBool defaultEnableSSL2,
SSLVersionRange *vrange, PRBool *enableSSL2)
SSLVersionRange *vrange)
{
const char *colonPos;
size_t colonIndex;
const char *maxStr;
if (!input || !vrange || !enableSSL2) {
if (!input || !vrange) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
// We don't support SSL2 any longer.
if (defaultVersionRange.min < SSL_LIBRARY_VERSION_3_0 ||
defaultVersionRange.max < SSL_LIBRARY_VERSION_3_0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (!strcmp(input, ":")) {
/* special value, use default */
*enableSSL2 = defaultEnableSSL2;
*vrange = defaultVersionRange;
return SECSuccess;
}
@ -3760,7 +3761,6 @@ SECU_ParseSSLVersionRangeString(const char *input,
if (!colonIndex) {
/* colon was first character, min version is empty */
*enableSSL2 = defaultEnableSSL2;
vrange->min = defaultVersionRange.min;
} else {
PRUint16 version;
@ -3770,13 +3770,7 @@ SECU_ParseSSLVersionRangeString(const char *input,
return SECFailure;
}
if (version == SSL_LIBRARY_VERSION_2) {
*enableSSL2 = PR_TRUE;
vrange->min = defaultVersionRange.min;
} else {
*enableSSL2 = PR_FALSE;
vrange->min = version;
}
vrange->min = version;
}
if (!*maxStr) {
@ -3790,18 +3784,12 @@ SECU_ParseSSLVersionRangeString(const char *input,
return SECFailure;
}
if (version == SSL_LIBRARY_VERSION_2) {
/* consistency checking, require that min allows enableSSL2, too */
if (!*enableSSL2) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* we use 0 because SSL_LIBRARY_VERSION_NONE is private: */
vrange->min = 0;
vrange->max = 0;
} else {
vrange->max = version;
}
vrange->max = version;
}
if (vrange->min > vrange->max) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
return SECSuccess;

View File

@ -398,21 +398,15 @@ SECU_SECItemHexStringToBinary(SECItem* srcdest);
* and all implemented versions greater than or equal to min will be enabled.
* A string consisting of a colon only means "all versions enabled".
*
* Because output parameter type SSLVersionRange doesn't allow to set
* version 2 values, we use a separate boolean output parameter
* to return whether SSL 2 is enabled.
*
* In order to avoid a link dependency from libsectool to libssl,
* the caller must provide the desired default values for the min/max values,
* by providing defaultEnableSSL2 and defaultVersionRange
* (which can be obtained from libssl by calling SSL_VersionRangeGetSupported).
* by providing defaultVersionRange (which can be obtained from libssl by
* calling SSL_VersionRangeGetSupported).
*/
SECStatus
SECU_ParseSSLVersionRangeString(const char *input,
const SSLVersionRange defaultVersionRange,
const PRBool defaultEnableSSL2,
SSLVersionRange *vrange,
PRBool *enableSSL2);
SSLVersionRange *vrange);
/*
*

View File

@ -54,8 +54,7 @@ int main(int argc, char **argv)
info.keaTypeName, info.authAlgorithmName, info.symCipherName,
info.effectiveKeyBits, info.macAlgorithmName,
enabled ? "Enabled" : "Disabled",
info.isFIPS ? "FIPS" :
(SSL_IS_SSL2_CIPHER(info.cipherSuite) ? "SSL2" : ""),
info.isFIPS ? "FIPS" : "",
info.isExportable ? "Export" : "Domestic",
info.nonStandard ? "nonStandard" : "");
}

View File

@ -243,7 +243,7 @@ struct Pk11Install_Info_str {
Pk11Install_Info*
Pk11Install_Info_new();
void
Pk11Install_Info_init();
Pk11Install_Info_init(Pk11Install_Info* _this);
void
Pk11Install_Info_delete(Pk11Install_Info* _this);
/*// Returns NULL for success, error message if parse error.*/

View File

@ -77,7 +77,7 @@ ExportPublicKey(FILE *outFile, CERTCertificate *cert)
if (!cert)
return -1;
publicKey = CERT_ExtractPublicKey(cert);
if (!publicKey)
return -1;
@ -86,17 +86,17 @@ ExportPublicKey(FILE *outFile, CERTCertificate *cert)
SECKEY_DestroyPublicKey(publicKey);
if (!item)
return -1;
data = PL_Base64Encode((const char*)item->data, item->len, NULL);
SECITEM_FreeItem(item, PR_TRUE);
if (!data)
return -1;
fputs("pubkey:\n", outFile);
fputs(data, outFile);
fputs("\n", outFile);
PR_Free(data);
return 0;
}
@ -105,66 +105,86 @@ SignFile(FILE *outFile, PRFileDesc *inFile, CERTCertificate *cert)
{
SECItem data2sign;
SECStatus rv;
char *data;
SECKEYPrivateKey *privKey;
SECOidTag algID;
PLArenaPool *arena;
CERTSignedData sd;
SECItem *result;
SECKEYPrivateKey *privKey = NULL;
char *data = NULL;
PLArenaPool *arena = NULL;
SECItem *result = NULL;
int returnValue = 0;
if (outFile == NULL || inFile == NULL || cert == NULL)
if (outFile == NULL || inFile == NULL || cert == NULL) {
return -1;
}
/* suck the file in */
if (SECU_ReadDERFromFile(&data2sign, inFile, PR_FALSE,
PR_FALSE) != SECSuccess)
PR_FALSE) != SECSuccess) {
return -1;
}
privKey = NULL;
privKey = NULL;
privKey = PK11_FindKeyByAnyCert(cert, NULL);
if (!privKey) {
returnValue = -1;
goto loser;
}
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, SEC_OID_SHA1);
if (algID == SEC_OID_UNKNOWN)
return -1;
if (algID == SEC_OID_UNKNOWN) {
returnValue = -1;
goto loser;
}
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
rv = SEC_SignData(&(sd.signature), data2sign.data, data2sign.len, privKey, algID);
if (rv != SECSuccess) {
fprintf (stderr, "Could not sign.\n");
return -1;
returnValue = -1;
goto loser;
}
sd.signature.len = sd.signature.len << 3;
rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0);
if (rv != SECSuccess) {
fprintf (stderr, "Could not set alg id.\n");
return -1;
returnValue = -1;
goto loser;
}
result = SEC_ASN1EncodeItem(arena, NULL, &sd, CERTSignatureDataTemplate);
SECITEM_FreeItem(&(sd.signature), PR_FALSE);
if (!result) {
fprintf (stderr, "Could not encode.\n");
return -1;
returnValue = -1;
goto loser;
}
data = PL_Base64Encode((const char*)result->data, result->len, NULL);
if (!data)
return -1;
if (!data){
returnValue = -1;
goto loser;
}
fputs("signature:\n", outFile);
fputs(data, outFile);
fputs("\n", outFile);
ExportPublicKey(outFile, cert);
SECKEY_DestroyPrivateKey(privKey);
loser:
if (privKey) {
SECKEY_DestroyPrivateKey(privKey);
}
if (data) {
PORT_Free(data);
}
PORT_FreeArena(arena, PR_FALSE);
return 0;
return returnValue;
}
int

View File

@ -94,16 +94,6 @@ typedef enum ocspStaplingModeEnum ocspStaplingModeType;
static char *ocspStaplingCA = NULL;
static SECItemArray *certStatus[kt_kea_size] = { NULL };
const int ssl2CipherSuites[] = {
SSL_EN_RC4_128_WITH_MD5, /* A */
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
0
};
const int ssl3CipherSuites[] = {
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
@ -178,7 +168,7 @@ PrintParameterUsage()
fputs(
"-V [min]:[max] restricts the set of enabled SSL/TLS protocol versions.\n"
" All versions are enabled by default.\n"
" Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
" Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
" Example: \"-V ssl3:\" enables SSL 3 and newer.\n"
"-B bypasses the PKCS11 layer for SSL encryption and MACing\n"
"-q checks for bypassability\n"
@ -242,13 +232,6 @@ PrintCipherUsage(const char *progName)
PrintUsageHeader(progName);
fputs(
"-c ciphers Letter(s) chosen from the following list\n"
"A SSL2 RC4 128 WITH MD5\n"
"B SSL2 RC4 128 EXPORT40 WITH MD5\n"
"C SSL2 RC2 128 CBC WITH MD5\n"
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
"\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
@ -828,7 +811,6 @@ logger(void *arg)
PRBool useModelSocket = PR_FALSE;
static SSLVersionRange enabledVersions;
PRBool enableSSL2 = PR_TRUE;
PRBool disableRollBack = PR_FALSE;
PRBool NoReuse = PR_FALSE;
PRBool hasSidCache = PR_FALSE;
@ -1865,8 +1847,7 @@ server_main(
}
/* do SSL configuration. */
rv = SSL_OptionSet(model_sock, SSL_SECURITY,
enableSSL2 || enabledVersions.min != 0);
rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0);
if (rv < 0) {
errExit("SSL_OptionSet SSL_SECURITY");
}
@ -1876,11 +1857,6 @@ server_main(
errExit("error setting SSL/TLS version range ");
}
rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, enableSSL2);
if (rv != SECSuccess) {
errExit("error enabling SSLv2 ");
}
rv = SSL_OptionSet(model_sock, SSL_ROLLBACK_DETECTION, !disableRollBack);
if (rv != SECSuccess) {
errExit("error enabling RollBack detection ");
@ -2282,8 +2258,7 @@ main(int argc, char **argv)
case 'U': configureReuseECDHE = (PORT_Atoi(optstate->value) != 0); break;
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
enabledVersions, enableSSL2,
&enabledVersions, &enableSSL2) != SECSuccess) {
enabledVersions, &enabledVersions) != SECSuccess) {
Usage(progName);
}
break;
@ -2544,7 +2519,7 @@ main(int argc, char **argv)
}
}
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
/* all SSL3 cipher suites are enabled by default. */
if (cipherString) {
char *cstringSaved = cipherString;
int ndx;
@ -2553,12 +2528,11 @@ main(int argc, char **argv)
disableAllSSLCiphers();
while (0 != (ndx = *cipherString++)) {
int cipher;
int cipher = 0;
if (ndx == ':') {
int ctmp;
cipher = 0;
HEXCHAR_TO_INT(*cipherString, ctmp)
cipher |= (ctmp << 12);
cipherString++;
@ -2572,16 +2546,15 @@ main(int argc, char **argv)
cipher |= ctmp;
cipherString++;
} else {
const int *cptr;
if (! isalpha(ndx)) {
fprintf(stderr,
"Non-alphabetic char in cipher string (-c arg).\n");
exit(9);
}
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
ndx = tolower(ndx) - 'a';
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
cipher = ssl3CipherSuites[ndx];
}
}
if (cipher > 0) {
SECStatus status;

View File

@ -46,16 +46,6 @@
* cipher selection code.
*/
int ssl2CipherSuites[] = {
SSL_EN_RC4_128_WITH_MD5, /* A */
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
0
};
int ssl3CipherSuites[] = {
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA * b */
@ -122,7 +112,6 @@ static SSL3Statistics * ssl3stats;
static int failed_already = 0;
static SSLVersionRange enabledVersions;
static PRBool enableSSL2 = PR_TRUE;
static PRBool bypassPKCS11 = PR_FALSE;
static PRBool disableLocking = PR_FALSE;
static PRBool ignoreErrors = PR_FALSE;
@ -163,7 +152,7 @@ Usage(const char *progName)
" -P means do a specified percentage of full handshakes (0-100)\n"
" -V [min]:[max] restricts the set of enabled SSL/TLS protocols versions.\n"
" All versions are enabled by default.\n"
" Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
" Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
" Example: \"-V ssl3:\" enables SSL 3 and newer.\n"
" -U means enable throttling up threads\n"
" -B bypasses the PKCS11 layer for SSL encryption and MACing\n"
@ -338,7 +327,7 @@ printSecurityInfo(PRFileDesc *fd)
#define MAX_THREADS 128
typedef int startFn(void *a, void *b, int c);
typedef SECStatus startFn(void *a, void *b, int c);
static PRInt32 numConnected;
@ -558,7 +547,7 @@ lockedVars_AddToCount(lockedVars * lv, int addend)
return rv;
}
int
SECStatus
do_writes(
void * a,
void * b,
@ -719,7 +708,7 @@ myHandshakeCallback(PRFileDesc *socket, void *arg)
/* one copy of this function is launched in a separate thread for each
** connection to be made.
*/
int
SECStatus
do_connects(
void * a,
void * b,
@ -731,7 +720,7 @@ do_connects(
PRFileDesc * tcp_sock = 0;
PRStatus prStatus;
PRUint32 sleepInterval = 50; /* milliseconds */
int rv = SECSuccess;
SECStatus rv = SECSuccess;
PRSocketOptionData opt;
retry:
@ -795,7 +784,6 @@ retry:
goto retry;
}
errWarn("PR_Connect");
rv = SECFailure;
goto done;
} else {
if (ThrottleUp) {
@ -866,7 +854,7 @@ done:
} else if (tcp_sock) {
PR_Close(tcp_sock);
}
return SECSuccess;
return rv;
}
@ -1097,7 +1085,7 @@ client_main(
/* all suites except RSA_NULL_MD5 are enabled by Domestic Policy */
NSS_SetDomesticPolicy();
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
/* all SSL3 cipher suites are enabled by default. */
if (cipherString) {
int ndx;
@ -1125,11 +1113,10 @@ client_main(
}
} else {
if (isalpha(ndx)) {
const int *cptr;
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
ndx = tolower(ndx) - 'a';
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
cipher = ssl3CipherSuites[ndx];
}
}
if (cipher <= 0) {
fprintf(stderr, "strsclnt: Invalid cipher letter: %c\n",
@ -1163,8 +1150,7 @@ client_main(
/* do SSL configuration. */
rv = SSL_OptionSet(model_sock, SSL_SECURITY,
enableSSL2 || enabledVersions.min != 0);
rv = SSL_OptionSet(model_sock, SSL_SECURITY, enabledVersions.min != 0);
if (rv < 0) {
errExit("SSL_OptionSet SSL_SECURITY");
}
@ -1174,16 +1160,6 @@ client_main(
errExit("error setting SSL/TLS version range ");
}
rv = SSL_OptionSet(model_sock, SSL_ENABLE_SSL2, enableSSL2);
if (rv != SECSuccess) {
errExit("error enabling SSLv2 ");
}
rv = SSL_OptionSet(model_sock, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
if (rv != SECSuccess) {
errExit("error enabling SSLv2 compatible hellos ");
}
if (bigBuf.data) { /* doing FDX */
rv = SSL_OptionSet(model_sock, SSL_ENABLE_FDX, 1);
if (rv < 0) {
@ -1262,7 +1238,7 @@ client_main(
if (!NoReuse) {
remaining_connections = 1;
rv = launch_thread(do_connects, &addr, model_sock, 0);
launch_thread(do_connects, &addr, model_sock, 0);
/* wait for the first connection to terminate, then launch the rest. */
reap_threads();
remaining_connections = total_connections - 1 ;
@ -1271,7 +1247,7 @@ client_main(
active_threads = PR_MIN(active_threads, remaining_connections);
/* Start up the threads */
for (i=0;i<active_threads;i++) {
rv = launch_thread(do_connects, &addr, model_sock, i);
launch_thread(do_connects, &addr, model_sock, i);
}
reap_threads();
}
@ -1368,8 +1344,7 @@ main(int argc, char **argv)
case 'U': ThrottleUp = PR_TRUE; break;
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
enabledVersions, enableSSL2,
&enabledVersions, &enableSSL2) != SECSuccess) {
enabledVersions, &enabledVersions) != SECSuccess) {
Usage(progName);
}
break;
@ -1510,22 +1485,13 @@ main(int argc, char **argv)
PL_strfree(hostName);
/* some final stats. */
if (ssl3stats->hsh_sid_cache_hits +
ssl3stats->hsh_sid_cache_misses +
ssl3stats->hsh_sid_cache_not_ok +
ssl3stats->hsh_sid_stateless_resumes == 0) {
/* presumably we were testing SSL2. */
printf("strsclnt: SSL2 - %d server certificates tested.\n",
certsTested);
} else {
printf(
"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
" %ld stateless resumes\n",
ssl3stats->hsh_sid_cache_hits,
ssl3stats->hsh_sid_cache_misses,
ssl3stats->hsh_sid_cache_not_ok,
ssl3stats->hsh_sid_stateless_resumes);
}
printf(
"strsclnt: %ld cache hits; %ld cache misses, %ld cache not reusable\n"
" %ld stateless resumes\n",
ssl3stats->hsh_sid_cache_hits,
ssl3stats->hsh_sid_cache_misses,
ssl3stats->hsh_sid_cache_not_ok,
ssl3stats->hsh_sid_stateless_resumes);
if (!NoReuse) {
if (enableSessionTickets)
@ -1539,16 +1505,9 @@ main(int argc, char **argv)
} else {
printf("strsclnt: NoReuse - %d server certificates tested.\n",
certsTested);
if (ssl3stats->hsh_sid_cache_hits +
ssl3stats->hsh_sid_cache_misses +
ssl3stats->hsh_sid_cache_not_ok +
ssl3stats->hsh_sid_stateless_resumes > 0) {
exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
(ssl3stats->hsh_sid_stateless_resumes != 0) ||
(certsTested != connections);
} else { /* ssl2 connections */
exitVal = (certsTested != connections);
}
exitVal = (ssl3stats->hsh_sid_cache_misses != connections) ||
(ssl3stats->hsh_sid_stateless_resumes != 0) ||
(certsTested != connections);
}
exitVal = ( exitVal || failed_already );

View File

@ -56,16 +56,6 @@
PRIntervalTime maxInterval = PR_INTERVAL_NO_TIMEOUT;
int ssl2CipherSuites[] = {
SSL_EN_RC4_128_WITH_MD5, /* A */
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
0
};
int ssl3CipherSuites[] = {
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
@ -219,14 +209,14 @@ static void PrintParameterUsage(void)
fprintf(stderr,
"%-20s Restricts the set of enabled SSL/TLS protocols versions.\n"
"%-20s All versions are enabled by default.\n"
"%-20s Possible values for min/max: ssl2 ssl3 tls1.0 tls1.1 tls1.2\n"
"%-20s Possible values for min/max: ssl3 tls1.0 tls1.1 tls1.2\n"
"%-20s Example: \"-V ssl3:\" enables SSL 3 and newer.\n",
"-V [min]:[max]", "", "", "");
fprintf(stderr, "%-20s Send TLS_FALLBACK_SCSV\n", "-K");
fprintf(stderr, "%-20s Prints only payload data. Skips HTTP header.\n", "-S");
fprintf(stderr, "%-20s Client speaks first. \n", "-f");
fprintf(stderr, "%-20s Use synchronous certificate validation "
"(required for SSL2)\n", "-O");
"(currently required for TLS 1.3)\n", "-O");
fprintf(stderr, "%-20s Override bad server cert. Make it OK.\n", "-o");
fprintf(stderr, "%-20s Disable SSL socket locking.\n", "-s");
fprintf(stderr, "%-20s Verbose progress reporting.\n", "-v");
@ -273,13 +263,6 @@ static void PrintCipherUsage(const char *progName)
fprintf(stderr, "%-20s Letter(s) chosen from the following list\n",
"-c ciphers");
fprintf(stderr,
"A SSL2 RC4 128 WITH MD5\n"
"B SSL2 RC4 128 EXPORT40 WITH MD5\n"
"C SSL2 RC2 128 CBC WITH MD5\n"
"D SSL2 RC2 128 CBC EXPORT40 WITH MD5\n"
"E SSL2 DES 64 CBC WITH MD5\n"
"F SSL2 DES 192 EDE3 CBC WITH MD5\n"
"\n"
"c SSL3 RSA WITH RC4 128 MD5\n"
"d SSL3 RSA WITH 3DES EDE CBC SHA\n"
"e SSL3 RSA WITH DES CBC SHA\n"
@ -920,7 +903,6 @@ int main(int argc, char **argv)
int npds;
int override = 0;
SSLVersionRange enabledVersions;
PRBool enableSSL2 = PR_TRUE;
int bypassPKCS11 = 0;
int disableLocking = 0;
int useExportPolicy = 0;
@ -1035,8 +1017,7 @@ int main(int argc, char **argv)
case 'U': enableSignedCertTimestamps = 1; break;
case 'V': if (SECU_ParseSSLVersionRangeString(optstate->value,
enabledVersions, enableSSL2,
&enabledVersions, &enableSSL2) != SECSuccess) {
enabledVersions, &enabledVersions) != SECSuccess) {
Usage(progName);
}
break;
@ -1250,7 +1231,7 @@ int main(int argc, char **argv)
else
NSS_SetDomesticPolicy();
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
/* all SSL3 cipher suites are enabled by default. */
if (cipherString) {
/* disable all the ciphers, then enable the ones we want. */
disableAllSSLCiphers();
@ -1289,18 +1270,17 @@ int main(int argc, char **argv)
return 1;
}
/* all the SSL2 and SSL3 cipher suites are enabled by default. */
/* all SSL3 cipher suites are enabled by default. */
if (cipherString) {
char *cstringSaved = cipherString;
int ndx;
while (0 != (ndx = *cipherString++)) {
int cipher;
int cipher = 0;
if (ndx == ':') {
int ctmp = 0;
cipher = 0;
HEXCHAR_TO_INT(*cipherString, ctmp)
cipher |= (ctmp << 12);
cipherString++;
@ -1314,13 +1294,12 @@ int main(int argc, char **argv)
cipher |= ctmp;
cipherString++;
} else {
const int *cptr;
if (! isalpha(ndx))
Usage(progName);
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
ndx = tolower(ndx) - 'a';
if (ndx < PR_ARRAY_SIZE(ssl3CipherSuites)) {
cipher = ssl3CipherSuites[ndx];
}
}
if (cipher > 0) {
SECStatus status;
@ -1340,18 +1319,6 @@ int main(int argc, char **argv)
return 1;
}
rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, enableSSL2);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling SSLv2 ");
return 1;
}
rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, enableSSL2);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling SSLv2 compatible hellos ");
return 1;
}
/* enable PKCS11 bypass */
rv = SSL_OptionSet(s, SSL_BYPASS_PKCS11, bypassPKCS11);
if (rv != SECSuccess) {
@ -1613,6 +1580,12 @@ int main(int argc, char **argv)
"%s: about to call PR_Poll on writable socket !\n",
progName);
cc = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
if (cc < 0) {
SECU_PrintError(progName,
"PR_Poll failed");
error = 1;
goto done;
}
FPRINTF(stderr,
"%s: PR_Poll returned with writable socket !\n",
progName);

View File

@ -41,8 +41,8 @@
#define RD_BUF_SIZE (60 * 1024)
extern int ssl2CipherSuites[];
extern int ssl3CipherSuites[];
extern int numSSL3CipherSuites;
GlobalThreadMgr threadMGR;
char *certNickname = NULL;
@ -507,12 +507,11 @@ main(int argc, char **argv)
disableAllSSLCiphers();
while (0 != (ndx = *cipherString++)) {
int cipher;
int cipher = 0;
if (ndx == ':') {
int ctmp = 0;
cipher = 0;
HEXCHAR_TO_INT(*cipherString, ctmp)
cipher |= (ctmp << 12);
cipherString++;
@ -526,12 +525,12 @@ main(int argc, char **argv)
cipher |= ctmp;
cipherString++;
} else {
const int *cptr;
if (! isalpha(ndx))
Usage(progName);
cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;
for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; )
/* do nothing */;
ndx = tolower(ndx) - 'a';
if (ndx < numSSL3CipherSuites) {
cipher = ssl3CipherSuites[ndx];
}
}
if (cipher > 0) {
SSL_CipherPrefSetDefault(cipher, PR_TRUE);

View File

@ -38,7 +38,6 @@
/* Declare SSL cipher suites. */
extern int cipherSuites[];
extern int ssl2CipherSuites[];
extern int ssl3CipherSuites[];
/* Data buffer read from a socket. */

View File

@ -14,16 +14,6 @@ extern void dumpCertChain(CERTCertificate *, SECCertUsage);
/* Declare SSL cipher suites. */
int ssl2CipherSuites[] = {
SSL_EN_RC4_128_WITH_MD5, /* A */
SSL_EN_RC4_128_EXPORT40_WITH_MD5, /* B */
SSL_EN_RC2_128_CBC_WITH_MD5, /* C */
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, /* D */
SSL_EN_DES_64_CBC_WITH_MD5, /* E */
SSL_EN_DES_192_EDE3_CBC_WITH_MD5, /* F */
0
};
int ssl3CipherSuites[] = {
-1, /* SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA* a */
-1, /* SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, * b */
@ -53,6 +43,7 @@ int ssl3CipherSuites[] = {
TLS_RSA_WITH_NULL_SHA, /* z */
0
};
int numSSL3CipherSuites = PR_ARRAY_SIZE(ssl3CipherSuites);
/**************************************************************************
**

View File

@ -21,10 +21,12 @@ endif
ifeq (,$(filter-out i%86,$(CPU_ARCH)))
ifdef USE_64
CC += -arch x86_64
CCC += -arch x86_64
override CPU_ARCH = x86_64
else
OS_REL_CFLAGS = -Di386
CC += -arch i386
CCC += -arch i386
override CPU_ARCH = x86
endif
else
@ -33,6 +35,7 @@ ifeq (arm,$(CPU_ARCH))
else
OS_REL_CFLAGS = -Dppc
CC += -arch ppc
CCC += -arch ppc
endif
endif
@ -136,3 +139,6 @@ ifeq (3,$(SYS_SQLITE3_VERSION_MAJOR))
NSS_USE_SYSTEM_SQLITE = 1
endif
endif
include $(CORE_DEPTH)/coreconf/sanitizers.mk
DARWIN_SDK_SHLIBFLAGS += $(SANITIZER_LDFLAGS)

View File

@ -21,7 +21,7 @@ ifeq ($(CPU_ARCH),amd64)
CPU_ARCH = x86_64
endif
OS_CFLAGS = $(DSO_CFLAGS) -ansi -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK
OS_CFLAGS = $(DSO_CFLAGS) -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK
DSO_CFLAGS = -fPIC
DSO_LDOPTS = -shared -Wl,-soname -Wl,$(notdir $@)

View File

@ -153,8 +153,12 @@ DSO_LDOPTS = -shared $(ARCHFLAG) -Wl,--gc-sections
# The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8)
# incorrectly reports undefined references in the libraries we link with, so
# we don't use -z defs there.
# Also, -z defs conflicts with Address Sanitizer, which emits relocations
# against the libsanitizer runtime built into the main executable.
ZDEFS_FLAG = -Wl,-z,defs
ifneq ($(USE_ASAN),1)
DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG))
endif
LDFLAGS += $(ARCHFLAG)
# On Maemo, we need to use the -rpath-link flag for even the standard system
@ -210,3 +214,5 @@ PROCESS_MAP_FILE = grep -v ';-' $< | \
ifeq ($(OS_RELEASE),2.4)
DEFINES += -DNO_FORK_CHECK
endif
include $(CORE_DEPTH)/coreconf/sanitizers.mk

View File

@ -26,7 +26,7 @@ else
DLL_SUFFIX = so.1.0
endif
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -Wno-switch -pipe -DNETBSD -Dunix -DHAVE_STRERROR -DHAVE_BSD_FLOCK
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -pipe -DNETBSD -Dunix -DHAVE_STRERROR -DHAVE_BSD_FLOCK
OS_LIBS = -lcompat

View File

@ -26,7 +26,7 @@ endif
DLL_SUFFIX = so.1.0
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -Wno-switch -pipe -DOPENBSD
OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -pipe -DOPENBSD
OS_LIBS =

View File

@ -5,6 +5,19 @@
# This sets WARNING_CFLAGS for gcc-like compilers.
ifndef CC_IS_CLANG
CC_IS_CLANG := $(and $(findstring clang, $(shell $(CC) --version 2>&1)), 1)
# Export CC_IS_CLANG to save a shell invocation when recursing.
export CC_IS_CLANG
endif
ifdef CC_IS_CLANG
# Clang claims GCC 4.2.1 compatibility, see GCC_VERSION
CC_IS_GCC = 1
# Export CC_IS_GCC to save a shell invocation when recursing.
export CC_IS_GCC
endif
ifndef CC_IS_GCC
CC_IS_GCC := $(shell $(CC) -x c -E -Wall -Werror /dev/null >/dev/null 2>&1 && echo 1)
# Export CC_IS_GCC to save a shell invocation when recursing.
@ -38,7 +51,7 @@ ifndef WARNING_CFLAGS
disable_warning = $(shell $(CC) -x c -E -Werror -W$(1) /dev/null >/dev/null 2>&1 && echo -Wno-$(1))
WARNING_CFLAGS = -Wall
ifeq ($(CC_NAME),clang)
ifdef CC_IS_CLANG
# -Qunused-arguments : clang objects to arguments that it doesn't understand
# and fixing this would require rearchitecture
WARNING_CFLAGS += -Qunused-arguments
@ -62,10 +75,10 @@ ifndef WARNING_CFLAGS
NSS_ENABLE_WERROR = 0
$(warning OS_TARGET is Android, disabling -Werror)
else
ifeq ($(CC_NAME),clang)
ifdef CC_IS_CLANG
# Clang reports its version as an older gcc, but it's OK
NSS_ENABLE_WERROR = 1
else ifeq ($(CC_NAME),gcc)
else
ifneq (,$(filter 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
NSS_ENABLE_WERROR = 1
endif

View File

@ -13,6 +13,7 @@
# OS_TARGET User defined, or set to OS_ARCH
# CPU_ARCH (from unmame -m or -p, ONLY on WINNT)
# OS_CONFIG OS_TARGET + OS_RELEASE
# ASAN_TAG
# OBJDIR_TAG
# OBJDIR_NAME
#######################################################################
@ -256,18 +257,28 @@ endif
OS_CONFIG = $(OS_TARGET)$(OS_RELEASE)
#
# Set Address Sanitizer prefix.
#
ifeq ($(USE_ASAN), 1)
ASAN_TAG = _ASAN
else
ASAN_TAG =
endif
#
# OBJDIR_TAG depends on the predefined variable BUILD_OPT,
# to distinguish between debug and release builds.
#
ifdef BUILD_OPT
OBJDIR_TAG = $(64BIT_TAG)_OPT
OBJDIR_TAG = $(64BIT_TAG)$(ASAN_TAG)_OPT
else
ifdef BUILD_IDG
OBJDIR_TAG = $(64BIT_TAG)_IDG
OBJDIR_TAG = $(64BIT_TAG)$(ASAN_TAG)_IDG
else
OBJDIR_TAG = $(64BIT_TAG)_DBG
OBJDIR_TAG = $(64BIT_TAG)$(ASAN_TAG)_DBG
endif
endif

View File

@ -174,6 +174,17 @@ ifdef NSS_PKIX_NO_LDAP
DEFINES += -DNSS_PKIX_NO_LDAP
endif
# FIPS support requires startup tests to be executed at load time of shared modules.
# For performance reasons, these tests are disabled by default.
# When compiling binaries that must support FIPS mode,
# you should define NSS_FORCE_FIPS
#
# NSS_NO_INIT_SUPPORT is always defined on platforms that don't support
# executing the startup tests at library load time.
ifndef NSS_FORCE_FIPS
DEFINES += -DNSS_NO_INIT_SUPPORT
endif
# Avoid building object leak test code for optimized library
ifndef BUILD_OPT
ifdef PKIX_OBJECT_LEAK_TEST

View File

@ -10,4 +10,3 @@
*/
#error "Do not include this header file."

View File

@ -0,0 +1,19 @@
# Address Sanitizer support; include this in OS-specific .mk files
# *after* defining the variables that are appended to here.
ifeq ($(USE_ASAN), 1)
SANITIZER_FLAGS_COMMON = -fsanitize=address $(EXTRA_SANITIZER_FLAGS)
SANITIZER_CFLAGS = $(SANITIZER_FLAGS_COMMON)
SANITIZER_LDFLAGS = $(SANITIZER_FLAGS_COMMON)
OS_CFLAGS += $(SANITIZER_CFLAGS)
LDFLAGS += $(SANITIZER_LDFLAGS)
# ASan needs frame pointers to save stack traces for allocation/free sites.
# (Warning: some platforms, like ARM Linux in Thumb mode, don't have useful
# frame pointers even with this option.)
SANITIZER_CFLAGS += -fno-omit-frame-pointer
# You probably want to be able to get debug info for failures, even with an
# optimized build.
OPTIMIZER += -g
endif

View File

@ -8,6 +8,7 @@ DEPTH = ..
DIRS = \
google_test \
der_gtest \
util_gtest \
pk11_gtest \
ssl_gtest \
$(NULL)

View File

@ -7,6 +7,7 @@
/* This file contains functions for frobbing the internals of libssl */
#include "libssl_internals.h"
#include "nss.h"
#include "seccomon.h"
#include "ssl.h"
#include "sslimpl.h"
@ -14,8 +15,7 @@
SECStatus
SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd)
{
sslSocket *ss = (sslSocket *)fd->secret;
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure;
}
@ -45,3 +45,85 @@ SSLInt_DetermineKEABits(PRUint16 serverKeyBits, SSLAuthType authAlgorithm) {
return PR_MAX(SSL_RSASTRENGTH_TO_ECSTRENGTH(serverKeyBits), minKeaBits);
}
/* Use this function to update the ClientRandom of a client's handshake state
* after replacing its ClientHello message. We for example need to do this
* when replacing an SSLv3 ClientHello with its SSLv2 equivalent. */
SECStatus
SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd, uint8_t *rnd, size_t rnd_len,
uint8_t *msg, size_t msg_len)
{
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure;
}
SECStatus rv = ssl3_InitState(ss);
if (rv != SECSuccess) {
return rv;
}
rv = ssl3_RestartHandshakeHashes(ss);
if (rv != SECSuccess) {
return rv;
}
// Zero the client_random struct.
PORT_Memset(&ss->ssl3.hs.client_random, 0, SSL3_RANDOM_LENGTH);
// Copy over the challenge bytes.
size_t offset = SSL3_RANDOM_LENGTH - rnd_len;
PORT_Memcpy(&ss->ssl3.hs.client_random.rand[offset], rnd, rnd_len);
// Rehash the SSLv2 client hello message.
return ssl3_UpdateHandshakeHashes(ss, msg, msg_len);
}
PRBool
SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext)
{
sslSocket *ss = ssl_FindSocket(fd);
return (PRBool)(ss && ssl3_ExtensionNegotiated(ss, ext));
}
void
SSLInt_ClearSessionTicketKey()
{
ssl3_SessionTicketShutdown(NULL, NULL);
NSS_UnregisterShutdown(ssl3_SessionTicketShutdown, NULL);
}
PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd)
{
PRCList *cur_p;
PRInt32 ct = 0;
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return -1;
}
for (cur_p = PR_NEXT_LINK(&ss->ssl3.hs.cipherSpecs);
cur_p != &ss->ssl3.hs.cipherSpecs;
cur_p = PR_NEXT_LINK(cur_p)) {
++ct;
}
return ct;
}
/* Force a timer expiry by backdating when the timer was started.
* We could set the remaining time to 0 but then backoff would not
* work properly if we decide to test it. */
void SSLInt_ForceTimerExpiry(PRFileDesc *fd)
{
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return;
}
if (!ss->ssl3.hs.rtTimerCb)
return;
ss->ssl3.hs.rtTimerStarted = PR_IntervalNow() -
PR_MillisecondsToInterval(ss->ssl3.hs.rtTimeoutMs + 1);
}

View File

@ -7,6 +7,8 @@
#ifndef libssl_internals_h_
#define libssl_internals_h_
#include <stdint.h>
#include "prio.h"
#include "seccomon.h"
#include "sslt.h"
@ -16,6 +18,15 @@ SECStatus SSLInt_IncrementClientHandshakeVersion(PRFileDesc *fd);
PRUint32 SSLInt_DetermineKEABits(PRUint16 serverKeyBits,
SSLAuthType authAlgorithm);
SECStatus SSLInt_UpdateSSLv2ClientRandom(PRFileDesc *fd,
uint8_t *rnd, size_t rnd_len,
uint8_t *msg, size_t msg_len);
PRBool SSLInt_ExtensionNegotiated(PRFileDesc *fd, PRUint16 ext);
void SSLInt_ClearSessionTicketKey();
PRInt32 SSLInt_CountTls13CipherSpecs(PRFileDesc *fd);
void SSLInt_ForceTimerExpiry(PRFileDesc *fd);
#endif

View File

@ -12,6 +12,7 @@ CSRCS = \
$(NULL)
CPPSRCS = \
ssl_v2_client_hello_unittest.cc \
ssl_agent_unittest.cc \
ssl_loopback_unittest.cc \
ssl_extension_unittest.cc \

View File

@ -15,138 +15,6 @@
namespace nss_test {
class TlsExtensionFilter : public TlsHandshakeFilter {
protected:
virtual PacketFilter::Action FilterHandshake(
const HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
if (header.handshake_type() == kTlsHandshakeClientHello) {
TlsParser parser(input);
if (!FindClientHelloExtensions(&parser, header)) {
return KEEP;
}
return FilterExtensions(&parser, input, output);
}
if (header.handshake_type() == kTlsHandshakeServerHello) {
TlsParser parser(input);
if (!FindServerHelloExtensions(&parser, header.version())) {
return KEEP;
}
return FilterExtensions(&parser, input, output);
}
return KEEP;
}
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer& input,
DataBuffer* output) = 0;
public:
static bool FindClientHelloExtensions(TlsParser* parser, const Versioned& header) {
if (!parser->Skip(2 + 32)) { // version + random
return false;
}
if (!parser->SkipVariable(1)) { // session ID
return false;
}
if (header.is_dtls() && !parser->SkipVariable(1)) { // DTLS cookie
return false;
}
if (!parser->SkipVariable(2)) { // cipher suites
return false;
}
if (!parser->SkipVariable(1)) { // compression methods
return false;
}
return true;
}
static bool FindServerHelloExtensions(TlsParser* parser, uint16_t version) {
if (!parser->Skip(2 + 32)) { // version + random
return false;
}
if (!parser->SkipVariable(1)) { // session ID
return false;
}
if (!parser->Skip(2)) { // cipher suite
return false;
}
if (NormalizeTlsVersion(version) <= SSL_LIBRARY_VERSION_TLS_1_2) {
if (!parser->Skip(1)) { // compression method
return false;
}
}
return true;
}
private:
PacketFilter::Action FilterExtensions(TlsParser* parser,
const DataBuffer& input,
DataBuffer* output) {
size_t length_offset = parser->consumed();
uint32_t all_extensions;
if (!parser->Read(&all_extensions, 2)) {
return KEEP; // no extensions, odd but OK
}
if (all_extensions != parser->remaining()) {
return KEEP; // malformed
}
bool changed = false;
// Write out the start of the message.
output->Allocate(input.len());
size_t offset = output->Write(0, input.data(), parser->consumed());
while (parser->remaining()) {
uint32_t extension_type;
if (!parser->Read(&extension_type, 2)) {
return KEEP; // malformed
}
DataBuffer extension;
if (!parser->ReadVariable(&extension, 2)) {
return KEEP; // malformed
}
DataBuffer filtered;
PacketFilter::Action action = FilterExtension(extension_type, extension,
&filtered);
if (action == DROP) {
changed = true;
std::cerr << "extension drop: " << extension << std::endl;
continue;
}
const DataBuffer* source = &extension;
if (action == CHANGE) {
EXPECT_GT(0x10000U, filtered.len());
changed = true;
std::cerr << "extension old: " << extension << std::endl;
std::cerr << "extension new: " << filtered << std::endl;
source = &filtered;
}
// Write out extension.
offset = output->Write(offset, extension_type, 2);
offset = output->Write(offset, source->len(), 2);
offset = output->Write(offset, *source);
}
output->Truncate(offset);
if (changed) {
size_t newlen = output->len() - length_offset - 2;
EXPECT_GT(0x10000U, newlen);
if (newlen >= 0x10000) {
return KEEP; // bad: size increased too much
}
output->Write(length_offset, newlen, 2);
return CHANGE;
}
return KEEP;
}
};
class TlsExtensionTruncator : public TlsExtensionFilter {
public:
TlsExtensionTruncator(uint16_t extension, size_t length)
@ -254,26 +122,6 @@ class TlsExtensionInjector : public TlsHandshakeFilter {
const DataBuffer data_;
};
class TlsExtensionCapture : public TlsExtensionFilter {
public:
TlsExtensionCapture(uint16_t ext)
: extension_(ext), data_() {}
virtual PacketFilter::Action FilterExtension(
uint16_t extension_type, const DataBuffer& input, DataBuffer* output) {
if (extension_type == extension_) {
data_.Assign(input);
}
return KEEP;
}
const DataBuffer& extension() const { return data_; }
private:
const uint16_t extension_;
DataBuffer data_;
};
class TlsExtensionTestBase : public TlsConnectTestBase {
protected:
TlsExtensionTestBase(Mode mode, uint16_t version)
@ -323,11 +171,20 @@ class TlsExtensionTestDtls
class TlsExtensionTest12Plus
: public TlsExtensionTestBase,
public ::testing::WithParamInterface<std::string> {
public ::testing::WithParamInterface<std::tuple<std::string, uint16_t>> {
public:
TlsExtensionTest12Plus()
: TlsExtensionTestBase(TlsConnectTestBase::ToMode(GetParam()),
SSL_LIBRARY_VERSION_TLS_1_2) {}
: TlsExtensionTestBase(TlsConnectTestBase::ToMode((std::get<0>(GetParam()))),
std::get<1>(GetParam())) {}
};
class TlsExtensionTest12
: public TlsExtensionTestBase,
public ::testing::WithParamInterface<std::tuple<std::string, uint16_t>> {
public:
TlsExtensionTest12()
: TlsExtensionTestBase(TlsConnectTestBase::ToMode((std::get<0>(GetParam()))),
std::get<1>(GetParam())) {}
};
class TlsExtensionTest13
@ -348,6 +205,15 @@ class TlsExtensionTestGeneric
std::get<1>(GetParam())) {}
};
class TlsExtensionTestPre13
: public TlsExtensionTestBase,
public ::testing::WithParamInterface<std::tuple<std::string, uint16_t>> {
public:
TlsExtensionTestPre13()
: TlsExtensionTestBase(TlsConnectTestBase::ToMode((std::get<0>(GetParam()))),
std::get<1>(GetParam())) {}
};
TEST_P(TlsExtensionTestGeneric, DamageSniLength) {
ClientHelloErrorTest(new TlsExtensionDamager(ssl_server_name_xtn, 1));
}
@ -431,42 +297,44 @@ TEST_P(TlsExtensionTestGeneric, AlpnMismatch) {
ClientHelloErrorTest(nullptr, kTlsAlertNoApplicationProtocol);
}
TEST_P(TlsExtensionTestGeneric, AlpnReturnedEmptyList) {
// Many of these tests fail in TLS 1.3 because the extension is encrypted, which
// prevents modification of the value from the ServerHello.
TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyList) {
EnableAlpn();
const uint8_t val[] = { 0x00, 0x00 };
DataBuffer extension(val, sizeof(val));
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
}
TEST_P(TlsExtensionTestGeneric, AlpnReturnedEmptyName) {
TEST_P(TlsExtensionTestPre13, AlpnReturnedEmptyName) {
EnableAlpn();
const uint8_t val[] = { 0x00, 0x01, 0x00 };
DataBuffer extension(val, sizeof(val));
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
}
TEST_P(TlsExtensionTestGeneric, AlpnReturnedListTrailingData) {
TEST_P(TlsExtensionTestPre13, AlpnReturnedListTrailingData) {
EnableAlpn();
const uint8_t val[] = { 0x00, 0x02, 0x01, 0x61, 0x00 };
DataBuffer extension(val, sizeof(val));
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
}
TEST_P(TlsExtensionTestGeneric, AlpnReturnedExtraEntry) {
TEST_P(TlsExtensionTestPre13, AlpnReturnedExtraEntry) {
EnableAlpn();
const uint8_t val[] = { 0x00, 0x04, 0x01, 0x61, 0x01, 0x62 };
DataBuffer extension(val, sizeof(val));
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
}
TEST_P(TlsExtensionTestGeneric, AlpnReturnedBadListLength) {
TEST_P(TlsExtensionTestPre13, AlpnReturnedBadListLength) {
EnableAlpn();
const uint8_t val[] = { 0x00, 0x99, 0x01, 0x61, 0x00 };
DataBuffer extension(val, sizeof(val));
ServerHelloErrorTest(new TlsExtensionReplacer(ssl_app_layer_protocol_xtn, extension));
}
TEST_P(TlsExtensionTestGeneric, AlpnReturnedBadNameLength) {
TEST_P(TlsExtensionTestPre13, AlpnReturnedBadNameLength) {
EnableAlpn();
const uint8_t val[] = { 0x00, 0x02, 0x99, 0x61 };
DataBuffer extension(val, sizeof(val));
@ -549,35 +417,35 @@ TEST_P(TlsExtensionTestGeneric, SupportedCurvesTrailingData) {
extension));
}
TEST_P(TlsExtensionTestGeneric, SupportedPointsEmpty) {
TEST_P(TlsExtensionTestPre13, SupportedPointsEmpty) {
const uint8_t val[] = { 0x00 };
DataBuffer extension(val, sizeof(val));
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn,
extension));
}
TEST_P(TlsExtensionTestGeneric, SupportedPointsBadLength) {
TEST_P(TlsExtensionTestPre13, SupportedPointsBadLength) {
const uint8_t val[] = { 0x99, 0x00, 0x00 };
DataBuffer extension(val, sizeof(val));
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn,
extension));
}
TEST_P(TlsExtensionTestGeneric, SupportedPointsTrailingData) {
TEST_P(TlsExtensionTestPre13, SupportedPointsTrailingData) {
const uint8_t val[] = { 0x01, 0x00, 0x00 };
DataBuffer extension(val, sizeof(val));
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_ec_point_formats_xtn,
extension));
}
TEST_P(TlsExtensionTestGeneric, RenegotiationInfoBadLength) {
TEST_P(TlsExtensionTestPre13, RenegotiationInfoBadLength) {
const uint8_t val[] = { 0x99 };
DataBuffer extension(val, sizeof(val));
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_renegotiation_info_xtn,
extension));
}
TEST_P(TlsExtensionTestGeneric, RenegotiationInfoMismatch) {
TEST_P(TlsExtensionTestPre13, RenegotiationInfoMismatch) {
const uint8_t val[] = { 0x01, 0x00 };
DataBuffer extension(val, sizeof(val));
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_renegotiation_info_xtn,
@ -585,13 +453,15 @@ TEST_P(TlsExtensionTestGeneric, RenegotiationInfoMismatch) {
}
// The extension has to contain a length.
TEST_P(TlsExtensionTestGeneric, RenegotiationInfoExtensionEmpty) {
TEST_P(TlsExtensionTestPre13, RenegotiationInfoExtensionEmpty) {
DataBuffer extension;
ClientHelloErrorTest(new TlsExtensionReplacer(ssl_renegotiation_info_xtn,
extension));
}
TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmConfiguration) {
// This only works on TLS 1.2, since it relies on static RSA; otherwise libssl
// picks the wrong cipher suite.
TEST_P(TlsExtensionTest12, SignatureAlgorithmConfiguration) {
const SSLSignatureAndHashAlg algorithms[] = {
{ssl_hash_sha512, ssl_sign_rsa},
{ssl_hash_sha384, ssl_sign_ecdsa}
@ -619,6 +489,7 @@ TEST_P(TlsExtensionTest12Plus, SignatureAlgorithmConfiguration) {
/*
* Tests for Certificate Transparency (RFC 6962)
* These don't work with TLS 1.3: see bug 1252745.
*/
// Helper class - stores signed certificate timestamps as provided
@ -647,11 +518,11 @@ class SignedCertificateTimestampsExtractor {
}
void assertTimestamps(const DataBuffer& timestamps) {
ASSERT_TRUE(auth_timestamps_);
ASSERT_EQ(timestamps, *auth_timestamps_);
EXPECT_TRUE(auth_timestamps_);
EXPECT_EQ(timestamps, *auth_timestamps_);
ASSERT_TRUE(handshake_timestamps_);
ASSERT_EQ(timestamps, *handshake_timestamps_);
EXPECT_TRUE(handshake_timestamps_);
EXPECT_EQ(timestamps, *handshake_timestamps_);
}
private:
@ -660,7 +531,7 @@ class SignedCertificateTimestampsExtractor {
};
// Test timestamps extraction during a successful handshake.
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsHandshake) {
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsHandshake) {
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
const DataBuffer timestamps(val, sizeof(val));
@ -683,7 +554,7 @@ TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsHandshake) {
// Test SSL_PeerSignedCertTimestamps returning zero-length SECItem
// when the client / the server / both have not enabled the feature.
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveClient) {
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsInactiveClient) {
uint8_t val[] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
const SECItem si_timestamps = { siBuffer, val, sizeof(val) };
@ -700,7 +571,7 @@ TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveClient) {
timestamps_extractor.assertTimestamps(DataBuffer());
}
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveServer) {
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsInactiveServer) {
server_->StartConnect();
client_->StartConnect();
@ -714,7 +585,7 @@ TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveServer) {
timestamps_extractor.assertTimestamps(DataBuffer());
}
TEST_P(TlsExtensionTestGeneric, SignedCertificateTimestampsInactiveBoth) {
TEST_P(TlsExtensionTestPre13, SignedCertificateTimestampsInactiveBoth) {
server_->StartConnect();
client_->StartConnect();
@ -732,21 +603,34 @@ TEST_P(TlsExtensionTest13, EmptyClientKeyShare) {
kTlsAlertHandshakeFailure);
}
INSTANTIATE_TEST_CASE_P(ExtensionTls10, TlsExtensionTestGeneric,
INSTANTIATE_TEST_CASE_P(ExtensionStream, TlsExtensionTestGeneric,
::testing::Combine(
TlsConnectTestBase::kTlsModesStream,
TlsConnectTestBase::kTlsV10));
INSTANTIATE_TEST_CASE_P(ExtensionVariants, TlsExtensionTestGeneric,
TlsConnectTestBase::kTlsVAll));
INSTANTIATE_TEST_CASE_P(ExtensionDatagram, TlsExtensionTestGeneric,
::testing::Combine(
TlsConnectTestBase::kTlsModesAll,
TlsConnectTestBase::kTlsV11Plus));
INSTANTIATE_TEST_CASE_P(ExtensionDatagramOnly, TlsExtensionTestDtls,
TlsConnectTestBase::kTlsV11Plus);
INSTANTIATE_TEST_CASE_P(ExtensionTls12Plus, TlsExtensionTest12Plus,
::testing::Combine(
TlsConnectTestBase::kTlsModesAll,
TlsConnectTestBase::kTlsV12Plus));
INSTANTIATE_TEST_CASE_P(ExtensionPre13Stream, TlsExtensionTestPre13,
::testing::Combine(
TlsConnectTestBase::kTlsModesStream,
TlsConnectTestBase::kTlsV10To12));
INSTANTIATE_TEST_CASE_P(ExtensionPre13Datagram, TlsExtensionTestPre13,
::testing::Combine(
TlsConnectTestBase::kTlsModesAll,
TlsConnectTestBase::kTlsV11V12));
INSTANTIATE_TEST_CASE_P(ExtensionTls12Plus, TlsExtensionTest12Plus,
TlsConnectTestBase::kTlsModesAll);
#ifdef NSS_ENABLE_TLS_1_3
INSTANTIATE_TEST_CASE_P(ExtensionTls13, TlsExtensionTest13,
TlsConnectTestBase::kTlsModesStream);
TlsConnectTestBase::kTlsModesAll);
#endif
INSTANTIATE_TEST_CASE_P(ExtensionDgram, TlsExtensionTestDtls,
TlsConnectTestBase::kTlsV11V12);
} // namespace nspr_test

View File

@ -146,13 +146,13 @@ TEST_P(TlsConnectGeneric, ConnectEcdsa) {
CheckKeys(ssl_kea_ecdh, ssl_auth_ecdsa);
}
TEST_P(TlsConnectGeneric, ConnectFalseStart) {
TEST_P(TlsConnectGenericPre13, ConnectFalseStart) {
client_->EnableFalseStart();
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectResumed) {
TEST_P(TlsConnectGenericPre13, ConnectResumed) {
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
Connect();
@ -164,36 +164,47 @@ TEST_P(TlsConnectGeneric, ConnectResumed) {
TEST_P(TlsConnectGeneric, ConnectClientCacheDisabled) {
ConfigureSessionCache(RESUME_NONE, RESUME_SESSIONID);
Connect();
SendReceive();
ResetRsa();
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectServerCacheDisabled) {
ConfigureSessionCache(RESUME_SESSIONID, RESUME_NONE);
Connect();
SendReceive();
ResetRsa();
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectSessionCacheDisabled) {
ConfigureSessionCache(RESUME_NONE, RESUME_NONE);
Connect();
SendReceive();
ResetRsa();
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectResumeSupportBoth) {
// This prefers tickets.
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
Connect();
SendReceive();
ResetRsa();
ConfigureSessionCache(RESUME_BOTH, RESUME_BOTH);
ExpectResumption(RESUME_TICKET);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) {
@ -201,57 +212,67 @@ TEST_P(TlsConnectGeneric, ConnectResumeClientTicketServerBoth) {
// session cache to resume even with tickets.
ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH);
Connect();
SendReceive();
ResetRsa();
ConfigureSessionCache(RESUME_TICKET, RESUME_BOTH);
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicket) {
// This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect();
SendReceive();
ResetRsa();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_TICKET);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectClientServerTicketOnly) {
TEST_P(TlsConnectGenericPre13, ConnectResumeClientServerTicketOnly) {
// This causes no resumption because the client needs the
// session cache to resume even with tickets.
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
Connect();
SendReceive();
ResetRsa();
ConfigureSessionCache(RESUME_TICKET, RESUME_TICKET);
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectClientBothServerNone) {
TEST_P(TlsConnectGenericPre13, ConnectResumeClientBothServerNone) {
ConfigureSessionCache(RESUME_BOTH, RESUME_NONE);
Connect();
SendReceive();
ResetRsa();
ConfigureSessionCache(RESUME_BOTH, RESUME_NONE);
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ConnectClientNoneServerBoth) {
TEST_P(TlsConnectGenericPre13, ConnectResumeClientNoneServerBoth) {
ConfigureSessionCache(RESUME_NONE, RESUME_BOTH);
Connect();
SendReceive();
ResetRsa();
ConfigureSessionCache(RESUME_NONE, RESUME_BOTH);
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
TEST_P(TlsConnectGeneric, ResumeWithHigherVersion) {
TEST_P(TlsConnectGenericPre13, ConnectResumeWithHigherVersion) {
EnsureTlsSetup();
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
ConfigureSessionCache(RESUME_SESSIONID, RESUME_SESSIONID);
@ -272,15 +293,21 @@ TEST_P(TlsConnectGeneric, ResumeWithHigherVersion) {
Connect();
}
TEST_P(TlsConnectGeneric, ClientAuth) {
client_->SetupClientAuth();
server_->RequestClientAuth(true);
TEST_P(TlsConnectGeneric, ConnectResumeClientBothTicketServerTicketForget) {
// This causes a ticket resumption.
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
Connect();
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
SendReceive();
ResetRsa();
ClearServerCache();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
ExpectResumption(RESUME_NONE);
Connect();
SendReceive();
}
// Temporary copy for TLS 1.3 because 1.3 is stream only.
TEST_P(TlsConnectStream, ClientAuth) {
TEST_P(TlsConnectGeneric, ClientAuth) {
client_->SetupClientAuth();
server_->RequestClientAuth(true);
Connect();
@ -297,7 +324,7 @@ TEST_P(TlsConnectStream, DISABLED_ClientAuthRequiredRejected) {
ConnectExpectFail();
}
TEST_P(TlsConnectStream, ClientAuthRequestedRejected) {
TEST_P(TlsConnectGeneric, ClientAuthRequestedRejected) {
server_->RequestClientAuth(false);
Connect();
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
@ -362,7 +389,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
// There is no need for overlap on signatures; since we don't actually use the
// signatures for static RSA, this should still connect successfully.
// This should also work in TLS 1.0 and 1.1 where the algorithms aren't used.
TEST_P(TlsConnectGeneric, SignatureAlgorithmNoOverlapStaticRsa) {
TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
client_->SetSignatureAlgorithms(SignatureRsaSha384,
PR_ARRAY_SIZE(SignatureRsaSha384));
server_->SetSignatureAlgorithms(SignatureRsaSha256,
@ -372,7 +399,7 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmNoOverlapStaticRsa) {
CheckKeys(ssl_kea_rsa, ssl_auth_rsa);
}
TEST_P(TlsConnectStreamPre13, ConnectStaticRSA) {
TEST_P(TlsConnectGenericPre13, ConnectStaticRSA) {
DisableDheAndEcdheCiphers();
Connect();
CheckKeys(ssl_kea_rsa, ssl_auth_rsa);
@ -415,18 +442,77 @@ TEST_P(TlsConnectGeneric, ConnectAlpn) {
server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, "a");
}
// Temporary copy to test Alpn with TLS 1.3.
TEST_P(TlsConnectStream, ConnectAlpn) {
EnableAlpn();
Connect();
client_->CheckAlpn(SSL_NEXT_PROTO_SELECTED, "a");
server_->CheckAlpn(SSL_NEXT_PROTO_NEGOTIATED, "a");
}
TEST_P(TlsConnectDatagram, ConnectSrtp) {
EnableSrtp();
Connect();
CheckSrtp();
SendReceive();
}
// This class selectively drops complete writes. This relies on the fact that
// writes in libssl are on record boundaries.
class SelectiveDropFilter : public PacketFilter, public PollTarget {
public:
SelectiveDropFilter(uint32_t pattern)
: pattern_(pattern),
counter_(0) {}
protected:
virtual Action Filter(const DataBuffer& input, DataBuffer* output) override {
if (counter_ >= 32) {
return KEEP;
}
return ((1 << counter_++) & pattern_) ? DROP : KEEP;
}
private:
const uint32_t pattern_;
uint8_t counter_;
};
TEST_P(TlsConnectDatagram, DropClientFirstFlightOnce) {
client_->SetPacketFilter(new SelectiveDropFilter(0x1));
Connect();
SendReceive();
}
TEST_P(TlsConnectDatagram, DropServerFirstFlightOnce) {
server_->SetPacketFilter(new SelectiveDropFilter(0x1));
Connect();
SendReceive();
}
// This drops the first transmission from both the client and server of all
// flights that they send. Note: In DTLS 1.3, the shorter handshake means that
// this will also drop some application data, so we can't call SendReceive().
TEST_P(TlsConnectDatagram, DropAllFirstTransmissions) {
client_->SetPacketFilter(new SelectiveDropFilter(0x15));
server_->SetPacketFilter(new SelectiveDropFilter(0x5));
Connect();
}
// This drops the server's first flight three times.
TEST_P(TlsConnectDatagram, DropServerFirstFlightThrice) {
server_->SetPacketFilter(new SelectiveDropFilter(0x7));
Connect();
}
// This drops the client's second flight once
TEST_P(TlsConnectDatagram, DropClientSecondFlightOnce) {
client_->SetPacketFilter(new SelectiveDropFilter(0x2));
Connect();
}
// This drops the client's second flight three times.
TEST_P(TlsConnectDatagram, DropClientSecondFlightThrice) {
client_->SetPacketFilter(new SelectiveDropFilter(0xe));
Connect();
}
// This drops the server's second flight three times.
TEST_P(TlsConnectDatagram, DropServerSecondFlightThrice) {
server_->SetPacketFilter(new SelectiveDropFilter(0xe));
Connect();
}
// 1.3 is disabled in the next few tests because we don't
@ -447,7 +533,8 @@ TEST_P(TlsConnectStreamPre13, ConnectAndServerRenegotiate) {
CheckConnected();
}
TEST_P(TlsConnectStreamPre13, ConnectDhe) {
// TODO implement DHE for 1.3
TEST_P(TlsConnectGenericPre13, ConnectDhe) {
DisableEcdheCiphers();
Connect();
CheckKeys(ssl_kea_dh, ssl_auth_rsa);
@ -486,7 +573,7 @@ TEST_P(TlsConnectStreamPre13, ConnectStaticRSABogusPMSVersionDetect) {
// Test that a PMS with a bogus version number is ignored when
// rollback detection is disabled. This is a positive control for
// ConnectStaticRSABogusPMSVersionDetect.
TEST_P(TlsConnectGeneric, ConnectStaticRSABogusPMSVersionIgnore) {
TEST_P(TlsConnectGenericPre13, ConnectStaticRSABogusPMSVersionIgnore) {
DisableDheAndEcdheCiphers();
client_->SetPacketFilter(new TlsInspectorClientHelloVersionChanger(
server_));
@ -494,12 +581,13 @@ TEST_P(TlsConnectGeneric, ConnectStaticRSABogusPMSVersionIgnore) {
Connect();
}
TEST_P(TlsConnectStream, ConnectEcdhe) {
TEST_P(TlsConnectGeneric, ConnectEcdhe) {
Connect();
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
}
TEST_P(TlsConnectStreamPre13, ConnectEcdheTwiceReuseKey) {
// Prior to TLS 1.3, we were not fully ephemeral; though 1.3 fixes that
TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceReuseKey) {
TlsInspectorRecordHandshakeMessage* i1 =
new TlsInspectorRecordHandshakeMessage(kTlsHandshakeServerKeyExchange);
server_->SetPacketFilter(i1);
@ -526,7 +614,8 @@ TEST_P(TlsConnectStreamPre13, ConnectEcdheTwiceReuseKey) {
dhe1.public_key_.len()));
}
TEST_P(TlsConnectStreamPre13, ConnectEcdheTwiceNewKey) {
// This test parses the ServerKeyExchange, which isn't in 1.3
TEST_P(TlsConnectGenericPre13, ConnectEcdheTwiceNewKey) {
server_->EnsureTlsSetup();
SECStatus rv =
SSL_OptionSet(server_->ssl_fd(), SSL_REUSE_SERVER_ECDHE_KEY, PR_FALSE);
@ -616,7 +705,7 @@ TEST_P(TlsConnectStream, ShortRead) {
ASSERT_EQ(1200U, client_->received_bytes());
}
TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecret) {
TEST_P(TlsConnectGenericPre13, ConnectExtendedMasterSecret) {
EnableExtendedMasterSecret();
Connect();
ResetRsa();
@ -625,8 +714,7 @@ TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecret) {
Connect();
}
TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecretStaticRSA) {
TEST_P(TlsConnectGenericPre13, ConnectExtendedMasterSecretStaticRSA) {
DisableDheAndEcdheCiphers();
EnableExtendedMasterSecret();
Connect();
@ -671,7 +759,7 @@ TEST_P(TlsConnectStreamPre13, ConnectExtendedMasterSecretStaticRSABogusPMSVersio
Connect();
}
TEST_P(TlsConnectGeneric, ConnectExtendedMasterSecretECDHE) {
TEST_P(TlsConnectGenericPre13, ConnectExtendedMasterSecretECDHE) {
EnableExtendedMasterSecret();
Connect();
@ -734,22 +822,18 @@ TEST_P(TlsConnectGenericPre13,
Connect();
}
TEST_P(TlsConnectStream, ConnectWithCompressionMaybe)
TEST_P(TlsConnectGeneric, ConnectWithCompressionMaybe)
{
EnsureTlsSetup();
client_->EnableCompression();
server_->EnableCompression();
Connect();
EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3, client_->is_compressed());
EXPECT_EQ(client_->version() < SSL_LIBRARY_VERSION_TLS_1_3 &&
mode_ != DGRAM, client_->is_compressed());
SendReceive();
}
TEST_P(TlsConnectStream, ConnectSendReceive) {
Connect();
SendReceive();
}
TEST_P(TlsConnectStream, ServerNegotiateTls10) {
uint16_t minver, maxver;
client_->GetVersionRange(&minver, &maxver);
@ -760,7 +844,7 @@ TEST_P(TlsConnectStream, ServerNegotiateTls10) {
Connect();
}
TEST_P(TlsConnectStream, ServerNegotiateTls11) {
TEST_P(TlsConnectGeneric, ServerNegotiateTls11) {
if (version_ < SSL_LIBRARY_VERSION_TLS_1_1)
return;
@ -773,7 +857,7 @@ TEST_P(TlsConnectStream, ServerNegotiateTls11) {
Connect();
}
TEST_P(TlsConnectStream, ServerNegotiateTls12) {
TEST_P(TlsConnectGeneric, ServerNegotiateTls12) {
if (version_ < SSL_LIBRARY_VERSION_TLS_1_2)
return;
@ -859,6 +943,65 @@ TEST_F(TlsConnectTest, TestFallbackFromTls13) {
ConnectExpectFail();
ASSERT_EQ(SSL_ERROR_RX_MALFORMED_SERVER_HELLO, client_->error_code());
}
// Test that two TLS resumptions work and produce the same ticket.
// This will change after bug 1257047 is fixed.
TEST_F(TlsConnectTest, TestTls13ResumptionTwice) {
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
SendReceive(); // Need to read so that we absorb the session ticket.
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
ResetRsa();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
TlsExtensionCapture *c1 =
new TlsExtensionCapture(kTlsExtensionPreSharedKey);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
ExpectResumption(RESUME_TICKET);
Connect();
SendReceive();
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
DataBuffer psk1(c1->extension());
ASSERT_GE(psk1.len(), 0UL);
ResetRsa();
ClearStats();
ConfigureSessionCache(RESUME_BOTH, RESUME_TICKET);
TlsExtensionCapture *c2 =
new TlsExtensionCapture(kTlsExtensionPreSharedKey);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_3);
ExpectResumption(RESUME_TICKET);
Connect();
SendReceive();
CheckKeys(ssl_kea_ecdh, ssl_auth_rsa);
DataBuffer psk2(c2->extension());
ASSERT_GE(psk2.len(), 0UL);
// TODO(ekr@rtfm.com): This will change when we fix bug 1257047.
ASSERT_EQ(psk1, psk2);
}
TEST_P(TlsConnectDatagram, TestDtlsHolddownExpiry) {
Connect();
std::cerr << "Expiring holddown timer\n";
SSLInt_ForceTimerExpiry(client_->ssl_fd());
SSLInt_ForceTimerExpiry(server_->ssl_fd());
SendReceive();
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
EXPECT_EQ(1, SSLInt_CountTls13CipherSpecs(client_->ssl_fd()));
}
}
#endif
class BeforeFinished : public TlsRecordFilter {
@ -934,8 +1077,7 @@ class BeforeFinished : public TlsRecordFilter {
HandshakeState state_;
};
// TODO Pre13
TEST_P(TlsConnectGeneric, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
TEST_P(TlsConnectGenericPre13, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
client_->EnableFalseStart();
server_->SetPacketFilter(new BeforeFinished(client_, server_, [this]() {
EXPECT_TRUE(client_->can_falsestart_hook_called());
@ -949,7 +1091,7 @@ TEST_P(TlsConnectGeneric, ClientWriteBetweenCCSAndFinishedWithFalseStart) {
Receive(10);
}
TEST_P(TlsConnectGeneric, AuthCompleteBeforeFinishedWithFalseStart) {
TEST_P(TlsConnectGenericPre13, AuthCompleteBeforeFinishedWithFalseStart) {
client_->EnableFalseStart();
client_->SetAuthCertificateCallback(
[](TlsAgent&, PRBool, PRBool) -> SECStatus {
@ -970,38 +1112,43 @@ TEST_P(TlsConnectGeneric, AuthCompleteBeforeFinishedWithFalseStart) {
Receive(10);
}
INSTANTIATE_TEST_CASE_P(VariantsStream10, TlsConnectGeneric,
INSTANTIATE_TEST_CASE_P(GenericStream, TlsConnectGeneric,
::testing::Combine(
TlsConnectTestBase::kTlsModesStream,
TlsConnectTestBase::kTlsV10));
INSTANTIATE_TEST_CASE_P(VariantsAll, TlsConnectGeneric,
TlsConnectTestBase::kTlsVAll));
INSTANTIATE_TEST_CASE_P(GenericDatagram, TlsConnectGeneric,
::testing::Combine(
TlsConnectTestBase::kTlsModesAll,
TlsConnectTestBase::kTlsV11V12));
INSTANTIATE_TEST_CASE_P(VersionsDatagram, TlsConnectDatagram,
TlsConnectTestBase::kTlsV11V12);
INSTANTIATE_TEST_CASE_P(Variants12, TlsConnectTls12,
TlsConnectTestBase::kTlsModesAll);
INSTANTIATE_TEST_CASE_P(Variants12, TlsChaCha20Poly1305Test,
TlsConnectTestBase::kTlsModesDatagram,
TlsConnectTestBase::kTlsV11Plus));
INSTANTIATE_TEST_CASE_P(StreamOnly, TlsConnectStream,
TlsConnectTestBase::kTlsVAll);
INSTANTIATE_TEST_CASE_P(DatagramOnly, TlsConnectDatagram,
TlsConnectTestBase::kTlsV11Plus);
INSTANTIATE_TEST_CASE_P(ChaCha20, TlsChaCha20Poly1305Test,
TlsConnectTestBase::kTlsModesAll);
INSTANTIATE_TEST_CASE_P(Pre12Stream, TlsConnectPre12,
::testing::Combine(
TlsConnectTestBase::kTlsModesStream,
TlsConnectTestBase::kTlsV10));
INSTANTIATE_TEST_CASE_P(Pre12All, TlsConnectPre12,
TlsConnectTestBase::kTlsV10V11));
INSTANTIATE_TEST_CASE_P(Pre12Datagram, TlsConnectPre12,
::testing::Combine(
TlsConnectTestBase::kTlsModesAll,
TlsConnectTestBase::kTlsModesDatagram,
TlsConnectTestBase::kTlsV11));
INSTANTIATE_TEST_CASE_P(VersionsStream10, TlsConnectStream,
TlsConnectTestBase::kTlsV10);
INSTANTIATE_TEST_CASE_P(VersionsStream, TlsConnectStream,
TlsConnectTestBase::kTlsV11V12);
INSTANTIATE_TEST_CASE_P(VersionsStream10Pre13, TlsConnectStreamPre13,
TlsConnectTestBase::kTlsV10);
INSTANTIATE_TEST_CASE_P(VersionsStreamPre13, TlsConnectStreamPre13,
TlsConnectTestBase::kTlsV11V12);
#ifdef NSS_ENABLE_TLS_1_3
INSTANTIATE_TEST_CASE_P(VersionsStream13, TlsConnectStream,
TlsConnectTestBase::kTlsV13);
#endif
INSTANTIATE_TEST_CASE_P(Version12Only, TlsConnectTls12,
TlsConnectTestBase::kTlsModesAll);
INSTANTIATE_TEST_CASE_P(Pre13Stream, TlsConnectGenericPre13,
::testing::Combine(
TlsConnectTestBase::kTlsModesStream,
TlsConnectTestBase::kTlsV10To12));
INSTANTIATE_TEST_CASE_P(Pre13Datagram, TlsConnectGenericPre13,
::testing::Combine(
TlsConnectTestBase::kTlsModesDatagram,
TlsConnectTestBase::kTlsV11V12));
INSTANTIATE_TEST_CASE_P(Pre13StreamOnly, TlsConnectStreamPre13,
TlsConnectTestBase::kTlsV10To12);
} // namespace nspr_test

View File

@ -0,0 +1,406 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"
#include "pk11pub.h"
extern "C" {
// This is not something that should make you happy.
#include "libssl_internals.h"
}
#include "tls_filter.h"
#include "tls_connect.h"
#include "gtest_utils.h"
namespace nss_test {
// Replaces the client hello with an SSLv2 version once.
class SSLv2ClientHelloFilter : public PacketFilter
{
public:
SSLv2ClientHelloFilter(TlsAgent* client, uint16_t version)
: replaced_(false), client_(client), version_(version), pad_len_(0),
reported_pad_len_(0), client_random_len_(16), ciphers_(0),
send_escape_(false)
{ }
void
SetVersion(uint16_t version)
{
version_ = version;
}
void
SetCipherSuites(const std::vector<uint16_t>& ciphers)
{
ciphers_ = ciphers;
}
// Set a padding length and announce it correctly.
void
SetPadding(uint8_t pad_len)
{
SetPadding(pad_len, pad_len);
}
// Set a padding length and allow to lie about its length.
void
SetPadding(uint8_t pad_len, uint8_t reported_pad_len)
{
pad_len_ = pad_len;
reported_pad_len_ = reported_pad_len;
}
void
SetClientRandomLength(uint16_t client_random_len)
{
client_random_len_ = client_random_len;
}
void
SetSendEscape(bool send_escape)
{
send_escape_ = send_escape;
}
protected:
virtual PacketFilter::Action
Filter(const DataBuffer& input, DataBuffer* output)
{
if (replaced_) {
return KEEP;
}
// Replace only the very first packet.
replaced_ = true;
// The SSLv2 client hello size.
size_t packet_len = SSL_HL_CLIENT_HELLO_HBYTES + (ciphers_.size() * 3) +
client_random_len_ + pad_len_;
size_t idx = 0;
*output = input;
output->Allocate(packet_len);
output->Truncate(packet_len);
// Write record length.
if (pad_len_ > 0) {
size_t masked_len = 0x3fff & packet_len;
if (send_escape_) {
masked_len |= 0x4000;
}
idx = output->Write(idx, masked_len, 2);
idx = output->Write(idx, reported_pad_len_, 1);
} else {
PR_ASSERT(!send_escape_);
idx = output->Write(idx, 0x8000 | packet_len, 2);
}
// Remember header length.
size_t hdr_len = idx;
// Write client hello.
idx = output->Write(idx, SSL_MT_CLIENT_HELLO, 1);
idx = output->Write(idx, version_, 2);
// Cipher list length.
idx = output->Write(idx, (ciphers_.size() * 3), 2);
// Session ID length.
idx = output->Write(idx, static_cast<uint32_t>(0), 2);
// ClientRandom length.
idx = output->Write(idx, client_random_len_, 2);
// Cipher suites.
for (auto cipher : ciphers_) {
idx = output->Write(idx, static_cast<uint32_t>(cipher), 3);
}
// Challenge.
std::vector<uint8_t> challenge(client_random_len_);
PK11_GenerateRandom(challenge.data(), challenge.size());
idx = output->Write(idx, challenge.data(), challenge.size());
// Add padding if any.
if (pad_len_ > 0) {
std::vector<uint8_t> pad(pad_len_);
idx = output->Write(idx, pad.data(), pad.size());
}
// Update the client random so that the handshake succeeds.
SECStatus rv = SSLInt_UpdateSSLv2ClientRandom(client_->ssl_fd(),
challenge.data(),
challenge.size(),
output->data() + hdr_len,
output->len() - hdr_len);
EXPECT_EQ(SECSuccess, rv);
return CHANGE;
}
private:
bool replaced_;
TlsAgent* client_;
uint16_t version_;
uint8_t pad_len_;
uint8_t reported_pad_len_;
uint16_t client_random_len_;
std::vector<uint16_t> ciphers_;
bool send_escape_;
};
class SSLv2ClientHelloTestF : public TlsConnectTestBase
{
public:
SSLv2ClientHelloTestF()
: TlsConnectTestBase(STREAM, 0), filter_(nullptr)
{ }
SSLv2ClientHelloTestF(Mode mode, uint16_t version)
: TlsConnectTestBase(mode, version), filter_(nullptr)
{ }
void
SetUp()
{
TlsConnectTestBase::SetUp();
filter_ = new SSLv2ClientHelloFilter(client_, version_);
client_->SetPacketFilter(filter_);
}
void
RequireSafeRenegotiation()
{
server_->EnsureTlsSetup();
SECStatus rv =
SSL_OptionSet(server_->ssl_fd(), SSL_REQUIRE_SAFE_NEGOTIATION, PR_TRUE);
EXPECT_EQ(rv, SECSuccess);
}
void
SetExpectedVersion(uint16_t version)
{
TlsConnectTestBase::SetExpectedVersion(version);
filter_->SetVersion(version);
}
void
SetAvailableCipherSuite(uint16_t cipher)
{
filter_->SetCipherSuites(std::vector<uint16_t>(1, cipher));
}
void
SetAvailableCipherSuites(const std::vector<uint16_t>& ciphers)
{
filter_->SetCipherSuites(ciphers);
}
void
SetPadding(uint8_t pad_len)
{
filter_->SetPadding(pad_len);
}
void
SetPadding(uint8_t pad_len, uint8_t reported_pad_len)
{
filter_->SetPadding(pad_len, reported_pad_len);
}
void
SetClientRandomLength(uint16_t client_random_len)
{
filter_->SetClientRandomLength(client_random_len);
}
void
SetSendEscape(bool send_escape)
{
filter_->SetSendEscape(send_escape);
}
private:
SSLv2ClientHelloFilter* filter_;
};
// Parameterized version of SSLv2ClientHelloTestF we can
// use with TEST_P to test multiple TLS versions easily.
class SSLv2ClientHelloTest : public SSLv2ClientHelloTestF,
public ::testing::WithParamInterface<uint16_t>
{
public:
SSLv2ClientHelloTest()
: SSLv2ClientHelloTestF(STREAM, GetParam())
{ }
};
// Test negotiating TLS 1.0 - 1.2.
TEST_P(SSLv2ClientHelloTest, Connect) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
Connect();
}
// Test negotiating TLS 1.3.
#ifdef NSS_ENABLE_TLS_1_3
TEST_F(SSLv2ClientHelloTestF, Connect13) {
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_3);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
SSL_LIBRARY_VERSION_TLS_1_3);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_3,
SSL_LIBRARY_VERSION_TLS_1_3);
std::vector<uint16_t> cipher_suites =
{ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 };
SetAvailableCipherSuites(cipher_suites);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
}
#endif
// Test negotiating an EC suite.
TEST_P(SSLv2ClientHelloTest, NegotiateECSuite) {
SetAvailableCipherSuite(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA);
Connect();
}
// Test negotiating TLS 1.0 - 1.2 with a padded client hello.
TEST_P(SSLv2ClientHelloTest, AddPadding) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
SetPadding(255);
Connect();
}
// Test that sending a security escape fails the handshake.
TEST_P(SSLv2ClientHelloTest, SendSecurityEscape) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
// Send a security escape.
SetSendEscape(true);
// Set a big padding so that the server fails instead of timing out.
SetPadding(255);
ConnectExpectFail();
}
// Invalid SSLv2 client hello padding must fail the handshake.
TEST_P(SSLv2ClientHelloTest, AddErroneousPadding) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
// Append 5 bytes of padding but say it's only 4.
SetPadding(5, 4);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
}
// Invalid SSLv2 client hello padding must fail the handshake.
TEST_P(SSLv2ClientHelloTest, AddErroneousPadding2) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
// Append 5 bytes of padding but say it's 6.
SetPadding(5, 6);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
}
// Wrong amount of bytes for the ClientRandom must fail the handshake.
TEST_P(SSLv2ClientHelloTest, SmallClientRandom) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
// Send a ClientRandom that's too small.
SetClientRandomLength(15);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
}
// Test sending the maximum accepted number of ClientRandom bytes.
TEST_P(SSLv2ClientHelloTest, MaxClientRandom) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
SetClientRandomLength(32);
Connect();
}
// Wrong amount of bytes for the ClientRandom must fail the handshake.
TEST_P(SSLv2ClientHelloTest, BigClientRandom) {
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
// Send a ClientRandom that's too big.
SetClientRandomLength(33);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, server_->error_code());
}
// Connection must fail if we require safe renegotiation but the client doesn't
// include TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites.
TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiation) {
RequireSafeRenegotiation();
SetAvailableCipherSuite(TLS_DHE_RSA_WITH_AES_128_CBC_SHA);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_UNSAFE_NEGOTIATION, server_->error_code());
}
// Connection must succeed when requiring safe renegotiation and the client
// includes TLS_EMPTY_RENEGOTIATION_INFO_SCSV in the list of cipher suites.
TEST_P(SSLv2ClientHelloTest, RequireSafeRenegotiationWithSCSV) {
RequireSafeRenegotiation();
std::vector<uint16_t> cipher_suites =
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV };
SetAvailableCipherSuites(cipher_suites);
Connect();
}
// Connect to the server with TLS 1.1, signalling that this is a fallback from
// a higher version. As the server doesn't support anything higher than TLS 1.1
// it must accept the connection.
TEST_F(SSLv2ClientHelloTestF, FallbackSCSV) {
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_1);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_1);
std::vector<uint16_t> cipher_suites =
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_FALLBACK_SCSV };
SetAvailableCipherSuites(cipher_suites);
Connect();
}
// Connect to the server with TLS 1.1, signalling that this is a fallback from
// a higher version. As the server supports TLS 1.2 though it must reject the
// connection due to a possible downgrade attack.
TEST_F(SSLv2ClientHelloTestF, InappropriateFallbackSCSV) {
SetExpectedVersion(SSL_LIBRARY_VERSION_TLS_1_1);
client_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_1);
server_->SetVersionRange(SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_2);
std::vector<uint16_t> cipher_suites =
{ TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_FALLBACK_SCSV };
SetAvailableCipherSuites(cipher_suites);
ConnectExpectFail();
EXPECT_EQ(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, server_->error_code());
}
INSTANTIATE_TEST_CASE_P(VersionsStream10Pre13, SSLv2ClientHelloTest,
TlsConnectTestBase::kTlsV10);
INSTANTIATE_TEST_CASE_P(VersionsStreamPre13, SSLv2ClientHelloTest,
TlsConnectTestBase::kTlsV11V12);
} // namespace nss_test

View File

@ -443,7 +443,8 @@ void Poller::SetTimer(uint32_t timer_ms, PollTarget *target, PollCallback cb,
}
bool Poller::Poll() {
std::cerr << "Poll() waiters = " << waiters_.size() << std::endl;
std::cerr << "Poll() waiters = " << waiters_.size()
<< " timers = " << timers_.size() << std::endl;
PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
PRTime now = PR_Now();
bool fired = false;

View File

@ -36,6 +36,7 @@ TlsAgent::TlsAgent(const std::string& name, Role role, Mode mode, SSLKEAType kea
ssl_fd_(nullptr),
role_(role),
state_(STATE_INIT),
timer_handle_(nullptr),
falsestart_enabled_(false),
expected_version_(0),
expected_cipher_suite_(0),
@ -63,6 +64,9 @@ TlsAgent::~TlsAgent() {
if (adapter_) {
Poller::Instance()->Cancel(READABLE_EVENT, adapter_);
}
if (timer_handle_) {
timer_handle_->Cancel();
}
if (pr_fd_) {
PR_Close(pr_fd_);
@ -414,9 +418,11 @@ void TlsAgent::CheckCallbacks() const {
EXPECT_TRUE(handshake_callback_called_);
}
// These callbacks shouldn't fire if we are resuming.
// These callbacks shouldn't fire if we are resuming, except on TLS 1.3.
if (role_ == SERVER) {
EXPECT_EQ(!expect_resumption_, sni_hook_called_);
PRBool have_sni = SSLInt_ExtensionNegotiated(ssl_fd_, ssl_server_name_xtn);
EXPECT_EQ(((!expect_resumption_ && have_sni) ||
expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3), sni_hook_called_);
} else {
EXPECT_EQ(!expect_resumption_, auth_certificate_hook_called_);
// Note that this isn't unconditionally called, even with false start on.
@ -445,6 +451,10 @@ void TlsAgent::Connected() {
EXPECT_EQ(SECSuccess, rv);
EXPECT_EQ(sizeof(csinfo_), csinfo_.length);
if (expected_version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
PRInt32 cipherSuites = SSLInt_CountTls13CipherSpecs(ssl_fd_);
EXPECT_EQ(((mode_ == DGRAM) && (role_ == CLIENT)) ? 2 : 1, cipherSuites);
}
SetState(STATE_CONNECTED);
}
@ -491,6 +501,7 @@ void TlsAgent::SetDowngradeCheckVersion(uint16_t version) {
}
void TlsAgent::Handshake() {
LOG("Handshake");
SECStatus rv = SSL_ForceHandshake(ssl_fd_);
if (rv == SECSuccess) {
Connected();
@ -504,13 +515,23 @@ void TlsAgent::Handshake() {
switch (err) {
case PR_WOULD_BLOCK_ERROR:
LOG("Would have blocked");
// TODO(ekr@rtfm.com): set DTLS timeouts
if (mode_ == DGRAM) {
if (timer_handle_) {
timer_handle_->Cancel();
}
PRIntervalTime timeout;
rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout);
if (rv == SECSuccess) {
Poller::Instance()->SetTimer(timeout, this,
&TlsAgent::ReadableCallback,
&timer_handle_);
}
}
Poller::Instance()->Wait(READABLE_EVENT, adapter_, this,
&TlsAgent::ReadableCallback);
return;
break;
// TODO(ekr@rtfm.com): needs special case for DTLS
case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
default:
if (IS_SSL_ERROR(err)) {

View File

@ -112,6 +112,8 @@ class TlsAgent : public PollTarget {
void EnableCompression();
void SetDowngradeCheckVersion(uint16_t version);
const std::string& name() const { return name_; }
Role role() const { return role_; }
State state() const { return state_; }
@ -210,10 +212,12 @@ class TlsAgent : public PollTarget {
static void ReadableCallback(PollTarget* self, Event event) {
TlsAgent* agent = static_cast<TlsAgent*>(self);
if (event == TIMER_EVENT) {
agent->timer_handle_ = nullptr;
}
agent->ReadableCallback_int();
}
void ReadableCallback_int() {
LOG("Readable");
switch (state_) {
@ -234,7 +238,8 @@ class TlsAgent : public PollTarget {
TlsAgent* agent = reinterpret_cast<TlsAgent*>(arg);
agent->CheckPreliminaryInfo();
agent->sni_hook_called_ = true;
return SSL_SNI_CURRENT_CONFIG_IS_USED;
EXPECT_EQ(1UL, srvNameArrSize);
return 0; // First configuration.
}
static SECStatus CanFalseStartCallback(PRFileDesc *fd, void *arg,
@ -269,6 +274,7 @@ class TlsAgent : public PollTarget {
PRFileDesc* ssl_fd_;
Role role_;
State state_;
Poller::Timer *timer_handle_;
bool falsestart_enabled_;
uint16_t expected_version_;
uint16_t expected_cipher_suite_;

View File

@ -5,6 +5,9 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "tls_connect.h"
extern "C" {
#include "libssl_internals.h"
}
#include <iostream>
@ -18,26 +21,68 @@ namespace nss_test {
static const std::string kTlsModesStreamArr[] = {"TLS"};
::testing::internal::ParamGenerator<std::string>
TlsConnectTestBase::kTlsModesStream = ::testing::ValuesIn(kTlsModesStreamArr);
static const std::string kTlsModesDatagramArr[] = {"DTLS"};
::testing::internal::ParamGenerator<std::string>
TlsConnectTestBase::kTlsModesDatagram =
::testing::ValuesIn(kTlsModesDatagramArr);
static const std::string kTlsModesAllArr[] = {"TLS", "DTLS"};
::testing::internal::ParamGenerator<std::string>
TlsConnectTestBase::kTlsModesAll = ::testing::ValuesIn(kTlsModesAllArr);
static const uint16_t kTlsV10Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV10 = ::testing::ValuesIn(kTlsV10Arr);
static const uint16_t kTlsV11Arr[] = {SSL_LIBRARY_VERSION_TLS_1_1};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV11 = ::testing::ValuesIn(kTlsV11Arr);
static const uint16_t kTlsV10V11Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_1};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV10V11 = ::testing::ValuesIn(kTlsV10V11Arr);
static const uint16_t kTlsV10To12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_0,
SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_2};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV10To12 = ::testing::ValuesIn(kTlsV10To12Arr);
static const uint16_t kTlsV11V12Arr[] = {SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_2};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV11V12 = ::testing::ValuesIn(kTlsV11V12Arr);
// TODO: add TLS 1.3
static const uint16_t kTlsV12PlusArr[] = {SSL_LIBRARY_VERSION_TLS_1_2};
static const uint16_t kTlsV11PlusArr[] = {
#ifdef NSS_ENABLE_TLS_1_3
SSL_LIBRARY_VERSION_TLS_1_3,
#endif
SSL_LIBRARY_VERSION_TLS_1_2,
SSL_LIBRARY_VERSION_TLS_1_1
};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV11Plus = ::testing::ValuesIn(kTlsV11PlusArr);
static const uint16_t kTlsV12PlusArr[] = {
#ifdef NSS_ENABLE_TLS_1_3
SSL_LIBRARY_VERSION_TLS_1_3,
#endif
SSL_LIBRARY_VERSION_TLS_1_2
};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV12Plus = ::testing::ValuesIn(kTlsV12PlusArr);
static const uint16_t kTlsV13Arr[] = {SSL_LIBRARY_VERSION_TLS_1_3};
#ifdef NSS_ENABLE_TLS_1_3
static const uint16_t kTlsV13Arr[] = {
SSL_LIBRARY_VERSION_TLS_1_3
};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsV13 = ::testing::ValuesIn(kTlsV13Arr);
#endif
static const uint16_t kTlsVAllArr[] = {
#ifdef NSS_ENABLE_TLS_1_3
SSL_LIBRARY_VERSION_TLS_1_3,
#endif
SSL_LIBRARY_VERSION_TLS_1_2,
SSL_LIBRARY_VERSION_TLS_1_1,
SSL_LIBRARY_VERSION_TLS_1_0
};
::testing::internal::ParamGenerator<uint16_t>
TlsConnectTestBase::kTlsVAll = ::testing::ValuesIn(kTlsVAllArr);
static std::string VersionString(uint16_t version) {
switch(version) {
@ -66,20 +111,34 @@ TlsConnectTestBase::TlsConnectTestBase(Mode mode, uint16_t version)
expected_resumption_mode_(RESUME_NONE),
session_ids_(),
expect_extended_master_secret_(false) {
std::cerr << "Version: " << mode_ << " " << VersionString(version_) << std::endl;
std::string v;
if (mode_ == DGRAM && version_ == SSL_LIBRARY_VERSION_TLS_1_1) {
v = "1.0";
} else {
v = VersionString(version_);
}
std::cerr << "Version: " << mode_ << " " << v << std::endl;
}
TlsConnectTestBase::~TlsConnectTestBase() {
}
void TlsConnectTestBase::SetUp() {
// Configure a fresh session cache.
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
void TlsConnectTestBase::ClearStats() {
// Clear statistics.
SSL3Statistics* stats = SSL_GetStatistics();
memset(stats, 0, sizeof(*stats));
}
void TlsConnectTestBase::ClearServerCache() {
SSL_ShutdownServerSessionIDCache();
SSLInt_ClearSessionTicketKey();
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
}
void TlsConnectTestBase::SetUp() {
SSL_ConfigServerSessionIDCache(1024, 0, 0, g_working_dir_path.c_str());
SSLInt_ClearSessionTicketKey();
ClearStats();
Init();
}
@ -88,6 +147,7 @@ void TlsConnectTestBase::TearDown() {
delete server_;
SSL_ClearSessionCache();
SSLInt_ClearSessionTicketKey();
SSL_ShutdownServerSessionIDCache();
}
@ -250,8 +310,11 @@ void TlsConnectTestBase::CheckResumption(SessionResumptionMode expected) {
EXPECT_EQ(stateless_ct, stats->hch_sid_stateless_resumes);
EXPECT_EQ(stateless_ct, stats->hsh_sid_stateless_resumes);
if (resume_ct) {
if (resume_ct &&
client_->version() < SSL_LIBRARY_VERSION_TLS_1_3) {
// Check that the last two session ids match.
// TLS 1.3 doesn't do session id-based resumption. It's all
// tickets.
EXPECT_EQ(2U, session_ids_.size());
EXPECT_EQ(session_ids_[session_ids_.size()-1],
session_ids_[session_ids_.size()-2]);

View File

@ -22,12 +22,17 @@ namespace nss_test {
class TlsConnectTestBase : public ::testing::Test {
public:
static ::testing::internal::ParamGenerator<std::string> kTlsModesStream;
static ::testing::internal::ParamGenerator<std::string> kTlsModesDatagram;
static ::testing::internal::ParamGenerator<std::string> kTlsModesAll;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV10;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV11;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV10V11;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV11V12;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV12Plus;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV10To12;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV13;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV11Plus;
static ::testing::internal::ParamGenerator<uint16_t> kTlsV12Plus;
static ::testing::internal::ParamGenerator<uint16_t> kTlsVAll;
static inline Mode ToMode(const std::string& str) {
return str == "TLS" ? STREAM : DGRAM;
@ -41,6 +46,10 @@ class TlsConnectTestBase : public ::testing::Test {
// Initialize client and server.
void Init();
// Clear the statistics.
void ClearStats();
// Clear the server session cache.
void ClearServerCache();
// Re-initialize client and server with the default RSA cert.
void ResetRsa();
// Re-initialize client and server with an ECDSA cert on the server

View File

@ -5,6 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "tls_filter.h"
#include "sslproto.h"
#include <iostream>
#include "gtest_utils.h"
@ -271,4 +272,136 @@ PacketFilter::Action ChainedPacketFilter::Filter(const DataBuffer& input,
return changed ? CHANGE : KEEP;
}
PacketFilter::Action TlsExtensionFilter::FilterHandshake(
const HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output) {
if (header.handshake_type() == kTlsHandshakeClientHello) {
TlsParser parser(input);
if (!FindClientHelloExtensions(&parser, header)) {
return KEEP;
}
return FilterExtensions(&parser, input, output);
}
if (header.handshake_type() == kTlsHandshakeServerHello) {
TlsParser parser(input);
if (!FindServerHelloExtensions(&parser, header.version())) {
return KEEP;
}
return FilterExtensions(&parser, input, output);
}
return KEEP;
}
bool TlsExtensionFilter::FindClientHelloExtensions(TlsParser* parser,
const Versioned& header) {
if (!parser->Skip(2 + 32)) { // version + random
return false;
}
if (!parser->SkipVariable(1)) { // session ID
return false;
}
if (header.is_dtls() && !parser->SkipVariable(1)) { // DTLS cookie
return false;
}
if (!parser->SkipVariable(2)) { // cipher suites
return false;
}
if (!parser->SkipVariable(1)) { // compression methods
return false;
}
return true;
}
bool TlsExtensionFilter::FindServerHelloExtensions(TlsParser* parser,
uint16_t version) {
if (!parser->Skip(2 + 32)) { // version + random
return false;
}
if (!parser->SkipVariable(1)) { // session ID
return false;
}
if (!parser->Skip(2)) { // cipher suite
return false;
}
if (NormalizeTlsVersion(version) <= SSL_LIBRARY_VERSION_TLS_1_2) {
if (!parser->Skip(1)) { // compression method
return false;
}
}
return true;
}
PacketFilter::Action TlsExtensionFilter::FilterExtensions(
TlsParser* parser, const DataBuffer& input, DataBuffer* output) {
size_t length_offset = parser->consumed();
uint32_t all_extensions;
if (!parser->Read(&all_extensions, 2)) {
return KEEP; // no extensions, odd but OK
}
if (all_extensions != parser->remaining()) {
return KEEP; // malformed
}
bool changed = false;
// Write out the start of the message.
output->Allocate(input.len());
size_t offset = output->Write(0, input.data(), parser->consumed());
while (parser->remaining()) {
uint32_t extension_type;
if (!parser->Read(&extension_type, 2)) {
return KEEP; // malformed
}
DataBuffer extension;
if (!parser->ReadVariable(&extension, 2)) {
return KEEP; // malformed
}
DataBuffer filtered;
PacketFilter::Action action = FilterExtension(extension_type, extension,
&filtered);
if (action == DROP) {
changed = true;
std::cerr << "extension drop: " << extension << std::endl;
continue;
}
const DataBuffer* source = &extension;
if (action == CHANGE) {
EXPECT_GT(0x10000U, filtered.len());
changed = true;
std::cerr << "extension old: " << extension << std::endl;
std::cerr << "extension new: " << filtered << std::endl;
source = &filtered;
}
// Write out extension.
offset = output->Write(offset, extension_type, 2);
offset = output->Write(offset, source->len(), 2);
offset = output->Write(offset, *source);
}
output->Truncate(offset);
if (changed) {
size_t newlen = output->len() - length_offset - 2;
EXPECT_GT(0x10000U, newlen);
if (newlen >= 0x10000) {
return KEEP; // bad: size increased too much
}
output->Write(length_offset, newlen, 2);
return CHANGE;
}
return KEEP;
}
PacketFilter::Action TlsExtensionCapture::FilterExtension(
uint16_t extension_type, const DataBuffer& input, DataBuffer* output) {
if (extension_type == extension_) {
data_.Assign(input);
}
return KEEP;
}
} // namespace nss_test

View File

@ -181,6 +181,41 @@ class ChainedPacketFilter : public PacketFilter {
std::vector<PacketFilter*> filters_;
};
class TlsExtensionFilter : public TlsHandshakeFilter {
protected:
virtual PacketFilter::Action FilterHandshake(
const HandshakeHeader& header,
const DataBuffer& input, DataBuffer* output);
virtual PacketFilter::Action FilterExtension(uint16_t extension_type,
const DataBuffer& input,
DataBuffer* output) = 0;
public:
static bool FindClientHelloExtensions(TlsParser* parser,
const Versioned& header);
static bool FindServerHelloExtensions(TlsParser* parser, uint16_t version);
private:
PacketFilter::Action FilterExtensions(TlsParser* parser,
const DataBuffer& input,
DataBuffer* output);
};
class TlsExtensionCapture : public TlsExtensionFilter {
public:
TlsExtensionCapture(uint16_t ext)
: extension_(ext), data_() {}
virtual PacketFilter::Action FilterExtension(
uint16_t extension_type, const DataBuffer& input, DataBuffer* output);
const DataBuffer& extension() const { return data_; }
private:
const uint16_t extension_;
DataBuffer data_;
};
} // namespace nss_test
#endif

View File

@ -42,6 +42,8 @@ const uint8_t kTlsAlertDecodeError = 50;
const uint8_t kTlsAlertUnsupportedExtension = 110;
const uint8_t kTlsAlertNoApplicationProtocol = 120;
const uint8_t kTlsExtensionPreSharedKey = 41;
const uint8_t kTlsFakeChangeCipherSpec[] = {
kTlsChangeCipherSpecType, // Type
0xfe, 0xff, // Version

View File

@ -21,12 +21,13 @@ include $(CORE_DEPTH)/coreconf/config.mk
#######################################################################
#######################################################################
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
#######################################################################
include config.mk
include ../common/gtest.mk
CFLAGS += -I$(CORE_DEPTH)/lib/util
#######################################################################
# (5) Execute "global" rules. (OPTIONAL) #
@ -38,11 +39,7 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (6) Execute "component" rules. (OPTIONAL) #
#######################################################################
#include $(CORE_DEPTH)/$(MODULE)/config/rules.mk
#######################################################################
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################

View File

@ -0,0 +1,25 @@
# -*- makefile -*-
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
CORE_DEPTH = ../..
DEPTH = ../..
MODULE = nss
CPPSRCS = \
util_gtest.cc \
util_utf8_unittest.cc \
$(NULL)
INCLUDES += \
-I$(CORE_DEPTH)/external_tests/google_test/gtest/include \
-I$(CORE_DEPTH)/external_tests/common \
$(NULL)
REQUIRES = nspr gtest
PROGRAM = util_gtest
EXTRA_LIBS = \
$(DIST)/lib/$(LIB_PREFIX)gtest.$(LIB_SUFFIX) \
$(DIST)/lib/$(LIB_PREFIX)nssutil.$(LIB_SUFFIX) \
$(NULL)

View File

@ -0,0 +1,9 @@
#define GTEST_HAS_RTTI 0
#include "gtest/gtest.h"
int main(int argc, char **argv) {
// Start the tests
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

File diff suppressed because it is too large Load Diff

View File

@ -1398,14 +1398,13 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
char* rawEmailAddr = NULL;
char* addrBuf = NULL;
char* pBuf = NULL;
PLArenaPool* tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
PORTCheapArenaPool tmpArena;
PRUint32 maxLen = 0;
PRInt32 finalLen = 0;
SECStatus rv;
SECItem subAltName;
if (!tmpArena)
return addrBuf;
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
subAltName.data = NULL;
maxLen = cert->derCert.len;
@ -1413,35 +1412,37 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
if (!maxLen)
maxLen = 2000; /* a guess, should never happen */
pBuf = addrBuf = (char*)PORT_ArenaZAlloc(tmpArena, maxLen + 1);
pBuf = addrBuf = (char*)PORT_ArenaZAlloc(&tmpArena.arena, maxLen + 1);
if (!addrBuf)
goto loser;
rawEmailAddr =
CERT_GetNameElement(tmpArena, &cert->subject, SEC_OID_PKCS9_EMAIL_ADDRESS);
rawEmailAddr = CERT_GetNameElement(&tmpArena.arena, &cert->subject,
SEC_OID_PKCS9_EMAIL_ADDRESS);
pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
rawEmailAddr =
CERT_GetNameElement(tmpArena, &cert->subject, SEC_OID_RFC1274_MAIL);
rawEmailAddr = CERT_GetNameElement(&tmpArena.arena, &cert->subject,
SEC_OID_RFC1274_MAIL);
pBuf = appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, &subAltName);
if (rv == SECSuccess && subAltName.data) {
CERTGeneralName* nameList = NULL;
if (!!(nameList = CERT_DecodeAltNameExtension(tmpArena, &subAltName))) {
if (!!(nameList = CERT_DecodeAltNameExtension(&tmpArena.arena, &subAltName))) {
CERTGeneralName* current = nameList;
do {
if (current->type == certDirectoryName) {
rawEmailAddr =
CERT_GetNameElement(tmpArena, &current->name.directoryName,
CERT_GetNameElement(&tmpArena.arena,
&current->name.directoryName,
SEC_OID_PKCS9_EMAIL_ADDRESS);
pBuf =
appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
rawEmailAddr =
CERT_GetNameElement(
tmpArena, &current->name.directoryName, SEC_OID_RFC1274_MAIL);
CERT_GetNameElement(&tmpArena.arena,
&current->name.directoryName,
SEC_OID_RFC1274_MAIL);
pBuf =
appendStringToBuf(pBuf, rawEmailAddr, &maxLen);
} else if (current->type == certRFC822Name) {
@ -1464,8 +1465,7 @@ cert_GetCertificateEmailAddresses(CERTCertificate* cert)
}
}
loser:
if (tmpArena)
PORT_FreeArena(tmpArena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return pBuf;
}

View File

@ -257,27 +257,22 @@ SECStatus
CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
{
int rv;
PLArenaPool *arena;
PORTCheapArenaPool tmpArena;
CERTSignedData sd;
void *tmpptr;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
return (SECFailure);
}
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &sd, CERT_SignedDataTemplate,
derCert);
if (rv) {
goto loser;
}
PORT_Memset(derName, 0, sizeof(SECItem));
rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate,
&sd.data);
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, derName,
SEC_CertIssuerTemplate, &sd.data);
if (rv) {
goto loser;
}
@ -290,11 +285,11 @@ CERT_IssuerNameFromDERCert(SECItem *derCert, SECItem *derName)
PORT_Memcpy(derName->data, tmpptr, derName->len);
PORT_FreeArena(arena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return (SECSuccess);
loser:
PORT_FreeArena(arena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return (SECFailure);
}
@ -302,27 +297,22 @@ SECStatus
CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
{
int rv;
PLArenaPool *arena;
PORTCheapArenaPool tmpArena;
CERTSignedData sd;
void *tmpptr;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
return (SECFailure);
}
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
PORT_Memset(&sd, 0, sizeof(CERTSignedData));
rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &sd, CERT_SignedDataTemplate,
derCert);
if (rv) {
goto loser;
}
PORT_Memset(derName, 0, sizeof(SECItem));
rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate,
&sd.data);
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, derName,
SEC_CertSerialNumberTemplate, &sd.data);
if (rv) {
goto loser;
}
@ -335,11 +325,11 @@ CERT_SerialNumberFromDERCert(SECItem *derCert, SECItem *derName)
PORT_Memcpy(derName->data, tmpptr, derName->len);
PORT_FreeArena(arena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return (SECSuccess);
loser:
PORT_FreeArena(arena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return (SECFailure);
}
@ -2072,36 +2062,27 @@ CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
unsigned int cType = cert->nsCertType;
PRBool ret = PR_FALSE;
if (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
NS_CERT_TYPE_OBJECT_SIGNING_CA)) {
ret = PR_TRUE;
} else {
SECStatus rv;
CERTBasicConstraints constraints;
rv = CERT_FindBasicConstraintExten(cert, &constraints);
if (rv == SECSuccess && constraints.isCA) {
ret = PR_TRUE;
cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
}
}
/* finally check if it's an X.509 v1 root CA */
if (!ret &&
(cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3)) {
ret = PR_TRUE;
/*
* Check if the constraints are available and it's a CA, OR if it's
* a X.509 v1 Root CA.
*/
CERTBasicConstraints constraints;
if ((CERT_FindBasicConstraintExten(cert, &constraints) == SECSuccess &&
constraints.isCA) ||
(cert->isRoot && cert_Version(cert) < SEC_CERTIFICATE_VERSION_3))
cType |= (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
}
/* Now apply trust overrides, if any */
/*
* Apply trust overrides, if any.
*/
cType = cert_ComputeTrustOverrides(cert, cType);
ret = (cType & (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
NS_CERT_TYPE_OBJECT_SIGNING_CA))
? PR_TRUE
: PR_FALSE;
NS_CERT_TYPE_OBJECT_SIGNING_CA)) ? PR_TRUE : PR_FALSE;
if (rettype != NULL) {
if (rettype) {
*rettype = cType;
}
return ret;
}

View File

@ -129,18 +129,15 @@ CERT_FindSubjectKeyIDExtension(CERTCertificate *cert, SECItem *retItem)
rv = cert_FindExtension(cert->extensions, SEC_OID_X509_SUBJECT_KEY_ID,
&encodedValue);
if (rv == SECSuccess) {
PLArenaPool *tmpArena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (tmpArena) {
rv = SEC_QuickDERDecodeItem(tmpArena, &decodedValue,
SEC_ASN1_GET(SEC_OctetStringTemplate),
&encodedValue);
if (rv == SECSuccess) {
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
}
PORT_FreeArena(tmpArena, PR_FALSE);
} else {
rv = SECFailure;
PORTCheapArenaPool tmpArena;
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &decodedValue,
SEC_ASN1_GET(SEC_OctetStringTemplate),
&encodedValue);
if (rv == SECSuccess) {
rv = SECITEM_CopyItem(NULL, retItem, &decodedValue);
}
PORT_DestroyCheapArena(&tmpArena);
}
SECITEM_FreeItem(&encodedValue, PR_FALSE);
return rv;

View File

@ -394,24 +394,21 @@ CERT_FindBitStringExtension(CERTCertExtension **extensions, int tag,
{
SECItem wrapperItem, tmpItem = { siBuffer, 0 };
SECStatus rv;
PLArenaPool *arena = NULL;
PORTCheapArenaPool tmpArena;
wrapperItem.data = NULL;
tmpItem.data = NULL;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!arena) {
return (SECFailure);
}
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
rv = cert_FindExtension(extensions, tag, &wrapperItem);
if (rv != SECSuccess) {
goto loser;
}
rv = SEC_QuickDERDecodeItem(
arena, &tmpItem, SEC_ASN1_GET(SEC_BitStringTemplate), &wrapperItem);
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &tmpItem,
SEC_ASN1_GET(SEC_BitStringTemplate),
&wrapperItem);
if (rv != SECSuccess) {
goto loser;
@ -432,9 +429,7 @@ loser:
rv = SECFailure;
done:
if (arena) {
PORT_FreeArena(arena, PR_FALSE);
}
PORT_DestroyCheapArena(&tmpArena);
if (wrapperItem.data) {
PORT_Free(wrapperItem.data);

View File

@ -608,7 +608,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
const SEC_ASN1Template *theTemplate = NULL;
enum { conv_none, conv_ucs4, conv_ucs2, conv_iso88591 } convert = conv_none;
SECItem avaValue = { siBuffer, 0 };
PLArenaPool *newarena = NULL;
PORTCheapArenaPool tmpArena;
if (!derAVAValue || !derAVAValue->len || !derAVAValue->data) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
@ -648,20 +648,17 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
}
PORT_Memset(&avaValue, 0, sizeof(SECItem));
newarena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (!newarena) {
return NULL;
}
if (SEC_QuickDERDecodeItem(newarena, &avaValue, theTemplate, derAVAValue) !=
SECSuccess) {
PORT_FreeArena(newarena, PR_FALSE);
PORT_InitCheapArena(&tmpArena, DER_DEFAULT_CHUNKSIZE);
if (SEC_QuickDERDecodeItem(&tmpArena.arena, &avaValue, theTemplate,
derAVAValue) != SECSuccess) {
PORT_DestroyCheapArena(&tmpArena);
return NULL;
}
if (convert != conv_none) {
unsigned int utf8ValLen = avaValue.len * 3;
unsigned char *utf8Val =
(unsigned char *)PORT_ArenaZAlloc(newarena, utf8ValLen);
(unsigned char *)PORT_ArenaZAlloc(&tmpArena.arena, utf8ValLen);
switch (convert) {
case conv_ucs4:
@ -669,7 +666,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
!PORT_UCS4_UTF8Conversion(PR_FALSE, avaValue.data,
avaValue.len, utf8Val, utf8ValLen,
&utf8ValLen)) {
PORT_FreeArena(newarena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL;
}
@ -679,7 +676,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
!PORT_UCS2_UTF8Conversion(PR_FALSE, avaValue.data,
avaValue.len, utf8Val, utf8ValLen,
&utf8ValLen)) {
PORT_FreeArena(newarena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL;
}
@ -688,7 +685,7 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
if (!PORT_ISO88591_UTF8Conversion(avaValue.data, avaValue.len,
utf8Val, utf8ValLen,
&utf8ValLen)) {
PORT_FreeArena(newarena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL;
}
@ -703,6 +700,6 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
}
retItem = SECITEM_DupItem(&avaValue);
PORT_FreeArena(newarena, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return retItem;
}

View File

@ -93,7 +93,7 @@ CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
const SECItem *encodedValue)
{
EncodedContext decodeContext;
PLArenaPool *our_pool;
PORTCheapArenaPool tmpArena;
SECStatus rv = SECSuccess;
do {
@ -104,13 +104,9 @@ CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
decodeContext.isCA.data = &hexFalse;
decodeContext.isCA.len = 1;
our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (our_pool == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
GEN_BREAK(SECFailure);
}
PORT_InitCheapArena(&tmpArena, SEC_ASN1_DEFAULT_ARENA_SIZE);
rv = SEC_QuickDERDecodeItem(our_pool, &decodeContext,
rv = SEC_QuickDERDecodeItem(&tmpArena.arena, &decodeContext,
CERTBasicConstraintsTemplate, encodedValue);
if (rv == SECFailure)
break;
@ -140,8 +136,8 @@ CERT_DecodeBasicConstraintValue(CERTBasicConstraints *value,
GEN_BREAK(SECFailure);
break;
}
} while (0);
PORT_FreeArena(our_pool, PR_FALSE);
PORT_DestroyCheapArena(&tmpArena);
return (rv);
}

View File

@ -355,6 +355,9 @@ crmf_copy_poposigningkey(PLArenaPool *poolp,
if (inPopoSignKey->derInput.data != NULL) {
rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput,
&inPopoSignKey->derInput);
if (rv != SECSuccess) {
goto loser;
}
}
destPopoSignKey->algorithmIdentifier = (poolp == NULL) ? PORT_ZNew(SECAlgorithmID)
: PORT_ArenaZNew(poolp, SECAlgorithmID);

View File

@ -1020,7 +1020,7 @@ __expand_table(HTAB *hashp)
hashp->DSIZE = dirsize << 1;
}
if ((hashp->dir[new_segnum] =
(SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(SEGMENT))) == NULL)
(SEGMENT)calloc((size_t)hashp->SGSIZE, sizeof(BUFHEAD *))) == NULL)
return (-1);
hashp->exsegs++;
hashp->nsegs++;
@ -1091,13 +1091,13 @@ alloc_segs(
register SEGMENT store;
if ((hashp->dir =
(SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT *))) == NULL) {
(SEGMENT *)calloc((size_t)hashp->DSIZE, sizeof(SEGMENT))) == NULL) {
errno = ENOMEM;
return (-1);
}
/* Allocate segments */
if ((store =
(SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(SEGMENT))) == NULL) {
(SEGMENT)calloc((size_t)nsegs << hashp->SSHIFT, sizeof(BUFHEAD *))) == NULL) {
errno = ENOMEM;
return (-1);
}

View File

@ -46,13 +46,24 @@ ifeq ($(FREEBL_NO_DEPEND),1)
endif
ifeq ($(FREEBL_LOWHASH),1)
DEFINES += -DFREEBL_LOWHASH
LOWHASH_SRCS = nsslowhash.c
LOWHASH_EXPORTS = nsslowhash.h
MAPFILE_SOURCE = freebl_hash.def
MAPFILE_SOURCE = freebl_hash_vector.def
NEED_STUB_BUILD = 1
else
MAPFILE_SOURCE = freebl.def
endif
ifdef USE_STUB_BUILD
CSRCS = lowhash_vector.c
SIMPLE_OBJS = $(CSRCS:.c=$(OBJ_SUFFIX))
OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(SIMPLE_OBJS))
ALL_TRASH := $(TARGETS) $(OBJS) $(OBJDIR) LOGS TAGS $(GARBAGE) \
$(NOSUCHFILE) so_locations
MAPFILE_SOURCE = freebl_hash.def
endif
# FREEBL_USE_PRELINK
#
# Most modern version of Linux support a speed optimization scheme where an
@ -87,6 +98,10 @@ ifdef LINUX
DEFINES += -D__GNU_SOURCE=1
endif
endif
ifdef NSS_NO_INIT_SUPPORT
DEFINES += -DNSS_NO_INIT_SUPPORT
endif
ifdef FREEBL_PRELINK_COMMAND
DEFINES +=-DFREEBL_PRELINK_COMMAND=\"$(FREEBL_PRELINK_COMMAND)\"
endif
@ -112,7 +127,7 @@ ifeq (OS2,$(OS_TARGET))
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D
DEFINES += -DMP_USE_UINT_DIGIT -DMP_NO_MP_WORD
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
DEFINES += -DMP_IS_LITTLE_ENDIAN
endif
ifeq (,$(filter-out WINNT WIN95,$(OS_TARGET)))
@ -148,7 +163,7 @@ else
endif
else
# -DMP_NO_MP_WORD
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
DEFINES += -DMP_IS_LITTLE_ENDIAN
ifdef NS_USE_GCC
# Ideally, we should use amd64 assembly code, but it's not yet mingw-w64
# compatible.
@ -203,7 +218,7 @@ ifeq ($(CPU_ARCH),x86_64)
ASFLAGS += -fPIC -Wa,--noexecstack
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
DEFINES += -DNSS_USE_COMBA
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
DEFINES += -DMP_IS_LITTLE_ENDIAN
# DEFINES += -DMPI_AMD64_ADD
# comment the next four lines to turn off Intel HW acceleration.
DEFINES += -DUSE_HW_AES -DINTEL_GCM
@ -216,7 +231,7 @@ ifeq ($(CPU_ARCH),x86)
ASFILES = mpi_x86.s
DEFINES += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE
DEFINES += -DMP_ASSEMBLY_DIV_2DX1D -DMP_USE_UINT_DIGIT
DEFINES += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
DEFINES += -DMP_IS_LITTLE_ENDIAN
# The floating point ECC code doesn't work on Linux x86 (bug 311432).
#ECL_USE_FP = 1
endif
@ -226,6 +241,11 @@ ifeq ($(CPU_ARCH),arm)
DEFINES += -DSHA_NO_LONG_LONG # avoid 64-bit arithmetic in SHA512
MPI_SRCS += mpi_arm.c
endif
ifeq ($(CPU_ARCH),ppc)
ifdef USE_64
DEFINES += -DNSS_NO_INIT_SUPPORT
endif # USE_64
endif # ppc
endif # Linux
ifeq ($(OS_TARGET),AIX)
@ -454,7 +474,7 @@ else
# Intel acceleration for GCM does not build currently with Studio
endif
DEFINES += -DNSS_BEVAND_ARCFOUR -DMPI_AMD64 -DMP_ASSEMBLY_MULTIPLY
DEFINES += -DNSS_USE_COMBA -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
DEFINES += -DNSS_USE_COMBA -DMP_IS_LITTLE_ENDIAN
# comment the next two lines to turn off Intel HW acceleration
DEFINES += -DUSE_HW_AES
ASFILES += intel-aes.s
@ -484,7 +504,7 @@ endif
# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
# in GCC 4.6.0.
ifeq ($(CC_NAME),clang)
ifdef CC_IS_CLANG
HAVE_INT128_SUPPORT = 1
else ifeq (1,$(CC_IS_GCC))
ifneq (,$(filter 4.6 4.7 4.8 4.9,$(word 1,$(GCC_VERSION)).$(word 2,$(GCC_VERSION))))
@ -598,6 +618,17 @@ release_md libs:: $(SINGLE_SHLIB_DIR)
endif
ifdef NEED_STUB_BUILD
SINGLE_SHLIB_DIR = $(OBJDIR)/$(OS_TARGET)_SINGLE_SHLIB
ALL_TRASH += $(SINGLE_SHLIB_DIR)
$(SINGLE_SHLIB_DIR):
-mkdir $(SINGLE_SHLIB_DIR)
release_md libs:: $(SINGLE_SHLIB_DIR)
$(MAKE) FREEBL_CHILD_BUILD=1 USE_STUB_BUILD=1 \
OBJDIR=$(SINGLE_SHLIB_DIR) $@
endif
# multiple shared libraries
######################## ABI32_FPU stuff #########################
@ -697,8 +728,8 @@ $(OBJDIR)/$(PROG_PREFIX)intel-gcm-wrap$(OBJ_SUFFIX): CFLAGS += -mssse3
# symbolic names to registers, for example,
# .set Htbl, %rdi
# So we can't use Clang's integrated assembler with intel-gcm.s.
ifneq (,$(findstring clang,$(shell $(AS) --version)))
$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): ASFLAGS += -no-integrated-as
ifdef CC_IS_CLANG
$(OBJDIR)/$(PROG_PREFIX)intel-gcm$(OBJ_SUFFIX): CFLAGS += -no-integrated-as
endif
endif

View File

@ -21,6 +21,9 @@ typedef void (*freeblDestroyFunc)(void *cx, PRBool freeit);
SEC_BEGIN_PROTOS
SECStatus BL_FIPSEntryOK(PRBool freeblOnly);
PRBool BL_POSTRan(PRBool freeblOnly);
#if defined(XP_UNIX) && !defined(NO_FORK_CHECK)
extern PRBool bl_parentForkedAfterC_Initialize;

View File

@ -0,0 +1,98 @@
/*
* * blname.c - determine the freebl library name.
* *
* * This Source Code Form is subject to the terms of the Mozilla Public
* * License, v. 2.0. If a copy of the MPL was not distributed with this
* * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#if defined(FREEBL_LOWHASH)
static const char* default_name =
SHLIB_PREFIX"freeblpriv"SHLIB_VERSION"."SHLIB_SUFFIX;
#else
static const char* default_name =
SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
#endif
/* getLibName() returns the name of the library to load. */
#if defined(SOLARIS) && defined(__sparc)
#include <stddef.h>
#include <strings.h>
#include <sys/systeminfo.h>
#if defined(NSS_USE_64)
const static char fpu_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
const static char int_hybrid_shared_lib[] = "libfreebl_64int_3.so";
const static char non_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
const static char int_hybrid_isa[] = "sparcv9";
const static char fpu_hybrid_isa[] = "sparcv9+vis";
#else
const static char fpu_hybrid_shared_lib[] = "libfreebl_32fpu_3.so";
const static char int_hybrid_shared_lib[] = "libfreebl_32int64_3.so";
/* This was for SPARC V8, now obsolete. */
const static char *const non_hybrid_shared_lib = NULL;
const static char int_hybrid_isa[] = "sparcv8plus";
const static char fpu_hybrid_isa[] = "sparcv8plus+vis";
#endif
static const char *
getLibName(void)
{
char * found_int_hybrid;
char * found_fpu_hybrid;
long buflen;
char buf[256];
buflen = sysinfo(SI_ISALIST, buf, sizeof buf);
if (buflen <= 0)
return NULL;
/* sysinfo output is always supposed to be NUL terminated, but ... */
if (buflen < sizeof buf)
buf[buflen] = '\0';
else
buf[(sizeof buf) - 1] = '\0';
/* The ISA list is a space separated string of names of ISAs and
* ISA extensions, in order of decreasing performance.
* There are two different ISAs with which NSS's crypto code can be
* accelerated. If both are in the list, we take the first one.
* If one is in the list, we use it, and if neither then we use
* the base unaccelerated code.
*/
found_int_hybrid = strstr(buf, int_hybrid_isa);
found_fpu_hybrid = strstr(buf, fpu_hybrid_isa);
if (found_fpu_hybrid &&
(!found_int_hybrid ||
(found_int_hybrid - found_fpu_hybrid) >= 0)) {
return fpu_hybrid_shared_lib;
}
if (found_int_hybrid) {
return int_hybrid_shared_lib;
}
return non_hybrid_shared_lib;
}
#elif defined(HPUX) && !defined(NSS_USE_64) && !defined(__ia64)
#include <unistd.h>
/* This code tests to see if we're running on a PA2.x CPU.
** It returns true (1) if so, and false (0) otherwise.
*/
static const char *
getLibName(void)
{
long cpu = sysconf(_SC_CPU_VERSION);
return (cpu == CPU_PA_RISC2_0)
? "libfreebl_32fpu_3.sl"
: "libfreebl_32int_3.sl" ;
}
#else
/* default case, for platforms/ABIs that have only one freebl shared lib. */
static const char * getLibName(void) { return default_name; }
#endif

View File

@ -30,6 +30,7 @@ CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
}
/* Invariant: 0 < ctr->bufPtr <= blocksize */
ctr->checkWrap = PR_FALSE;
ctr->bufPtr = blocksize; /* no unused data in the buffer */
ctr->cipher = cipher;
ctr->context = context;
@ -40,6 +41,10 @@ CTR_InitContext(CTRContext *ctr, void *context, freeblCipherFunc cipher,
return SECFailure;
}
PORT_Memcpy(ctr->counter, ctrParams->cb, blocksize);
if (ctr->counterBits < 64) {
PORT_Memcpy(ctr->counterFirst, ctr->counter, blocksize);
ctr->checkWrap = PR_TRUE;
}
return SECSuccess;
}
@ -147,6 +152,12 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
ctr->counter, blocksize, blocksize);
ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
if (ctr->checkWrap) {
if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
}
if (rv != SECSuccess) {
return SECFailure;
}
@ -162,6 +173,12 @@ CTR_Update(CTRContext *ctr, unsigned char *outbuf,
rv = (*ctr->cipher)(ctr->context, ctr->buffer, &tmp, blocksize,
ctr->counter, blocksize, blocksize);
ctr_GetNextCtr(ctr->counter, ctr->counterBits, blocksize);
if (ctr->checkWrap) {
if (PORT_Memcmp(ctr->counter, ctr->counterFirst, blocksize) == 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
}
if (rv != SECSuccess) {
return SECFailure;
}

View File

@ -14,6 +14,8 @@ struct CTRContextStr {
void *context;
unsigned char counter[MAX_BLOCK_SIZE];
unsigned char buffer[MAX_BLOCK_SIZE];
unsigned char counterFirst[MAX_BLOCK_SIZE]; /* counter overlfow value */
PRBool checkWrap; /*check for counter overflow*/
unsigned long counterBits;
unsigned int bufPtr;
};

View File

@ -97,6 +97,7 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
unsigned int tmp;
int fullblocks;
int written;
unsigned char *saveout = outbuf;
SECStatus rv;
if (inlen < blocksize) {
@ -141,6 +142,8 @@ CTS_EncryptUpdate(CTSContext *cts, unsigned char *outbuf,
PORT_Memset(lastBlock, 0, blocksize);
if (rv == SECSuccess) {
*outlen = written + blocksize;
} else {
PORT_Memset(saveout, 0, written+blocksize);
}
return rv;
}
@ -184,6 +187,7 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
unsigned char Cn[MAX_BLOCK_SIZE]; /* block Cn */
unsigned char lastBlock[MAX_BLOCK_SIZE];
const unsigned char *tmp;
unsigned char *saveout = outbuf;
unsigned int tmpLen;
unsigned int fullblocks, pad;
unsigned int i;
@ -280,6 +284,8 @@ CTS_DecryptUpdate(CTSContext *cts, unsigned char *outbuf,
rv = (*cts->cipher)(cts->context, Pn, &tmpLen, blocksize, lastBlock,
blocksize, blocksize);
if (rv != SECSuccess) {
PORT_Memset(lastBlock, 0, blocksize);
PORT_Memset(saveout, 0, *outlen);
return SECFailure;
}
/* make up for the out of order CBC decryption */

View File

@ -173,8 +173,8 @@ DH_NewKey(DHParams *params, DHPrivateKey **privKey)
/* Generate private key xa */
SECITEM_AllocItem(arena, &key->privateValue,
dh_GetSecretKeyLen(params->prime.len));
RNG_GenerateGlobalRandomBytes(key->privateValue.data,
key->privateValue.len);
CHECK_SEC_OK(RNG_GenerateGlobalRandomBytes(key->privateValue.data,
key->privateValue.len));
SECITEM_TO_MPINT( key->privateValue, &xa );
/* xa < p */
CHECK_MPI_OK( mp_mod(&xa, &p, &xa) );
@ -191,8 +191,10 @@ cleanup:
MP_TO_SEC_ERROR(err);
rv = SECFailure;
}
if (rv)
if (rv) {
*privKey = NULL;
PORT_FreeArena(arena, PR_TRUE);
}
return rv;
}
@ -272,6 +274,10 @@ DH_Derive(SECItem *publicValue,
/* allocate a buffer which can hold the entire derived secret. */
secret = PORT_Alloc(len);
if (secret == NULL) {
err = MP_MEM;
goto cleanup;
}
/* grab the derived secret */
err = mp_to_unsigned_octets(&ZZ, secret, len);
if (err >= 0) err = MP_OKAY;
@ -285,7 +291,10 @@ DH_Derive(SECItem *publicValue,
nb = outBytes;
else
nb = len;
SECITEM_AllocItem(NULL, derivedSecret, nb);
if (SECITEM_AllocItem(NULL, derivedSecret, nb) == NULL) {
err = MP_MEM;
goto cleanup;
}
if (len < nb) {
unsigned int offset = nb - len;
memset(derivedSecret->data, 0, offset);
@ -360,11 +369,19 @@ KEA_Derive(SECItem *prime,
/* allocate a buffer for the full derived secret */
len = mp_unsigned_octet_size(&w);
secret = PORT_Alloc(len);
if (secret == NULL) {
err = MP_MEM;
goto cleanup;
}
/* grab the secret */
err = mp_to_unsigned_octets(&w, secret, len);
if (err > 0) err = MP_OKAY;
/* allocate output buffer */
SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN);
if (SECITEM_AllocItem(NULL, derivedSecret, KEA_DERIVED_SECRET_LEN)
== NULL) {
err = MP_MEM;
goto cleanup;
}
memset(derivedSecret->data, 0, derivedSecret->len);
/* copy in the 128 lsb of the secret */
if (len >= KEA_DERIVED_SECRET_LEN) {
@ -387,6 +404,8 @@ cleanup:
PORT_ZFree(secret, len);
if (err) {
MP_TO_SEC_ERROR(err);
if (derivedSecret->data)
PORT_ZFree(derivedSecret->data, derivedSecret->len);
return SECFailure;
}
return SECSuccess;

View File

@ -76,7 +76,7 @@ struct RNGContextStr {
#define V(rng) (((rng)->V_Data)+1)
#define VSize(rng) ((sizeof (rng)->V_Data) -1)
PRUint8 C[PRNG_SEEDLEN]; /* internal state variables */
PRUint8 oldV[PRNG_SEEDLEN]; /* for continuous rng checking */
PRUint8 lastOutput[SHA256_LENGTH]; /* for continuous rng checking */
/* If we get calls for the PRNG to return less than the length of our
* hash, we extend the request for a full hash (since we'll be doing
* the full hash anyway). Future requests for random numbers are fulfilled
@ -286,6 +286,8 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
unsigned int no_of_returned_bytes)
{
PRUint8 data[VSize(rng)];
PRUint8 thisHash[SHA256_LENGTH];
PRUint8 *lastHash = rng->lastOutput;
PORT_Memcpy(data, V(rng), VSize(rng));
while (no_of_returned_bytes) {
@ -295,7 +297,16 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
SHA256_Begin(&ctx);
SHA256_Update(&ctx, data, sizeof data);
SHA256_End(&ctx, returned_bytes, &len, no_of_returned_bytes);
SHA256_End(&ctx, thisHash, &len, SHA256_LENGTH);
if (PORT_Memcmp(lastHash, thisHash, len) == 0) {
rng->isValid = PR_FALSE;
break;
}
if (no_of_returned_bytes < SHA256_LENGTH) {
len = no_of_returned_bytes;
}
PORT_Memcpy(returned_bytes, thisHash, len);
lastHash = returned_bytes;
returned_bytes += len;
no_of_returned_bytes -= len;
/* The carry parameter is a bool (increment or not).
@ -303,7 +314,9 @@ prng_Hashgen(RNGContext *rng, PRUint8 *returned_bytes,
carry = no_of_returned_bytes;
PRNG_ADD_CARRY_ONLY(data, (sizeof data)- 1, carry);
}
PORT_Memcpy(rng->lastOutput, thisHash, SHA256_LENGTH);
PORT_Memset(data, 0, sizeof data);
PORT_Memset(thisHash, 0, sizeof thisHash);
}
/*
@ -347,8 +360,13 @@ prng_generateNewBytes(RNGContext *rng,
}
if (no_of_returned_bytes == SHA256_LENGTH) {
/* short_cut to hashbuf and save a copy and a clear */
/* short_cut to hashbuf and a couple of copies and clears */
SHA256_HashBuf(returned_bytes, V(rng), VSize(rng) );
/* continuous rng check */
if (memcmp(rng->lastOutput, returned_bytes, SHA256_LENGTH) == 0) {
rng->isValid = PR_FALSE;
}
PORT_Memcpy(rng->lastOutput, returned_bytes, sizeof rng->lastOutput);
} else {
prng_Hashgen(rng, returned_bytes, no_of_returned_bytes);
}
@ -362,13 +380,12 @@ prng_generateNewBytes(RNGContext *rng,
carry = 1;
PRNG_ADD_CARRY_ONLY(rng->reseed_counter,(sizeof rng->reseed_counter)-1, carry);
/* continuous rng check */
if (memcmp(V(rng), rng->oldV, sizeof rng->oldV) == 0) {
rng->isValid = PR_FALSE;
/* if the prng failed, don't return any output, signal softoken */
if (!rng->isValid) {
PORT_Memset(returned_bytes, 0, no_of_returned_bytes);
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
PORT_Memcpy(rng->oldV, V(rng), sizeof rng->oldV);
return SECSuccess;
}

View File

@ -61,16 +61,16 @@ ec_points_mul(const ECParams *params, const mp_int *k1, const mp_int *k2,
printf("\n");
if (k1 != NULL) {
mp_tohex(k1, mpstr);
mp_tohex((mp_int*)k1, mpstr);
printf("ec_points_mul: scalar k1: %s\n", mpstr);
mp_todecimal(k1, mpstr);
mp_todecimal((mp_int*)k1, mpstr);
printf("ec_points_mul: scalar k1: %s (dec)\n", mpstr);
}
if (k2 != NULL) {
mp_tohex(k2, mpstr);
mp_tohex((mp_int*)k2, mpstr);
printf("ec_points_mul: scalar k2: %s\n", mpstr);
mp_todecimal(k2, mpstr);
mp_todecimal((mp_int*)k2, mpstr);
printf("ec_points_mul: scalar k2: %s (dec)\n", mpstr);
}
@ -376,7 +376,7 @@ cleanup:
rv = SECFailure;
}
if (rv != SECSuccess && privKeyBytes) {
PORT_Free(privKeyBytes);
PORT_ZFree(privKeyBytes,2*len);
privKeyBytes = NULL;
}
return privKeyBytes;
@ -1075,7 +1075,7 @@ cleanup:
mp_clear(&v);
mp_clear(&n);
if (pointC.data) SECITEM_FreeItem(&pointC, PR_FALSE);
if (pointC.data) SECITEM_ZfreeItem(&pointC, PR_FALSE);
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;

View File

@ -5,10 +5,10 @@
/* This source file is meant to be included by other source files
* (ecp_fp###.c, where ### is one of 160, 192, 224) and should not
* constitute an independent compilation unit. It requires the following
* preprocessor definitions be made: ECFP_BSIZE - the number of bits in
* the field's prime
* preprocessor definitions be made:
* ECFP_BSIZE - the number of bits in the field's prime
* ECFP_NUMDOUBLES - the number of doubles to store one
* multi-precision integer in floating point
* multi-precision integer in floating point */
/* Adds a prefix to a given token to give a unique token name. Prefixes
* with "ecfp" + ECFP_BSIZE + "_". e.g. if ECFP_BSIZE = 160, then

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
;+#
;+# This Source Code Form is subject to the terms of the Mozilla Public
;+# License, v. 2.0. If a copy of the MPL was not distributed with this
;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
;+#
;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
;+# 1. For all unix platforms, the string ";-" means "remove this line"
;+# 2. For all unix platforms, the string " DATA " will be removed from any
;+# line on which it occurs.
;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
;+# On AIX, lines containing ";+" will be removed.
;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
;+# 5. For all unix platforms, after the above processing has taken place,
;+# all characters after the first ";" on the line will be removed.
;+# And for AIX, the first ";" will also be removed.
;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
;+# directives are hidden behind ";", ";+", and ";-"
;+
;+NSSprivate_3.11 { # NSS 3.11 release
;+ global:
LIBRARY freebl3 ;-
EXPORTS ;-
FREEBL_GetVector;
;+ local:
;+ *;
;+};
;+NSSprivate_3.16 { # NSS 3.11 release
;+ global:
LIBRARY freebl3 ;-
EXPORTS ;-
NSSLOW_GetVector;
;+ local:
;+ *;
;+};

View File

@ -192,9 +192,7 @@ gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
mp_clear(&ghash->H);
mp_clear(&ghash->X);
mp_clear(&ghash->C_i);
MP_DIGITS(&ghash->H) = 0;
MP_DIGITS(&ghash->X) = 0;
MP_DIGITS(&ghash->C_i) = 0;
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
if (freeit) {
PORT_Free(ghash);
}
@ -267,6 +265,7 @@ gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
}
rv = SECSuccess;
cleanup:
PORT_Memset(tmp_buf, 0, sizeof(tmp_buf));
if (rv != SECSuccess) {
MP_TO_SEC_ERROR(err);
}
@ -366,6 +365,7 @@ cleanup:
static void
gcmHash_DestroyContext(gcmHashContext *ghash, PRBool freeit)
{
PORT_Memset(ghash, 0, sizeof(gcmHashContext));
if (freeit) {
PORT_Free(ghash);
}
@ -423,6 +423,7 @@ gcm_HashMult(gcmHashContext *ghash, const unsigned char *buf,
}
GCM_TRACE_X(ghash, "X%d = ")
}
PORT_Memset(C_i, 0, sizeof(C_i));
return SECSuccess;
}
@ -538,26 +539,30 @@ gcmHash_Final(gcmHashContext *ghash, unsigned char *outbuf,
rv = gcmHash_Sync(ghash, blocksize);
if (rv != SECSuccess) {
return SECFailure;
goto cleanup;
}
rv = gcm_HashMult(ghash, ghash->counterBuf, (GCM_HASH_LEN_LEN*2)/blocksize,
blocksize);
if (rv != SECSuccess) {
return SECFailure;
goto cleanup;
}
GCM_TRACE_X(ghash, "GHASH(H,A,C) = ")
rv = gcm_getX(ghash, T, blocksize);
if (rv != SECSuccess) {
return SECFailure;
goto cleanup;
}
if (maxout > blocksize) maxout = blocksize;
PORT_Memcpy(outbuf, T, maxout);
*outlen = maxout;
return SECSuccess;
rv = SECSuccess;
cleanup:
PORT_Memset(T, 0, sizeof(T));
return rv;
}
SECStatus
@ -695,6 +700,8 @@ GCM_DestroyContext(GCMContext *gcm, PRBool freeit)
* allocated data (like mp_int's) */
CTR_DestroyContext(&gcm->ctr_context, PR_FALSE);
gcmHash_DestroyContext(&gcm->ghash_context, PR_FALSE);
PORT_Memset(&gcm->tagBits, 0, sizeof(gcm->tagBits));
PORT_Memset(gcm->tagKey, 0, sizeof(gcm->tagKey));
if (freeit) {
PORT_Free(gcm);
}
@ -838,8 +845,10 @@ GCM_DecryptUpdate(GCMContext *gcm, unsigned char *outbuf,
if (NSS_SecureMemcmp(tag, intag, tagBytes) != 0) {
/* force a CKR_ENCRYPTED_DATA_INVALID error at in softoken */
PORT_SetError(SEC_ERROR_BAD_DATA);
PORT_Memset(tag, 0, sizeof(tag));
return SECFailure;
}
PORT_Memset(tag, 0, sizeof(tag));
/* finish the decryption */
return CTR_Update(&gcm->ctr_context, outbuf, outlen, maxout,
inbuf, inlen, blocksize);

View File

@ -12,7 +12,7 @@ extern int FREEBL_InitStubs(void);
#include "loader.h"
#include "alghmac.h"
#include "hmacct.h"
#include "blapii.h"
static const struct FREEBLVectorStr vector =
{
@ -299,15 +299,54 @@ static const struct FREEBLVectorStr vector =
/* End of Version 3.018 */
};
const FREEBLVector *
FREEBL_GetVector(void)
{
#ifdef FREEBL_NO_DEPEND
SECStatus rv;
#endif
#define NSS_VERSION_VARIABLE __nss_freebl_version
#include "verref.h"
#ifdef FREEBL_NO_DEPEND
FREEBL_InitStubs();
/* this entry point is only valid if nspr and nss-util has been loaded */
rv = FREEBL_InitStubs();
if (rv != SECSuccess) {
return NULL;
}
#endif
/* make sure the Full self tests have been run before continuing */
BL_POSTRan(PR_FALSE);
return &vector;
}
#ifdef FREEBL_LOWHASH
static const struct NSSLOWVectorStr nssvector =
{
sizeof nssvector,
NSSLOW_VERSION,
FREEBL_GetVector,
NSSLOW_Init,
NSSLOW_Shutdown,
NSSLOW_Reset,
NSSLOWHASH_NewContext,
NSSLOWHASH_Begin,
NSSLOWHASH_Update,
NSSLOWHASH_End,
NSSLOWHASH_Destroy,
NSSLOWHASH_Length
};
const NSSLOWVector *
NSSLOW_GetVector(void)
{
/* POST check and stub init happens in FREEBL_GetVector() and
* NSSLOW_Init() respectively */
return &nssvector;
}
#endif

View File

@ -10,93 +10,7 @@
#include "prerror.h"
#include "prinit.h"
#include "prenv.h"
static const char* default_name =
SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
/* getLibName() returns the name of the library to load. */
#if defined(SOLARIS) && defined(__sparc)
#include <stddef.h>
#include <strings.h>
#include <sys/systeminfo.h>
#if defined(NSS_USE_64)
const static char fpu_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
const static char int_hybrid_shared_lib[] = "libfreebl_64int_3.so";
const static char non_hybrid_shared_lib[] = "libfreebl_64fpu_3.so";
const static char int_hybrid_isa[] = "sparcv9";
const static char fpu_hybrid_isa[] = "sparcv9+vis";
#else
const static char fpu_hybrid_shared_lib[] = "libfreebl_32fpu_3.so";
const static char int_hybrid_shared_lib[] = "libfreebl_32int64_3.so";
/* This was for SPARC V8, now obsolete. */
const static char *const non_hybrid_shared_lib = NULL;
const static char int_hybrid_isa[] = "sparcv8plus";
const static char fpu_hybrid_isa[] = "sparcv8plus+vis";
#endif
static const char *
getLibName(void)
{
char * found_int_hybrid;
char * found_fpu_hybrid;
long buflen;
char buf[256];
buflen = sysinfo(SI_ISALIST, buf, sizeof buf);
if (buflen <= 0)
return NULL;
/* sysinfo output is always supposed to be NUL terminated, but ... */
if (buflen < sizeof buf)
buf[buflen] = '\0';
else
buf[(sizeof buf) - 1] = '\0';
/* The ISA list is a space separated string of names of ISAs and
* ISA extensions, in order of decreasing performance.
* There are two different ISAs with which NSS's crypto code can be
* accelerated. If both are in the list, we take the first one.
* If one is in the list, we use it, and if neither then we use
* the base unaccelerated code.
*/
found_int_hybrid = strstr(buf, int_hybrid_isa);
found_fpu_hybrid = strstr(buf, fpu_hybrid_isa);
if (found_fpu_hybrid &&
(!found_int_hybrid ||
(found_int_hybrid - found_fpu_hybrid) >= 0)) {
return fpu_hybrid_shared_lib;
}
if (found_int_hybrid) {
return int_hybrid_shared_lib;
}
return non_hybrid_shared_lib;
}
#elif defined(HPUX) && !defined(NSS_USE_64) && !defined(__ia64)
#include <unistd.h>
/* This code tests to see if we're running on a PA2.x CPU.
** It returns true (1) if so, and false (0) otherwise.
*/
static const char *
getLibName(void)
{
long cpu = sysconf(_SC_CPU_VERSION);
return (cpu == CPU_PA_RISC2_0)
? "libfreebl_32fpu_3.sl"
: "libfreebl_32int_3.sl" ;
}
#else
/* default case, for platforms/ABIs that have only one freebl shared lib. */
static const char * getLibName(void) { return default_name; }
#endif
#include "blname.c"
#include "prio.h"
#include "prprf.h"
@ -106,7 +20,7 @@ static const char * getLibName(void) { return default_name; }
static const char *NameOfThisSharedLib =
SHLIB_PREFIX"softokn"SOFTOKEN_SHLIB_VERSION"."SHLIB_SUFFIX;
static PRLibrary* blLib;
static PRLibrary* blLib = NULL;
#define LSB(x) ((x)&0xff)
#define MSB(x) ((x)>>8)
@ -149,12 +63,12 @@ freebl_LoadDSO( void )
}
}
#ifdef DEBUG
{
if (blLib) {
PRStatus status = PR_UnloadLibrary(blLib);
PORT_Assert(PR_SUCCESS == status);
}
#else
PR_UnloadLibrary(blLib);
if (blLib) PR_UnloadLibrary(blLib);
#endif
}
return PR_FAILURE;
@ -2184,3 +2098,4 @@ ChaCha20Poly1305_Open(const ChaCha20Poly1305Context *ctx,
ctx, output, outputLen, maxOutputLen, input, inputLen,
nonce, nonceLen, ad, adLen);
}

View File

@ -10,6 +10,7 @@
#include "blapi.h"
#define FREEBL_VERSION 0x0312
struct FREEBLVectorStr {
@ -740,8 +741,43 @@ struct FREEBLVectorStr {
typedef struct FREEBLVectorStr FREEBLVector;
#ifdef FREEBL_LOWHASH
#include "nsslowhash.h"
#define NSSLOW_VERSION 0x0300
struct NSSLOWVectorStr {
unsigned short length; /* of this struct in bytes */
unsigned short version; /* of this struct. */
const FREEBLVector *(*p_FREEBL_GetVector)(void);
NSSLOWInitContext *(*p_NSSLOW_Init)(void);
void (*p_NSSLOW_Shutdown)(NSSLOWInitContext *context);
void (*p_NSSLOW_Reset)(NSSLOWInitContext *context);
NSSLOWHASHContext *(*p_NSSLOWHASH_NewContext)(
NSSLOWInitContext *initContext,
HASH_HashType hashType);
void (*p_NSSLOWHASH_Begin)(NSSLOWHASHContext *context);
void (*p_NSSLOWHASH_Update)(NSSLOWHASHContext *context,
const unsigned char *buf,
unsigned int len);
void (*p_NSSLOWHASH_End)(NSSLOWHASHContext *context,
unsigned char *buf,
unsigned int *ret, unsigned int len);
void (*p_NSSLOWHASH_Destroy)(NSSLOWHASHContext *context);
unsigned int (*p_NSSLOWHASH_Length)(NSSLOWHASHContext *context);
};
typedef struct NSSLOWVectorStr NSSLOWVector;
#endif
SEC_BEGIN_PROTOS
#ifdef FREEBL_LOWHASH
typedef const NSSLOWVector * NSSLOWGetVectorFn(void);
extern NSSLOWGetVectorFn NSSLOW_GetVector;
#endif
typedef const FREEBLVector * FREEBLGetVectorFn(void);
extern FREEBLGetVectorFn FREEBL_GetVector;

View File

@ -0,0 +1,206 @@
/*
* loader.c - load platform dependent DSO containing freebl implementation.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#define _GNU_SOURCE 1
#include "loader.h"
#include "prmem.h"
#include "prerror.h"
#include "prinit.h"
#include "prenv.h"
#include "blname.c"
#include "prio.h"
#include "prprf.h"
#include <stdio.h>
#include "prsystem.h"
#include "nsslowhash.h"
#include <dlfcn.h>
#include "pratom.h"
static PRLibrary* blLib;
#define LSB(x) ((x)&0xff)
#define MSB(x) ((x)>>8)
static const NSSLOWVector *vector;
static const char *libraryName = NULL;
/* pretty much only glibc uses this, make sure we don't have any depenencies
* on nspr.. */
#undef PORT_Alloc
#undef PORT_Free
#define PORT_Alloc malloc
#define PR_Malloc malloc
#define PORT_Free free
#define PR_Free free
#define PR_GetDirectorySeparator() '/'
#define PR_LoadLibraryWithFlags(libspec,flags) \
(PRLibrary*)dlopen(libSpec.value.pathname,RTLD_NOW|RTLD_LOCAL)
#define PR_GetLibraryFilePathname(name,addr) \
freebl_lowhash_getLibraryFilePath(addr)
static char *
freebl_lowhash_getLibraryFilePath(void *addr)
{
Dl_info dli;
if (dladdr(addr, &dli) == 0) {
return NULL;
}
return strdup(dli.dli_fname);
}
/*
* The PR_LoadLibraryWithFlags call above defines this variable away, so we
* don't need it..
*/
#ifdef nodef
static const char *NameOfThisSharedLib =
SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX;
#endif
#include "genload.c"
/* This function must be run only once. */
/* determine if hybrid platform, then actually load the DSO. */
static PRStatus
freebl_LoadDSO( void )
{
PRLibrary * handle;
const char * name = getLibName();
if (!name) {
/*PR_SetError(PR_LOAD_LIBRARY_ERROR,0); */
return PR_FAILURE;
}
handle = loader_LoadLibrary(name);
if (handle) {
void *address = dlsym(handle, "NSSLOW_GetVector");
if (address) {
NSSLOWGetVectorFn * getVector = (NSSLOWGetVectorFn *)address;
const NSSLOWVector * dsoVector = getVector();
if (dsoVector) {
unsigned short dsoVersion = dsoVector->version;
unsigned short myVersion = NSSLOW_VERSION;
if (MSB(dsoVersion) == MSB(myVersion) &&
LSB(dsoVersion) >= LSB(myVersion) &&
dsoVector->length >= sizeof(NSSLOWVector)) {
vector = dsoVector;
libraryName = name;
blLib = handle;
return PR_SUCCESS;
}
}
}
(void)dlclose(handle);
}
return PR_FAILURE;
}
static PRCallOnceType loadFreeBLOnce;
static PRStatus
freebl_RunLoaderOnce( void )
{
/* Don't have NSPR, so can use the real PR_CallOnce, implement a stripped
* down version. */
if (loadFreeBLOnce.initialized) {
return loadFreeBLOnce.status;
}
if (__sync_lock_test_and_set(&loadFreeBLOnce.inProgress,1) == 0) {
loadFreeBLOnce.status = freebl_LoadDSO();
loadFreeBLOnce.initialized = 1;
} else {
/* shouldn't have a lot of takers on the else clause, which is good
* since we don't have condition variables yet.
* 'initialized' only ever gets set (not cleared) so we don't
* need the traditional locks. */
while (!loadFreeBLOnce.initialized) {
sleep(1); /* don't have condition variables, just give up the CPU */
}
}
return loadFreeBLOnce.status;
}
const FREEBLVector *FREEBL_GetVector(void)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return NULL;
return (vector->p_FREEBL_GetVector)();
}
NSSLOWInitContext *NSSLOW_Init(void)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return NULL;
return (vector->p_NSSLOW_Init)();
}
void NSSLOW_Shutdown(NSSLOWInitContext *context)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_NSSLOW_Shutdown)(context);
}
void NSSLOW_Reset(NSSLOWInitContext *context)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_NSSLOW_Reset)(context);
}
NSSLOWHASHContext *NSSLOWHASH_NewContext(
NSSLOWInitContext *initContext,
HASH_HashType hashType)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return NULL;
return (vector->p_NSSLOWHASH_NewContext)(initContext, hashType);
}
void NSSLOWHASH_Begin(NSSLOWHASHContext *context)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_NSSLOWHASH_Begin)(context);
}
void NSSLOWHASH_Update(NSSLOWHASHContext *context,
const unsigned char *buf,
unsigned int len)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_NSSLOWHASH_Update)(context, buf, len);
}
void NSSLOWHASH_End(NSSLOWHASHContext *context,
unsigned char *buf,
unsigned int *ret, unsigned int len)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_NSSLOWHASH_End)(context, buf, ret, len);
}
void NSSLOWHASH_Destroy(NSSLOWHASHContext *context)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return;
(vector->p_NSSLOWHASH_Destroy)(context);
}
unsigned int NSSLOWHASH_Length(NSSLOWHASHContext *context)
{
if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
return -1;
return (vector->p_NSSLOWHASH_Length)(context);
}

View File

@ -10,6 +10,30 @@ CORE_DEPTH = ../..
MODULE = nss
# copied from Linux.mk. We have a chicken and egg issue here. We need to set
# Library name before we call the platform code in coreconf, but we need to
# Pick up the automatic setting of FREEBL_LOWHASH before we can set the
# Library name... so for now we mimic the code in Linux.mk to get the
# automatic setting early...
#
# On Linux 2.6 or later, build libfreebl3.so with no NSPR and libnssutil3.so
# dependencies by default. Set FREEBL_NO_DEPEND to 0 in the environment to
# override this.
#
#
include $(CORE_DEPTH)/coreconf/arch.mk
ifeq ($(OS_ARCH),Linux)
ifneq ($(OS_TARGET),Android)
ifeq (2.6,$(firstword $(sort 2.6 $(OS_RELEASE))))
ifndef FREEBL_NO_DEPEND
FREEBL_NO_DEPEND = 1
FREEBL_LOWHASH = 1
endif
endif
endif
endif
LIBRARY_NAME = freebl
LIBRARY_VERSION = 3
@ -29,6 +53,13 @@ ifdef FREEBL_CHILD_BUILD
ifdef USE_ABI64_FPU
LIBRARY_NAME = freebl_64fpu
endif
ifdef FREEBL_LOWHASH
LIBRARY_NAME = freeblpriv
endif
ifdef USE_STUB_BUILD
# for the stub build, reset name to the default (from freeblpriv)
LIBRARY_NAME = freebl
endif
endif
# if the library name contains _, we prefix the version with _
@ -105,6 +136,7 @@ CSRCS = \
chacha20poly1305.c \
cts.c \
ctr.c \
fipsfreebl.c \
gcm.c \
hmacct.c \
rijndael.c \

View File

@ -545,7 +545,9 @@ mp_err mp_div_d(const mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
rem = DIGIT(a, 0) & mask;
if(q) {
mp_copy(a, q);
if((res = mp_copy(a, q)) != MP_OKAY) {
return res;
}
s_mp_div_2d(q, pow);
}
@ -1314,8 +1316,8 @@ mp_err mp_sqrt(const mp_int *a, mp_int *b)
for(;;) {
/* t = (x * x) - a */
mp_copy(&x, &t); /* can't fail, t is big enough for original x */
if((res = mp_sqr(&t, &t)) != MP_OKAY ||
if((res = mp_copy(&x, &t)) != MP_OKAY ||
(res = mp_sqr(&t, &t)) != MP_OKAY ||
(res = mp_sub(&t, a, &t)) != MP_OKAY)
goto CLEANUP;
@ -1488,8 +1490,10 @@ mp_err s_mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *m, mp_int *c
mp_set(&s, 1);
/* mu = b^2k / m */
s_mp_add_d(&mu, 1);
s_mp_lshd(&mu, 2 * USED(m));
if((res = s_mp_add_d(&mu, 1)) != MP_OKAY)
goto CLEANUP;
if((res = s_mp_lshd(&mu, 2 * USED(m))) != MP_OKAY)
goto CLEANUP;
if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
goto CLEANUP;
@ -1675,7 +1679,7 @@ int mp_cmp(const mp_int *a, const mp_int *b)
Compares |a| <=> |b|, and returns an appropriate comparison result
*/
int mp_cmp_mag(mp_int *a, mp_int *b)
int mp_cmp_mag(const mp_int *a, const mp_int *b)
{
ARGCHK(a != NULL && b != NULL, MP_EQ);
@ -1700,7 +1704,8 @@ int mp_cmp_int(const mp_int *a, long z)
ARGCHK(a != NULL, MP_EQ);
mp_init(&tmp); mp_set_int(&tmp, z);
mp_init(&tmp);
mp_set_int(&tmp, z);
out = mp_cmp(a, &tmp);
mp_clear(&tmp);
@ -1937,8 +1942,8 @@ mp_err mp_xgcd(const mp_int *a, const mp_int *b, mp_int *g, mp_int *x, mp_int *y
MP_CHECKOK( s_mp_mul_2d(&gx,n) );
}
mp_copy(&xc, &u);
mp_copy(&yc, &v);
MP_CHECKOK(mp_copy(&xc, &u));
MP_CHECKOK(mp_copy(&yc, &v));
mp_set(&A, 1); mp_set(&D, 1);
/* Loop through binary GCD algorithm */
@ -4275,7 +4280,7 @@ mp_err s_mp_div(mp_int *rem, /* i: dividend, o: remainder */
*/
for (i = 4; s_mp_cmp(&t, &part) > 0 && i > 0; --i) {
--q_msd;
s_mp_sub(&t, div); /* t -= div */
MP_CHECKOK(s_mp_sub(&t, div)); /* t -= div */
}
if (i < 0) {
res = MP_RANGE;

View File

@ -219,7 +219,7 @@ mp_err mp_exptmod_d(const mp_int *a, mp_digit d, const mp_int *m, mp_int *c);
int mp_cmp_z(const mp_int *a);
int mp_cmp_d(const mp_int *a, mp_digit d);
int mp_cmp(const mp_int *a, const mp_int *b);
int mp_cmp_mag(mp_int *a, mp_int *b);
int mp_cmp_mag(const mp_int *a, const mp_int *b);
int mp_cmp_int(const mp_int *a, long z);
int mp_isodd(const mp_int *a);
int mp_iseven(const mp_int *a);

View File

@ -21,15 +21,6 @@
#endif
#include <stddef.h> /* ptrdiff_t */
/* if MP_CHAR_STORE_SLOW is defined, we */
/* need to know endianness of this platform. */
#ifdef MP_CHAR_STORE_SLOW
#if !defined(MP_IS_BIG_ENDIAN) && !defined(MP_IS_LITTLE_ENDIAN)
#error "You must define MP_IS_BIG_ENDIAN or MP_IS_LITTLE_ENDIAN\n" \
" if you define MP_CHAR_STORE_SLOW."
#endif
#endif
#define STATIC
#define MAX_ODD_INTS 32 /* 2 ** (WINDOW_BITS - 1) */
@ -506,17 +497,16 @@ mp_err mp_set_safe_modexp(int value)
#ifdef MP_USING_CACHE_SAFE_MOD_EXP
#define WEAVE_WORD_SIZE 4
#ifndef MP_CHAR_STORE_SLOW
/*
* mpi_to_weave takes an array of bignums, a matrix in which each bignum
* occupies all the columns of a row, and transposes it into a matrix in
* mpi_to_weave takes an array of bignums, a matrix in which each bignum
* occupies all the columns of a row, and transposes it into a matrix in
* which each bignum occupies a column of every row. The first row of the
* input matrix becomes the first column of the output matrix. The n'th
* row of input becomes the n'th column of output. The input data is said
* to be "interleaved" or "woven" into the output matrix.
*
* The array of bignums is left in this woven form. Each time a single
* bignum value is needed, it is recreated by fetching the n'th column,
* bignum value is needed, it is recreated by fetching the n'th column,
* forming a single row which is the new bignum.
*
* The purpose of this interleaving is make it impossible to determine which
@ -526,46 +516,37 @@ mp_err mp_set_safe_modexp(int value)
* The weaving function does not transpose the entire input matrix in one call.
* It transposes 4 rows of mp_ints into their respective columns of output.
*
* There are two different implementations of the weaving and unweaving code
* in this file. One uses byte loads and stores. The second uses loads and
* stores of mp_weave_word size values. The weaved forms of these two
* implementations differ. Consequently, each one has its own explanation.
*
* Here is the explanation for the byte-at-a-time implementation.
*
* This implementation treats each mp_int bignum as an array of bytes,
* rather than as an array of mp_digits. It stores those bytes as a
* column of bytes in the output matrix. It doesn't care if the machine
* uses big-endian or little-endian byte ordering within mp_digits.
* The first byte of the mp_digit array becomes the first byte in the output
* column, regardless of whether that byte is the MSB or LSB of the mp_digit.
* This implementation treats each mp_int bignum as an array of mp_digits,
* It stores those bytes as a column of mp_digits in the output matrix. It
* doesn't care if the machine uses big-endian or little-endian byte ordering
* within mp_digits.
*
* "bignums" is an array of mp_ints.
* It points to four rows, four mp_ints, a subset of a larger array of mp_ints.
*
* "weaved" is the weaved output matrix.
* "weaved" is the weaved output matrix.
* The first byte of bignums[0] is stored in weaved[0].
*
* "nBignums" is the total number of bignums in the array of which "bignums"
* is a part.
*
* "nDigits" is the size in mp_digits of each mp_int in the "bignums" array.
* mp_ints that use less than nDigits digits are logically padded with zeros
* "nBignums" is the total number of bignums in the array of which "bignums"
* is a part.
*
* "nDigits" is the size in mp_digits of each mp_int in the "bignums" array.
* mp_ints that use less than nDigits digits are logically padded with zeros
* while being stored in the weaved array.
*/
mp_err mpi_to_weave(const mp_int *bignums,
unsigned char *weaved,
mp_size nDigits, /* in each mp_int of input */
mp_size nBignums) /* in the entire source array */
mp_err mpi_to_weave(const mp_int *bignums,
mp_digit *weaved,
mp_size nDigits, /* in each mp_int of input */
mp_size nBignums) /* in the entire source array */
{
mp_size i;
unsigned char * endDest = weaved + (nDigits * nBignums * sizeof(mp_digit));
mp_digit *endDest = weaved + (nDigits * nBignums);
for (i=0; i < WEAVE_WORD_SIZE; i++) {
mp_size used = MP_USED(&bignums[i]);
unsigned char *pSrc = (unsigned char *)MP_DIGITS(&bignums[i]);
unsigned char *endSrc = pSrc + (used * sizeof(mp_digit));
unsigned char *pDest = weaved + i;
mp_digit *pSrc = MP_DIGITS(&bignums[i]);
mp_digit *endSrc = pSrc + used;
mp_digit *pDest = weaved + i;
ARGCHK(MP_SIGN(&bignums[i]) == MP_ZPOS, MP_BADARG);
ARGCHK(used <= nDigits, MP_BADARG);
@ -583,267 +564,45 @@ mp_err mpi_to_weave(const mp_int *bignums,
return MP_OKAY;
}
/*
* These functions return 0xffffffff if the output is true, and 0 otherwise.
*/
#define CONST_TIME_MSB(x) (0L - ((x) >> (8*sizeof(x) - 1)))
#define CONST_TIME_EQ_Z(x) CONST_TIME_MSB(~(x) & ((x)-1))
#define CONST_TIME_EQ(a, b) CONST_TIME_EQ_Z((a) ^ (b))
/* Reverse the operation above for one mp_int.
* Reconstruct one mp_int from its column in the weaved array.
* "pSrc" points to the offset into the weave array of the bignum we
* are going to reconstruct.
* Every read accesses every element of the weaved array, in order to
* avoid timing attacks based on patterns of memory accesses.
*/
mp_err weave_to_mpi(mp_int *a, /* output, result */
const unsigned char *pSrc, /* input, byte matrix */
mp_size nDigits, /* per mp_int output */
mp_size nBignums) /* bignums in weaved matrix */
mp_err weave_to_mpi(mp_int *a, /* out, result */
const mp_digit *weaved, /* in, byte matrix */
mp_size index, /* which column to read */
mp_size nDigits, /* number of mp_digits in each bignum */
mp_size nBignums) /* width of the matrix */
{
unsigned char *pDest = (unsigned char *)MP_DIGITS(a);
unsigned char *endDest = pDest + (nDigits * sizeof(mp_digit));
/* these are indices, but need to be the same size as mp_digit
* because of the CONST_TIME operations */
mp_digit i, j;
mp_digit d;
mp_digit *pDest = MP_DIGITS(a);
MP_SIGN(a) = MP_ZPOS;
MP_USED(a) = nDigits;
for (; pDest < endDest; pSrc += nBignums, pDest++) {
*pDest = *pSrc;
}
s_mp_clamp(a);
return MP_OKAY;
}
#else
/* Need a primitive that we know is 32 bits long... */
/* this is true on all modern processors we know of today*/
typedef unsigned int mp_weave_word;
/*
* on some platforms character stores into memory is very expensive since they
* generate a read/modify/write operation on the bus. On those platforms
* we need to do integer writes to the bus. Because of some unrolled code,
* in this current code the size of mp_weave_word must be four. The code that
* makes this assumption explicity is called out. (on some platforms a write
* of 4 bytes still requires a single read-modify-write operation.
*
* This function is takes the identical parameters as the function above,
* however it lays out the final array differently. Where the previous function
* treats the mpi_int as an byte array, this function treats it as an array of
* mp_digits where each digit is stored in big endian order.
*
* since we need to interleave on a byte by byte basis, we need to collect
* several mpi structures together into a single PRUint32 before we write. We
* also need to make sure the PRUint32 is arranged so that the first value of
* the first array winds up in b[0]. This means construction of that PRUint32
* is endian specific (even though the layout of the mp_digits in the array
* is always big endian).
*
* The final data is stored as follows :
*
* Our same logical array p array, m is sizeof(mp_digit),
* N is still count and n is now b_size. If we define p[i].digit[j]0 as the
* most significant byte of the word p[i].digit[j], p[i].digit[j]1 as
* the next most significant byte of p[i].digit[j], ... and p[i].digit[j]m-1
* is the least significant byte.
* Our array would look like:
* p[0].digit[0]0 p[1].digit[0]0 ... p[N-2].digit[0]0 p[N-1].digit[0]0
* p[0].digit[0]1 p[1].digit[0]1 ... p[N-2].digit[0]1 p[N-1].digit[0]1
* . .
* p[0].digit[0]m-1 p[1].digit[0]m-1 ... p[N-2].digit[0]m-1 p[N-1].digit[0]m-1
* p[0].digit[1]0 p[1].digit[1]0 ... p[N-2].digit[1]0 p[N-1].digit[1]0
* . .
* . .
* p[0].digit[n-1]m-2 p[1].digit[n-1]m-2 ... p[N-2].digit[n-1]m-2 p[N-1].digit[n-1]m-2
* p[0].digit[n-1]m-1 p[1].digit[n-1]m-1 ... p[N-2].digit[n-1]m-1 p[N-1].digit[n-1]m-1
*
*/
mp_err mpi_to_weave(const mp_int *a, unsigned char *b,
mp_size b_size, mp_size count)
{
mp_size i;
mp_digit *digitsa0;
mp_digit *digitsa1;
mp_digit *digitsa2;
mp_digit *digitsa3;
mp_size useda0;
mp_size useda1;
mp_size useda2;
mp_size useda3;
mp_weave_word *weaved = (mp_weave_word *)b;
count = count/sizeof(mp_weave_word);
/* this code pretty much depends on this ! */
#if MP_ARGCHK == 2
assert(WEAVE_WORD_SIZE == 4);
assert(sizeof(mp_weave_word) == 4);
#endif
digitsa0 = MP_DIGITS(&a[0]);
digitsa1 = MP_DIGITS(&a[1]);
digitsa2 = MP_DIGITS(&a[2]);
digitsa3 = MP_DIGITS(&a[3]);
useda0 = MP_USED(&a[0]);
useda1 = MP_USED(&a[1]);
useda2 = MP_USED(&a[2]);
useda3 = MP_USED(&a[3]);
ARGCHK(MP_SIGN(&a[0]) == MP_ZPOS, MP_BADARG);
ARGCHK(MP_SIGN(&a[1]) == MP_ZPOS, MP_BADARG);
ARGCHK(MP_SIGN(&a[2]) == MP_ZPOS, MP_BADARG);
ARGCHK(MP_SIGN(&a[3]) == MP_ZPOS, MP_BADARG);
ARGCHK(useda0 <= b_size, MP_BADARG);
ARGCHK(useda1 <= b_size, MP_BADARG);
ARGCHK(useda2 <= b_size, MP_BADARG);
ARGCHK(useda3 <= b_size, MP_BADARG);
#define SAFE_FETCH(digit, used, word) ((word) < (used) ? (digit[word]) : 0)
for (i=0; i < b_size; i++) {
mp_digit d0 = SAFE_FETCH(digitsa0,useda0,i);
mp_digit d1 = SAFE_FETCH(digitsa1,useda1,i);
mp_digit d2 = SAFE_FETCH(digitsa2,useda2,i);
mp_digit d3 = SAFE_FETCH(digitsa3,useda3,i);
register mp_weave_word acc;
/*
* ONE_STEP takes the MSB of each of our current digits and places that
* byte in the appropriate position for writing to the weaved array.
* On little endian:
* b3 b2 b1 b0
* On big endian:
* b0 b1 b2 b3
* When the data is written it would always wind up:
* b[0] = b0
* b[1] = b1
* b[2] = b2
* b[3] = b3
*
* Once we've written the MSB, we shift the whole digit up left one
* byte, putting the Next Most Significant Byte in the MSB position,
* so we we repeat the next one step that byte will be written.
* NOTE: This code assumes sizeof(mp_weave_word) and MP_WEAVE_WORD_SIZE
* is 4.
*/
#ifdef MP_IS_LITTLE_ENDIAN
#define MPI_WEAVE_ONE_STEP \
acc = (d0 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d0 <<= 8; /*b0*/ \
acc |= (d1 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d1 <<= 8; /*b1*/ \
acc |= (d2 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d2 <<= 8; /*b2*/ \
acc |= (d3 >> (MP_DIGIT_BIT-32)) & 0xff000000; d3 <<= 8; /*b3*/ \
*weaved = acc; weaved += count;
#else
#define MPI_WEAVE_ONE_STEP \
acc = (d0 >> (MP_DIGIT_BIT-32)) & 0xff000000; d0 <<= 8; /*b0*/ \
acc |= (d1 >> (MP_DIGIT_BIT-24)) & 0x00ff0000; d1 <<= 8; /*b1*/ \
acc |= (d2 >> (MP_DIGIT_BIT-16)) & 0x0000ff00; d2 <<= 8; /*b2*/ \
acc |= (d3 >> (MP_DIGIT_BIT-8)) & 0x000000ff; d3 <<= 8; /*b3*/ \
*weaved = acc; weaved += count;
#endif
switch (sizeof(mp_digit)) {
case 32:
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
case 16:
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
case 8:
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
case 4:
MPI_WEAVE_ONE_STEP
MPI_WEAVE_ONE_STEP
case 2:
MPI_WEAVE_ONE_STEP
case 1:
MPI_WEAVE_ONE_STEP
break;
}
}
return MP_OKAY;
}
/* reverse the operation above for one entry.
* b points to the offset into the weave array of the power we are
* calculating */
mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
mp_size b_size, mp_size count)
{
mp_digit *pb = MP_DIGITS(a);
mp_digit *end = &pb[b_size];
MP_SIGN(a) = MP_ZPOS;
MP_USED(a) = b_size;
for (; pb < end; pb++) {
register mp_digit digit;
digit = *b << 8; b += count;
#define MPI_UNWEAVE_ONE_STEP digit |= *b; b += count; digit = digit << 8;
switch (sizeof(mp_digit)) {
case 32:
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
case 16:
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
case 8:
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
case 4:
MPI_UNWEAVE_ONE_STEP
MPI_UNWEAVE_ONE_STEP
case 2:
break;
/* Fetch the proper column in constant time, indexing over the whole array */
for (i=0; i<nDigits; ++i) {
d = 0;
for (j=0; j<nBignums; ++j) {
d |= weaved[i*nBignums + j] & CONST_TIME_EQ(j, index);
}
digit |= *b; b += count;
*pb = digit;
pDest[i] = d;
}
s_mp_clamp(a);
return MP_OKAY;
}
#endif
#define SQR(a,b) \
MP_CHECKOK( mp_sqr(a, b) );\
@ -859,7 +618,7 @@ mp_err weave_to_mpi(mp_int *a, const unsigned char *b,
#endif
#define MUL(x,a,b) \
MP_CHECKOK( weave_to_mpi(&tmp, powers + (x), nLen, num_powers) ); \
MP_CHECKOK( weave_to_mpi(&tmp, powers, (x), nLen, num_powers) ); \
MUL_NOWEAVE(&tmp,a,b)
#define SWAPPA ptmp = pa1; pa1 = pa2; pa2 = ptmp
@ -883,8 +642,8 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase,
int expOff;
mp_int accum1, accum2, accum[WEAVE_WORD_SIZE];
mp_int tmp;
unsigned char *powersArray = NULL;
unsigned char *powers = NULL;
mp_digit *powersArray = NULL;
mp_digit *powers = NULL;
MP_DIGITS(&accum1) = 0;
MP_DIGITS(&accum2) = 0;
@ -915,13 +674,13 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase,
MP_CHECKOK( mp_copy(montBase, &accum[1]) );
SQR(montBase, &accum[2]);
MUL_NOWEAVE(montBase, &accum[2], &accum[3]);
powersArray = (unsigned char *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
powersArray = (mp_digit *)malloc(num_powers*(nLen*sizeof(mp_digit)+1));
if (!powersArray) {
res = MP_MEM;
goto CLEANUP;
}
/* powers[i] = base ** (i); */ \
powers = (unsigned char *)MP_ALIGN(powersArray,num_powers); \
powers = (mp_digit *)MP_ALIGN(powersArray,num_powers); \
MP_CHECKOK( mpi_to_weave(accum, powers, nLen, num_powers) );
if (first_window < 4) {
MP_CHECKOK( mp_copy(&accum[first_window], &accum1) );
@ -968,7 +727,7 @@ mp_err mp_exptmod_safe_i(const mp_int * montBase,
* value is overwritten, so we need to fetch it from the stored
* weave array */
if (i > 2* WEAVE_WORD_SIZE) {
MP_CHECKOK(weave_to_mpi(&accum2, powers+i/2, nLen, num_powers));
MP_CHECKOK(weave_to_mpi(&accum2, powers, i/2, nLen, num_powers));
SQR(&accum2, &accum[acc_index]);
} else {
int half_power_index = (i/2) & (WEAVE_WORD_SIZE-1);

View File

@ -410,31 +410,32 @@ mp_err mpp_make_prime(mp_int *start, mp_size nBits, mp_size strong,
MP_DIGITS(&q) = 0;
MP_CHECKOK( mp_init(&trial) );
MP_CHECKOK( mp_init(&q) );
/* values taken from table 4.4, HandBook of Applied Cryptography */
if (nBits >= 1300) {
num_tests = 2;
} else if (nBits >= 850) {
/* values originally taken from table 4.4,
* HandBook of Applied Cryptography, augmented by FIPS-186
* requirements, Table C.2 and C.3 */
if (nBits >= 2000) {
num_tests = 3;
} else if (nBits >= 650) {
} else if (nBits >= 1536) {
num_tests = 4;
} else if (nBits >= 550) {
} else if (nBits >= 1024) {
num_tests = 5;
} else if (nBits >= 450) {
} else if (nBits >= 550) {
num_tests = 6;
} else if (nBits >= 400) {
} else if (nBits >= 450) {
num_tests = 7;
} else if (nBits >= 350) {
} else if (nBits >= 400) {
num_tests = 8;
} else if (nBits >= 300) {
} else if (nBits >= 350) {
num_tests = 9;
} else if (nBits >= 300) {
num_tests = 10;
} else if (nBits >= 250) {
num_tests = 12;
num_tests = 20;
} else if (nBits >= 200) {
num_tests = 15;
} else if (nBits >= 150) {
num_tests = 18;
num_tests = 41;
} else if (nBits >= 100) {
num_tests = 27;
num_tests = 38; /* funny anomaly in the FIPS tables, for aux primes, the
* required more iterations for larger aux primes */
} else
num_tests = 50;

View File

@ -171,7 +171,7 @@ ifeq ($(TARGET),x86LINUX)
#Linux
AS_OBJS = mpi_x86.o
MPICMN += -DMP_ASSEMBLY_MULTIPLY -DMP_ASSEMBLY_SQUARE -DMP_ASSEMBLY_DIV_2DX1D
MPICMN += -DMP_MONT_USE_MP_MUL -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
MPICMN += -DMP_MONT_USE_MP_MUL -DMP_IS_LITTLE_ENDIAN
CFLAGS= -O2 -fPIC -DLINUX1_2 -Di386 -D_XOPEN_SOURCE -DLINUX2_1 -ansi -Wall \
-pipe -DLINUX -Dlinux -D_POSIX_SOURCE -D_BSD_SOURCE -DHAVE_STRERROR \
-DXP_UNIX -UDEBUG -DNDEBUG -D_REENTRANT $(MPICMN)
@ -193,7 +193,7 @@ ifeq ($(TARGET),AMD64SOLARIS)
ASFLAGS += -xarch=generic64
AS_OBJS = mpi_amd64.o mpi_amd64_sun.o
MP_CONFIG = -DMP_ASSEMBLY_MULTIPLY -DMPI_AMD64
MP_CONFIG += -DMP_CHAR_STORE_SLOW -DMP_IS_LITTLE_ENDIAN
MP_CONFIG += -DMP_IS_LITTLE_ENDIAN
CFLAGS = -xarch=generic64 -xO4 -I. -DMP_API_COMPATIBLE -DMP_IOFUNC $(MP_CONFIG)
MPICMN += $(MP_CONFIG)

View File

@ -7,244 +7,11 @@
#endif
#include "prtypes.h"
#include "secerr.h"
#include "pkcs11t.h"
#include "blapi.h"
#include "hasht.h"
#include "plhash.h"
#include "nsslowhash.h"
/* FIPS preprocessor directives for message digests */
#define FIPS_KNOWN_HASH_MESSAGE_LENGTH 64 /* 512-bits */
/* Known Hash Message (512-bits). Used for all hashes (incl. SHA-N [N>1]). */
static const PRUint8 known_hash_message[] = {
"The test message for the MD2, MD5, and SHA-1 hashing algorithms." };
static CK_RV
freebl_fips_MD2_PowerUpSelfTest( void )
{
/* MD2 Known Digest Message (128-bits). */
static const PRUint8 md2_known_digest[] = {
0x41,0x5a,0x12,0xb2,0x3f,0x28,0x97,0x17,
0x0c,0x71,0x4e,0xcc,0x40,0xc8,0x1d,0x1b};
/* MD2 variables. */
MD2Context * md2_context;
unsigned int md2_bytes_hashed;
PRUint8 md2_computed_digest[MD2_LENGTH];
/***********************************************/
/* MD2 Single-Round Known Answer Hashing Test. */
/***********************************************/
md2_context = MD2_NewContext();
if( md2_context == NULL )
return( CKR_HOST_MEMORY );
MD2_Begin( md2_context );
MD2_Update( md2_context, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
MD2_End( md2_context, md2_computed_digest, &md2_bytes_hashed, MD2_LENGTH );
MD2_DestroyContext( md2_context , PR_TRUE );
if( ( md2_bytes_hashed != MD2_LENGTH ) ||
( PORT_Memcmp( md2_computed_digest, md2_known_digest,
MD2_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
return( CKR_OK );
}
static CK_RV
freebl_fips_MD5_PowerUpSelfTest( void )
{
/* MD5 Known Digest Message (128-bits). */
static const PRUint8 md5_known_digest[] = {
0x25,0xc8,0xc0,0x10,0xc5,0x6e,0x68,0x28,
0x28,0xa4,0xa5,0xd2,0x98,0x9a,0xea,0x2d};
/* MD5 variables. */
PRUint8 md5_computed_digest[MD5_LENGTH];
SECStatus md5_status;
/***********************************************/
/* MD5 Single-Round Known Answer Hashing Test. */
/***********************************************/
md5_status = MD5_HashBuf( md5_computed_digest, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( md5_status != SECSuccess ) ||
( PORT_Memcmp( md5_computed_digest, md5_known_digest,
MD5_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
return( CKR_OK );
}
static CK_RV
freebl_fips_SHA_PowerUpSelfTest( void )
{
/* SHA-1 Known Digest Message (160-bits). */
static const PRUint8 sha1_known_digest[] = {
0x0a,0x6d,0x07,0xba,0x1e,0xbd,0x8a,0x1b,
0x72,0xf6,0xc7,0x22,0xf1,0x27,0x9f,0xf0,
0xe0,0x68,0x47,0x7a};
/* SHA-224 Known Digest Message (224-bits). */
static const PRUint8 sha224_known_digest[] = {
0x89,0x5e,0x7f,0xfd,0x0e,0xd8,0x35,0x6f,
0x64,0x6d,0xf2,0xde,0x5e,0xed,0xa6,0x7f,
0x29,0xd1,0x12,0x73,0x42,0x84,0x95,0x4f,
0x8e,0x08,0xe5,0xcb};
/* SHA-256 Known Digest Message (256-bits). */
static const PRUint8 sha256_known_digest[] = {
0x38,0xa9,0xc1,0xf0,0x35,0xf6,0x5d,0x61,
0x11,0xd4,0x0b,0xdc,0xce,0x35,0x14,0x8d,
0xf2,0xdd,0xaf,0xaf,0xcf,0xb7,0x87,0xe9,
0x96,0xa5,0xd2,0x83,0x62,0x46,0x56,0x79};
/* SHA-384 Known Digest Message (384-bits). */
static const PRUint8 sha384_known_digest[] = {
0x11,0xfe,0x1c,0x00,0x89,0x48,0xde,0xb3,
0x99,0xee,0x1c,0x18,0xb4,0x10,0xfb,0xfe,
0xe3,0xa8,0x2c,0xf3,0x04,0xb0,0x2f,0xc8,
0xa3,0xc4,0x5e,0xea,0x7e,0x60,0x48,0x7b,
0xce,0x2c,0x62,0xf7,0xbc,0xa7,0xe8,0xa3,
0xcf,0x24,0xce,0x9c,0xe2,0x8b,0x09,0x72};
/* SHA-512 Known Digest Message (512-bits). */
static const PRUint8 sha512_known_digest[] = {
0xc8,0xb3,0x27,0xf9,0x0b,0x24,0xc8,0xbf,
0x4c,0xba,0x33,0x54,0xf2,0x31,0xbf,0xdb,
0xab,0xfd,0xb3,0x15,0xd7,0xfa,0x48,0x99,
0x07,0x60,0x0f,0x57,0x41,0x1a,0xdd,0x28,
0x12,0x55,0x25,0xac,0xba,0x3a,0x99,0x12,
0x2c,0x7a,0x8f,0x75,0x3a,0xe1,0x06,0x6f,
0x30,0x31,0xc9,0x33,0xc6,0x1b,0x90,0x1a,
0x6c,0x98,0x9a,0x87,0xd0,0xb2,0xf8,0x07};
/* SHA-X variables. */
PRUint8 sha_computed_digest[HASH_LENGTH_MAX];
SECStatus sha_status;
/*************************************************/
/* SHA-1 Single-Round Known Answer Hashing Test. */
/*************************************************/
sha_status = SHA1_HashBuf( sha_computed_digest, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( sha_status != SECSuccess ) ||
( PORT_Memcmp( sha_computed_digest, sha1_known_digest,
SHA1_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
/***************************************************/
/* SHA-224 Single-Round Known Answer Hashing Test. */
/***************************************************/
sha_status = SHA224_HashBuf( sha_computed_digest, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( sha_status != SECSuccess ) ||
( PORT_Memcmp( sha_computed_digest, sha224_known_digest,
SHA224_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
/***************************************************/
/* SHA-256 Single-Round Known Answer Hashing Test. */
/***************************************************/
sha_status = SHA256_HashBuf( sha_computed_digest, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( sha_status != SECSuccess ) ||
( PORT_Memcmp( sha_computed_digest, sha256_known_digest,
SHA256_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
/***************************************************/
/* SHA-384 Single-Round Known Answer Hashing Test. */
/***************************************************/
sha_status = SHA384_HashBuf( sha_computed_digest, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( sha_status != SECSuccess ) ||
( PORT_Memcmp( sha_computed_digest, sha384_known_digest,
SHA384_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
/***************************************************/
/* SHA-512 Single-Round Known Answer Hashing Test. */
/***************************************************/
sha_status = SHA512_HashBuf( sha_computed_digest, known_hash_message,
FIPS_KNOWN_HASH_MESSAGE_LENGTH );
if( ( sha_status != SECSuccess ) ||
( PORT_Memcmp( sha_computed_digest, sha512_known_digest,
SHA512_LENGTH ) != 0 ) )
return( CKR_DEVICE_ERROR );
return( CKR_OK );
}
static CK_RV
freebl_fipsSoftwareIntegrityTest(void)
{
CK_RV crv = CKR_OK;
/* make sure that our check file signatures are OK */
if (!BLAPI_VerifySelf(SHLIB_PREFIX"freebl"SHLIB_VERSION"."SHLIB_SUFFIX)) {
crv = CKR_DEVICE_ERROR; /* better error code? checksum error? */
}
return crv;
}
CK_RV
freebl_fipsPowerUpSelfTest( void )
{
CK_RV rv;
/* MD2 Power-Up SelfTest(s). */
rv = freebl_fips_MD2_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* MD5 Power-Up SelfTest(s). */
rv = freebl_fips_MD5_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* SHA-X Power-Up SelfTest(s). */
rv = freebl_fips_SHA_PowerUpSelfTest();
if( rv != CKR_OK )
return rv;
/* Software/Firmware Integrity Test. */
rv = freebl_fipsSoftwareIntegrityTest();
if( rv != CKR_OK )
return rv;
/* Passed Power-Up SelfTest(s). */
return( CKR_OK );
}
#include "blapii.h"
struct NSSLOWInitContextStr {
int count;
@ -276,36 +43,28 @@ static int nsslow_GetFIPSEnabled(void) {
return 1;
}
static int post = 0;
static int post_failed = 0;
static NSSLOWInitContext dummyContext = { 0 };
static PRBool post_failed = PR_TRUE;
NSSLOWInitContext *
NSSLOW_Init(void)
{
CK_RV crv;
#ifdef FREEBL_NO_DEPEND
(void)FREEBL_InitStubs();
(void) FREEBL_InitStubs();
#endif
if (post_failed) {
return NULL;
}
if (!post && nsslow_GetFIPSEnabled()) {
crv = freebl_fipsPowerUpSelfTest();
if (crv != CKR_OK) {
post_failed = 1;
/* make sure the FIPS product is installed if we are trying to
* go into FIPS mode */
if (nsslow_GetFIPSEnabled()) {
if (BL_FIPSEntryOK(PR_TRUE) != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
post_failed = PR_TRUE;
return NULL;
}
}
post = 1;
}
post_failed = PR_FALSE;
return &dummyContext;
return &dummyContext;
}
void
@ -319,8 +78,6 @@ void
NSSLOW_Reset(NSSLOWInitContext *context)
{
PORT_Assert(context == &dummyContext);
post_failed = 0;
post = 0;
return;
}

View File

@ -43,7 +43,8 @@ typedef enum {
* implement Lucas and adjust these two functions. See FIPS 186-3 Appendix C
* and F for more information.
*/
int prime_testcount_p(int L, int N)
static int
prime_testcount_p(int L, int N)
{
switch (L) {
case 1024:
@ -61,7 +62,8 @@ int prime_testcount_p(int L, int N)
/* The q numbers are different if you run M-R followd by Lucas. I created
* a separate function so if someone wanted to add the Lucas check, they
* could do so fairly easily */
int prime_testcount_q(int L, int N)
static int
prime_testcount_q(int L, int N)
{
return prime_testcount_p(L,N);
}
@ -486,7 +488,7 @@ cleanup:
** steps 16 through 34 of FIPS 186-2 C.6
*/
#define MAX_ST_SEED_BITS (HASH_LENGTH_MAX*PR_BITS_PER_BYTE)
SECStatus
static SECStatus
makePrimefromPrimesShaweTaylor(
HASH_HashType hashtype, /* selected Hashing algorithm */
unsigned int length, /* input. Length of prime in bits. */
@ -701,6 +703,7 @@ cleanup:
mp_clear(&a);
mp_clear(&z);
mp_clear(&two_length_minus_1);
PORT_Memset(x, 0, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@ -720,7 +723,7 @@ cleanup:
**
** This generates a provable prime from a seed
*/
SECStatus
static SECStatus
makePrimefromSeedShaweTaylor(
HASH_HashType hashtype, /* selected Hashing algorithm */
unsigned int length, /* input. Length of prime in bits. */
@ -856,6 +859,7 @@ cleanup:
mp_clear(&c);
mp_clear(&c0);
mp_clear(&one);
PORT_Memset(x, 0, sizeof(x));
if (err) {
MP_TO_SEC_ERROR(err);
rv = SECFailure;
@ -1256,6 +1260,42 @@ pqg_ParamGen(unsigned int L, unsigned int N, pqgGenType type,
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
/* Initialize bignums */
MP_DIGITS(&P) = 0;
MP_DIGITS(&Q) = 0;
MP_DIGITS(&G) = 0;
MP_DIGITS(&H) = 0;
MP_DIGITS(&l) = 0;
MP_DIGITS(&p0) = 0;
CHECK_MPI_OK( mp_init(&P) );
CHECK_MPI_OK( mp_init(&Q) );
CHECK_MPI_OK( mp_init(&G) );
CHECK_MPI_OK( mp_init(&H) );
CHECK_MPI_OK( mp_init(&l) );
CHECK_MPI_OK( mp_init(&p0) );
/* parameters have been passed in, only generate G */
if (*pParams != NULL) {
/* we only support G index generation if generating separate from PQ */
if ((*pVfy == NULL) || (type == FIPS186_1_TYPE) ||
((*pVfy)->h.len != 1) || ((*pVfy)->h.data == NULL) ||
((*pVfy)->seed.data == NULL) || ((*pVfy)->seed.len == 0)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
params = *pParams;
verify = *pVfy;
/* fill in P Q, */
SECITEM_TO_MPINT((*pParams)->prime, &P);
SECITEM_TO_MPINT((*pParams)->subPrime, &Q);
hashtype = getFirstHash(L,N);
CHECK_SEC_OK(makeGfromIndex(hashtype, &P, &Q, &(*pVfy)->seed,
(*pVfy)->h.data[0], &G) );
MPINT_TO_SECITEM(&G, &(*pParams)->base, (*pParams)->arena);
goto cleanup;
}
/* Initialize an arena for the params. */
arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
if (!arena) {
@ -1513,8 +1553,12 @@ cleanup:
rv = SECFailure;
}
if (rv) {
PORT_FreeArena(params->arena, PR_TRUE);
PORT_FreeArena(verify->arena, PR_TRUE);
if (params) {
PORT_FreeArena(params->arena, PR_TRUE);
}
if (verify) {
PORT_FreeArena(verify->arena, PR_TRUE);
}
}
if (hit.data) {
SECITEM_FreeItem(&hit, PR_FALSE);

View File

@ -21,8 +21,11 @@
#ifdef USE_HW_AES
#include "intel-aes.h"
#endif
#include "mpi.h"
#ifdef USE_HW_AES
static int has_intel_aes = 0;
static PRBool use_hw_aes = PR_FALSE;
@ -1168,6 +1171,7 @@ AES_InitContext(AESContext *cx, const unsigned char *key, unsigned int keysize,
AES_DestroyContext(cx, PR_FALSE);
return rv;
}
cx->mode = mode;
/* finally, set up any mode specific contexts */
switch (mode) {
@ -1291,6 +1295,23 @@ AES_Encrypt(AESContext *cx, unsigned char *output,
return SECFailure;
}
*outputLen = inputLen;
#if UINT_MAX > MP_32BIT_MAX
/*
* we can guarentee that GSM won't overlfow if we limit the input to
* 2^36 bytes. For simplicity, we are limiting it to 2^32 for now.
*
* We do it here to cover both hardware and software GCM operations.
*/
{PR_STATIC_ASSERT(sizeof(unsigned int) > 4);}
if ((cx->mode == NSS_AES_GCM) && (inputLen > MP_32BIT_MAX)) {
PORT_SetError(SEC_ERROR_OUTPUT_LEN);
return SECFailure;
}
#else
/* if we can't pass in a 32_bit number, then no such check needed */
{PR_STATIC_ASSERT(sizeof(unsigned int) <= 4);}
#endif
return (*cx->worker)(cx->worker_cx, output, outputLen, maxOutputLen,
input, inputLen, blocksize);
}

View File

@ -62,6 +62,7 @@ struct AESContextStr
freeblDestroyFunc destroy;
void *worker_cx;
PRBool isBlock;
int mode;
};
#endif /* _RIJNDAEL_H_ */

View File

@ -138,7 +138,7 @@ rsa_build_from_primes(const mp_int *p, const mp_int *q,
CHECK_MPI_OK( mp_sub_d(p, 1, &psub1) );
CHECK_MPI_OK( mp_sub_d(q, 1, &qsub1) );
if (needPublicExponent || needPrivateExponent) {
CHECK_MPI_OK( mp_mul(&psub1, &qsub1, &phi) );
CHECK_MPI_OK( mp_lcm(&psub1, &qsub1, &phi) );
/* 3. Compute d = e**-1 mod(phi) */
/* or e = d**-1 mod(phi) as necessary */
if (needPublicExponent) {
@ -225,6 +225,45 @@ cleanup:
return rv;
}
/*
* make sure the key components meet fips186 requirements.
*/
static PRBool
rsa_fips186_verify(mp_int *p, mp_int *q, mp_int *d, int keySizeInBits)
{
mp_int pq_diff;
mp_err err = MP_OKAY;
PRBool ret=PR_FALSE;
if (keySizeInBits < 250) {
/* not a valid FIPS length, no point in our other tests */
/* if you are here, and in FIPS mode, you are outside the security
* policy */
return PR_TRUE;
}
/* p & q are already known to be greater then sqrt(2)*2^(keySize/2-1) */
/* we also know that gcd(p-1,e) = 1 and gcd(q-1,e) = 1 because the
* mp_invmod() function will fail. */
/* now check p-q > 2^(keysize/2-100) */
MP_DIGITS(&pq_diff) = 0;
CHECK_MPI_OK( mp_init(&pq_diff) );
/* NSS always has p > q, so we know pq_diff is positive */
CHECK_MPI_OK( mp_sub(p,q,&pq_diff) );
if ((unsigned)mpl_significant_bits(&pq_diff) < (keySizeInBits/2 - 100)) {
goto cleanup;
}
/* now verify d is large enough*/
if ((unsigned)mpl_significant_bits(d) < (keySizeInBits/2)) {
goto cleanup;
}
ret = PR_TRUE;
cleanup:
mp_clear(&pq_diff);
return ret;
}
/*
** Generate and return a new RSA public and private key.
** Both keys are encoded in a single RSAPrivateKey structure.
@ -241,6 +280,7 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
unsigned int primeLen;
mp_int p, q, e, d;
int kiter;
int max_attempts;
mp_err err = MP_OKAY;
SECStatus rv = SECSuccess;
int prerr = 0;
@ -281,6 +321,7 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
/* 3. Set the public exponent */
SECITEM_TO_MPINT(*publicExponent, &e);
kiter = 0;
max_attempts = 5*(keySizeInBits/2); /* FIPS 186-4 B.3.3 steps 4.7 and 5.8 */
do {
prerr = 0;
PORT_SetError(0);
@ -298,12 +339,17 @@ RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
&e, PR_FALSE, /* needPublicExponent=false */
&d, PR_TRUE, /* needPrivateExponent=true */
key, keySizeInBits);
if (rv == SECSuccess)
break; /* generated two good primes */
prerr = PORT_GetError();
if (rv == SECSuccess) {
if (rsa_fips186_verify(&p, &q, &d, keySizeInBits) ){
break;
}
prerr = SEC_ERROR_NEED_RANDOM; /* retry with different values */
} else {
prerr = PORT_GetError();
}
kiter++;
/* loop until have primes */
} while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS);
} while (prerr == SEC_ERROR_NEED_RANDOM && kiter < max_attempts);
if (prerr)
goto cleanup;
cleanup:

Some files were not shown because too many files have changed in this diff Show More