Bug 1420060 - land NSS 04fc9a90997b UPGRADE_NSS_RELEASE, r=me

MozReview-Commit-ID: 5VMV4wtzMKA

--HG--
extra : rebase_source : 43ea63a50d243bcc46fbae3b65f5d117e8fba771
This commit is contained in:
Franziskus Kiefer 2017-12-19 15:26:12 +01:00
Родитель 791887bedd
Коммит da627bdc03
65 изменённых файлов: 2243 добавлений и 397 удалений

Просмотреть файл

@ -51,6 +51,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0x32, 0xE1, 0xBD, 0x24, 0x93, 0xFF, 0xC6, 0xD9, 0x20, 0x6D, 0x11, 0xBC, 0xD6, 0x77, 0x07, 0x39 },
52 /* Bin Number */
},
{
/* TrustCor_RootCert_CA_2 */
{ 0x07, 0x53, 0xE9, 0x40, 0x37, 0x8C, 0x1B, 0xD5, 0xE3, 0x83, 0x6E, 0x39, 0x5D, 0xAE, 0xA5, 0xCB,
0x83, 0x9E, 0x50, 0x46, 0xF1, 0xBD, 0x0E, 0xAE, 0x19, 0x51, 0xCF, 0x10, 0xFE, 0xC7, 0xC9, 0x65 },
191 /* Bin Number */
},
{
/* AddTrust_Public_CA_Root */
{ 0x07, 0x91, 0xCA, 0x07, 0x49, 0xB2, 0x07, 0x82, 0xAA, 0xD3, 0xC7, 0xD7, 0xBD, 0x0C, 0xDF, 0xC9,
@ -165,6 +171,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0x5A, 0x65, 0xE2, 0xBC, 0x6E, 0x55, 0xB5, 0xAF, 0x7E, 0x78, 0x99, 0xC8, 0xA2, 0x66, 0xD9, 0x2E },
47 /* Bin Number */
},
{
/* SSL_com_EV_Root_Certification_Authority_ECC */
{ 0x22, 0xA2, 0xC1, 0xF7, 0xBD, 0xED, 0x70, 0x4C, 0xC1, 0xE7, 0x01, 0xB5, 0xF4, 0x08, 0xC3, 0x10,
0x88, 0x0F, 0xE9, 0x56, 0xB5, 0xDE, 0x2A, 0x4A, 0x44, 0xF9, 0x9C, 0x87, 0x3A, 0x25, 0xA7, 0xC8 },
196 /* Bin Number */
},
{
/* VeriSign_Universal_Root_Certification_Authority */
{ 0x23, 0x99, 0x56, 0x11, 0x27, 0xA5, 0x71, 0x25, 0xDE, 0x8C, 0xEF, 0xEA, 0x61, 0x0D, 0xDF, 0x2F,
@ -201,6 +213,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0xA5, 0x80, 0x26, 0xEF, 0x1F, 0xCC, 0x0A, 0x5F, 0xB3, 0xD9, 0xDC, 0x01, 0x2F, 0x60, 0x0D, 0x19 },
85 /* Bin Number */
},
{
/* SSL_com_EV_Root_Certification_Authority_RSA_R2 */
{ 0x2E, 0x7B, 0xF1, 0x6C, 0xC2, 0x24, 0x85, 0xA7, 0xBB, 0xE2, 0xAA, 0x86, 0x96, 0x75, 0x07, 0x61,
0xB0, 0xAE, 0x39, 0xBE, 0x3B, 0x2F, 0xE9, 0xD0, 0xCC, 0x6D, 0x4E, 0xF7, 0x34, 0x91, 0x42, 0x5C },
195 /* Bin Number */
},
{
/* IdenTrust_Public_Sector_Root_CA_1 */
{ 0x30, 0xD0, 0x89, 0x5A, 0x9A, 0x44, 0x8A, 0x26, 0x20, 0x91, 0x63, 0x55, 0x22, 0xD1, 0xF5, 0x20,
@ -219,6 +237,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0xA4, 0x77, 0x6E, 0xFD, 0xAE, 0x2F, 0xDF, 0x6D, 0x01, 0x68, 0xEA, 0x1C, 0x4F, 0x55, 0x67, 0xD0 },
70 /* Bin Number */
},
{
/* SSL_com_Root_Certification_Authority_ECC */
{ 0x34, 0x17, 0xBB, 0x06, 0xCC, 0x60, 0x07, 0xDA, 0x1B, 0x96, 0x1C, 0x92, 0x0B, 0x8A, 0xB4, 0xCE,
0x3F, 0xAD, 0x82, 0x0E, 0x4A, 0xA3, 0x0B, 0x9A, 0xCB, 0xC4, 0xA7, 0x4E, 0xBD, 0xCE, 0xBC, 0x65 },
194 /* Bin Number */
},
{
/* EBG_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_ */
{ 0x35, 0xAE, 0x5B, 0xDD, 0xD8, 0xF7, 0xAE, 0x63, 0x5C, 0xFF, 0xBA, 0x56, 0x82, 0xA8, 0xF0, 0x0B,
@ -405,6 +429,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0x5A, 0x5B, 0x2B, 0x45, 0x7D, 0x81, 0xF3, 0x69, 0x2B, 0x61, 0x0A, 0x98, 0x67, 0x2F, 0x0E, 0x1B },
139 /* Bin Number */
},
{
/* TrustCor_ECA_1 */
{ 0x5A, 0x88, 0x5D, 0xB1, 0x9C, 0x01, 0xD9, 0x12, 0xC5, 0x75, 0x93, 0x88, 0x93, 0x8C, 0xAF, 0xBB,
0xDF, 0x03, 0x1A, 0xB2, 0xD4, 0x8E, 0x91, 0xEE, 0x15, 0x58, 0x9B, 0x42, 0x97, 0x1D, 0x03, 0x9C },
192 /* Bin Number */
},
{
/* Certum_Trusted_Network_CA */
{ 0x5C, 0x58, 0x46, 0x8D, 0x55, 0xF5, 0x8E, 0x49, 0x7E, 0x74, 0x39, 0x82, 0xD2, 0xB5, 0x00, 0x10,
@ -579,6 +609,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0x95, 0x43, 0x1E, 0xDA, 0x37, 0xCC, 0x5E, 0x36, 0x43, 0x0E, 0x79, 0xC7, 0xA8, 0x88, 0x63, 0x8B },
5 /* Bin Number */
},
{
/* SSL_com_Root_Certification_Authority_RSA */
{ 0x85, 0x66, 0x6A, 0x56, 0x2E, 0xE0, 0xBE, 0x5C, 0xE9, 0x25, 0xC1, 0xD8, 0x89, 0x0A, 0x6F, 0x76,
0xA8, 0x7E, 0xC1, 0x6D, 0x4D, 0x7D, 0x5F, 0x29, 0xEA, 0x74, 0x19, 0xCF, 0x20, 0x12, 0x3B, 0x69 },
193 /* Bin Number */
},
{
/* QuoVadis_Root_CA_2 */
{ 0x85, 0xA0, 0xDD, 0x7D, 0xD7, 0x20, 0xAD, 0xB7, 0xFF, 0x05, 0xF8, 0x3D, 0x54, 0x2B, 0x20, 0x9D,
@ -861,6 +897,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0xE9, 0xBA, 0xD1, 0xA6, 0xB9, 0xBD, 0x51, 0x5E, 0xDC, 0x5C, 0x6D, 0x5B, 0x87, 0x11, 0xAC, 0x44 },
117 /* Bin Number */
},
{
/* GDCA_TrustAUTH_R5_ROOT */
{ 0xBF, 0xFF, 0x8F, 0xD0, 0x44, 0x33, 0x48, 0x7D, 0x6A, 0x8A, 0xA6, 0x0C, 0x1A, 0x29, 0x76, 0x7A,
0x9F, 0xC2, 0xBB, 0xB0, 0x5E, 0x42, 0x0F, 0x71, 0x3A, 0x13, 0xB9, 0x92, 0x89, 0x1D, 0x38, 0x93 },
189 /* Bin Number */
},
{
/* OU_ePKI_Root_Certification_Authority_O__Chunghwa_Telecom_Co___Ltd___C_TW */
{ 0xC0, 0xA6, 0xF4, 0xDC, 0x63, 0xA2, 0x4B, 0xFD, 0xCF, 0x54, 0xEF, 0x2A, 0x6A, 0x08, 0x2A, 0x0A,
@ -933,6 +975,12 @@ static const struct CertAuthorityHash ROOT_TABLE[] = {
0x51, 0x0C, 0x42, 0x75, 0xB0, 0xE5, 0xF9, 0x4F, 0x40, 0xBB, 0xAE, 0x86, 0x5E, 0x19, 0xF6, 0x73 },
13 /* Bin Number */
},
{
/* TrustCor_RootCert_CA_1 */
{ 0xD4, 0x0E, 0x9C, 0x86, 0xCD, 0x8F, 0xE4, 0x68, 0xC1, 0x77, 0x69, 0x59, 0xF4, 0x9E, 0xA7, 0x74,
0xFA, 0x54, 0x86, 0x84, 0xB6, 0xC4, 0x06, 0xF3, 0x90, 0x92, 0x61, 0xF4, 0xDC, 0xE2, 0x57, 0x5C },
190 /* Bin Number */
},
{
/* Staat_der_Nederlanden_Root_CA */
{ 0xD4, 0x1D, 0x82, 0x9E, 0x8C, 0x16, 0x59, 0x82, 0x2A, 0xF9, 0x3F, 0xCE, 0x62, 0xBF, 0xFC, 0xDE,

Просмотреть файл

@ -948,7 +948,47 @@
"label": "TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi___Surum_1",
"binNumber": 188,
"sha256Fingerprint": "Ru3DaJBG1TpFP7MQSrgNyuxliyZg6hYp3X6GeZBkhxY="
},
{
"label": "GDCA_TrustAUTH_R5_ROOT",
"binNumber": 189,
"sha256Fingerprint": "v/+P0EQzSH1qiqYMGil2ep/Cu7BeQg9xOhO5kokdOJM="
},
{
"label": "TrustCor_RootCert_CA_1",
"binNumber": 190,
"sha256Fingerprint": "1A6chs2P5GjBd2lZ9J6ndPpUhoS2xAbzkJJh9NziV1w="
},
{
"label": "TrustCor_RootCert_CA_2",
"binNumber": 191,
"sha256Fingerprint": "B1PpQDeMG9Xjg245Xa6ly4OeUEbxvQ6uGVHPEP7HyWU="
},
{
"label": "TrustCor_ECA_1",
"binNumber": 192,
"sha256Fingerprint": "WohdsZwB2RLFdZOIk4yvu98DGrLUjpHuFVibQpcdA5w="
},
{
"label": "SSL_com_Root_Certification_Authority_RSA",
"binNumber": 193,
"sha256Fingerprint": "hWZqVi7gvlzpJcHYiQpvdqh+wW1NfV8p6nQZzyASO2k="
},
{
"label": "SSL_com_Root_Certification_Authority_ECC",
"binNumber": 194,
"sha256Fingerprint": "NBe7BsxgB9oblhySC4q0zj+tgg5Kowuay8SnTr3OvGU="
},
{
"label": "SSL_com_EV_Root_Certification_Authority_RSA_R2",
"binNumber": 195,
"sha256Fingerprint": "LnvxbMIkhae74qqGlnUHYbCuOb47L+nQzG1O9zSRQlw="
},
{
"label": "SSL_com_EV_Root_Certification_Authority_ECC",
"binNumber": 196,
"sha256Fingerprint": "IqLB973tcEzB5wG19AjDEIgP6Va13ipKRPmchzolp8g="
}
],
"maxBin": 188
"maxBin": 196
}

Просмотреть файл

@ -1 +1 @@
ceb8b9290b35
04fc9a90997b

Просмотреть файл

@ -0,0 +1,8 @@
Functions changes summary: 1 Removed, 0 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 Removed function:
'function void PR_EXPERIMENTAL_ONLY_IN_4_17_GetOverlappedIOHandle(void**)' {PR_EXPERIMENTAL_ONLY_IN_4_17_GetOverlappedIOHandle}

Просмотреть файл

@ -0,0 +1,3 @@
Functions changes summary: 0 Removed, 0 Changed (5 filtered out), 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

Просмотреть файл

@ -271,15 +271,18 @@ check_abi()
> ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt
if [ $? -ne 0 ]; then
ABI_PROBLEM_FOUND=1
print_log "FAILED to run abidiff {$PREVDIST , $NEWDIST} for $SO, or failed writing to ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt"
fi
if [ ! -f ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt ]; then
ABI_PROBLEM_FOUND=1
print_log "FAILED to access report file: ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt"
fi
diff -wB -u ${HGDIR}/nss/automation/abi-check/expected-report-$SO.txt \
${HGDIR}/nss/automation/abi-check/new-report-$SO.txt >> ${ABI_REPORT}
if [ ! -f ${ABI_REPORT} ]; then
ABI_PROBLEM_FOUND=1
print_log "FAILED to compare exepcted and new report: ${HGDIR}/nss/automation/abi-check/new-report-$SO.txt"
fi
done

Просмотреть файл

@ -1,4 +1,4 @@
4.17
4.18
# The first line of this file must contain the human readable NSPR
# version number, which is the minimum required version of NSPR

Просмотреть файл

@ -9,59 +9,22 @@ ENV haclrepo https://github.com/mitls/hacl-star.git
# Define versions of dependencies
ENV opamv 4.04.2
ENV haclversion daa7e159f0adf252b5e6962967bc0f27dbac243b
ENV haclversion dcd48329d535727dbde93877b124c5ec4a7a2b20
# Install required packages and set versions
RUN apt-get -qq update
RUN apt-get install --yes sudo libssl-dev libsqlite3-dev g++-5 gcc-5 m4 make opam pkg-config python libgmp3-dev cmake curl libtool-bin autoconf wget
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 200
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 200
ADD setup.sh /tmp/setup.sh
RUN bash /tmp/setup.sh
# Create user
# Create user, add scripts.
RUN useradd -ms /bin/bash worker
RUN echo "worker ALL=(ALL:ALL) NOPASSWD:ALL" >> /etc/sudoers
WORKDIR /home/worker
# Add build and test scripts.
ADD bin /home/worker/bin
RUN chmod +x /home/worker/bin/*
USER worker
# Prepare build (OCaml packages)
# Build F*, HACL*, verify. Install a few more dependencies.
ENV OPAMYES true
RUN opam init
RUN echo ". /home/worker/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true" >> .bashrc
RUN opam switch -v ${opamv}
RUN opam install ocamlfind batteries sqlite3 fileutils yojson ppx_deriving_yojson zarith pprint menhir ulex process fix wasm stdint
# Get the HACL* code
RUN git clone ${haclrepo} hacl-star
RUN git -C hacl-star checkout ${haclversion}
# Prepare submodules, and build, verify, test, and extract c code
# This caches the extracted c code (pins the HACL* version). All we need to do
# on CI now is comparing the code in this docker image with the one in NSS.
RUN opam config exec -- make -C hacl-star prepare -j$(nproc)
ENV PATH "/home/worker/hacl-star/dependencies/z3/bin:$PATH"
RUN make -C hacl-star verify-nss -j$(nproc)
RUN make -C hacl-star -f Makefile.build snapshots/nss -j$(nproc)
RUN KOPTS="-funroll-loops 5" make -C hacl-star/code/curve25519 test -j$(nproc)
RUN make -C hacl-star/code/salsa-family test -j$(nproc)
# Get clang-format-3.9
RUN curl -LO http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz
RUN curl -LO http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig
# Verify the signature.
RUN gpg --keyserver pool.sks-keyservers.net --recv-keys B6C8F98282B944E3B0D5C2530FC3042E345AD05D
RUN gpg --verify *.tar.xz.sig
# Install into /usr/local/.
RUN sudo tar xJvf *.tar.xz -C /usr/local --strip-components=1
# Cleanup.
RUN rm *.tar.xz*
# Cleanup
RUN rm -rf ~/.ccache ~/.cache
RUN rm -rf /home/worker/hacl-star/dependencies
RUN sudo apt-get autoremove -y
RUN sudo apt-get clean
RUN sudo apt-get autoclean
ADD setup-user.sh /tmp/setup-user.sh
ADD license.txt /tmp/license.txt
RUN bash /tmp/setup-user.sh

Просмотреть файл

@ -0,0 +1,15 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

Просмотреть файл

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -v -e -x
# Prepare build (OCaml packages)
opam init
echo ". /home/worker/.opam/opam-init/init.sh > /dev/null 2> /dev/null || true" >> .bashrc
opam switch -v ${opamv}
opam install ocamlfind batteries sqlite3 fileutils yojson ppx_deriving_yojson zarith pprint menhir ulex process fix wasm stdint
# Get the HACL* code
git clone ${haclrepo} hacl-star
git -C hacl-star checkout ${haclversion}
# Prepare submodules, and build, verify, test, and extract c code
# This caches the extracted c code (pins the HACL* version). All we need to do
# on CI now is comparing the code in this docker image with the one in NSS.
opam config exec -- make -C hacl-star prepare -j$(nproc)
make -C hacl-star verify-nss -j$(nproc)
make -C hacl-star -f Makefile.build snapshots/nss -j$(nproc)
KOPTS="-funroll-loops 5" make -C hacl-star/code/curve25519 test -j$(nproc)
make -C hacl-star/code/salsa-family test -j$(nproc)
make -C hacl-star/code/poly1305 test -j$(nproc)
# Cleanup.
rm -rf ~/.ccache ~/.cache

Просмотреть файл

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -v -e -x
# Update packages.
export DEBIAN_FRONTEND=noninteractive
apt-get -qq update
apt-get install --yes libssl-dev libsqlite3-dev g++-5 gcc-5 m4 make opam pkg-config python libgmp3-dev cmake curl libtool-bin autoconf wget locales
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 200
update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 200
# Get clang-format-3.9
curl -LO http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz
curl -LO http://releases.llvm.org/3.9.1/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz.sig
# Verify the signature.
gpg --keyserver pool.sks-keyservers.net --recv-keys B6C8F98282B944E3B0D5C2530FC3042E345AD05D
gpg --verify *.tar.xz.sig
# Install into /usr/local/.
tar xJvf *.tar.xz -C /usr/local --strip-components=1
# Cleanup.
rm *.tar.xz*
locale-gen en_US.UTF-8
dpkg-reconfigure locales
# Cleanup.
rm -rf ~/.ccache ~/.cache
apt-get autoremove -y
apt-get clean
apt-get autoclean

Просмотреть файл

@ -159,6 +159,18 @@ export default async function main() {
],
});
await scheduleLinux("Linux 64 (opt, make)", {
env: {USE_64: "1", BUILD_OPT: "1"},
platform: "linux64",
image: LINUX_IMAGE,
collection: "make",
command: [
"/bin/bash",
"-c",
"bin/checkout.sh && nss/automation/taskcluster/scripts/build.sh"
],
});
await scheduleLinux("Linux 32 (debug, make)", {
platform: "linux32",
image: LINUX_IMAGE,

Просмотреть файл

@ -54,6 +54,7 @@ export async function buildTask({name, path}) {
],
platform: "nss-decision",
features: ["dind"],
maxRunTime: 7200,
kind: "build",
symbol: "I"
};

Просмотреть файл

@ -12,6 +12,15 @@ set -e -x -v
# The extracted C code from HACL* is already generated and the HACL* tests were
# successfully executed.
# Verify Poly1305 (doesn't work in docker image build)
make verify -C ~/hacl-star/code/poly1305 -j$(nproc)
# Add license header to specs
spec_files=($(find ~/hacl-star/specs -type f -name '*.fst'))
for f in "${spec_files[@]}"; do
cat /tmp/license.txt "$f" > /tmp/tmpfile && mv /tmp/tmpfile "$f"
done
# Format the extracted C code.
cd ~/hacl-star/snapshots/nss
cp ~/nss/.clang-format .

Просмотреть файл

@ -653,12 +653,12 @@ ListCerts(CERTCertDBHandle *handle, char *nickname, char *email,
}
static SECStatus
DeleteCert(CERTCertDBHandle *handle, char *name)
DeleteCert(CERTCertDBHandle *handle, char *name, void *pwdata)
{
SECStatus rv;
CERTCertificate *cert;
cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata);
if (!cert) {
SECU_PrintError(progName, "could not find certificate named \"%s\"",
name);
@ -674,12 +674,12 @@ DeleteCert(CERTCertDBHandle *handle, char *name)
}
static SECStatus
RenameCert(CERTCertDBHandle *handle, char *name, char *newName)
RenameCert(CERTCertDBHandle *handle, char *name, char *newName, void *pwdata)
{
SECStatus rv;
CERTCertificate *cert;
cert = CERT_FindCertByNicknameOrEmailAddr(handle, name);
cert = CERT_FindCertByNicknameOrEmailAddrCX(handle, name, pwdata);
if (!cert) {
SECU_PrintError(progName, "could not find certificate named \"%s\"",
name);
@ -3334,12 +3334,12 @@ certutil_main(int argc, char **argv, PRBool initialize)
}
/* Delete cert (-D) */
if (certutil.commands[cmd_DeleteCert].activated) {
rv = DeleteCert(certHandle, name);
rv = DeleteCert(certHandle, name, &pwdata);
goto shutdown;
}
/* Rename cert (--rename) */
if (certutil.commands[cmd_Rename].activated) {
rv = RenameCert(certHandle, name, newName);
rv = RenameCert(certHandle, name, newName, &pwdata);
goto shutdown;
}
/* Delete key (-F) */

Просмотреть файл

@ -96,6 +96,7 @@ PRBool verbose;
int dumpServerChain = 0;
int renegotiationsToDo = 0;
int renegotiationsDone = 0;
PRBool initializedServerSessionCache = PR_FALSE;
static char *progName;
@ -179,7 +180,7 @@ PrintUsageHeader(const char *progName)
"[-n nickname] [-Bafosvx] [-c ciphers] [-Y] [-Z]\n"
"[-V [min-version]:[max-version]] [-K] [-T] [-U]\n"
"[-r N] [-w passwd] [-W pwfile] [-q [-t seconds]] [-I groups]\n"
"[-A requestfile] [-L totalconnections]\n"
"[-A requestfile] [-L totalconnections] [-P {client,server}] [-Q]\n"
"\n",
progName);
}
@ -203,7 +204,7 @@ PrintParameterUsage(void)
fprintf(stderr, "%-20s Print certificate chain information\n", "-C");
fprintf(stderr, "%-20s (use -C twice to print more certificate details)\n", "");
fprintf(stderr, "%-20s (use -C three times to include PEM format certificate dumps)\n", "");
fprintf(stderr, "%-20s Nickname of key and cert for client auth\n",
fprintf(stderr, "%-20s Nickname of key and cert\n",
"-n nickname");
fprintf(stderr,
"%-20s Restricts the set of enabled SSL/TLS protocols versions.\n"
@ -253,6 +254,8 @@ PrintParameterUsage(void)
"%-20s P256, P384, P521, x25519, FF2048, FF3072, FF4096, FF6144, FF8192\n",
"-I", "", "");
fprintf(stderr, "%-20s Enable alternative TLS 1.3 handshake\n", "-X alt-server-hello");
fprintf(stderr, "%-20s Use DTLS\n", "-P {client, server}");
fprintf(stderr, "%-20s Exit after handshake\n", "-Q");
}
static void
@ -917,6 +920,11 @@ PRInt32 requestStringLen = 0;
PRBool requestSent = PR_FALSE;
PRBool enableZeroRtt = PR_FALSE;
PRBool enableAltServerHello = PR_FALSE;
PRBool useDTLS = PR_FALSE;
PRBool actAsServer = PR_FALSE;
PRBool stopAfterHandshake = PR_FALSE;
PRBool requestToExit = PR_FALSE;
char *versionString = NULL;
static int
writeBytesToServer(PRFileDesc *s, const char *buf, int nb)
@ -999,12 +1007,129 @@ handshakeCallback(PRFileDesc *fd, void *client_data)
writeBytesToServer(fd, requestString, requestStringLen);
}
}
if (stopAfterHandshake) {
requestToExit = PR_TRUE;
}
}
#define REQUEST_WAITING (requestString && !requestSent)
static SECStatus
installServerCertificate(PRFileDesc *s, char *nickname)
{
CERTCertificate *cert;
SECKEYPrivateKey *privKey = NULL;
if (!nickname) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
cert = PK11_FindCertFromNickname(nickname, &pwdata);
if (cert == NULL) {
return SECFailure;
}
privKey = PK11_FindKeyByAnyCert(cert, &pwdata);
if (privKey == NULL) {
return SECFailure;
}
if (SSL_ConfigServerCert(s, cert, privKey, NULL, 0) != SECSuccess) {
return SECFailure;
}
SECKEY_DestroyPrivateKey(privKey);
CERT_DestroyCertificate(cert);
return SECSuccess;
}
static SECStatus
bindToClient(PRFileDesc *s)
{
PRStatus status;
status = PR_Bind(s, &addr);
if (status != PR_SUCCESS) {
return SECFailure;
}
for (;;) {
/* Bind the remote address on first packet. This must happen
* before we SSL-ize the socket because we need to get the
* peer's address before SSLizing. Recvfrom gives us that
* while not consuming any data. */
unsigned char tmp;
PRNetAddr remote;
int nb;
nb = PR_RecvFrom(s, &tmp, 1, PR_MSG_PEEK,
&remote, PR_INTERVAL_NO_TIMEOUT);
if (nb != 1)
continue;
status = PR_Connect(s, &remote, PR_INTERVAL_NO_TIMEOUT);
if (status != PR_SUCCESS) {
SECU_PrintError(progName, "server bind to remote end failed");
return SECFailure;
}
return SECSuccess;
}
/* Unreachable. */
}
static SECStatus
connectToServer(PRFileDesc *s, PRPollDesc *pollset)
{
PRStatus status;
PRInt32 filesReady;
status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
if (status != PR_SUCCESS) {
if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
if (verbose)
SECU_PrintError(progName, "connect");
milliPause(50 * multiplier);
pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
pollset[SSOCK_FD].out_flags = 0;
pollset[SSOCK_FD].fd = s;
while (1) {
FPRINTF(stderr,
"%s: about to call PR_Poll for connect completion!\n",
progName);
filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
if (filesReady < 0) {
SECU_PrintError(progName, "unable to connect (poll)");
return SECFailure;
}
FPRINTF(stderr,
"%s: PR_Poll returned 0x%02x for socket out_flags.\n",
progName, pollset[SSOCK_FD].out_flags);
if (filesReady == 0) { /* shouldn't happen! */
SECU_PrintError(progName, "%s: PR_Poll returned zero!\n");
return SECFailure;
}
status = PR_GetConnectStatus(pollset);
if (status == PR_SUCCESS) {
break;
}
if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
SECU_PrintError(progName, "unable to connect (poll)");
return SECFailure;
}
SECU_PrintError(progName, "poll");
milliPause(50 * multiplier);
}
} else {
SECU_PrintError(progName, "unable to connect");
return SECFailure;
}
}
return SECSuccess;
}
static int
run_client(void)
run(void)
{
int headerSeparatorPtrnId = 0;
int error = 0;
@ -1020,13 +1145,23 @@ run_client(void)
requestSent = PR_FALSE;
/* Create socket */
s = PR_OpenTCPSocket(addr.raw.family);
if (useDTLS) {
s = PR_OpenUDPSocket(addr.raw.family);
} else {
s = PR_OpenTCPSocket(addr.raw.family);
}
if (s == NULL) {
SECU_PrintError(progName, "error creating socket");
error = 1;
goto done;
}
if (actAsServer) {
if (bindToClient(s) != SECSuccess) {
return 1;
}
}
opt.option = PR_SockOpt_Nonblocking;
opt.value.non_blocking = PR_TRUE; /* default */
if (serverCertAuth.testFreshStatusFromSideChannel) {
@ -1039,13 +1174,16 @@ run_client(void)
goto done;
}
s = SSL_ImportFD(NULL, s);
if (useDTLS) {
s = DTLS_ImportFD(NULL, s);
} else {
s = SSL_ImportFD(NULL, s);
}
if (s == NULL) {
SECU_PrintError(progName, "error importing socket");
error = 1;
goto done;
}
SSL_SetPKCS11PinArg(s, &pwdata);
rv = SSL_OptionSet(s, SSL_SECURITY, 1);
@ -1055,7 +1193,7 @@ run_client(void)
goto done;
}
rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, 1);
rv = SSL_OptionSet(s, actAsServer ? SSL_HANDSHAKE_AS_SERVER : SSL_HANDSHAKE_AS_CLIENT, 1);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error enabling client handshake");
error = 1;
@ -1225,7 +1363,21 @@ run_client(void)
if (override) {
SSL_BadCertHook(s, ownBadCertHandler, NULL);
}
SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);
if (actAsServer) {
rv = installServerCertificate(s, nickname);
if (rv != SECSuccess) {
SECU_PrintError(progName, "error installing server cert");
return 1;
}
rv = SSL_ConfigServerSessionIDCache(1024, 0, 0, ".");
if (rv != SECSuccess) {
SECU_PrintError(progName, "error configuring session cache");
return 1;
}
initializedServerSessionCache = PR_TRUE;
} else {
SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);
}
SSL_HandshakeCallback(s, handshakeCallback, hs2SniHostName);
if (hs1SniHostName) {
SSL_SetURL(s, hs1SniHostName);
@ -1233,56 +1385,27 @@ run_client(void)
SSL_SetURL(s, host);
}
/* Try to connect to the server */
status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);
if (status != PR_SUCCESS) {
if (PR_GetError() == PR_IN_PROGRESS_ERROR) {
if (verbose)
SECU_PrintError(progName, "connect");
milliPause(50 * multiplier);
pollset[SSOCK_FD].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;
pollset[SSOCK_FD].out_flags = 0;
pollset[SSOCK_FD].fd = s;
while (1) {
FPRINTF(stderr,
"%s: about to call PR_Poll for connect completion!\n",
progName);
filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);
if (filesReady < 0) {
SECU_PrintError(progName, "unable to connect (poll)");
error = 1;
goto done;
}
FPRINTF(stderr,
"%s: PR_Poll returned 0x%02x for socket out_flags.\n",
progName, pollset[SSOCK_FD].out_flags);
if (filesReady == 0) { /* shouldn't happen! */
FPRINTF(stderr, "%s: PR_Poll returned zero!\n", progName);
error = 1;
goto done;
}
status = PR_GetConnectStatus(pollset);
if (status == PR_SUCCESS) {
break;
}
if (PR_GetError() != PR_IN_PROGRESS_ERROR) {
SECU_PrintError(progName, "unable to connect (poll)");
error = 1;
goto done;
}
SECU_PrintError(progName, "poll");
milliPause(50 * multiplier);
}
} else {
SECU_PrintError(progName, "unable to connect");
if (actAsServer) {
rv = SSL_ResetHandshake(s, PR_TRUE /* server */);
if (rv != SECSuccess) {
return 1;
}
} else {
/* Try to connect to the server */
rv = connectToServer(s, pollset);
if (rv != SECSuccess) {
;
error = 1;
goto done;
}
}
pollset[SSOCK_FD].fd = s;
pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT |
(clientSpeaksFirst ? 0 : PR_POLL_READ);
pollset[SSOCK_FD].in_flags = PR_POLL_EXCEPT;
if (!actAsServer)
pollset[SSOCK_FD].in_flags |= (clientSpeaksFirst ? 0 : PR_POLL_READ);
else
pollset[SSOCK_FD].in_flags |= PR_POLL_READ;
pollset[STDIN_FD].fd = PR_GetSpecialFD(PR_StandardInput);
if (!REQUEST_WAITING) {
pollset[STDIN_FD].in_flags = PR_POLL_READ;
@ -1332,9 +1455,11 @@ run_client(void)
** Select on stdin and on the socket. Write data from stdin to
** socket, read data from socket and write to stdout.
*/
requestToExit = PR_FALSE;
FPRINTF(stderr, "%s: ready...\n", progName);
while ((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) ||
REQUEST_WAITING) {
while (!requestToExit &&
((pollset[SSOCK_FD].in_flags | pollset[STDIN_FD].in_flags) ||
REQUEST_WAITING)) {
char buf[4000]; /* buffer for stdin */
int nb; /* num bytes read from stdin. */
@ -1520,12 +1645,10 @@ main(int argc, char **argv)
}
}
SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledVersions);
/* XXX: 'B' was used in the past but removed in 3.28,
* please leave some time before resuing it. */
optstate = PL_CreateOptState(argc, argv,
"46A:CDFGHI:KL:M:OR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z");
"46A:CDFGHI:KL:M:OP:QR:STUV:W:X:YZa:bc:d:fgh:m:n:op:qr:st:uvw:z");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@ -1606,6 +1729,21 @@ main(int argc, char **argv)
};
break;
case 'P':
useDTLS = PR_TRUE;
if (!strcmp(optstate->value, "server")) {
actAsServer = 1;
} else {
if (strcmp(optstate->value, "client")) {
Usage(progName);
}
}
break;
case 'Q':
stopAfterHandshake = PR_TRUE;
break;
case 'R':
rootModule = PORT_Strdup(optstate->value);
break;
@ -1623,12 +1761,7 @@ main(int argc, char **argv)
break;
case 'V':
if (SECU_ParseSSLVersionRangeString(optstate->value,
enabledVersions, &enabledVersions) !=
SECSuccess) {
fprintf(stderr, "Bad version specified.\n");
Usage(progName);
}
versionString = PORT_Strdup(optstate->value);
break;
case 'X':
@ -1747,9 +1880,20 @@ main(int argc, char **argv)
break;
}
}
PL_DestroyOptState(optstate);
SSL_VersionRangeGetSupported(useDTLS ? ssl_variant_datagram : ssl_variant_stream, &enabledVersions);
if (versionString) {
if (SECU_ParseSSLVersionRangeString(versionString,
enabledVersions, &enabledVersions) !=
SECSuccess) {
fprintf(stderr, "Bad version specified.\n");
Usage(progName);
}
PORT_Free(versionString);
}
if (optstatus == PL_OPT_BAD) {
Usage(progName);
}
@ -1778,7 +1922,7 @@ main(int argc, char **argv)
PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
PK11_SetPasswordFunc(SECU_GetModulePassword);
memset(&addr, 0, sizeof(addr));
status = PR_StringToNetAddr(host, &addr);
if (status == PR_SUCCESS) {
addr.inet.port = PR_htons(portno);
@ -1790,6 +1934,7 @@ main(int argc, char **argv)
addrInfo = PR_GetAddrInfoByName(host, PR_AF_UNSPEC,
PR_AI_ADDRCONFIG | PR_AI_NOCANONNAME);
if (!addrInfo) {
fprintf(stderr, "HOSTNAME=%s\n", host);
SECU_PrintError(progName, "error looking up host");
error = 1;
goto done;
@ -1904,7 +2049,7 @@ main(int argc, char **argv)
}
while (numConnections--) {
error = run_client();
error = run();
if (error) {
goto done;
}
@ -1935,6 +2080,12 @@ done:
}
if (NSS_IsInitialized()) {
SSL_ClearSessionCache();
if (initializedServerSessionCache) {
if (SSL_ShutdownServerSessionIDCache() != SECSuccess) {
error = 1;
}
}
if (NSS_Shutdown() != SECSuccess) {
error = 1;
}

Просмотреть файл

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

Просмотреть файл

@ -362,3 +362,17 @@ SECStatus SSLInt_SetSocketMaxEarlyDataSize(PRFileDesc *fd, uint32_t size) {
void SSLInt_RolloverAntiReplay(void) {
tls13_AntiReplayRollover(ssl_TimeUsec());
}
SECStatus SSLInt_GetEpochs(PRFileDesc *fd, PRUint16 *readEpoch,
PRUint16 *writeEpoch) {
sslSocket *ss = ssl_FindSocket(fd);
if (!ss || !readEpoch || !writeEpoch) {
return SECFailure;
}
ssl_GetSpecReadLock(ss);
*readEpoch = ss->ssl3.crSpec->epoch;
*writeEpoch = ss->ssl3.cwSpec->epoch;
ssl_ReleaseSpecReadLock(ss);
return SECSuccess;
}

Просмотреть файл

@ -39,6 +39,8 @@ SECStatus SSLInt_AdvanceWriteSeqNum(PRFileDesc *fd, PRUint64 to);
SECStatus SSLInt_AdvanceReadSeqNum(PRFileDesc *fd, PRUint64 to);
SECStatus SSLInt_AdvanceWriteSeqByAWindow(PRFileDesc *fd, PRInt32 extra);
SSLKEAType SSLInt_GetKEAType(SSLNamedGroup group);
SECStatus SSLInt_GetEpochs(PRFileDesc *fd, PRUint16 *readEpoch,
PRUint16 *writeEpoch);
SECStatus SSLInt_SetCipherSpecChangeFunc(PRFileDesc *fd,
sslCipherSpecChangedFunc func,

Просмотреть файл

@ -32,6 +32,7 @@ CPPSRCS = \
ssl_gtest.cc \
ssl_hrr_unittest.cc \
ssl_keylog_unittest.cc \
ssl_keyupdate_unittest.cc \
ssl_loopback_unittest.cc \
ssl_misc_unittest.cc \
ssl_record_unittest.cc \

Просмотреть файл

@ -612,13 +612,7 @@ TEST_P(TlsConnectTls13, ZeroRttOrdering) {
});
std::vector<uint8_t> buf(10);
// The first read here blocks because there isn't any 0-RTT to deliver so it
// processes everything. When the EndOfEarlyData message is read, it stalls
// out of the loop. The second read should return the early data.
PRInt32 read = PR_Read(server_->ssl_fd(), buf.data(), buf.size());
EXPECT_GT(0, read);
EXPECT_EQ(PR_WOULD_BLOCK_ERROR, PORT_GetError());
read = PR_Read(server_->ssl_fd(), buf.data(), buf.size());
ASSERT_EQ(static_cast<PRInt32>(early_data.size()), read);
buf.resize(read);
EXPECT_EQ(early_data, buf);

Просмотреть файл

@ -235,27 +235,29 @@ TEST_P(TlsCipherSuiteTest, ResumeCipherSuite) {
ConnectAndCheckCipherSuite();
}
// This only works for stream ciphers because we modify the sequence number -
// which is included explicitly in the DTLS record header - and that trips a
// different error code. Note that the message that the client sends would not
// decrypt (the nonce/IV wouldn't match), but the record limit is hit before
// attempting to decrypt a record.
TEST_P(TlsCipherSuiteTest, ReadLimit) {
SetupCertificate();
EnableSingleCipher();
ConnectAndCheckCipherSuite();
EXPECT_EQ(SECSuccess,
SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), last_safe_write()));
EXPECT_EQ(SECSuccess,
SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last_safe_write()));
if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
uint64_t last = last_safe_write();
EXPECT_EQ(SECSuccess, SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), last));
EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last));
client_->SendData(10, 10);
server_->ReadBytes(); // This should be OK.
client_->SendData(10, 10);
server_->ReadBytes(); // This should be OK.
} else {
// In TLS 1.3, reading or writing triggers a KeyUpdate. That would mean
// that the sequence numbers would reset and we wouldn't hit the limit. So
// we move the sequence number to one less than the limit directly and don't
// test sending and receiving just before the limit.
uint64_t last = record_limit() - 1;
EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), last));
}
// The payload needs to be big enough to pass for encrypted. In the extreme
// case (TLS 1.3), this means 1 for payload, 1 for content type and 16 for
// authentication tag.
static const uint8_t payload[18] = {6};
// The payload needs to be big enough to pass for encrypted. The code checks
// the limit before it tries to decrypt.
static const uint8_t payload[32] = {6};
DataBuffer record;
uint64_t epoch;
if (variant_ == ssl_variant_datagram) {
@ -270,13 +272,17 @@ TEST_P(TlsCipherSuiteTest, ReadLimit) {
TlsAgentTestBase::MakeRecord(variant_, kTlsApplicationDataType, version_,
payload, sizeof(payload), &record,
(epoch << 48) | record_limit());
server_->adapter()->PacketReceived(record);
client_->SendDirect(record);
server_->ExpectReadWriteError();
server_->ReadBytes();
EXPECT_EQ(SSL_ERROR_TOO_MANY_RECORDS, server_->error_code());
}
TEST_P(TlsCipherSuiteTest, WriteLimit) {
// This asserts in TLS 1.3 because we expect an automatic update.
if (version_ >= SSL_LIBRARY_VERSION_TLS_1_3) {
return;
}
SetupCertificate();
EnableSingleCipher();
ConnectAndCheckCipherSuite();

Просмотреть файл

@ -77,7 +77,7 @@ void InstallManyWriters(std::shared_ptr<TlsAgent> agent,
SSLExtensionWriter writer, size_t *installed = nullptr,
size_t *called = nullptr) {
for (size_t i = 0; i < PR_ARRAY_SIZE(kManyExtensions); ++i) {
SSLExtensionSupport support;
SSLExtensionSupport support = ssl_ext_none;
SECStatus rv = SSL_GetExtensionSupport(kManyExtensions[i], &support);
ASSERT_EQ(SECSuccess, rv) << "SSL_GetExtensionSupport cannot fail";

Просмотреть файл

@ -352,6 +352,9 @@ TEST_F(TlsDropDatagram13, DropSecondHalfOfServerCertificate) {
// overlapping message ranges are handled properly; and that extra
// retransmissions are handled properly.
class TlsFragmentationAndRecoveryTest : public TlsDropDatagram13 {
public:
TlsFragmentationAndRecoveryTest() : cert_len_(0) {}
protected:
void RunTest(size_t dropped_half) {
FirstFlightDropCertificate();

Просмотреть файл

@ -33,6 +33,7 @@
'ssl_gtest.cc',
'ssl_hrr_unittest.cc',
'ssl_keylog_unittest.cc',
'ssl_keyupdate_unittest.cc',
'ssl_loopback_unittest.cc',
'ssl_misc_unittest.cc',
'ssl_record_unittest.cc',

Просмотреть файл

@ -4,6 +4,8 @@
* 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/. */
#ifdef NSS_ALLOW_SSLKEYLOGFILE
#include <cstdlib>
#include <fstream>
#include <sstream>
@ -14,6 +16,7 @@
namespace nss_test {
static const std::string keylog_file_path = "keylog.txt";
static const std::string keylog_env = "SSLKEYLOGFILE=" + keylog_file_path;
class KeyLogFileTest : public TlsConnectGeneric {
public:
@ -21,15 +24,13 @@ class KeyLogFileTest : public TlsConnectGeneric {
TlsConnectTestBase::SetUp();
// Remove previous results (if any).
(void)remove(keylog_file_path.c_str());
std::ostringstream sstr;
sstr << "SSLKEYLOGFILE=" << keylog_file_path;
PR_SetEnv(sstr.str().c_str());
PR_SetEnv(keylog_env.c_str());
}
void CheckKeyLog() {
std::ifstream f(keylog_file_path);
std::map<std::string, size_t> labels;
std::string last_client_random;
std::set<std::string> client_randoms;
for (std::string line; std::getline(f, line);) {
if (line[0] == '#') {
continue;
@ -39,27 +40,50 @@ class KeyLogFileTest : public TlsConnectGeneric {
std::string label, client_random, secret;
iss >> label >> client_random >> secret;
ASSERT_EQ(1U, client_random.size());
ASSERT_TRUE(last_client_random.empty() ||
last_client_random == client_random);
last_client_random = client_random;
ASSERT_EQ(64U, client_random.size());
client_randoms.insert(client_random);
labels[label]++;
}
if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
ASSERT_EQ(1U, labels["CLIENT_RANDOM"]);
ASSERT_EQ(1U, client_randoms.size());
} else {
ASSERT_EQ(1U, labels["CLIENT_EARLY_TRAFFIC_SECRET"]);
ASSERT_EQ(1U, labels["CLIENT_HANDSHAKE_TRAFFIC_SECRET"]);
ASSERT_EQ(1U, labels["SERVER_HANDSHAKE_TRAFFIC_SECRET"]);
ASSERT_EQ(1U, labels["CLIENT_TRAFFIC_SECRET_0"]);
ASSERT_EQ(1U, labels["SERVER_TRAFFIC_SECRET_0"]);
ASSERT_EQ(1U, labels["EXPORTER_SECRET"]);
/* two handshakes for 0-RTT */
ASSERT_EQ(2U, client_randoms.size());
}
// Every entry occurs twice (one log from server, one from client).
if (version_ < SSL_LIBRARY_VERSION_TLS_1_3) {
ASSERT_EQ(2U, labels["CLIENT_RANDOM"]);
} else {
ASSERT_EQ(2U, labels["CLIENT_EARLY_TRAFFIC_SECRET"]);
ASSERT_EQ(2U, labels["EARLY_EXPORTER_SECRET"]);
ASSERT_EQ(4U, labels["CLIENT_HANDSHAKE_TRAFFIC_SECRET"]);
ASSERT_EQ(4U, labels["SERVER_HANDSHAKE_TRAFFIC_SECRET"]);
ASSERT_EQ(4U, labels["CLIENT_TRAFFIC_SECRET_0"]);
ASSERT_EQ(4U, labels["SERVER_TRAFFIC_SECRET_0"]);
ASSERT_EQ(4U, labels["EXPORTER_SECRET"]);
}
}
void ConnectAndCheck() {
Connect();
// This is a child process, ensure that error messages immediately
// propagate or else it will not be visible.
::testing::GTEST_FLAG(throw_on_failure) = true;
if (version_ == SSL_LIBRARY_VERSION_TLS_1_3) {
SetupForZeroRtt();
client_->Set0RttEnabled(true);
server_->Set0RttEnabled(true);
ExpectResumption(RESUME_TICKET);
ZeroRttSendReceive(true, true);
Handshake();
ExpectEarlyDataAccepted(true);
CheckConnected();
SendReceive();
} else {
Connect();
}
CheckKeyLog();
_exit(0);
}
@ -90,3 +114,5 @@ INSTANTIATE_TEST_CASE_P(
#endif
} // namespace nss_test
#endif // NSS_ALLOW_SSLKEYLOGFILE

Просмотреть файл

@ -0,0 +1,178 @@
/* -*- 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 "secerr.h"
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"
extern "C" {
// This is not something that should make you happy.
#include "libssl_internals.h"
}
#include "gtest_utils.h"
#include "scoped_ptrs.h"
#include "tls_connect.h"
#include "tls_filter.h"
#include "tls_parser.h"
namespace nss_test {
// All stream only tests; DTLS isn't supported yet.
TEST_F(TlsConnectTest, KeyUpdateClient) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
SendReceive(50);
SendReceive(60);
CheckEpochs(4, 3);
}
TEST_F(TlsConnectTest, KeyUpdateClientRequestUpdate) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
// SendReceive() only gives each peer one chance to read. This isn't enough
// when the read on one side generates another handshake message. A second
// read gives each peer an extra chance to consume the KeyUpdate.
SendReceive(50);
SendReceive(60); // Cumulative count.
CheckEpochs(4, 4);
}
TEST_F(TlsConnectTest, KeyUpdateServer) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
SendReceive(50);
SendReceive(60);
CheckEpochs(3, 4);
}
TEST_F(TlsConnectTest, KeyUpdateServerRequestUpdate) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
SendReceive(50);
SendReceive(60);
CheckEpochs(4, 4);
}
TEST_F(TlsConnectTest, KeyUpdateConsecutiveRequests) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
SendReceive(50);
SendReceive(60);
// The server should have updated twice, but the client should have declined
// to respond to the second request from the server, since it doesn't send
// anything in between those two requests.
CheckEpochs(4, 5);
}
// Check that a local update can be immediately followed by a remotely triggered
// update even if there is no use of the keys.
TEST_F(TlsConnectTest, KeyUpdateLocalUpdateThenConsecutiveRequests) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
// This should trigger an update on the client.
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
// The client should update for the first request.
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
// ...but not the second.
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
SendReceive(50);
SendReceive(60);
// Both should have updated twice.
CheckEpochs(5, 5);
}
TEST_F(TlsConnectTest, KeyUpdateMultiple) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_FALSE));
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_FALSE));
SendReceive(50);
SendReceive(60);
CheckEpochs(5, 6);
}
// Both ask the other for an update, and both should react.
TEST_F(TlsConnectTest, KeyUpdateBothRequest) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
Connect();
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(client_->ssl_fd(), PR_TRUE));
EXPECT_EQ(SECSuccess, SSL_KeyUpdate(server_->ssl_fd(), PR_TRUE));
SendReceive(50);
SendReceive(60);
CheckEpochs(5, 5);
}
// If the sequence number exceeds the number of writes before an automatic
// update (currently 3/4 of the max records for the cipher suite), then the
// stack should send an update automatically (but not request one).
TEST_F(TlsConnectTest, KeyUpdateAutomaticOnWrite) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);
// Set this to one below the write threshold.
uint64_t threshold = (0x5aULL << 28) * 3 / 4;
EXPECT_EQ(SECSuccess,
SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));
// This should be OK.
client_->SendData(10);
server_->ReadBytes();
// This should cause the client to update.
client_->SendData(10);
server_->ReadBytes();
SendReceive(100);
CheckEpochs(4, 3);
}
// If the sequence number exceeds a certain number of reads (currently 7/8 of
// the max records for the cipher suite), then the stack should send AND request
// an update automatically. However, the sender (client) will be above its
// automatic update threshold, so the KeyUpdate - that it sends with the old
// cipher spec - will exceed the receiver (server) automatic update threshold.
// The receiver gets a packet with a sequence number over its automatic read
// update threshold. Even though the sender has updated, the code that checks
// the sequence numbers at the receiver doesn't know this and it will request an
// update. This causes two updates: one from the sender (without requesting a
// response) and one from the receiver (which does request a response).
TEST_F(TlsConnectTest, KeyUpdateAutomaticOnRead) {
ConfigureVersion(SSL_LIBRARY_VERSION_TLS_1_3);
ConnectWithCipherSuite(TLS_AES_128_GCM_SHA256);
// Move to right at the read threshold. Unlike the write test, we can't send
// packets because that would cause the client to update, which would spoil
// the test.
uint64_t threshold = ((0x5aULL << 28) * 7 / 8) + 1;
EXPECT_EQ(SECSuccess,
SSLInt_AdvanceWriteSeqNum(client_->ssl_fd(), threshold));
EXPECT_EQ(SECSuccess, SSLInt_AdvanceReadSeqNum(server_->ssl_fd(), threshold));
// This should cause the client to update, but not early enough to prevent the
// server from updating also.
client_->SendData(10);
server_->ReadBytes();
// Need two SendReceive() calls to ensure that the update that the server
// requested is properly generated and consumed.
SendReceive(70);
SendReceive(80);
CheckEpochs(5, 4);
}
} // namespace nss_test

Просмотреть файл

@ -165,6 +165,22 @@ void TlsConnectTestBase::CheckShares(
EXPECT_EQ(shares.len(), i);
}
void TlsConnectTestBase::CheckEpochs(uint16_t client_epoch,
uint16_t server_epoch) const {
uint16_t read_epoch = 0;
uint16_t write_epoch = 0;
EXPECT_EQ(SECSuccess,
SSLInt_GetEpochs(client_->ssl_fd(), &read_epoch, &write_epoch));
EXPECT_EQ(server_epoch, read_epoch) << "client read epoch";
EXPECT_EQ(client_epoch, write_epoch) << "client write epoch";
EXPECT_EQ(SECSuccess,
SSLInt_GetEpochs(server_->ssl_fd(), &read_epoch, &write_epoch));
EXPECT_EQ(client_epoch, read_epoch) << "server read epoch";
EXPECT_EQ(server_epoch, write_epoch) << "server write epoch";
}
void TlsConnectTestBase::ClearStats() {
// Clear statistics.
SSL3Statistics* stats = SSL_GetStatistics();
@ -593,10 +609,12 @@ void TlsConnectTestBase::CheckSrtp() const {
server_->CheckSrtp();
}
void TlsConnectTestBase::SendReceive() {
client_->SendData(50);
server_->SendData(50);
Receive(50);
void TlsConnectTestBase::SendReceive(size_t total) {
ASSERT_GT(total, client_->received_bytes());
ASSERT_GT(total, server_->received_bytes());
client_->SendData(total - server_->received_bytes());
server_->SendData(total - client_->received_bytes());
Receive(total); // Receive() is cumulative
}
// Do a first connection so we can do 0-RTT on the second one.

Просмотреть файл

@ -94,6 +94,7 @@ class TlsConnectTestBase : public ::testing::Test {
std::function<void(SSLNamedGroup)> check_group);
void CheckShares(const DataBuffer& shares,
std::function<void(SSLNamedGroup)> check_group);
void CheckEpochs(uint16_t client_epoch, uint16_t server_epoch) const;
void ConfigureVersion(uint16_t version);
void SetExpectedVersion(uint16_t version);
@ -114,7 +115,7 @@ class TlsConnectTestBase : public ::testing::Test {
void CheckAlpn(const std::string& val);
void EnableSrtp();
void CheckSrtp() const;
void SendReceive();
void SendReceive(size_t total = 50);
void SetupForZeroRtt();
void SetupForResume();
void ZeroRttSendReceive(

Просмотреть файл

@ -426,6 +426,9 @@ ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp,
last_bfp = NULL;
scopyto = (uint16)copyto; /* ANSI */
if (ino[0] < 1) {
return DATABASE_CORRUPTED_ERROR;
}
n = ino[0] - 1;
while (n < ino[0]) {
@ -463,7 +466,13 @@ ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp,
* Fix up the old page -- the extra 2 are the fields
* which contained the overflow information.
*/
if (ino[0] < (moved + 2)) {
return DATABASE_CORRUPTED_ERROR;
}
ino[0] -= (moved + 2);
if (scopyto < sizeof(uint16) * (ino[0] + 3)) {
return DATABASE_CORRUPTED_ERROR;
}
FREESPACE(ino) =
scopyto - sizeof(uint16) * (ino[0] + 3);
OFFSET(ino) = scopyto;
@ -486,8 +495,14 @@ ugly_split(HTAB *hashp, uint32 obucket, BUFHEAD *old_bufp,
for (n = 1; (n < ino[0]) && (ino[n + 1] >= REAL_KEY); n += 2) {
cino = (char *)ino;
key.data = (uint8 *)cino + ino[n];
if (off < ino[n]) {
return DATABASE_CORRUPTED_ERROR;
}
key.size = off - ino[n];
val.data = (uint8 *)cino + ino[n + 1];
if (ino[n] < ino[n + 1]) {
return DATABASE_CORRUPTED_ERROR;
}
val.size = ino[n] - ino[n + 1];
off = ino[n + 1];

Просмотреть файл

@ -32,15 +32,21 @@ nssCryptokiObject_Create(
/* a failure here indicates a device error */
return (nssCryptokiObject *)NULL;
}
if (cert_template[0].ulValueLen == 0) {
nss_ZFreeIf(cert_template[1].pValue);
return (nssCryptokiObject *)NULL;
}
object = nss_ZNEW(NULL, nssCryptokiObject);
if (!object) {
nss_ZFreeIf(cert_template[0].pValue);
nss_ZFreeIf(cert_template[1].pValue);
return (nssCryptokiObject *)NULL;
}
object->handle = h;
object->token = nssToken_AddRef(t);
isTokenObject = (CK_BBOOL *)cert_template[0].pValue;
object->isTokenObject = *isTokenObject;
nss_ZFreeIf(isTokenObject);
nss_ZFreeIf(cert_template[0].pValue);
NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[1], object->label);
return object;
}

Просмотреть файл

@ -492,8 +492,6 @@ else
endif # Solaris for non-sparc family CPUs
endif # target == SunO
# poly1305-donna-x64-sse2-incremental-source.c requires __int128 support
# in GCC 4.6.0.
ifdef USE_64
ifdef CC_IS_CLANG
HAVE_INT128_SUPPORT = 1
@ -517,7 +515,7 @@ endif
ifndef NSS_DISABLE_CHACHAPOLY
ifeq ($(CPU_ARCH),x86_64)
ifdef HAVE_INT128_SUPPORT
EXTRA_SRCS += poly1305-donna-x64-sse2-incremental-source.c
EXTRA_SRCS += Hacl_Poly1305_64.c
else
EXTRA_SRCS += poly1305.c
endif

Просмотреть файл

@ -14,7 +14,11 @@
#include "blapit.h"
#ifndef NSS_DISABLE_CHACHAPOLY
#if defined(HAVE_INT128_SUPPORT) && (defined(NSS_X86_OR_X64) || defined(__aarch64__))
#include "verified/Hacl_Poly1305_64.h"
#else
#include "poly1305.h"
#endif
#include "chacha20.h"
#include "chacha20poly1305.h"
#endif
@ -22,6 +26,49 @@
/* Poly1305Do writes the Poly1305 authenticator of the given additional data
* and ciphertext to |out|. */
#ifndef NSS_DISABLE_CHACHAPOLY
#if defined(HAVE_INT128_SUPPORT) && (defined(NSS_X86_OR_X64) || defined(__aarch64__))
static void
Poly1305PadUpdate(Hacl_Impl_Poly1305_64_State_poly1305_state state, unsigned char *block, const unsigned char *p, const unsigned int pLen)
{
unsigned int pRemLen = pLen % 16;
Hacl_Poly1305_64_update(state, (uint8_t *)p, (pLen / 16));
if (pRemLen > 0) {
memcpy(block, p + (pLen - pRemLen), pRemLen);
Hacl_Poly1305_64_update(state, block, 1);
}
}
static void
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
const unsigned char *ciphertext, unsigned int ciphertextLen,
const unsigned char key[32])
{
uint64_t tmp1[6U] = { 0U };
Hacl_Impl_Poly1305_64_State_poly1305_state state = Hacl_Poly1305_64_mk_state(tmp1, tmp1 + 3);
unsigned char block[16] = { 0 };
Hacl_Poly1305_64_init(state, (uint8_t *)key);
Poly1305PadUpdate(state, block, ad, adLen);
memset(block, 0, 16);
Poly1305PadUpdate(state, block, ciphertext, ciphertextLen);
unsigned int i;
unsigned int j;
for (i = 0, j = adLen; i < 8; i++, j >>= 8) {
block[i] = j;
}
for (i = 8, j = ciphertextLen; i < 16; i++, j >>= 8) {
block[i] = j;
}
Hacl_Poly1305_64_update(state, block, 1);
Hacl_Poly1305_64_finish(state, out, (uint8_t *)(key + 16));
}
#else
static void
Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
const unsigned char *ciphertext, unsigned int ciphertextLen,
@ -56,7 +103,9 @@ Poly1305Do(unsigned char *out, const unsigned char *ad, unsigned int adLen,
Poly1305Update(&state, lengthBytes, sizeof(lengthBytes));
Poly1305Finish(&state, out);
}
#endif
#endif /* HAVE_INT128_SUPPORT */
#endif /* NSS_DISABLE_CHACHAPOLY */
SECStatus
ChaCha20Poly1305_InitContext(ChaCha20Poly1305Context *ctx,

Просмотреть файл

@ -145,13 +145,35 @@
}],
[ 'disable_chachapoly==0', {
'conditions': [
[ 'OS!="win" and target_arch=="x64"', {
'sources': [
'chacha20_vec.c',
'poly1305-donna-x64-sse2-incremental-source.c',
[ 'OS!="win"', {
'conditions': [
[ 'target_arch=="x64"', {
'sources': [
'chacha20_vec.c',
'verified/Hacl_Poly1305_64.c',
],
}, {
# !Windows & !x64
'conditions': [
[ 'target_arch=="arm64" or target_arch=="aarch64"', {
'sources': [
'chacha20.c',
'verified/Hacl_Chacha20.c',
'verified/Hacl_Poly1305_64.c',
],
}, {
# !Windows & !x64 & !arm64 & !aarch64
'sources': [
'chacha20.c',
'verified/Hacl_Chacha20.c',
'poly1305.c',
],
}],
],
}],
],
}, {
# not x64
# Windows
'sources': [
'chacha20.c',
'verified/Hacl_Chacha20.c',

Просмотреть файл

@ -41,22 +41,6 @@ Hacl_Impl_Chacha20_rotate_left(uint32_t a, uint32_t s)
return a << s | a >> ((uint32_t)32U - s);
}
inline static void
Hacl_Impl_Chacha20_setup(uint32_t *st, uint8_t *k, uint8_t *n1, uint32_t c)
{
uint32_t *stcst = st;
uint32_t *stk = st + (uint32_t)4U;
uint32_t *stc = st + (uint32_t)12U;
uint32_t *stn = st + (uint32_t)13U;
stcst[0U] = (uint32_t)0x61707865U;
stcst[1U] = (uint32_t)0x3320646eU;
stcst[2U] = (uint32_t)0x79622d32U;
stcst[3U] = (uint32_t)0x6b206574U;
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stk, k, (uint32_t)8U);
stc[0U] = c;
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stn, n1, (uint32_t)3U);
}
inline static void
Hacl_Impl_Chacha20_quarter_round(uint32_t *st, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
@ -146,7 +130,17 @@ Hacl_Impl_Chacha20_chacha20_block(uint8_t *stream_block, uint32_t *st, uint32_t
inline static void
Hacl_Impl_Chacha20_init(uint32_t *st, uint8_t *k, uint8_t *n1)
{
Hacl_Impl_Chacha20_setup(st, k, n1, (uint32_t)0U);
uint32_t *stcst = st;
uint32_t *stk = st + (uint32_t)4U;
uint32_t *stc = st + (uint32_t)12U;
uint32_t *stn = st + (uint32_t)13U;
stcst[0U] = (uint32_t)0x61707865U;
stcst[1U] = (uint32_t)0x3320646eU;
stcst[2U] = (uint32_t)0x79622d32U;
stcst[3U] = (uint32_t)0x6b206574U;
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stk, k, (uint32_t)8U);
stc[0U] = (uint32_t)0U;
Hacl_Lib_LoadStore32_uint32s_from_le_bytes(stn, n1, (uint32_t)3U);
}
static void
@ -188,11 +182,11 @@ static void
Hacl_Impl_Chacha20_chacha20_counter_mode_blocks(
uint8_t *output,
uint8_t *plain,
uint32_t len,
uint32_t num_blocks,
uint32_t *st,
uint32_t ctr)
{
for (uint32_t i = (uint32_t)0U; i < len; i = i + (uint32_t)1U) {
for (uint32_t i = (uint32_t)0U; i < num_blocks; i = i + (uint32_t)1U) {
uint8_t *b = plain + (uint32_t)64U * i;
uint8_t *o = output + (uint32_t)64U * i;
Hacl_Impl_Chacha20_update(o, b, st, ctr + i);
@ -242,6 +236,27 @@ Hacl_Chacha20_chacha20_key_block(uint8_t *block, uint8_t *k, uint8_t *n1, uint32
Hacl_Impl_Chacha20_chacha20_block(block, st, ctr);
}
/*
This function implements Chacha20
val chacha20 :
output:uint8_p ->
plain:uint8_p{ disjoint output plain } ->
len:uint32_t{ v len = length output /\ v len = length plain } ->
key:uint8_p{ length key = 32 } ->
nonce:uint8_p{ length nonce = 12 } ->
ctr:uint32_t{ v ctr + length plain / 64 < pow2 32 } ->
Stack unit
(requires
fun h -> live h output /\ live h plain /\ live h nonce /\ live h key)
(ensures
fun h0 _ h1 ->
live h1 output /\ live h0 plain /\ modifies_1 output h0 h1 /\
live h0 nonce /\
live h0 key /\
h1.[ output ] ==
chacha20_encrypt_bytes h0.[ key ] h0.[ nonce ] (v ctr) h0.[ plain ])
*/
void
Hacl_Chacha20_chacha20(
uint8_t *output,

Просмотреть файл

@ -49,6 +49,27 @@ typedef uint32_t Hacl_Chacha20_uint32_t;
void Hacl_Chacha20_chacha20_key_block(uint8_t *block, uint8_t *k, uint8_t *n1, uint32_t ctr);
/*
This function implements Chacha20
val chacha20 :
output:uint8_p ->
plain:uint8_p{ disjoint output plain } ->
len:uint32_t{ v len = length output /\ v len = length plain } ->
key:uint8_p{ length key = 32 } ->
nonce:uint8_p{ length nonce = 12 } ->
ctr:uint32_t{ v ctr + length plain / 64 < pow2 32 } ->
Stack unit
(requires
fun h -> live h output /\ live h plain /\ live h nonce /\ live h key)
(ensures
fun h0 _ h1 ->
live h1 output /\ live h0 plain /\ modifies_1 output h0 h1 /\
live h0 nonce /\
live h0 key /\
h1.[ output ] ==
chacha20_encrypt_bytes h0.[ key ] h0.[ nonce ] (v ctr) h0.[ plain ])
*/
void
Hacl_Chacha20_chacha20(
uint8_t *output,

Просмотреть файл

@ -0,0 +1,485 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Hacl_Poly1305_64.h"
inline static void
Hacl_Bignum_Modulo_reduce(uint64_t *b)
{
uint64_t b0 = b[0U];
b[0U] = (b0 << (uint32_t)4U) + (b0 << (uint32_t)2U);
}
inline static void
Hacl_Bignum_Modulo_carry_top(uint64_t *b)
{
uint64_t b2 = b[2U];
uint64_t b0 = b[0U];
uint64_t b2_42 = b2 >> (uint32_t)42U;
b[2U] = b2 & (uint64_t)0x3ffffffffffU;
b[0U] = (b2_42 << (uint32_t)2U) + b2_42 + b0;
}
inline static void
Hacl_Bignum_Modulo_carry_top_wide(FStar_UInt128_t *b)
{
FStar_UInt128_t b2 = b[2U];
FStar_UInt128_t b0 = b[0U];
FStar_UInt128_t
b2_ = FStar_UInt128_logand(b2, FStar_UInt128_uint64_to_uint128((uint64_t)0x3ffffffffffU));
uint64_t b2_42 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(b2, (uint32_t)42U));
FStar_UInt128_t
b0_ = FStar_UInt128_add(b0, FStar_UInt128_uint64_to_uint128((b2_42 << (uint32_t)2U) + b2_42));
b[2U] = b2_;
b[0U] = b0_;
}
inline static void
Hacl_Bignum_Fproduct_copy_from_wide_(uint64_t *output, FStar_UInt128_t *input)
{
for (uint32_t i = (uint32_t)0U; i < (uint32_t)3U; i = i + (uint32_t)1U) {
FStar_UInt128_t xi = input[i];
output[i] = FStar_UInt128_uint128_to_uint64(xi);
}
}
inline static void
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(
FStar_UInt128_t *output,
uint64_t *input,
uint64_t s)
{
for (uint32_t i = (uint32_t)0U; i < (uint32_t)3U; i = i + (uint32_t)1U) {
FStar_UInt128_t xi = output[i];
uint64_t yi = input[i];
output[i] = FStar_UInt128_add_mod(xi, FStar_UInt128_mul_wide(yi, s));
}
}
inline static void
Hacl_Bignum_Fproduct_carry_wide_(FStar_UInt128_t *tmp)
{
for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) {
uint32_t ctr = i;
FStar_UInt128_t tctr = tmp[ctr];
FStar_UInt128_t tctrp1 = tmp[ctr + (uint32_t)1U];
uint64_t r0 = FStar_UInt128_uint128_to_uint64(tctr) & (uint64_t)0xfffffffffffU;
FStar_UInt128_t c = FStar_UInt128_shift_right(tctr, (uint32_t)44U);
tmp[ctr] = FStar_UInt128_uint64_to_uint128(r0);
tmp[ctr + (uint32_t)1U] = FStar_UInt128_add(tctrp1, c);
}
}
inline static void
Hacl_Bignum_Fproduct_carry_limb_(uint64_t *tmp)
{
for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) {
uint32_t ctr = i;
uint64_t tctr = tmp[ctr];
uint64_t tctrp1 = tmp[ctr + (uint32_t)1U];
uint64_t r0 = tctr & (uint64_t)0xfffffffffffU;
uint64_t c = tctr >> (uint32_t)44U;
tmp[ctr] = r0;
tmp[ctr + (uint32_t)1U] = tctrp1 + c;
}
}
inline static void
Hacl_Bignum_Fmul_shift_reduce(uint64_t *output)
{
uint64_t tmp = output[2U];
for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) {
uint32_t ctr = (uint32_t)3U - i - (uint32_t)1U;
uint64_t z = output[ctr - (uint32_t)1U];
output[ctr] = z;
}
output[0U] = tmp;
Hacl_Bignum_Modulo_reduce(output);
}
static void
Hacl_Bignum_Fmul_mul_shift_reduce_(FStar_UInt128_t *output, uint64_t *input, uint64_t *input2)
{
for (uint32_t i = (uint32_t)0U; i < (uint32_t)2U; i = i + (uint32_t)1U) {
uint64_t input2i = input2[i];
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
Hacl_Bignum_Fmul_shift_reduce(input);
}
uint32_t i = (uint32_t)2U;
uint64_t input2i = input2[i];
Hacl_Bignum_Fproduct_sum_scalar_multiplication_(output, input, input2i);
}
inline static void
Hacl_Bignum_Fmul_fmul(uint64_t *output, uint64_t *input, uint64_t *input2)
{
uint64_t tmp[3U] = { 0U };
memcpy(tmp, input, (uint32_t)3U * sizeof input[0U]);
KRML_CHECK_SIZE(FStar_UInt128_uint64_to_uint128((uint64_t)0U), (uint32_t)3U);
FStar_UInt128_t t[3U];
for (uint32_t _i = 0U; _i < (uint32_t)3U; ++_i)
t[_i] = FStar_UInt128_uint64_to_uint128((uint64_t)0U);
Hacl_Bignum_Fmul_mul_shift_reduce_(t, tmp, input2);
Hacl_Bignum_Fproduct_carry_wide_(t);
Hacl_Bignum_Modulo_carry_top_wide(t);
Hacl_Bignum_Fproduct_copy_from_wide_(output, t);
uint64_t i0 = output[0U];
uint64_t i1 = output[1U];
uint64_t i0_ = i0 & (uint64_t)0xfffffffffffU;
uint64_t i1_ = i1 + (i0 >> (uint32_t)44U);
output[0U] = i0_;
output[1U] = i1_;
}
inline static void
Hacl_Bignum_AddAndMultiply_add_and_multiply(uint64_t *acc, uint64_t *block, uint64_t *r)
{
for (uint32_t i = (uint32_t)0U; i < (uint32_t)3U; i = i + (uint32_t)1U) {
uint64_t xi = acc[i];
uint64_t yi = block[i];
acc[i] = xi + yi;
}
Hacl_Bignum_Fmul_fmul(acc, acc, r);
}
inline static void
Hacl_Impl_Poly1305_64_poly1305_update(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m)
{
Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st;
uint64_t *h = scrut0.h;
uint64_t *acc = h;
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *r = scrut.r;
uint64_t *r3 = r;
uint64_t tmp[3U] = { 0U };
FStar_UInt128_t m0 = load128_le(m);
uint64_t r0 = FStar_UInt128_uint128_to_uint64(m0) & (uint64_t)0xfffffffffffU;
uint64_t
r1 =
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)44U)) & (uint64_t)0xfffffffffffU;
uint64_t r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)88U));
tmp[0U] = r0;
tmp[1U] = r1;
tmp[2U] = r2;
uint64_t b2 = tmp[2U];
uint64_t b2_ = (uint64_t)0x10000000000U | b2;
tmp[2U] = b2_;
Hacl_Bignum_AddAndMultiply_add_and_multiply(acc, tmp, r3);
}
inline static void
Hacl_Impl_Poly1305_64_poly1305_process_last_block_(
uint8_t *block,
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint64_t rem_)
{
uint64_t tmp[3U] = { 0U };
FStar_UInt128_t m0 = load128_le(block);
uint64_t r0 = FStar_UInt128_uint128_to_uint64(m0) & (uint64_t)0xfffffffffffU;
uint64_t
r1 =
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)44U)) & (uint64_t)0xfffffffffffU;
uint64_t r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(m0, (uint32_t)88U));
tmp[0U] = r0;
tmp[1U] = r1;
tmp[2U] = r2;
Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st;
uint64_t *h = scrut0.h;
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *r = scrut.r;
Hacl_Bignum_AddAndMultiply_add_and_multiply(h, tmp, r);
}
inline static void
Hacl_Impl_Poly1305_64_poly1305_process_last_block(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint64_t rem_)
{
uint8_t zero1 = (uint8_t)0U;
KRML_CHECK_SIZE(zero1, (uint32_t)16U);
uint8_t block[16U];
for (uint32_t _i = 0U; _i < (uint32_t)16U; ++_i)
block[_i] = zero1;
uint32_t i0 = (uint32_t)rem_;
uint32_t i = (uint32_t)rem_;
memcpy(block, m, i * sizeof m[0U]);
block[i0] = (uint8_t)1U;
Hacl_Impl_Poly1305_64_poly1305_process_last_block_(block, st, m, rem_);
}
static void
Hacl_Impl_Poly1305_64_poly1305_last_pass(uint64_t *acc)
{
Hacl_Bignum_Fproduct_carry_limb_(acc);
Hacl_Bignum_Modulo_carry_top(acc);
uint64_t a0 = acc[0U];
uint64_t a10 = acc[1U];
uint64_t a20 = acc[2U];
uint64_t a0_ = a0 & (uint64_t)0xfffffffffffU;
uint64_t r0 = a0 >> (uint32_t)44U;
uint64_t a1_ = (a10 + r0) & (uint64_t)0xfffffffffffU;
uint64_t r1 = (a10 + r0) >> (uint32_t)44U;
uint64_t a2_ = a20 + r1;
acc[0U] = a0_;
acc[1U] = a1_;
acc[2U] = a2_;
Hacl_Bignum_Modulo_carry_top(acc);
uint64_t i0 = acc[0U];
uint64_t i1 = acc[1U];
uint64_t i0_ = i0 & (uint64_t)0xfffffffffffU;
uint64_t i1_ = i1 + (i0 >> (uint32_t)44U);
acc[0U] = i0_;
acc[1U] = i1_;
uint64_t a00 = acc[0U];
uint64_t a1 = acc[1U];
uint64_t a2 = acc[2U];
uint64_t mask0 = FStar_UInt64_gte_mask(a00, (uint64_t)0xffffffffffbU);
uint64_t mask1 = FStar_UInt64_eq_mask(a1, (uint64_t)0xfffffffffffU);
uint64_t mask2 = FStar_UInt64_eq_mask(a2, (uint64_t)0x3ffffffffffU);
uint64_t mask = (mask0 & mask1) & mask2;
uint64_t a0_0 = a00 - ((uint64_t)0xffffffffffbU & mask);
uint64_t a1_0 = a1 - ((uint64_t)0xfffffffffffU & mask);
uint64_t a2_0 = a2 - ((uint64_t)0x3ffffffffffU & mask);
acc[0U] = a0_0;
acc[1U] = a1_0;
acc[2U] = a2_0;
}
static Hacl_Impl_Poly1305_64_State_poly1305_state
Hacl_Impl_Poly1305_64_mk_state(uint64_t *r, uint64_t *h)
{
return ((Hacl_Impl_Poly1305_64_State_poly1305_state){.r = r, .h = h });
}
static void
Hacl_Standalone_Poly1305_64_poly1305_blocks(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint64_t len1)
{
if (!(len1 == (uint64_t)0U)) {
uint8_t *block = m;
uint8_t *tail1 = m + (uint32_t)16U;
Hacl_Impl_Poly1305_64_poly1305_update(st, block);
uint64_t len2 = len1 - (uint64_t)1U;
Hacl_Standalone_Poly1305_64_poly1305_blocks(st, tail1, len2);
}
}
static void
Hacl_Standalone_Poly1305_64_poly1305_partial(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *input,
uint64_t len1,
uint8_t *kr)
{
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *r = scrut.r;
uint64_t *x0 = r;
FStar_UInt128_t k1 = load128_le(kr);
FStar_UInt128_t
k_clamped =
FStar_UInt128_logand(k1,
FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0ffffffcU),
(uint32_t)64U),
FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0fffffffU)));
uint64_t r0 = FStar_UInt128_uint128_to_uint64(k_clamped) & (uint64_t)0xfffffffffffU;
uint64_t
r1 =
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)44U)) & (uint64_t)0xfffffffffffU;
uint64_t
r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)88U));
x0[0U] = r0;
x0[1U] = r1;
x0[2U] = r2;
Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st;
uint64_t *h = scrut0.h;
uint64_t *x00 = h;
x00[0U] = (uint64_t)0U;
x00[1U] = (uint64_t)0U;
x00[2U] = (uint64_t)0U;
Hacl_Standalone_Poly1305_64_poly1305_blocks(st, input, len1);
}
static void
Hacl_Standalone_Poly1305_64_poly1305_complete(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint64_t len1,
uint8_t *k1)
{
uint8_t *kr = k1;
uint64_t len16 = len1 >> (uint32_t)4U;
uint64_t rem16 = len1 & (uint64_t)0xfU;
uint8_t *part_input = m;
uint8_t *last_block = m + (uint32_t)((uint64_t)16U * len16);
Hacl_Standalone_Poly1305_64_poly1305_partial(st, part_input, len16, kr);
if (!(rem16 == (uint64_t)0U))
Hacl_Impl_Poly1305_64_poly1305_process_last_block(st, last_block, rem16);
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *h = scrut.h;
uint64_t *acc = h;
Hacl_Impl_Poly1305_64_poly1305_last_pass(acc);
}
static void
Hacl_Standalone_Poly1305_64_crypto_onetimeauth_(
uint8_t *output,
uint8_t *input,
uint64_t len1,
uint8_t *k1)
{
uint64_t buf[6U] = { 0U };
uint64_t *r = buf;
uint64_t *h = buf + (uint32_t)3U;
Hacl_Impl_Poly1305_64_State_poly1305_state st = Hacl_Impl_Poly1305_64_mk_state(r, h);
uint8_t *key_s = k1 + (uint32_t)16U;
Hacl_Standalone_Poly1305_64_poly1305_complete(st, input, len1, k1);
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *h3 = scrut.h;
uint64_t *acc = h3;
FStar_UInt128_t k_ = load128_le(key_s);
uint64_t h0 = acc[0U];
uint64_t h1 = acc[1U];
uint64_t h2 = acc[2U];
FStar_UInt128_t
acc_ =
FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128(h2
<< (uint32_t)24U |
h1 >> (uint32_t)20U),
(uint32_t)64U),
FStar_UInt128_uint64_to_uint128(h1 << (uint32_t)44U | h0));
FStar_UInt128_t mac_ = FStar_UInt128_add_mod(acc_, k_);
store128_le(output, mac_);
}
static void
Hacl_Standalone_Poly1305_64_crypto_onetimeauth(
uint8_t *output,
uint8_t *input,
uint64_t len1,
uint8_t *k1)
{
Hacl_Standalone_Poly1305_64_crypto_onetimeauth_(output, input, len1, k1);
}
Hacl_Impl_Poly1305_64_State_poly1305_state
Hacl_Poly1305_64_mk_state(uint64_t *r, uint64_t *acc)
{
return Hacl_Impl_Poly1305_64_mk_state(r, acc);
}
void
Hacl_Poly1305_64_init(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *k1)
{
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *r = scrut.r;
uint64_t *x0 = r;
FStar_UInt128_t k10 = load128_le(k1);
FStar_UInt128_t
k_clamped =
FStar_UInt128_logand(k10,
FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0ffffffcU),
(uint32_t)64U),
FStar_UInt128_uint64_to_uint128((uint64_t)0x0ffffffc0fffffffU)));
uint64_t r0 = FStar_UInt128_uint128_to_uint64(k_clamped) & (uint64_t)0xfffffffffffU;
uint64_t
r1 =
FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)44U)) & (uint64_t)0xfffffffffffU;
uint64_t
r2 = FStar_UInt128_uint128_to_uint64(FStar_UInt128_shift_right(k_clamped, (uint32_t)88U));
x0[0U] = r0;
x0[1U] = r1;
x0[2U] = r2;
Hacl_Impl_Poly1305_64_State_poly1305_state scrut0 = st;
uint64_t *h = scrut0.h;
uint64_t *x00 = h;
x00[0U] = (uint64_t)0U;
x00[1U] = (uint64_t)0U;
x00[2U] = (uint64_t)0U;
}
void
Hacl_Poly1305_64_update_block(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *m)
{
Hacl_Impl_Poly1305_64_poly1305_update(st, m);
}
void
Hacl_Poly1305_64_update(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint32_t num_blocks)
{
if (!(num_blocks == (uint32_t)0U)) {
uint8_t *block = m;
uint8_t *m_ = m + (uint32_t)16U;
uint32_t n1 = num_blocks - (uint32_t)1U;
Hacl_Poly1305_64_update_block(st, block);
Hacl_Poly1305_64_update(st, m_, n1);
}
}
void
Hacl_Poly1305_64_update_last(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint32_t len1)
{
if (!((uint64_t)len1 == (uint64_t)0U))
Hacl_Impl_Poly1305_64_poly1305_process_last_block(st, m, (uint64_t)len1);
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *h = scrut.h;
uint64_t *acc = h;
Hacl_Impl_Poly1305_64_poly1305_last_pass(acc);
}
void
Hacl_Poly1305_64_finish(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *mac,
uint8_t *k1)
{
Hacl_Impl_Poly1305_64_State_poly1305_state scrut = st;
uint64_t *h = scrut.h;
uint64_t *acc = h;
FStar_UInt128_t k_ = load128_le(k1);
uint64_t h0 = acc[0U];
uint64_t h1 = acc[1U];
uint64_t h2 = acc[2U];
FStar_UInt128_t
acc_ =
FStar_UInt128_logor(FStar_UInt128_shift_left(FStar_UInt128_uint64_to_uint128(h2
<< (uint32_t)24U |
h1 >> (uint32_t)20U),
(uint32_t)64U),
FStar_UInt128_uint64_to_uint128(h1 << (uint32_t)44U | h0));
FStar_UInt128_t mac_ = FStar_UInt128_add_mod(acc_, k_);
store128_le(mac, mac_);
}
void
Hacl_Poly1305_64_crypto_onetimeauth(
uint8_t *output,
uint8_t *input,
uint64_t len1,
uint8_t *k1)
{
Hacl_Standalone_Poly1305_64_crypto_onetimeauth(output, input, len1, k1);
}

Просмотреть файл

@ -0,0 +1,99 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "kremlib.h"
#ifndef __Hacl_Poly1305_64_H
#define __Hacl_Poly1305_64_H
typedef uint64_t Hacl_Bignum_Constants_limb;
typedef FStar_UInt128_t Hacl_Bignum_Constants_wide;
typedef FStar_UInt128_t Hacl_Bignum_Wide_t;
typedef uint64_t Hacl_Bignum_Limb_t;
typedef void *Hacl_Impl_Poly1305_64_State_log_t;
typedef uint8_t *Hacl_Impl_Poly1305_64_State_uint8_p;
typedef uint64_t *Hacl_Impl_Poly1305_64_State_bigint;
typedef void *Hacl_Impl_Poly1305_64_State_seqelem;
typedef uint64_t *Hacl_Impl_Poly1305_64_State_elemB;
typedef uint8_t *Hacl_Impl_Poly1305_64_State_wordB;
typedef uint8_t *Hacl_Impl_Poly1305_64_State_wordB_16;
typedef struct
{
uint64_t *r;
uint64_t *h;
} Hacl_Impl_Poly1305_64_State_poly1305_state;
typedef void *Hacl_Impl_Poly1305_64_log_t;
typedef uint64_t *Hacl_Impl_Poly1305_64_bigint;
typedef uint8_t *Hacl_Impl_Poly1305_64_uint8_p;
typedef uint64_t *Hacl_Impl_Poly1305_64_elemB;
typedef uint8_t *Hacl_Impl_Poly1305_64_wordB;
typedef uint8_t *Hacl_Impl_Poly1305_64_wordB_16;
typedef uint8_t *Hacl_Poly1305_64_uint8_p;
typedef uint64_t Hacl_Poly1305_64_uint64_t;
typedef uint8_t *Hacl_Poly1305_64_key;
typedef Hacl_Impl_Poly1305_64_State_poly1305_state Hacl_Poly1305_64_state;
Hacl_Impl_Poly1305_64_State_poly1305_state
Hacl_Poly1305_64_mk_state(uint64_t *r, uint64_t *acc);
void Hacl_Poly1305_64_init(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *k1);
void Hacl_Poly1305_64_update_block(Hacl_Impl_Poly1305_64_State_poly1305_state st, uint8_t *m);
void
Hacl_Poly1305_64_update(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint32_t num_blocks);
void
Hacl_Poly1305_64_update_last(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *m,
uint32_t len1);
void
Hacl_Poly1305_64_finish(
Hacl_Impl_Poly1305_64_State_poly1305_state st,
uint8_t *mac,
uint8_t *k1);
void
Hacl_Poly1305_64_crypto_onetimeauth(
uint8_t *output,
uint8_t *input,
uint64_t len1,
uint8_t *k1);
#endif

Просмотреть файл

@ -207,19 +207,19 @@ typedef const char *Prims_string;
#elif defined(__sun__)
#include <sys/byteorder.h>
#define htole64(x) LE_64(x)
#define le64toh(x) LE_IN64(x)
#define le64toh(x) LE_64(x)
#define htobe64(x) BE_64(x)
#define be64toh(x) BE_IN64(x)
#define be64toh(x) BE_64(x)
#define htole16(x) LE_16(x)
#define le16toh(x) LE_IN16(x)
#define le16toh(x) LE_16(x)
#define htobe16(x) BE_16(x)
#define be16toh(x) BE_IN16(x)
#define be16toh(x) BE_16(x)
#define htole32(x) LE_32(x)
#define le32toh(x) LE_IN32(x)
#define le32toh(x) LE_32(x)
#define htobe32(x) BE_32(x)
#define be32toh(x) BE_IN32(x)
#define be32toh(x) BE_32(x)
/* ... for the BSDs */
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)

Просмотреть файл

@ -1,3 +1,18 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module Spec.CTR
module ST = FStar.HyperStack.ST

Просмотреть файл

@ -1,3 +1,18 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module Spec.Chacha20
module ST = FStar.HyperStack.ST

Просмотреть файл

@ -0,0 +1,168 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module Spec.Curve25519
module ST = FStar.HyperStack.ST
open FStar.Mul
open FStar.Seq
open FStar.UInt8
open FStar.Endianness
open Spec.Lib
open Spec.Curve25519.Lemmas
#reset-options "--initial_fuel 0 --max_fuel 0 --z3rlimit 20"
(* Field types and parameters *)
let prime = pow2 255 - 19
type elem : Type0 = e:int{e >= 0 /\ e < prime}
let fadd e1 e2 = (e1 + e2) % prime
let fsub e1 e2 = (e1 - e2) % prime
let fmul e1 e2 = (e1 * e2) % prime
let zero : elem = 0
let one : elem = 1
let ( +@ ) = fadd
let ( *@ ) = fmul
(** Exponentiation *)
let rec ( ** ) (e:elem) (n:pos) : Tot elem (decreases n) =
if n = 1 then e
else
if n % 2 = 0 then op_Star_Star (e `fmul` e) (n / 2)
else e `fmul` (op_Star_Star (e `fmul` e) ((n-1)/2))
(* Type aliases *)
type scalar = lbytes 32
type serialized_point = lbytes 32
type proj_point = | Proj: x:elem -> z:elem -> proj_point
let decodeScalar25519 (k:scalar) =
let k = k.[0] <- (k.[0] &^ 248uy) in
let k = k.[31] <- ((k.[31] &^ 127uy) |^ 64uy) in k
let decodePoint (u:serialized_point) =
(little_endian u % pow2 255) % prime
let add_and_double qx nq nqp1 =
let x_1 = qx in
let x_2, z_2 = nq.x, nq.z in
let x_3, z_3 = nqp1.x, nqp1.z in
let a = x_2 `fadd` z_2 in
let aa = a**2 in
let b = x_2 `fsub` z_2 in
let bb = b**2 in
let e = aa `fsub` bb in
let c = x_3 `fadd` z_3 in
let d = x_3 `fsub` z_3 in
let da = d `fmul` a in
let cb = c `fmul` b in
let x_3 = (da `fadd` cb)**2 in
let z_3 = x_1 `fmul` ((da `fsub` cb)**2) in
let x_2 = aa `fmul` bb in
let z_2 = e `fmul` (aa `fadd` (121665 `fmul` e)) in
Proj x_2 z_2, Proj x_3 z_3
let ith_bit (k:scalar) (i:nat{i < 256}) =
let q = i / 8 in let r = i % 8 in
(v (k.[q]) / pow2 r) % 2
let rec montgomery_ladder_ (init:elem) x xp1 (k:scalar) (ctr:nat{ctr<=256})
: Tot proj_point (decreases ctr) =
if ctr = 0 then x
else (
let ctr' = ctr - 1 in
let (x', xp1') =
if ith_bit k ctr' = 1 then (
let nqp2, nqp1 = add_and_double init xp1 x in
nqp1, nqp2
) else add_and_double init x xp1 in
montgomery_ladder_ init x' xp1' k ctr'
)
let montgomery_ladder (init:elem) (k:scalar) : Tot proj_point =
montgomery_ladder_ init (Proj one zero) (Proj init one) k 256
let encodePoint (p:proj_point) : Tot serialized_point =
let p = p.x `fmul` (p.z ** (prime - 2)) in
little_bytes 32ul p
let scalarmult (k:scalar) (u:serialized_point) : Tot serialized_point =
let k = decodeScalar25519 k in
let u = decodePoint u in
let res = montgomery_ladder u k in
encodePoint res
(* ********************* *)
(* RFC 7748 Test Vectors *)
(* ********************* *)
let scalar1 = [
0xa5uy; 0x46uy; 0xe3uy; 0x6buy; 0xf0uy; 0x52uy; 0x7cuy; 0x9duy;
0x3buy; 0x16uy; 0x15uy; 0x4buy; 0x82uy; 0x46uy; 0x5euy; 0xdduy;
0x62uy; 0x14uy; 0x4cuy; 0x0auy; 0xc1uy; 0xfcuy; 0x5auy; 0x18uy;
0x50uy; 0x6auy; 0x22uy; 0x44uy; 0xbauy; 0x44uy; 0x9auy; 0xc4uy
]
let scalar2 = [
0x4buy; 0x66uy; 0xe9uy; 0xd4uy; 0xd1uy; 0xb4uy; 0x67uy; 0x3cuy;
0x5auy; 0xd2uy; 0x26uy; 0x91uy; 0x95uy; 0x7duy; 0x6auy; 0xf5uy;
0xc1uy; 0x1buy; 0x64uy; 0x21uy; 0xe0uy; 0xeauy; 0x01uy; 0xd4uy;
0x2cuy; 0xa4uy; 0x16uy; 0x9euy; 0x79uy; 0x18uy; 0xbauy; 0x0duy
]
let input1 = [
0xe6uy; 0xdbuy; 0x68uy; 0x67uy; 0x58uy; 0x30uy; 0x30uy; 0xdbuy;
0x35uy; 0x94uy; 0xc1uy; 0xa4uy; 0x24uy; 0xb1uy; 0x5fuy; 0x7cuy;
0x72uy; 0x66uy; 0x24uy; 0xecuy; 0x26uy; 0xb3uy; 0x35uy; 0x3buy;
0x10uy; 0xa9uy; 0x03uy; 0xa6uy; 0xd0uy; 0xabuy; 0x1cuy; 0x4cuy
]
let input2 = [
0xe5uy; 0x21uy; 0x0fuy; 0x12uy; 0x78uy; 0x68uy; 0x11uy; 0xd3uy;
0xf4uy; 0xb7uy; 0x95uy; 0x9duy; 0x05uy; 0x38uy; 0xaeuy; 0x2cuy;
0x31uy; 0xdbuy; 0xe7uy; 0x10uy; 0x6fuy; 0xc0uy; 0x3cuy; 0x3euy;
0xfcuy; 0x4cuy; 0xd5uy; 0x49uy; 0xc7uy; 0x15uy; 0xa4uy; 0x93uy
]
let expected1 = [
0xc3uy; 0xdauy; 0x55uy; 0x37uy; 0x9duy; 0xe9uy; 0xc6uy; 0x90uy;
0x8euy; 0x94uy; 0xeauy; 0x4duy; 0xf2uy; 0x8duy; 0x08uy; 0x4fuy;
0x32uy; 0xecuy; 0xcfuy; 0x03uy; 0x49uy; 0x1cuy; 0x71uy; 0xf7uy;
0x54uy; 0xb4uy; 0x07uy; 0x55uy; 0x77uy; 0xa2uy; 0x85uy; 0x52uy
]
let expected2 = [
0x95uy; 0xcbuy; 0xdeuy; 0x94uy; 0x76uy; 0xe8uy; 0x90uy; 0x7duy;
0x7auy; 0xaduy; 0xe4uy; 0x5cuy; 0xb4uy; 0xb8uy; 0x73uy; 0xf8uy;
0x8buy; 0x59uy; 0x5auy; 0x68uy; 0x79uy; 0x9fuy; 0xa1uy; 0x52uy;
0xe6uy; 0xf8uy; 0xf7uy; 0x64uy; 0x7auy; 0xacuy; 0x79uy; 0x57uy
]
let test () =
assert_norm(List.Tot.length scalar1 = 32);
assert_norm(List.Tot.length scalar2 = 32);
assert_norm(List.Tot.length input1 = 32);
assert_norm(List.Tot.length input2 = 32);
assert_norm(List.Tot.length expected1 = 32);
assert_norm(List.Tot.length expected2 = 32);
let scalar1 = createL scalar1 in
let scalar2 = createL scalar2 in
let input1 = createL input1 in
let input2 = createL input2 in
let expected1 = createL expected1 in
let expected2 = createL expected2 in
scalarmult scalar1 input1 = expected1
&& scalarmult scalar2 input2 = expected2

Просмотреть файл

@ -0,0 +1,107 @@
/* Copyright 2016-2017 INRIA and Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
module Spec.Poly1305
module ST = FStar.HyperStack.ST
open FStar.Math.Lib
open FStar.Mul
open FStar.Seq
open FStar.UInt8
open FStar.Endianness
open Spec.Poly1305.Lemmas
#set-options "--initial_fuel 0 --max_fuel 0 --initial_ifuel 0 --max_ifuel 0"
(* Field types and parameters *)
let prime = pow2 130 - 5
type elem = e:int{e >= 0 /\ e < prime}
let fadd (e1:elem) (e2:elem) = (e1 + e2) % prime
let fmul (e1:elem) (e2:elem) = (e1 * e2) % prime
let zero : elem = 0
let one : elem = 1
let op_Plus_At = fadd
let op_Star_At = fmul
(* Type aliases *)
let op_Amp_Bar = UInt.logand #128
type word = w:bytes{length w <= 16}
type word_16 = w:bytes{length w = 16}
type tag = word_16
type key = lbytes 32
type text = seq word
(* Specification code *)
let encode (w:word) =
(pow2 (8 * length w)) `fadd` (little_endian w)
let rec poly (txt:text) (r:e:elem) : Tot elem (decreases (length txt)) =
if length txt = 0 then zero
else
let a = poly (Seq.tail txt) r in
let n = encode (Seq.head txt) in
(n `fadd` a) `fmul` r
let encode_r (rb:word_16) =
(little_endian rb) &| 0x0ffffffc0ffffffc0ffffffc0fffffff
let finish (a:elem) (s:word_16) : Tot tag =
let n = (a + little_endian s) % pow2 128 in
little_bytes 16ul n
let rec encode_bytes (txt:bytes) : Tot text (decreases (length txt)) =
if length txt = 0 then createEmpty
else
let w, txt = split txt (min (length txt) 16) in
append_last (encode_bytes txt) w
let poly1305 (msg:bytes) (k:key) : Tot tag =
let text = encode_bytes msg in
let r = encode_r (slice k 0 16) in
let s = slice k 16 32 in
finish (poly text r) s
(* ********************* *)
(* RFC 7539 Test Vectors *)
(* ********************* *)
#reset-options "--initial_fuel 0 --max_fuel 0 --z3rlimit 20"
unfold let msg = [
0x43uy; 0x72uy; 0x79uy; 0x70uy; 0x74uy; 0x6fuy; 0x67uy; 0x72uy;
0x61uy; 0x70uy; 0x68uy; 0x69uy; 0x63uy; 0x20uy; 0x46uy; 0x6fuy;
0x72uy; 0x75uy; 0x6duy; 0x20uy; 0x52uy; 0x65uy; 0x73uy; 0x65uy;
0x61uy; 0x72uy; 0x63uy; 0x68uy; 0x20uy; 0x47uy; 0x72uy; 0x6fuy;
0x75uy; 0x70uy ]
unfold let k = [
0x85uy; 0xd6uy; 0xbeuy; 0x78uy; 0x57uy; 0x55uy; 0x6duy; 0x33uy;
0x7fuy; 0x44uy; 0x52uy; 0xfeuy; 0x42uy; 0xd5uy; 0x06uy; 0xa8uy;
0x01uy; 0x03uy; 0x80uy; 0x8auy; 0xfbuy; 0x0duy; 0xb2uy; 0xfduy;
0x4auy; 0xbfuy; 0xf6uy; 0xafuy; 0x41uy; 0x49uy; 0xf5uy; 0x1buy ]
unfold let expected = [
0xa8uy; 0x06uy; 0x1duy; 0xc1uy; 0x30uy; 0x51uy; 0x36uy; 0xc6uy;
0xc2uy; 0x2buy; 0x8buy; 0xafuy; 0x0cuy; 0x01uy; 0x27uy; 0xa9uy ]
let test () : Tot bool =
assert_norm(List.Tot.length msg = 34);
assert_norm(List.Tot.length k = 32);
assert_norm(List.Tot.length expected = 16);
let msg = createL msg in
let k = createL k in
let expected = createL expected in
poly1305 msg k = expected

Просмотреть файл

@ -133,7 +133,7 @@ lg_CopyAttribute(CK_ATTRIBUTE *attr, CK_ATTRIBUTE_TYPE type,
attr->ulValueLen = (CK_ULONG)-1;
return CKR_BUFFER_TOO_SMALL;
}
if (value != NULL) {
if (len > 0 && value != NULL) {
PORT_Memcpy(attr->pValue, value, len);
}
attr->ulValueLen = len;

Просмотреть файл

@ -1854,6 +1854,8 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
&dbentry->data[DB_SMIME_ENTRY_HEADER_LEN +
entry->subjectName.len],
entry->smimeOptions.len);
} else {
entry->smimeOptions.data = NULL;
}
if (entry->optionsDate.len) {
entry->optionsDate.data =
@ -1868,6 +1870,8 @@ DecodeDBSMimeEntry(certDBEntrySMime *entry, SECItem *dbentry, char *emailAddr)
entry->subjectName.len +
entry->smimeOptions.len],
entry->optionsDate.len);
} else {
entry->optionsDate.data = NULL;
}
/* both options and options date must either exist or not exist */
@ -2014,7 +2018,7 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
{
PLArenaPool *arena = NULL;
PLArenaPool *tmparena = NULL;
certDBEntrySMime *entry;
certDBEntrySMime *entry = NULL;
SECItem dbkey;
SECItem dbentry;
SECStatus rv;
@ -2031,8 +2035,8 @@ nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
goto loser;
}
entry = (certDBEntrySMime *)PORT_ArenaAlloc(arena,
sizeof(certDBEntrySMime));
entry = (certDBEntrySMime *)PORT_ArenaZAlloc(arena,
sizeof(certDBEntrySMime));
if (entry == NULL) {
PORT_SetError(SEC_ERROR_NO_MEMORY);
goto loser;

Просмотреть файл

@ -531,3 +531,12 @@ ER3(SSL_ERROR_NO_TIMERS_ERROR, (SSL_ERROR_BASE + 167),
ER3(SSL_ERROR_MISSING_COOKIE_EXTENSION, (SSL_ERROR_BASE + 168),
"A second ClientHello was received without a cookie extension.")
ER3(SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, (SSL_ERROR_BASE + 169),
"SSL received an unexpected key update message.")
ER3(SSL_ERROR_RX_MALFORMED_KEY_UPDATE, (SSL_ERROR_BASE + 170),
"SSL received a malformed key update message.")
ER3(SSL_ERROR_TOO_MANY_KEY_UPDATES, (SSL_ERROR_BASE + 171),
"SSL attempted too many key updates.")

Просмотреть файл

@ -78,7 +78,7 @@ dtls13_RememberFragment(sslSocket *ss,
SECStatus
dtls13_SendAck(sslSocket *ss)
{
sslBuffer buf = { NULL, 0, 0 };
sslBuffer buf = SSL_BUFFER_EMPTY;
SECStatus rv = SECSuccess;
PRCList *cursor;
PRInt32 sent;

Просмотреть файл

@ -2205,6 +2205,8 @@ ssl_ProtectRecord(sslSocket *ss, ssl3CipherSpec *cwSpec, SSL3ContentType type,
PORT_Assert(SSL_BUFFER_LEN(wrBuf) == 0);
PORT_Assert(cwSpec->cipherDef->max_records <= RECORD_SEQ_MAX);
if (cwSpec->seqNum >= cwSpec->cipherDef->max_records) {
/* We should have automatically updated before here in TLS 1.3. */
PORT_Assert(cwSpec->version < SSL_LIBRARY_VERSION_TLS_1_3);
SSL_TRC(3, ("%d: SSL[-]: write sequence number at limit 0x%0llx",
SSL_GETPID(), cwSpec->seqNum));
PORT_SetError(SSL_ERROR_TOO_MANY_RECORDS);
@ -8612,7 +8614,7 @@ loser:
* in asking to use the V3 handshake.
*/
SECStatus
ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, int length,
ssl3_HandleV2ClientHello(sslSocket *ss, unsigned char *buffer, unsigned int length,
PRUint8 padding)
{
sslSessionID *sid = NULL;

Просмотреть файл

@ -1,85 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is PRIVATE to SSL.
*
* 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 "prnetdb.h"
#include "seccomon.h"
#include "secerr.h"
#include "ssl3encode.h"
SECStatus
ssl3_AppendToItem(SECItem *item, const unsigned char *buf, PRUint32 bytes)
{
if (bytes > item->len) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
PORT_Memcpy(item->data, buf, bytes);
item->data += bytes;
item->len -= bytes;
return SECSuccess;
}
SECStatus
ssl3_AppendNumberToItem(SECItem *item, PRUint64 num, PRInt32 lenSize)
{
SECStatus rv;
PRUint8 b[sizeof(num)];
ssl_EncodeUintX(num, lenSize, b);
rv = ssl3_AppendToItem(item, &b[0], lenSize);
return rv;
}
SECStatus
ssl3_ConsumeFromItem(SECItem *item, unsigned char **buf, PRUint32 bytes)
{
if (bytes > item->len) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
*buf = item->data;
item->data += bytes;
item->len -= bytes;
return SECSuccess;
}
SECStatus
ssl3_ConsumeNumberFromItem(SECItem *item, PRUint32 *num, PRUint32 bytes)
{
unsigned int i;
if (bytes > item->len || bytes > sizeof(*num)) {
PORT_SetError(SEC_ERROR_BAD_DATA);
return SECFailure;
}
*num = 0;
for (i = 0; i < bytes; i++) {
*num = (*num << 8) + item->data[i];
}
item->data += bytes;
item->len -= bytes;
return SECSuccess;
}
/* Helper function to encode an unsigned integer into a buffer. */
PRUint8 *
ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to)
{
PRUint64 encoded;
PORT_Assert(bytes > 0 && bytes <= sizeof(encoded));
encoded = PR_htonll(value);
memcpy(to, ((unsigned char *)(&encoded)) + (sizeof(encoded) - bytes), bytes);
return to + bytes;
}

Просмотреть файл

@ -1,26 +0,0 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is PRIVATE to SSL.
*
* 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/. */
#ifndef __ssl3encode_h_
#define __ssl3encode_h_
#include "seccomon.h"
/* All of these functions modify the underlying SECItem, and so should
* be performed on a shallow copy.*/
SECStatus ssl3_AppendToItem(SECItem *item,
const unsigned char *buf, PRUint32 bytes);
SECStatus ssl3_AppendNumberToItem(SECItem *item,
PRUint64 num, PRInt32 lenSize);
SECStatus ssl3_ConsumeFromItem(SECItem *item,
unsigned char **buf, PRUint32 bytes);
SECStatus ssl3_ConsumeNumberFromItem(SECItem *item,
PRUint32 *num, PRUint32 bytes);
PRUint8 *ssl_EncodeUintX(PRUint64 value, unsigned int bytes, PRUint8 *to);
#endif

Просмотреть файл

@ -619,7 +619,7 @@ static SECStatus
ssl_CallCustomExtensionSenders(sslSocket *ss, sslBuffer *buf,
SSLHandshakeType message)
{
sslBuffer tail = { NULL, 0, 0 };
sslBuffer tail = SSL_BUFFER_EMPTY;
SECStatus rv;
PRCList *cursor;

Просмотреть файл

@ -665,7 +665,7 @@ ssl3_EncodeSessionTicket(sslSocket *ss, const NewSessionTicket *ticket,
PK11SymKey *secret, SECItem *ticket_data)
{
SECStatus rv;
sslBuffer plaintext = { NULL, 0, 0 };
sslBuffer plaintext = SSL_BUFFER_EMPTY;
SECItem ticket_buf = { 0, NULL, 0 };
sslSessionID sid;
unsigned char wrapped_ms[SSL3_MASTER_SECRET_LENGTH];

Просмотреть файл

@ -257,6 +257,9 @@ typedef enum {
SSL_ERROR_NO_TIMERS_FOUND = (SSL_ERROR_BASE + 167),
SSL_ERROR_MISSING_COOKIE_EXTENSION = (SSL_ERROR_BASE + 168),
SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE = (SSL_ERROR_BASE + 169),
SSL_ERROR_RX_MALFORMED_KEY_UPDATE = (SSL_ERROR_BASE + 170),
SSL_ERROR_TOO_MANY_KEY_UPDATES = (SSL_ERROR_BASE + 171),
SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
} SSLErrorCodes;
#endif /* NO_SECURITY_ERROR_ENUM */

Просмотреть файл

@ -340,6 +340,16 @@ typedef SSLHelloRetryRequestAction(PR_CALLBACK *SSLHelloRetryRequestCallback)(
SSLHelloRetryRequestCallback _cb, void *_arg), \
(fd, cb, arg))
/* Update traffic keys (TLS 1.3 only).
*
* The |requestUpdate| flag determines whether to request an update from the
* remote peer.
*/
#define SSL_KeyUpdate(fd, requestUpdate) \
SSL_EXPERIMENTAL_API("SSL_KeyUpdate", \
(PRFileDesc * _fd, PRBool _requestUpdate), \
(fd, requestUpdate))
#define SSL_UseAltServerHelloType(fd, enable) \
SSL_DEPRECATED_EXPERIMENTAL_API

Просмотреть файл

@ -726,6 +726,10 @@ struct ssl3StateStr {
ssl3CipherSpec *cwSpec; /* current write spec. */
ssl3CipherSpec *pwSpec; /* pending write spec. */
/* This is true after the peer requests a key update; false after a key
* update is initiated locally. */
PRBool peerRequestedKeyUpdate;
/* Internal callback for when we do a cipher suite change. Used for
* debugging in TLS 1.3. This can only be set by non-public functions. */
sslCipherSpecChangedFunc changedCipherSpecFunc;
@ -1373,7 +1377,7 @@ extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
* for dealing with SSL 3.0 clients sending SSL 2.0 format hellos
*/
extern SECStatus ssl3_HandleV2ClientHello(
sslSocket *ss, unsigned char *buffer, int length, PRUint8 padding);
sslSocket *ss, unsigned char *buffer, unsigned int length, PRUint8 padding);
SECStatus ssl3_SendClientHello(sslSocket *ss, sslClientHelloType type);

Просмотреть файл

@ -762,6 +762,55 @@ ssl_SecureShutdown(sslSocket *ss, int nsprHow)
/************************************************************************/
static SECStatus
tls13_CheckKeyUpdate(sslSocket *ss, CipherSpecDirection dir)
{
PRBool keyUpdate;
ssl3CipherSpec *spec;
sslSequenceNumber seqNum;
sslSequenceNumber margin;
SECStatus rv;
/* Bug 1413368: enable for DTLS */
if (ss->version < SSL_LIBRARY_VERSION_TLS_1_3 || IS_DTLS(ss)) {
return SECSuccess;
}
/* If both sides update at the same number, then this will cause two updates
* to happen at once. The problem is that the KeyUpdate itself consumes a
* sequence number, and that will trigger the reading side to request an
* update.
*
* If we have the writing side update first, the writer will be the one that
* drives the update. An update by the writer doesn't need a response, so
* it is more efficient overall. The margins here are pretty arbitrary, but
* having the write margin larger reduces the number of times that a
* KeyUpdate is sent by a reader. */
ssl_GetSpecReadLock(ss);
if (dir == CipherSpecRead) {
spec = ss->ssl3.crSpec;
margin = spec->cipherDef->max_records / 8;
} else {
spec = ss->ssl3.cwSpec;
margin = spec->cipherDef->max_records / 4;
}
seqNum = spec->seqNum;
keyUpdate = seqNum > spec->cipherDef->max_records - margin;
ssl_ReleaseSpecReadLock(ss);
if (!keyUpdate) {
return SECSuccess;
}
SSL_TRC(5, ("%d: SSL[%d]: automatic key update at %llx for %s cipher spec",
SSL_GETPID(), ss->fd, seqNum,
(dir == CipherSpecRead) ? "read" : "write"));
ssl_GetSSL3HandshakeLock(ss);
rv = tls13_SendKeyUpdate(ss, (dir == CipherSpecRead) ? update_requested : update_not_requested,
dir == CipherSpecWrite /* buffer */);
ssl_ReleaseSSL3HandshakeLock(ss);
return rv;
}
int
ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
{
@ -801,8 +850,17 @@ ssl_SecureRecv(sslSocket *ss, unsigned char *buf, int len, int flags)
rv = ssl_Do1stHandshake(ss);
}
ssl_Release1stHandshakeLock(ss);
} else {
if (tls13_CheckKeyUpdate(ss, CipherSpecRead) != SECSuccess) {
rv = PR_FAILURE;
}
}
if (rv < 0) {
if (PORT_GetError() == PR_WOULD_BLOCK_ERROR &&
!PR_CLIST_IS_EMPTY(&ss->ssl3.hs.bufferedEarlyData)) {
PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_TLS_1_3);
return tls13_Read0RttData(ss, buf, len);
}
return rv;
}
@ -884,11 +942,19 @@ ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
}
ssl_Release1stHandshakeLock(ss);
}
if (rv < 0) {
ss->writerThread = NULL;
goto done;
}
if (ss->firstHsDone) {
if (tls13_CheckKeyUpdate(ss, CipherSpecWrite) != SECSuccess) {
rv = PR_FAILURE;
goto done;
}
}
if (zeroRtt) {
/* There's a limit to the number of early data octets we can send.
*

Просмотреть файл

@ -107,7 +107,6 @@ sslSessionIDLookupFunc ssl_sid_lookup;
sslSessionIDCacheFunc ssl_sid_cache;
sslSessionIDUncacheFunc ssl_sid_uncache;
static PRBool ssl_inited = PR_FALSE;
static PRDescIdentity ssl_layer_id;
PRBool locksEverDisabled; /* implicitly PR_FALSE */
@ -3462,7 +3461,6 @@ ssl_InitIOLayer(void)
{
ssl_layer_id = PR_GetUniqueIdentity("SSL");
ssl_SetupIOMethods();
ssl_inited = PR_TRUE;
return PR_SUCCESS;
}
@ -3472,15 +3470,13 @@ ssl_PushIOLayer(sslSocket *ns, PRFileDesc *stack, PRDescIdentity id)
PRFileDesc *layer = NULL;
PRStatus status;
if (!ssl_inited) {
status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
if (status != PR_SUCCESS)
goto loser;
}
if (ns == NULL)
status = PR_CallOnce(&initIoLayerOnce, &ssl_InitIOLayer);
if (status != PR_SUCCESS) {
goto loser;
}
if (ns == NULL) {
goto loser;
}
layer = PR_CreateIOLayerStub(ssl_layer_id, &combined_methods);
if (layer == NULL)
goto loser;
@ -3934,6 +3930,7 @@ struct {
EXP(GetExtensionSupport),
EXP(HelloRetryRequestCallback),
EXP(InstallExtensionHooks),
EXP(KeyUpdate),
EXP(SendSessionTicket),
EXP(SetupAntiReplay),
#endif

Просмотреть файл

@ -252,7 +252,8 @@ void
ssl_DestroyCipherSpecs(PRCList *list)
{
while (!PR_CLIST_IS_EMPTY(list)) {
ssl_FreeCipherSpec((ssl3CipherSpec *)PR_LIST_TAIL(list));
ssl3CipherSpec *spec = (ssl3CipherSpec *)PR_LIST_TAIL(list);
ssl_FreeCipherSpec(spec);
}
}

Просмотреть файл

@ -24,7 +24,7 @@
#include "tls13exthandle.h"
#include "tls13hashstate.h"
static SECStatus tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
static SECStatus tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch,
CipherSpecDirection install,
PRBool deleteSecret);
static SECStatus tls13_AESGCM(
@ -125,13 +125,9 @@ const char keylogLabelClientHsTrafficSecret[] = "CLIENT_HANDSHAKE_TRAFFIC_SECRET
const char keylogLabelServerHsTrafficSecret[] = "SERVER_HANDSHAKE_TRAFFIC_SECRET";
const char keylogLabelClientTrafficSecret[] = "CLIENT_TRAFFIC_SECRET_0";
const char keylogLabelServerTrafficSecret[] = "SERVER_TRAFFIC_SECRET_0";
const char keylogLabelEarlyExporterSecret[] = "EARLY_EXPORTER_SECRET";
const char keylogLabelExporterSecret[] = "EXPORTER_SECRET";
#define TRAFFIC_SECRET(ss, dir, name) ((ss->sec.isServer ^ \
(dir == CipherSpecWrite)) \
? ss->ssl3.hs.client##name \
: ss->ssl3.hs.server##name)
/* Belt and suspenders in case we ever add a TLS 1.4. */
PR_STATIC_ASSERT(SSL_LIBRARY_VERSION_MAX_SUPPORTED <=
SSL_LIBRARY_VERSION_TLS_1_3);
@ -581,6 +577,239 @@ loser:
return SECFailure;
}
static PRBool
tls13_UseServerSecret(sslSocket *ss, CipherSpecDirection direction)
{
return ss->sec.isServer == (direction == CipherSpecWrite);
}
static PK11SymKey **
tls13_TrafficSecretRef(sslSocket *ss, CipherSpecDirection direction)
{
if (tls13_UseServerSecret(ss, direction)) {
return &ss->ssl3.hs.serverTrafficSecret;
}
return &ss->ssl3.hs.clientTrafficSecret;
}
SECStatus
tls13_UpdateTrafficKeys(sslSocket *ss, CipherSpecDirection direction)
{
PK11SymKey **secret;
PK11SymKey *updatedSecret;
PRUint16 epoch;
SECStatus rv;
secret = tls13_TrafficSecretRef(ss, direction);
rv = tls13_HkdfExpandLabel(*secret, tls13_GetHash(ss),
NULL, 0,
kHkdfLabelApplicationTrafficSecret,
strlen(kHkdfLabelApplicationTrafficSecret),
tls13_GetHmacMechanism(ss),
tls13_GetHashSize(ss),
&updatedSecret);
if (rv != SECSuccess) {
return SECFailure;
}
PK11_FreeSymKey(*secret);
*secret = updatedSecret;
ssl_GetSpecReadLock(ss);
if (direction == CipherSpecRead) {
epoch = ss->ssl3.crSpec->epoch;
} else {
epoch = ss->ssl3.cwSpec->epoch;
}
ssl_ReleaseSpecReadLock(ss);
if (epoch == PR_UINT16_MAX) {
/* Good chance that this is an overflow from too many updates. */
FATAL_ERROR(ss, SSL_ERROR_TOO_MANY_KEY_UPDATES, internal_error);
return SECFailure;
}
++epoch;
rv = tls13_SetCipherSpec(ss, epoch, direction, PR_FALSE);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}
return SECSuccess;
}
SECStatus
tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request, PRBool buffer)
{
SECStatus rv;
SSL_TRC(3, ("%d: TLS13[%d]: %s send key update, response %s",
SSL_GETPID(), ss->fd, SSL_ROLE(ss),
(request == update_requested) ? "requested"
: "not requested"));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
if (!ss->firstHsDone) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
}
rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_LIBRARY_FAILURE,
idle_handshake);
if (rv != SECSuccess) {
return SECFailure;
}
/* Not supported. */
if (IS_DTLS(ss)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
ssl_GetXmitBufLock(ss);
rv = ssl3_AppendHandshakeHeader(ss, ssl_hs_key_update, 1);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
}
rv = ssl3_AppendHandshakeNumber(ss, request, 1);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
goto loser;
}
/* If we have been asked to buffer, then do so. This allows us to coalesce
* a KeyUpdate with a pending write. */
rv = ssl3_FlushHandshake(ss, buffer ? ssl_SEND_FLAG_FORCE_INTO_BUFFER : 0);
if (rv != SECSuccess) {
goto loser; /* error code set by ssl3_FlushHandshake */
}
ssl_ReleaseXmitBufLock(ss);
rv = tls13_UpdateTrafficKeys(ss, CipherSpecWrite);
if (rv != SECSuccess) {
goto loser; /* error code set by tls13_UpdateTrafficKeys */
}
return SECSuccess;
loser:
ssl_ReleaseXmitBufLock(ss);
return SECFailure;
}
SECStatus
SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate)
{
SECStatus rv;
sslSocket *ss = ssl_FindSocket(fd);
if (!ss) {
return SECFailure;
}
if (!ss->firstHsDone) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
rv = TLS13_CHECK_HS_STATE(ss, SEC_ERROR_INVALID_ARGS,
idle_handshake);
if (rv != SECSuccess) {
return SECFailure;
}
ssl_GetSSL3HandshakeLock(ss);
rv = tls13_SendKeyUpdate(ss, requestUpdate ? update_requested : update_not_requested,
PR_FALSE /* don't buffer */);
/* Remember that we are the ones that initiated this KeyUpdate. */
if (rv == SECSuccess) {
ss->ssl3.peerRequestedKeyUpdate = PR_FALSE;
}
ssl_ReleaseSSL3HandshakeLock(ss);
return rv;
}
/*
* enum {
* update_not_requested(0), update_requested(1), (255)
* } KeyUpdateRequest;
*
* struct {
* KeyUpdateRequest request_update;
* } KeyUpdate;
*/
static SECStatus
tls13_HandleKeyUpdate(sslSocket *ss, PRUint8 *b, unsigned int length)
{
SECStatus rv;
PRUint32 update;
SSL_TRC(3, ("%d: TLS13[%d]: %s handle key update",
SSL_GETPID(), ss->fd, SSL_ROLE(ss)));
PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
PORT_Assert(ss->firstHsDone);
if (!ss->firstHsDone) {
FATAL_ERROR(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE, unexpected_message);
return SECFailure;
}
rv = TLS13_CHECK_HS_STATE(ss, SSL_ERROR_RX_UNEXPECTED_KEY_UPDATE,
idle_handshake);
if (rv != SECSuccess) {
/* We should never be idle_handshake prior to firstHsDone. */
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
}
rv = ssl3_ConsumeHandshakeNumber(ss, &update, 1, &b, &length);
if (rv != SECSuccess) {
return SECFailure; /* Error code set already. */
}
if (length != 0) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_UPDATE, decode_error);
return SECFailure;
}
if (!(update == update_requested ||
update == update_not_requested)) {
FATAL_ERROR(ss, SSL_ERROR_RX_MALFORMED_KEY_UPDATE, decode_error);
return SECFailure;
}
rv = tls13_UpdateTrafficKeys(ss, CipherSpecRead);
if (rv != SECSuccess) {
return SECFailure; /* Error code set by tls13_UpdateTrafficKeys. */
}
if (update == update_requested) {
PRBool sendUpdate;
if (ss->ssl3.peerRequestedKeyUpdate) {
/* Only send an update if we have sent with the current spec. This
* prevents us from being forced to crank forward pointlessly. */
ssl_GetSpecReadLock(ss);
sendUpdate = ss->ssl3.cwSpec->seqNum > 0;
ssl_ReleaseSpecReadLock(ss);
} else {
sendUpdate = PR_TRUE;
}
if (sendUpdate) {
/* Respond immediately (don't buffer). */
rv = tls13_SendKeyUpdate(ss, update_not_requested, PR_FALSE);
if (rv != SECSuccess) {
return SECFailure; /* Error already set. */
}
}
ss->ssl3.peerRequestedKeyUpdate = PR_TRUE;
}
return SECSuccess;
}
SECStatus
tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length)
{
@ -618,6 +847,9 @@ tls13_HandlePostHelloHandshakeMessage(sslSocket *ss, PRUint8 *b, PRUint32 length
case ssl_hs_end_of_early_data:
return tls13_HandleEndOfEarlyData(ss, b, length);
case ssl_hs_key_update:
return tls13_HandleKeyUpdate(ss, b, length);
default:
FATAL_ERROR(ss, SSL_ERROR_RX_UNKNOWN_HANDSHAKE, unexpected_message);
return SECFailure;
@ -767,20 +999,38 @@ tls13_ComputeEarlySecrets(sslSocket *ss)
if (rv != SECSuccess) {
return SECFailure;
}
rv = tls13_DeriveSecretNullHash(ss, ss->ssl3.hs.currentSecret,
kHkdfLabelEarlyExporterSecret,
strlen(kHkdfLabelEarlyExporterSecret),
&ss->ssl3.hs.earlyExporterSecret);
if (rv != SECSuccess) {
return SECFailure;
}
}
PORT_Assert(!ss->ssl3.hs.resumptionMasterSecret);
return SECSuccess;
}
/* This derives the early traffic and early exporter secrets. */
static SECStatus
tls13_DeriveEarlySecrets(sslSocket *ss)
{
SECStatus rv;
rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
kHkdfLabelClient,
kHkdfLabelEarlyTrafficSecret,
keylogLabelClientEarlyTrafficSecret,
&ss->ssl3.hs.clientEarlyTrafficSecret);
if (rv != SECSuccess) {
return SECFailure;
}
rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
NULL, kHkdfLabelEarlyExporterSecret,
keylogLabelEarlyExporterSecret,
&ss->ssl3.hs.earlyExporterSecret);
if (rv != SECSuccess) {
return SECFailure;
}
return SECSuccess;
}
static SECStatus
tls13_ComputeHandshakeSecrets(sslSocket *ss)
{
@ -1597,11 +1847,7 @@ tls13_HandleClientHelloPart2(sslSocket *ss,
sid = NULL;
if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
kHkdfLabelClient,
kHkdfLabelEarlyTrafficSecret,
keylogLabelClientEarlyTrafficSecret,
&ss->ssl3.hs.clientEarlyTrafficSecret);
rv = tls13_DeriveEarlySecrets(ss);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
@ -2218,8 +2464,7 @@ tls13_SendServerHelloSequence(sslSocket *ss)
ssl_CipherSpecAddRef(ss->ssl3.crSpec);
}
if (ss->ssl3.hs.zeroRttState == ssl_0rtt_accepted) {
rv = tls13_SetCipherSpec(ss,
TrafficKeyEarlyApplicationData,
rv = tls13_SetCipherSpec(ss, TrafficKeyEarlyApplicationData,
CipherSpecRead, PR_TRUE);
if (rv != SECSuccess) {
LOG_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE);
@ -2823,7 +3068,7 @@ tls13_DeriveSecretNullHash(sslSocket *ss, PK11SymKey *key,
return tls13_DeriveSecret(ss, key, label, labelLen, &hashes, dest);
}
/* Convenience wrapper that lets us supply a separate previx and suffix. */
/* Convenience wrapper that lets us supply a separate prefix and suffix. */
static SECStatus
tls13_DeriveSecretWrap(sslSocket *ss, PK11SymKey *key,
const char *prefix,
@ -2884,33 +3129,30 @@ tls13_DeriveTrafficKeys(sslSocket *ss, ssl3CipherSpec *spec,
CK_MECHANISM_TYPE bulkAlgorithm = ssl3_Alg2Mech(spec->cipherDef->calg);
PK11SymKey **prkp = NULL;
PK11SymKey *prk = NULL;
PRBool clientKey;
PRBool clientSecret;
SECStatus rv;
/* These labels are just used for debugging. */
static const char kHkdfPhaseEarlyApplicationDataKeys[] = "early application data";
static const char kHkdfPhaseHandshakeKeys[] = "handshake data";
static const char kHkdfPhaseApplicationDataKeys[] = "application data";
if (ss->sec.isServer ^ (spec->direction == CipherSpecWrite)) {
clientKey = PR_TRUE;
} else {
clientKey = PR_FALSE;
}
PORT_Assert(ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
clientSecret = !tls13_UseServerSecret(ss, spec->direction);
switch (type) {
case TrafficKeyEarlyApplicationData:
PORT_Assert(clientKey);
PORT_Assert(clientSecret);
prkp = &ss->ssl3.hs.clientEarlyTrafficSecret;
spec->phase = kHkdfPhaseEarlyApplicationDataKeys;
break;
case TrafficKeyHandshake:
prkp = clientKey ? &ss->ssl3.hs.clientHsTrafficSecret : &ss->ssl3.hs.serverHsTrafficSecret;
prkp = clientSecret ? &ss->ssl3.hs.clientHsTrafficSecret
: &ss->ssl3.hs.serverHsTrafficSecret;
spec->phase = kHkdfPhaseHandshakeKeys;
break;
case TrafficKeyApplicationData:
prkp = clientKey ? &ss->ssl3.hs.clientTrafficSecret : &ss->ssl3.hs.serverTrafficSecret;
prkp = clientSecret ? &ss->ssl3.hs.clientTrafficSecret
: &ss->ssl3.hs.serverTrafficSecret;
spec->phase = kHkdfPhaseApplicationDataKeys;
break;
default:
@ -3047,11 +3289,16 @@ tls13_SetAlertCipherSpec(sslSocket *ss)
return SECSuccess;
}
/* Install a new cipher spec for this direction. */
/* Install a new cipher spec for this direction.
*
* During the handshake, the values for |epoch| take values from the
* TrafficKeyType enum. Afterwards, key update increments them.
*/
static SECStatus
tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
tls13_SetCipherSpec(sslSocket *ss, PRUint16 epoch,
CipherSpecDirection direction, PRBool deleteSecret)
{
TrafficKeyType type;
SECStatus rv;
ssl3CipherSpec *spec = NULL;
ssl3CipherSpec **specp;
@ -3069,15 +3316,7 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
if (!spec) {
return SECFailure;
}
specp = (direction == CipherSpecRead) ? &ss->ssl3.crSpec : &ss->ssl3.cwSpec;
/* We use the epoch for cipher suite identification, so increment
* it in both TLS and DTLS. */
if ((*specp)->epoch == PR_UINT16_MAX) {
return SECFailure;
}
spec->epoch = (PRUint16)type;
spec->epoch = epoch;
spec->seqNum = 0;
if (IS_DTLS(ss)) {
dtls_InitRecvdRecords(&spec->recvdRecords);
@ -3086,15 +3325,17 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
/* This depends on spec having a valid direction and epoch. */
rv = tls13_SetupPendingCipherSpec(ss, spec);
if (rv != SECSuccess) {
return SECFailure;
goto loser;
}
type = (TrafficKeyType)PR_MIN(TrafficKeyApplicationData, epoch);
rv = tls13_DeriveTrafficKeys(ss, spec, type, deleteSecret);
if (rv != SECSuccess) {
return SECFailure;
goto loser;
}
/* Now that we've set almost everything up, finally cut over. */
specp = (direction == CipherSpecRead) ? &ss->ssl3.crSpec : &ss->ssl3.cwSpec;
ssl_GetSpecWriteLock(ss);
ssl_CipherSpecRelease(*specp); /* May delete old cipher. */
*specp = spec; /* Overwrite. */
@ -3109,6 +3350,10 @@ tls13_SetCipherSpec(sslSocket *ss, TrafficKeyType type,
direction == CipherSpecWrite, spec);
}
return SECSuccess;
loser:
ssl_CipherSpecRelease(spec);
return SECFailure;
}
SECStatus
@ -3934,7 +4179,7 @@ tls13_ServerHandleFinished(sslSocket *ss, PRUint8 *b, PRUint32 length)
}
rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
CipherSpecRead, PR_TRUE);
CipherSpecRead, PR_FALSE);
if (rv != SECSuccess) {
FATAL_ERROR(ss, SEC_ERROR_LIBRARY_FAILURE, internal_error);
return SECFailure;
@ -4141,7 +4386,7 @@ tls13_SendClientSecondRound(sslSocket *ss)
return SECFailure;
}
rv = tls13_SetCipherSpec(ss, TrafficKeyApplicationData,
CipherSpecWrite, PR_TRUE);
CipherSpecWrite, PR_FALSE);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
return SECFailure;
@ -4842,11 +5087,7 @@ tls13_MaybeDo0RTTHandshake(sslSocket *ss)
/* Cipher suite already set in tls13_SetupClientHello. */
ss->ssl3.hs.preliminaryInfo = 0;
rv = tls13_DeriveSecretWrap(ss, ss->ssl3.hs.currentSecret,
kHkdfLabelClient,
kHkdfLabelEarlyTrafficSecret,
keylogLabelClientEarlyTrafficSecret,
&ss->ssl3.hs.clientEarlyTrafficSecret);
rv = tls13_DeriveEarlySecrets(ss);
if (rv != SECSuccess) {
return SECFailure;
}
@ -4992,11 +5233,11 @@ tls13_EncodeDraftVersion(SSL3ProtocolVersion version)
/* Pick the highest version we support that is also advertised. */
SECStatus
tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supported_versions)
tls13_NegotiateVersion(sslSocket *ss, const TLSExtension *supportedVersions)
{
PRUint16 version;
/* Make a copy so we're nondestructive*/
SECItem data = supported_versions->data;
/* Make a copy so we're nondestructive. */
SECItem data = supportedVersions->data;
SECItem versions;
SECStatus rv;

Просмотреть файл

@ -18,6 +18,11 @@ typedef enum {
tls13_extension_unknown
} tls13ExtensionStatus;
typedef enum {
update_not_requested = 0,
update_requested = 1
} tls13KeyUpdateRequest;
#define TLS13_MAX_FINISHED_SIZE 64
SECStatus tls13_UnprotectRecord(
@ -101,13 +106,16 @@ SECStatus tls13_NegotiateVersion(sslSocket *ss,
PRBool tls13_IsReplay(const sslSocket *ss, const sslSessionID *sid);
void tls13_AntiReplayRollover(PRTime now);
SECStatus SSLExp_SetupAntiReplay(PRTime window, unsigned int k,
unsigned int bits);
SECStatus SSLExp_HelloRetryRequestCallback(PRFileDesc *fd,
SSLHelloRetryRequestCallback cb,
void *arg);
SECStatus SSLExp_UseAltHandshakeType(PRFileDesc *fd, PRBool enable);
SECStatus tls13_SendKeyUpdate(sslSocket *ss, tls13KeyUpdateRequest request,
PRBool buffer);
SECStatus SSLExp_KeyUpdate(PRFileDesc *fd, PRBool requestUpdate);
PRBool tls13_MaybeTls13(sslSocket *ss);
void tls13_SetSpecRecordVersion(sslSocket *ss, ssl3CipherSpec *spec);

Просмотреть файл

@ -1110,12 +1110,8 @@ _NSSUTIL_EvaluateConfigDir(const char *configdir,
NSSDBType dbType;
PRBool checkEnvDefaultDB = PR_FALSE;
*appName = NULL;
/* force the default */
#ifdef NSS_DISABLE_DBM
/* force the default */
dbType = NSS_DB_TYPE_SQL;
#else
dbType = NSS_DB_TYPE_LEGACY;
#endif
if (configdir == NULL) {
checkEnvDefaultDB = PR_TRUE;
} else if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS) - 1) == 0) {

Просмотреть файл

@ -111,6 +111,8 @@ RUN_FIPS=""
########################################################################
run_tests()
{
echo "Running test cycle: ${TEST_MODE} ----------------------"
echo "List of tests that will be executed: ${TESTS}"
for TEST in ${TESTS}
do
# NOTE: the spaces are important. If you don't include
@ -172,8 +174,9 @@ run_cycle_pkix()
NSS_SSL_TESTS=`echo "${NSS_SSL_TESTS}" | sed -e "s/normal//g" -e "s/fips//g" -e "s/_//g"`
export -n NSS_SSL_RUN
# use the default format
# use the default format. (unset for the shell, export -n for binaries)
export -n NSS_DEFAULT_DB_TYPE
unset NSS_DEFAULT_DB_TYPE
run_tests
}

Просмотреть файл

@ -514,11 +514,11 @@ cert_all_CA()
# Create RSA-PSS version of TestCA
ALL_CU_SUBJECT="CN=NSS Test CA (RSA-PSS), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
cert_rsa_pss_CA $CADIR TestCA-rsa-pss -x "CTu,CTu,CTu" ${D_CA} "1" SHA256
rm $CLIENT_CADIR/rsapssroot.cert $SERVER_CADIR/rsapssroot.cert
rm $CADIR/rsapssroot.cert
ALL_CU_SUBJECT="CN=NSS Test CA (RSA-PSS-SHA1), O=BOGUS NSS, L=Mountain View, ST=California, C=US"
cert_rsa_pss_CA $CADIR TestCA-rsa-pss-sha1 -x "CTu,CTu,CTu" ${D_CA} "1" SHA1
rm $CLIENT_CADIR/rsapssroot.cert $SERVER_CADIR/rsapssroot.cert
rm $CADIR/rsapssroot.cert
#
# Create EC version of TestCA

Просмотреть файл

@ -98,7 +98,7 @@ merge_init()
# are dbm databases.
if [ "${TEST_MODE}" = "UPGRADE_DB" ]; then
save=${NSS_DEFAULT_DB_TYPE}
NSS_DEFAULT_DB_TYPE= ; export NSS_DEFAULT_DB_TYPE
NSS_DEFAULT_DB_TYPE=dbm ; export NSS_DEFAULT_DB_TYPE
fi
certutil -N -d ${CONFLICT1DIR} -f ${R_PWFILE}

Просмотреть файл

@ -64,9 +64,9 @@ ssl_init()
PORT=$(($PORT + $padd))
fi
NSS_SSL_TESTS=${NSS_SSL_TESTS:-normal_normal}
nss_ssl_run="stapling signed_cert_timestamps cov auth stress"
nss_ssl_run="stapling signed_cert_timestamps cov auth stress dtls"
NSS_SSL_RUN=${NSS_SSL_RUN:-$nss_ssl_run}
# Test case files
SSLCOV=${QADIR}/ssl/sslcov.txt
SSLAUTH=${QADIR}/ssl/sslauth.txt
@ -1097,6 +1097,47 @@ ssl_crl_cache()
html "</TABLE><BR>"
}
############################ ssl_dtls ###################################
# local shell function to test tstclnt acting as client and server for DTLS
#########################################################################
ssl_dtls()
{
#verbose="-v"
html_head "SSL DTLS $NORM_EXT - server $SERVER_MODE/client $CLIENT_MODE"
testname="ssl_dtls"
value=0
if [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] ; then
echo "$SCRIPTNAME: skipping $testname (non-FIPS only)"
return 0
fi
echo "${testname}"
echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_SERVERDIR} $verbose ${SERVER_OPTIONS} \\"
echo " -U -V tls1.1:tls1.2 -P server -Q < ${REQUEST_FILE} &"
${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${SERVER_OPTIONS} \
-d ${P_R_SERVERDIR} $verbose -U -V tls1.1:tls1.2 -P server -n ${HOSTADDR} -w nss < ${REQUEST_FILE} 2>&1 &
PID=$!
sleep 1
echo "tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f -d ${P_R_CLIENTDIR} $verbose ${CLIENT_OPTIONS} \\"
echo " -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE}"
${PROFTOOL} ${BINDIR}/tstclnt -4 -p ${PORT} -h ${HOSTADDR} -f ${CLIENT_OPTIONS} \
-d ${P_R_CLIENTDIR} $verbose -U -V tls1.1:tls1.2 -P client -Q < ${REQUEST_FILE} 2>&1
ret=$?
html_msg $ret $value "${testname}" \
"produced a returncode of $ret, expected is $value"
kill ${PID}
html "</TABLE><BR>"
}
############################## ssl_cleanup #############################
# local shell function to finish this script (no exit since it might be
@ -1134,6 +1175,9 @@ ssl_run()
"stress")
ssl_stress
;;
"dtls")
ssl_dtls
;;
esac
done
}