diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac5d0956f559a3255fc996b42c2f3953d9bb0f8b..a7e55cb884254e458395dd3c16cb0c16c7ac2d6f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -107,6 +107,25 @@ jobs: - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} + self-hosted: + strategy: + matrix: + os: [freebsd-13.2, ubuntu-arm64-22.04] + runs-on: ${{ matrix.os }}-self-hosted + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - name: config + run: ./config enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-ssl3 enable-ssl3-method enable-trace + - name: config dump + run: ./configdata.pm --dump + - name: make + run: make -j4 + - name: get cpu info + run: ./util/opensslwrap.sh version -c + - name: make test + run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} + minimal: runs-on: ubuntu-latest steps: @@ -264,7 +283,7 @@ jobs: - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - full_feat_w_abidiff: + full_featured: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -279,25 +298,13 @@ jobs: - name: install extra config support run: sudo apt-get -y install libsctp-dev abigail-tools libzstd-dev zstd - name: config - run: ./config --banner=Configured -g --strict-warnings enable-ktls enable-fips enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-ssl3 enable-ssl3-method enable-trace enable-zlib enable-zstd && perl configdata.pm --dump + run: ./config --banner=Configured --strict-warnings enable-ktls enable-fips enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-ssl3 enable-ssl3-method enable-trace enable-zlib enable-zstd && perl configdata.pm --dump - name: make run: make -s -j4 - name: get cpu info run: | cat /proc/cpuinfo ./util/opensslwrap.sh version -c - - name: Check ABI compatibility for libcrypto - run: | - if ! abidiff ./.github/workflows/libcrypto-abi.xml ./libcrypto.so ; then - abidw --out-file libcrypto-abi-new.xml ./libcrypto.so - diff -u ./.github/workflows/libcrypto-abi.xml libcrypto-abi-new.xml - fi - - name: Check ABI compatibility for libssl - run: | - if ! abidiff ./.github/workflows/libssl-abi.xml ./libssl.so ; then - abidw --out-file libssl-abi-new.xml ./libssl.so - diff -u ./.github/workflows/libssl-abi.xml libssl-abi-new.xml - fi - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} diff --git a/.github/workflows/fips-checksums.yml b/.github/workflows/fips-checksums.yml index 1b56755bfbb176882b0fe31839240f06bffe5d11..9b0bec2a78f1335eb0b743737c6f0afb5fcb2c5a 100644 --- a/.github/workflows/fips-checksums.yml +++ b/.github/workflows/fips-checksums.yml @@ -5,7 +5,7 @@ # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html -name: FIPS Checksums +name: FIPS Check and ABIDIFF on: [pull_request] permissions: @@ -73,3 +73,47 @@ jobs: with: name: fips_checksum path: artifact/ + + compute-abidiff: + runs-on: ubuntu-latest + env: + BUILD_OPTS: -g --strict-warnings enable-ktls enable-fips enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-ssl3 enable-ssl3-method enable-trace enable-zlib enable-zstd + steps: + - name: create build dirs + run: | + mkdir ./build-pristine + mkdir ./source-pristine + mkdir ./build + mkdir ./source + mkdir ./artifact + - name: install extra config support + run: sudo apt-get -y install libsctp-dev abigail-tools libzstd-dev zstd + - uses: actions/checkout@v4 + with: + repository: ${{ github.event.pull_request.base.repo.full_name }} + ref: ${{ github.event.pull_request.base.ref }} + path: source-pristine + - name: config pristine + run: ../source-pristine/config --banner=Configured $BUILD_OPTS && perl configdata.pm --dump + working-directory: ./build-pristine + - name: make pristine + run: make -s -j4 + working-directory: ./build-pristine + - uses: actions/checkout@v4 + with: + path: source + - name: config + run: ../source/config --banner=Configured $BUILD_OPTS && perl configdata.pm --dump + working-directory: ./build + - name: make + run: make -s -j4 + working-directory: ./build + - name: abidiff + run: abidiff --headers-dir1 build-pristine/include/openssl --headers-dir2 build/include/openssl --drop-private-types ./build-pristine/libcrypto.so ./build/libcrypto.so && abidiff --headers-dir1 build-pristine/include/openssl --headers-dir2 build/include/openssl --drop-private-types ./build-pristine/libssl.so ./build/libssl.so && touch ./artifact/abi_unchanged || ( touch ./artifact/abi_changed ; echo ABI CHANGED ) + - name: save PR number + run: echo ${{ github.event.number }} > ./artifact/pr_num + - name: save artifact + uses: actions/upload-artifact@v3 + with: + name: abidiff + path: artifact/ diff --git a/.github/workflows/fips-label.yml b/.github/workflows/fips-label.yml index eed1d27cd79073794828addeb1622be172e27364..853dfb20d8a9a017e7430478adfab0b263c3bbac 100644 --- a/.github/workflows/fips-label.yml +++ b/.github/workflows/fips-label.yml @@ -5,10 +5,10 @@ # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html -name: FIPS Changed Label +name: FIPS and ABI Changed Label on: workflow_run: - workflows: ["FIPS Checksums"] + workflows: ["FIPS Check and ABIDIFF"] types: - completed @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.event == 'pull_request' }} steps: - - name: 'Download artifact' + - name: 'Download fipscheck artifact' if: ${{ github.event.workflow_run.conclusion == 'success' }} uses: actions/github-script@v7 with: @@ -79,3 +79,62 @@ jobs: } } } + - name: 'Cleanup artifact' + run: rm artifact.zip pr_num + + - name: 'Download abidiff artifact' + if: ${{ github.event.workflow_run.conclusion == 'success' }} + uses: actions/github-script@v7 + with: + script: | + var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{github.event.workflow_run.id }}, + }); + var matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "abidiff" + })[0]; + var download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/artifact.zip', Buffer.from(download.data)); + - run: unzip artifact.zip + if: ${{ github.event.workflow_run.conclusion == 'success' }} + - name: 'Check artifact and apply' + if: ${{ github.event.workflow_run.conclusion == 'success' }} + uses: actions/github-script@v7 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + var fs = require('fs'); + var pr_num = Number(fs.readFileSync('./pr_num')); + if ( fs.existsSync('./abi_changed') ) { + github.rest.issues.addLabels({ + issue_number: pr_num, + owner: context.repo.owner, + repo: context.repo.repo, + labels: ['severity: ABI change'] + }); + } else if ( fs.existsSync('./abi_unchanged') ) { + var labels = await github.rest.issues.listLabelsOnIssue({ + issue_number: pr_num, + owner: context.repo.owner, + repo: context.repo.repo + }); + + for ( var label in labels.data ) { + if (labels.data[label].name == 'severity: ABI change') { + github.rest.issues.removeLabel({ + issue_number: pr_num, + owner: context.repo.owner, + repo: context.repo.repo, + name: 'severity: fips change' + }); + } + } + } diff --git a/.github/workflows/libcrypto-abi.xml b/.github/workflows/libcrypto-abi.xml deleted file mode 100644 index e3fa029d01703686e13c6a7bb54856e5b889ff0f..0000000000000000000000000000000000000000 --- a/.github/workflows/libcrypto-abi.xml +++ /dev/null @@ -1,62593 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.github/workflows/libssl-abi.xml b/.github/workflows/libssl-abi.xml deleted file mode 100644 index ea8a797e21e6318d7e3364d81b0ccfaa1e5954aa..0000000000000000000000000000000000000000 --- a/.github/workflows/libssl-abi.xml +++ /dev/null @@ -1,20345 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.github/workflows/os-zoo.yml b/.github/workflows/os-zoo.yml index 41acadafe4f5aeb325c3e699782b4a1328fb1d7f..4a64a53ece9401346bfb32f7b7c797937def6291 100644 --- a/.github/workflows/os-zoo.yml +++ b/.github/workflows/os-zoo.yml @@ -166,3 +166,22 @@ jobs: - name: test working-directory: _build run: nmake test VERBOSE_FAILURE=yes HARNESS_JOBS=4 + + self-hosted: + strategy: + matrix: + os: [freebsd-13.2, ubuntu-arm64-22.04] + runs-on: ${{ matrix.os }}-self-hosted + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - name: config + run: ./config enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-ssl3 enable-ssl3-method enable-trace + - name: config dump + run: ./configdata.pm --dump + - name: make + run: make -j4 + - name: get cpu info + run: ./util/opensslwrap.sh version -c + - name: make test + run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0117fce16fede75835bb829e51254c8412f72261..11c31e0d696bd781655356e19aaf13892071a37a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -93,13 +93,5 @@ guidelines: with a specific release without having to sift through the higher noise ratio in git-log. - 8. For larger or more important user visible changes, as well as - security fixes, please add a line in [NEWS.md](NEWS.md). - On exception, it might be worth adding a multi-line entry (such as - the entry that announces all the types that became opaque with - OpenSSL 1.1.0). - This file helps users get a very quick summary of what comes with a - specific release, to see if an upgrade is worth the effort. - - 9. Guidelines how to integrate error output of new crypto library modules + 8. Guidelines how to integrate error output of new crypto library modules can be found in [crypto/err/README.md](crypto/err/README.md). diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 536a316a1314f2f5c7f4dbf462bcbc692f3acae8..d67da63ceac4e36236385ffb9addc898afc87f92 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -1387,18 +1387,16 @@ renumber: build_generated --renumber \ $(SSLHEADERS) -$(SRCDIR)/util/libcrypto.num: $(CRYPTOHEADERS) $(SRCDIR)/include/openssl/symhacks.h +.PHONY: ordinals +ordinals: build_generated $(PERL) $(SRCDIR)/util/mknum.pl --version $(VERSION_NUMBER) --no-warnings \ --ordinals $(SRCDIR)/util/libcrypto.num \ --symhacks $(SRCDIR)/include/openssl/symhacks.h \ $(CRYPTOHEADERS) -$(SRCDIR)/util/libssl.num: $(SSLHEADERS) $(SRCDIR)/include/openssl/symhacks.h $(PERL) $(SRCDIR)/util/mknum.pl --version $(VERSION_NUMBER) --no-warnings \ --ordinals $(SRCDIR)/util/libssl.num \ --symhacks $(SRCDIR)/include/openssl/symhacks.h \ $(SSLHEADERS) -.PHONY: ordinals -ordinals: build_generated $(SRCDIR)/util/libcrypto.num $(SRCDIR)/util/libssl.num test_ordinals: $(MAKE) run_tests TESTS=test_ordinals diff --git a/apps/cms.c b/apps/cms.c index 9c4e4ee5e0553aa81ac3436d1bf6316f09f99fd2..a16318f37c106fa8f280b3a458f5a02064161799 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -1447,6 +1447,7 @@ static CMS_ReceiptRequest STACK_OF(OPENSSL_STRING) *rr_from) { STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL; + CMS_ReceiptRequest *rr; rct_to = make_names_stack(rr_to); if (rct_to == NULL) @@ -1458,10 +1459,14 @@ static CMS_ReceiptRequest } else { rct_from = NULL; } - return CMS_ReceiptRequest_create0_ex(NULL, -1, rr_allorfirst, rct_from, - rct_to, app_get0_libctx()); + rr = CMS_ReceiptRequest_create0_ex(NULL, -1, rr_allorfirst, rct_from, + rct_to, app_get0_libctx()); + if (rr == NULL) + goto err; + return rr; err: sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free); + sk_GENERAL_NAMES_pop_free(rct_from, GENERAL_NAMES_free); return NULL; } diff --git a/apps/list.c b/apps/list.c index 8649598df7fcb327a44698b1319c102b125861fc..adcf6803b4950a394a2cede5eeeba39e76707571 100644 --- a/apps/list.c +++ b/apps/list.c @@ -1238,6 +1238,9 @@ static void list_provider_info(void) sk_OSSL_PROVIDER_sort(providers); for (i = 0; i < sk_OSSL_PROVIDER_num(providers); i++) { const OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(providers, i); + const char *provname = OSSL_PROVIDER_get0_name(prov); + + BIO_printf(bio_out, " %s\n", provname); /* Query the "known" information parameters, the order matches below */ params[0] = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_NAME, @@ -1250,23 +1253,23 @@ static void list_provider_info(void) params[4] = OSSL_PARAM_construct_end(); OSSL_PARAM_set_all_unmodified(params); if (!OSSL_PROVIDER_get_params(prov, params)) { - BIO_printf(bio_err, "ERROR: Unable to query provider parameters\n"); - return; - } - - /* Print out the provider information, the params order matches above */ - BIO_printf(bio_out, " %s\n", OSSL_PROVIDER_get0_name(prov)); - if (OSSL_PARAM_modified(params)) - BIO_printf(bio_out, " name: %s\n", name); - if (OSSL_PARAM_modified(params + 1)) - BIO_printf(bio_out, " version: %s\n", version); - if (OSSL_PARAM_modified(params + 2)) - BIO_printf(bio_out, " status: %sactive\n", status ? "" : "in"); - if (verbose) { - if (OSSL_PARAM_modified(params + 3)) - BIO_printf(bio_out, " build info: %s\n", buildinfo); - print_param_types("gettable provider parameters", - OSSL_PROVIDER_gettable_params(prov), 4); + BIO_printf(bio_err, + "WARNING: Unable to query provider parameters for %s\n", + provname); + } else { + /* Print out the provider information, the params order matches above */ + if (OSSL_PARAM_modified(params)) + BIO_printf(bio_out, " name: %s\n", name); + if (OSSL_PARAM_modified(params + 1)) + BIO_printf(bio_out, " version: %s\n", version); + if (OSSL_PARAM_modified(params + 2)) + BIO_printf(bio_out, " status: %sactive\n", status ? "" : "in"); + if (verbose) { + if (OSSL_PARAM_modified(params + 3)) + BIO_printf(bio_out, " build info: %s\n", buildinfo); + print_param_types("gettable provider parameters", + OSSL_PROVIDER_gettable_params(prov), 4); + } } } sk_OSSL_PROVIDER_free(providers); diff --git a/apps/rehash.c b/apps/rehash.c index 1e5cf38a7fe47bc6bf020e6da24afa6b38e3e8b5..4fea16fa38b21ca3c56a040308dc7466579c0bbd 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -45,9 +45,6 @@ # ifndef PATH_MAX # define PATH_MAX 4096 # endif -# ifndef NAME_MAX -# define NAME_MAX 255 -# endif # define MAX_COLLISIONS 256 # if defined(OPENSSL_SYS_VXWORKS) @@ -356,10 +353,10 @@ static int do_dir(const char *dirname, enum Hash h) struct stat st; unsigned char idmask[MAX_COLLISIONS / 8]; int n, numfiles, nextid, dirlen, buflen, errs = 0; - size_t i; + size_t i, fname_max_len = 20; /* maximum length of "%08x.r%d" */ const char *pathsep = ""; const char *filename; - char *buf, *copy = NULL; + char *buf = NULL, *copy = NULL; STACK_OF(OPENSSL_STRING) *files = NULL; if (app_access(dirname, W_OK) < 0) { @@ -371,8 +368,6 @@ static int do_dir(const char *dirname, enum Hash h) pathsep = "/"; dirlen++; } - buflen = dirlen + NAME_MAX + 1; - buf = app_malloc(buflen, "filename buffer"); if (verbose) BIO_printf(bio_out, "Doing %s\n", dirname); @@ -383,6 +378,8 @@ static int do_dir(const char *dirname, enum Hash h) goto err; } while ((filename = OPENSSL_DIR_read(&d, dirname)) != NULL) { + size_t fname_len = strlen(filename); + if ((copy = OPENSSL_strdup(filename)) == NULL || sk_OPENSSL_STRING_push(files, copy) == 0) { OPENSSL_free(copy); @@ -390,10 +387,15 @@ static int do_dir(const char *dirname, enum Hash h) errs = 1; goto err; } + if (fname_len > fname_max_len) + fname_max_len = fname_len; } OPENSSL_DIR_end(&d); sk_OPENSSL_STRING_sort(files); + buflen = dirlen + fname_max_len + 1; + buf = app_malloc(buflen, "filename buffer"); + numfiles = sk_OPENSSL_STRING_num(files); for (n = 0; n < numfiles; ++n) { filename = sk_OPENSSL_STRING_value(files, n); diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl index dd2c7038e47126eff47a1d99a110b01f7498c275..699ecfcd219d83d0fbf30acbd7da1ac7e8b059d7 100755 --- a/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/aes/asm/aesv8-armx.pl @@ -1751,6 +1751,747 @@ $code.=<<___; .size ${prefix}_cbc_encrypt,.-${prefix}_cbc_encrypt ___ }}} + +{{{ +my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); +my ($rounds,$roundsx,$cnt,$key_)=("w5","x5","w6","x7"); +my ($ctr,$tctr0,$tctr1,$tctr2)=map("w$_",(8..10,12)); +my ($tctr3,$tctr4,$tctr5,$tctr6)=map("w$_",(11,13..15)); +my ($tctr7,$tctr8,$tctr9,$tctr10,$tctr11)=map("w$_",(19..23)); + +# q0-q7 => v0-v7; q8-q23 => v16-v31; q24-q31 => v8-v15 +my ($ivec,$rndlast,$rndping,$rndpang)=map("q$_",(0..3)); +my ($in0,$in1,$in2,$in3,$in4,$in5)=map("q$_",(4..9)); +my ($in6,$in7,$in8,$in9,$in10,$in11)=map("q$_",(10..15)); +my ($dat0,$dat1,$dat2,$dat3,$dat4,$dat5)=map("q$_",(16..21)); +my ($dat6,$dat7,$dat8,$dat9,$dat10,$dat11)=map("q$_",(22..27)); +my ($tmp0,$tmp1,$tmp2)=map("q$_",(25..27)); + +#q_X => qX, for ldp & stp +my ($in0q,$in1q,$in2q,$in3q)=map("q_$_",(4..7)); +my ($in4q,$in5q,$in6q,$in7q,$in8q,$in9q,$in10q,$in11q)=map("q_$_",(16..23)); + +my ($dat8d,$dat9d,$dat10d,$dat11d)=map("d$_",(8..11)); + +$code.=<<___ if ($flavour =~ /64/); +.globl ${prefix}_ctr32_encrypt_blocks_unroll12_eor3 +.type ${prefix}_ctr32_encrypt_blocks_unroll12_eor3,%function +.align 5 +${prefix}_ctr32_encrypt_blocks_unroll12_eor3: + AARCH64_VALID_CALL_TARGET + // Armv8.3-A PAuth: even though x30 is pushed to stack it is not popped later. + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ldr $rounds,[$key,#240] + + ldr $ctr, [$ivp, #12] +#ifdef __AARCH64EB__ + vld1.8 {$dat0},[$ivp] +#else + vld1.32 {$dat0},[$ivp] +#endif + vld1.32 {$rndping-$rndpang},[$key] // load key schedule... + sub $rounds,$rounds,#4 + cmp $len,#2 + add $key_,$key,$roundsx,lsl#4 // pointer to last round key + sub $rounds,$rounds,#2 + add $key_, $key_, #64 + vld1.32 {$rndlast},[$key_] + add $key_,$key,#32 + mov $cnt,$rounds +#ifndef __AARCH64EB__ + rev $ctr, $ctr +#endif + + vorr $dat1,$dat0,$dat0 + add $tctr1, $ctr, #1 + vorr $dat2,$dat0,$dat0 + add $ctr, $ctr, #2 + vorr $ivec,$dat0,$dat0 + rev $tctr1, $tctr1 + vmov.32 ${dat1}[3],$tctr1 + b.ls .Lctr32_tail_unroll + cmp $len,#6 + rev $tctr2, $ctr + sub $len,$len,#3 // bias + vmov.32 ${dat2}[3],$tctr2 + b.lo .Loop3x_ctr32_unroll + cmp $len,#9 + vorr $dat3,$dat0,$dat0 + add $tctr3, $ctr, #1 + vorr $dat4,$dat0,$dat0 + add $tctr4, $ctr, #2 + rev $tctr3, $tctr3 + vorr $dat5,$dat0,$dat0 + add $ctr, $ctr, #3 + rev $tctr4, $tctr4 + vmov.32 ${dat3}[3],$tctr3 + rev $tctr5, $ctr + vmov.32 ${dat4}[3],$tctr4 + vmov.32 ${dat5}[3],$tctr5 + sub $len,$len,#3 + b.lo .Loop6x_ctr32_unroll + + // push regs to stack when 12 data chunks are interleaved + stp x19,x20,[sp,#-16]! + stp x21,x22,[sp,#-16]! + stp x23,x24,[sp,#-16]! + stp $dat8d,$dat9d,[sp,#-32]! + stp $dat10d,$dat11d,[sp,#-32]! + + add $tctr6,$ctr,#1 + add $tctr7,$ctr,#2 + add $tctr8,$ctr,#3 + add $tctr9,$ctr,#4 + add $tctr10,$ctr,#5 + add $ctr,$ctr,#6 + vorr $dat6,$dat0,$dat0 + rev $tctr6,$tctr6 + vorr $dat7,$dat0,$dat0 + rev $tctr7,$tctr7 + vorr $dat8,$dat0,$dat0 + rev $tctr8,$tctr8 + vorr $dat9,$dat0,$dat0 + rev $tctr9,$tctr9 + vorr $dat10,$dat0,$dat0 + rev $tctr10,$tctr10 + vorr $dat11,$dat0,$dat0 + rev $tctr11,$ctr + + sub $len,$len,#6 // bias + vmov.32 ${dat6}[3],$tctr6 + vmov.32 ${dat7}[3],$tctr7 + vmov.32 ${dat8}[3],$tctr8 + vmov.32 ${dat9}[3],$tctr9 + vmov.32 ${dat10}[3],$tctr10 + vmov.32 ${dat11}[3],$tctr11 + b .Loop12x_ctr32_unroll + +.align 4 +.Loop12x_ctr32_unroll: + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + aese $dat3,$rndping + aesmc $dat3,$dat3 + aese $dat4,$rndping + aesmc $dat4,$dat4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + aese $dat6,$rndping + aesmc $dat6,$dat6 + aese $dat7,$rndping + aesmc $dat7,$dat7 + aese $dat8,$rndping + aesmc $dat8,$dat8 + aese $dat9,$rndping + aesmc $dat9,$dat9 + aese $dat10,$rndping + aesmc $dat10,$dat10 + aese $dat11,$rndping + aesmc $dat11,$dat11 + vld1.32 {$rndping},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + aese $dat3,$rndpang + aesmc $dat3,$dat3 + aese $dat4,$rndpang + aesmc $dat4,$dat4 + aese $dat5,$rndpang + aesmc $dat5,$dat5 + aese $dat6,$rndpang + aesmc $dat6,$dat6 + aese $dat7,$rndpang + aesmc $dat7,$dat7 + aese $dat8,$rndpang + aesmc $dat8,$dat8 + aese $dat9,$rndpang + aesmc $dat9,$dat9 + aese $dat10,$rndpang + aesmc $dat10,$dat10 + aese $dat11,$rndpang + aesmc $dat11,$dat11 + vld1.32 {$rndpang},[$key_],#16 + b.gt .Loop12x_ctr32_unroll + + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + aese $dat3,$rndping + aesmc $dat3,$dat3 + aese $dat4,$rndping + aesmc $dat4,$dat4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + aese $dat6,$rndping + aesmc $dat6,$dat6 + aese $dat7,$rndping + aesmc $dat7,$dat7 + aese $dat8,$rndping + aesmc $dat8,$dat8 + aese $dat9,$rndping + aesmc $dat9,$dat9 + aese $dat10,$rndping + aesmc $dat10,$dat10 + aese $dat11,$rndping + aesmc $dat11,$dat11 + vld1.32 {$rndping},[$key_],#16 + + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + aese $dat3,$rndpang + aesmc $dat3,$dat3 + aese $dat4,$rndpang + aesmc $dat4,$dat4 + aese $dat5,$rndpang + aesmc $dat5,$dat5 + aese $dat6,$rndpang + aesmc $dat6,$dat6 + aese $dat7,$rndpang + aesmc $dat7,$dat7 + aese $dat8,$rndpang + aesmc $dat8,$dat8 + aese $dat9,$rndpang + aesmc $dat9,$dat9 + aese $dat10,$rndpang + aesmc $dat10,$dat10 + aese $dat11,$rndpang + aesmc $dat11,$dat11 + vld1.32 {$rndpang},[$key_],#16 + + aese $dat0,$rndping + aesmc $dat0,$dat0 + add $tctr0,$ctr,#1 + add $tctr1,$ctr,#2 + aese $dat1,$rndping + aesmc $dat1,$dat1 + add $tctr2,$ctr,#3 + add $tctr3,$ctr,#4 + aese $dat2,$rndping + aesmc $dat2,$dat2 + add $tctr4,$ctr,#5 + add $tctr5,$ctr,#6 + rev $tctr0,$tctr0 + aese $dat3,$rndping + aesmc $dat3,$dat3 + add $tctr6,$ctr,#7 + add $tctr7,$ctr,#8 + rev $tctr1,$tctr1 + rev $tctr2,$tctr2 + aese $dat4,$rndping + aesmc $dat4,$dat4 + add $tctr8,$ctr,#9 + add $tctr9,$ctr,#10 + rev $tctr3,$tctr3 + rev $tctr4,$tctr4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + add $tctr10,$ctr,#11 + add $tctr11,$ctr,#12 + rev $tctr5,$tctr5 + rev $tctr6,$tctr6 + aese $dat6,$rndping + aesmc $dat6,$dat6 + rev $tctr7,$tctr7 + rev $tctr8,$tctr8 + aese $dat7,$rndping + aesmc $dat7,$dat7 + rev $tctr9,$tctr9 + rev $tctr10,$tctr10 + aese $dat8,$rndping + aesmc $dat8,$dat8 + rev $tctr11,$tctr11 + aese $dat9,$rndping + aesmc $dat9,$dat9 + aese $dat10,$rndping + aesmc $dat10,$dat10 + aese $dat11,$rndping + aesmc $dat11,$dat11 + vld1.32 {$rndping},[$key_],#16 + + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + aese $dat3,$rndpang + aesmc $dat3,$dat3 + vld1.8 {$in0,$in1,$in2,$in3},[$inp],#64 + aese $dat4,$rndpang + aesmc $dat4,$dat4 + aese $dat5,$rndpang + aesmc $dat5,$dat5 + aese $dat6,$rndpang + aesmc $dat6,$dat6 + aese $dat7,$rndpang + aesmc $dat7,$dat7 + vld1.8 {$in4,$in5,$in6,$in7},[$inp],#64 + aese $dat8,$rndpang + aesmc $dat8,$dat8 + aese $dat9,$rndpang + aesmc $dat9,$dat9 + aese $dat10,$rndpang + aesmc $dat10,$dat10 + aese $dat11,$rndpang + aesmc $dat11,$dat11 + vld1.8 {$in8,$in9,$in10,$in11},[$inp],#64 + vld1.32 {$rndpang},[$key_],#16 + + mov $key_, $key + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + aese $dat3,$rndping + aesmc $dat3,$dat3 + aese $dat4,$rndping + aesmc $dat4,$dat4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + aese $dat6,$rndping + aesmc $dat6,$dat6 + aese $dat7,$rndping + aesmc $dat7,$dat7 + aese $dat8,$rndping + aesmc $dat8,$dat8 + aese $dat9,$rndping + aesmc $dat9,$dat9 + aese $dat10,$rndping + aesmc $dat10,$dat10 + aese $dat11,$rndping + aesmc $dat11,$dat11 + vld1.32 {$rndping},[$key_],#16 // re-pre-load rndkey[0] + + aese $dat0,$rndpang + eor3 $in0,$in0,$rndlast,$dat0 + vorr $dat0,$ivec,$ivec + aese $dat1,$rndpang + eor3 $in1,$in1,$rndlast,$dat1 + vorr $dat1,$ivec,$ivec + aese $dat2,$rndpang + eor3 $in2,$in2,$rndlast,$dat2 + vorr $dat2,$ivec,$ivec + aese $dat3,$rndpang + eor3 $in3,$in3,$rndlast,$dat3 + vorr $dat3,$ivec,$ivec + aese $dat4,$rndpang + eor3 $in4,$in4,$rndlast,$dat4 + vorr $dat4,$ivec,$ivec + aese $dat5,$rndpang + eor3 $in5,$in5,$rndlast,$dat5 + vorr $dat5,$ivec,$ivec + aese $dat6,$rndpang + eor3 $in6,$in6,$rndlast,$dat6 + vorr $dat6,$ivec,$ivec + aese $dat7,$rndpang + eor3 $in7,$in7,$rndlast,$dat7 + vorr $dat7,$ivec,$ivec + aese $dat8,$rndpang + eor3 $in8,$in8,$rndlast,$dat8 + vorr $dat8,$ivec,$ivec + aese $dat9,$rndpang + eor3 $in9,$in9,$rndlast,$dat9 + vorr $dat9,$ivec,$ivec + aese $dat10,$rndpang + eor3 $in10,$in10,$rndlast,$dat10 + vorr $dat10,$ivec,$ivec + aese $dat11,$rndpang + eor3 $in11,$in11,$rndlast,$dat11 + vorr $dat11,$ivec,$ivec + vld1.32 {$rndpang},[$key_],#16 // re-pre-load rndkey[1] + + vmov.32 ${dat0}[3],$tctr0 + vmov.32 ${dat1}[3],$tctr1 + vmov.32 ${dat2}[3],$tctr2 + vmov.32 ${dat3}[3],$tctr3 + vst1.8 {$in0,$in1,$in2,$in3},[$out],#64 + vmov.32 ${dat4}[3],$tctr4 + vmov.32 ${dat5}[3],$tctr5 + vmov.32 ${dat6}[3],$tctr6 + vmov.32 ${dat7}[3],$tctr7 + vst1.8 {$in4,$in5,$in6,$in7},[$out],#64 + vmov.32 ${dat8}[3],$tctr8 + vmov.32 ${dat9}[3],$tctr9 + vmov.32 ${dat10}[3],$tctr10 + vmov.32 ${dat11}[3],$tctr11 + vst1.8 {$in8,$in9,$in10,$in11},[$out],#64 + + mov $cnt,$rounds + + add $ctr,$ctr,#12 + subs $len,$len,#12 + b.hs .Loop12x_ctr32_unroll + + // pop regs from stack when 12 data chunks are interleaved + ldp $dat10d,$dat11d,[sp],#32 + ldp $dat8d,$dat9d,[sp],#32 + ldp x23,x24,[sp],#16 + ldp x21,x22,[sp],#16 + ldp x19,x20,[sp],#16 + + add $len,$len,#12 + cbz $len,.Lctr32_done_unroll + sub $ctr,$ctr,#12 + + cmp $len,#2 + b.ls .Lctr32_tail_unroll + + cmp $len,#6 + sub $len,$len,#3 // bias + add $ctr,$ctr,#3 + b.lo .Loop3x_ctr32_unroll + + sub $len,$len,#3 + add $ctr,$ctr,#3 + b.lo .Loop6x_ctr32_unroll + +.align 4 +.Loop6x_ctr32_unroll: + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + aese $dat3,$rndping + aesmc $dat3,$dat3 + aese $dat4,$rndping + aesmc $dat4,$dat4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + vld1.32 {$rndping},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + aese $dat3,$rndpang + aesmc $dat3,$dat3 + aese $dat4,$rndpang + aesmc $dat4,$dat4 + aese $dat5,$rndpang + aesmc $dat5,$dat5 + vld1.32 {$rndpang},[$key_],#16 + b.gt .Loop6x_ctr32_unroll + + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + aese $dat3,$rndping + aesmc $dat3,$dat3 + aese $dat4,$rndping + aesmc $dat4,$dat4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + vld1.32 {$rndping},[$key_],#16 + + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + aese $dat3,$rndpang + aesmc $dat3,$dat3 + aese $dat4,$rndpang + aesmc $dat4,$dat4 + aese $dat5,$rndpang + aesmc $dat5,$dat5 + vld1.32 {$rndpang},[$key_],#16 + + aese $dat0,$rndping + aesmc $dat0,$dat0 + add $tctr0,$ctr,#1 + add $tctr1,$ctr,#2 + aese $dat1,$rndping + aesmc $dat1,$dat1 + add $tctr2,$ctr,#3 + add $tctr3,$ctr,#4 + aese $dat2,$rndping + aesmc $dat2,$dat2 + add $tctr4,$ctr,#5 + add $tctr5,$ctr,#6 + rev $tctr0,$tctr0 + aese $dat3,$rndping + aesmc $dat3,$dat3 + rev $tctr1,$tctr1 + rev $tctr2,$tctr2 + aese $dat4,$rndping + aesmc $dat4,$dat4 + rev $tctr3,$tctr3 + rev $tctr4,$tctr4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + rev $tctr5,$tctr5 + vld1.32 {$rndping},[$key_],#16 + + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + vld1.8 {$in0,$in1,$in2,$in3},[$inp],#64 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + aese $dat3,$rndpang + aesmc $dat3,$dat3 + vld1.8 {$in4,$in5},[$inp],#32 + aese $dat4,$rndpang + aesmc $dat4,$dat4 + aese $dat5,$rndpang + aesmc $dat5,$dat5 + vld1.32 {$rndpang},[$key_],#16 + + mov $key_, $key + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + aese $dat3,$rndping + aesmc $dat3,$dat3 + aese $dat4,$rndping + aesmc $dat4,$dat4 + aese $dat5,$rndping + aesmc $dat5,$dat5 + vld1.32 {$rndping},[$key_],#16 // re-pre-load rndkey[0] + + aese $dat0,$rndpang + eor3 $in0,$in0,$rndlast,$dat0 + aese $dat1,$rndpang + eor3 $in1,$in1,$rndlast,$dat1 + aese $dat2,$rndpang + eor3 $in2,$in2,$rndlast,$dat2 + aese $dat3,$rndpang + eor3 $in3,$in3,$rndlast,$dat3 + aese $dat4,$rndpang + eor3 $in4,$in4,$rndlast,$dat4 + aese $dat5,$rndpang + eor3 $in5,$in5,$rndlast,$dat5 + vld1.32 {$rndpang},[$key_],#16 // re-pre-load rndkey[1] + + vorr $dat0,$ivec,$ivec + vorr $dat1,$ivec,$ivec + vorr $dat2,$ivec,$ivec + vorr $dat3,$ivec,$ivec + vorr $dat4,$ivec,$ivec + vorr $dat5,$ivec,$ivec + + vmov.32 ${dat0}[3],$tctr0 + vmov.32 ${dat1}[3],$tctr1 + vst1.8 {$in0,$in1,$in2,$in3},[$out],#64 + vmov.32 ${dat2}[3],$tctr2 + vmov.32 ${dat3}[3],$tctr3 + vst1.8 {$in4,$in5},[$out],#32 + vmov.32 ${dat4}[3],$tctr4 + vmov.32 ${dat5}[3],$tctr5 + + cbz $len,.Lctr32_done_unroll + mov $cnt,$rounds + + cmp $len,#2 + b.ls .Lctr32_tail_unroll + + sub $len,$len,#3 // bias + add $ctr,$ctr,#3 + b .Loop3x_ctr32_unroll + +.align 4 +.Loop3x_ctr32_unroll: + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat2,$rndping + aesmc $dat2,$dat2 + vld1.32 {$rndping},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + aese $dat2,$rndpang + aesmc $dat2,$dat2 + vld1.32 {$rndpang},[$key_],#16 + b.gt .Loop3x_ctr32_unroll + + aese $dat0,$rndping + aesmc $tmp0,$dat0 + aese $dat1,$rndping + aesmc $tmp1,$dat1 + vld1.8 {$in0,$in1,$in2},[$inp],#48 + vorr $dat0,$ivec,$ivec + aese $dat2,$rndping + aesmc $dat2,$dat2 + vld1.32 {$rndping},[$key_],#16 + vorr $dat1,$ivec,$ivec + aese $tmp0,$rndpang + aesmc $tmp0,$tmp0 + aese $tmp1,$rndpang + aesmc $tmp1,$tmp1 + aese $dat2,$rndpang + aesmc $tmp2,$dat2 + vld1.32 {$rndpang},[$key_],#16 + vorr $dat2,$ivec,$ivec + add $tctr0,$ctr,#1 + aese $tmp0,$rndping + aesmc $tmp0,$tmp0 + aese $tmp1,$rndping + aesmc $tmp1,$tmp1 + add $tctr1,$ctr,#2 + aese $tmp2,$rndping + aesmc $tmp2,$tmp2 + vld1.32 {$rndping},[$key_],#16 + add $ctr,$ctr,#3 + aese $tmp0,$rndpang + aesmc $tmp0,$tmp0 + aese $tmp1,$rndpang + aesmc $tmp1,$tmp1 + + rev $tctr0,$tctr0 + aese $tmp2,$rndpang + aesmc $tmp2,$tmp2 + vld1.32 {$rndpang},[$key_],#16 + vmov.32 ${dat0}[3], $tctr0 + mov $key_,$key + rev $tctr1,$tctr1 + aese $tmp0,$rndping + aesmc $tmp0,$tmp0 + + aese $tmp1,$rndping + aesmc $tmp1,$tmp1 + vmov.32 ${dat1}[3], $tctr1 + rev $tctr2,$ctr + aese $tmp2,$rndping + aesmc $tmp2,$tmp2 + vmov.32 ${dat2}[3], $tctr2 + + aese $tmp0,$rndpang + aese $tmp1,$rndpang + aese $tmp2,$rndpang + + eor3 $in0,$in0,$rndlast,$tmp0 + vld1.32 {$rndping},[$key_],#16 // re-pre-load rndkey[0] + eor3 $in1,$in1,$rndlast,$tmp1 + mov $cnt,$rounds + eor3 $in2,$in2,$rndlast,$tmp2 + vld1.32 {$rndpang},[$key_],#16 // re-pre-load rndkey[1] + vst1.8 {$in0,$in1,$in2},[$out],#48 + + cbz $len,.Lctr32_done_unroll + +.Lctr32_tail_unroll: + cmp $len,#1 + b.eq .Lctr32_tail_1_unroll + +.Lctr32_tail_2_unroll: + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + vld1.32 {$rndping},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + vld1.32 {$rndpang},[$key_],#16 + b.gt .Lctr32_tail_2_unroll + + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + vld1.32 {$rndping},[$key_],#16 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + vld1.32 {$rndpang},[$key_],#16 + vld1.8 {$in0,$in1},[$inp],#32 + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + vld1.32 {$rndping},[$key_],#16 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + aese $dat1,$rndpang + aesmc $dat1,$dat1 + vld1.32 {$rndpang},[$key_],#16 + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat1,$rndping + aesmc $dat1,$dat1 + aese $dat0,$rndpang + aese $dat1,$rndpang + + eor3 $in0,$in0,$rndlast,$dat0 + eor3 $in1,$in1,$rndlast,$dat1 + vst1.8 {$in0,$in1},[$out],#32 + b .Lctr32_done_unroll + +.Lctr32_tail_1_unroll: + aese $dat0,$rndping + aesmc $dat0,$dat0 + vld1.32 {$rndping},[$key_],#16 + subs $cnt,$cnt,#2 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + vld1.32 {$rndpang},[$key_],#16 + b.gt .Lctr32_tail_1_unroll + + aese $dat0,$rndping + aesmc $dat0,$dat0 + vld1.32 {$rndping},[$key_],#16 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + vld1.32 {$rndpang},[$key_],#16 + vld1.8 {$in0},[$inp] + aese $dat0,$rndping + aesmc $dat0,$dat0 + vld1.32 {$rndping},[$key_],#16 + aese $dat0,$rndpang + aesmc $dat0,$dat0 + vld1.32 {$rndpang},[$key_],#16 + aese $dat0,$rndping + aesmc $dat0,$dat0 + aese $dat0,$rndpang + + eor3 $in0,$in0,$rndlast,$dat0 + vst1.8 {$in0},[$out],#16 + +.Lctr32_done_unroll: + ldr x29,[sp],#16 + ret +.size ${prefix}_ctr32_encrypt_blocks_unroll12_eor3,.-${prefix}_ctr32_encrypt_blocks_unroll12_eor3 +___ +}}} + {{{ my ($inp,$out,$len,$key,$ivp)=map("x$_",(0..4)); my ($rounds,$cnt,$key_)=("w5","w6","x7"); @@ -3640,7 +4381,8 @@ ___ if ($flavour =~ /64/) { ######## 64-bit code my %opcode = ( "aesd" => 0x4e285800, "aese" => 0x4e284800, - "aesimc"=> 0x4e287800, "aesmc" => 0x4e286800 ); + "aesimc"=> 0x4e287800, "aesmc" => 0x4e286800, + "eor3" => 0xce000000, ); local *unaes = sub { my ($mnemonic,$arg)=@_; @@ -3651,10 +4393,21 @@ if ($flavour =~ /64/) { ######## 64-bit code $mnemonic,$arg; }; + sub unsha3 { + my ($mnemonic,$arg)=@_; + + $arg =~ m/[qv]([0-9]+)[^,]*,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv]([0-9]+)[^,]*(?:,\s*[qv#]([0-9\-]+))?)?/ + && + sprintf ".inst\t0x%08x\t//%s %s", + $opcode{$mnemonic}|$1|($2<<5)|($3<<16)|(eval($4)<<10), + $mnemonic,$arg; + } + foreach(split("\n",$code)) { s/\`([^\`]*)\`/eval($1)/geo; - s/\bq([0-9]+)\b/"v".($1<8?$1:$1+8).".16b"/geo; # old->new registers + s/\bq([0-9]+)\b/"v".($1<8?$1:($1<24?$1+8:$1-16)).".16b"/geo; # old->new registers + s/\bq_([0-9]+)\b/"q".$1/geo; # old->new registers s/@\s/\/\//o; # old->new style commentary #s/[v]?(aes\w+)\s+([qv].*)/unaes($1,$2)/geo or @@ -3667,6 +4420,7 @@ if ($flavour =~ /64/) { ######## 64-bit code s/vshr/ushr/o or s/^(\s+)v/$1/o or # strip off v prefix s/\bbx\s+lr\b/ret/o; + s/\b(eor3)\s+(v.*)/unsha3($1,$2)/ge; # fix up remaining legacy suffixes s/\.[ui]?8//o; diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h index 83acbe012654dfa458fab41dfed972d4bfd5d1a7..b76981f48b81f7dc200dc2983d0ee22485152b62 100644 --- a/crypto/arm_arch.h +++ b/crypto/arm_arch.h @@ -88,6 +88,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; # define ARMV8_SVE (1<<13) # define ARMV8_SVE2 (1<<14) # define ARMV8_HAVE_SHA3_AND_WORTH_USING (1<<15) +# define ARMV8_UNROLL12_EOR3 (1<<16) /* * MIDR_EL1 system register diff --git a/crypto/armcap.c b/crypto/armcap.c index b13da3be81ca9619ecf7ddccf67a95cc7cde01a8..adb8b6a188dcbeb1b9091451f9edc150bb8821e7 100644 --- a/crypto/armcap.c +++ b/crypto/armcap.c @@ -421,6 +421,10 @@ void OPENSSL_cpuid_setup(void) MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) && (OPENSSL_armcap_P & ARMV8_SHA3)) OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3; + if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || + MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)) && + (OPENSSL_armcap_P & ARMV8_SHA3)) + OPENSSL_armcap_P |= ARMV8_UNROLL12_EOR3; if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) || diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c index c1dbed05984fc241bd7829b705bdfa0cb9ee56e2..bc864346fb69d233a8c55da5c643ce2e88f14c31 100644 --- a/crypto/bn/bn_nist.c +++ b/crypto/bn/bn_nist.c @@ -319,6 +319,28 @@ static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top) # endif #endif /* BN_BITS2 != 64 */ +#ifdef NIST_INT64 +/* Helpers to load/store a 32-bit word (uint32_t) from/into a memory + * location and avoid potential aliasing issue. */ +static ossl_inline uint32_t load_u32(const void *ptr) +{ + uint32_t tmp; + + memcpy(&tmp, ptr, sizeof(tmp)); + return tmp; +} + +static ossl_inline void store_lo32(void *ptr, NIST_INT64 val) +{ + /* A cast is needed for big-endian system: on a 32-bit BE system + * NIST_INT64 may be defined as well if the compiler supports 64-bit + * long long. */ + uint32_t tmp = (uint32_t)val; + + memcpy(ptr, &tmp, sizeof(tmp)); +} +#endif /* NIST_INT64 */ + #define nist_set_192(to, from, a1, a2, a3) \ { \ bn_cp_64(to, 0, from, (a3) - 3) \ @@ -374,42 +396,42 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, unsigned int *rp = (unsigned int *)r_d; const unsigned int *bp = (const unsigned int *)buf.ui; - acc = rp[0]; + acc = load_u32(&rp[0]); acc += bp[3 * 2 - 6]; acc += bp[5 * 2 - 6]; - rp[0] = (unsigned int)acc; + store_lo32(&rp[0], acc); acc >>= 32; - acc += rp[1]; + acc += load_u32(&rp[1]); acc += bp[3 * 2 - 5]; acc += bp[5 * 2 - 5]; - rp[1] = (unsigned int)acc; + store_lo32(&rp[1], acc); acc >>= 32; - acc += rp[2]; + acc += load_u32(&rp[2]); acc += bp[3 * 2 - 6]; acc += bp[4 * 2 - 6]; acc += bp[5 * 2 - 6]; - rp[2] = (unsigned int)acc; + store_lo32(&rp[2], acc); acc >>= 32; - acc += rp[3]; + acc += load_u32(&rp[3]); acc += bp[3 * 2 - 5]; acc += bp[4 * 2 - 5]; acc += bp[5 * 2 - 5]; - rp[3] = (unsigned int)acc; + store_lo32(&rp[3], acc); acc >>= 32; - acc += rp[4]; + acc += load_u32(&rp[4]); acc += bp[4 * 2 - 6]; acc += bp[5 * 2 - 6]; - rp[4] = (unsigned int)acc; + store_lo32(&rp[4], acc); acc >>= 32; - acc += rp[5]; + acc += load_u32(&rp[5]); acc += bp[4 * 2 - 5]; acc += bp[5 * 2 - 5]; - rp[5] = (unsigned int)acc; + store_lo32(&rp[5], acc); carry = (int)(acc >> 32); } @@ -683,36 +705,36 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, unsigned int *rp = (unsigned int *)r_d; const unsigned int *bp = (const unsigned int *)buf.ui; - acc = rp[0]; + acc = load_u32(&rp[0]); acc += bp[8 - 8]; acc += bp[9 - 8]; acc -= bp[11 - 8]; acc -= bp[12 - 8]; acc -= bp[13 - 8]; acc -= bp[14 - 8]; - rp[0] = (unsigned int)acc; + store_lo32(&rp[0], acc); acc >>= 32; - acc += rp[1]; + acc += load_u32(&rp[1]); acc += bp[9 - 8]; acc += bp[10 - 8]; acc -= bp[12 - 8]; acc -= bp[13 - 8]; acc -= bp[14 - 8]; acc -= bp[15 - 8]; - rp[1] = (unsigned int)acc; + store_lo32(&rp[1], acc); acc >>= 32; - acc += rp[2]; + acc += load_u32(&rp[2]); acc += bp[10 - 8]; acc += bp[11 - 8]; acc -= bp[13 - 8]; acc -= bp[14 - 8]; acc -= bp[15 - 8]; - rp[2] = (unsigned int)acc; + store_lo32(&rp[2], acc); acc >>= 32; - acc += rp[3]; + acc += load_u32(&rp[3]); acc += bp[11 - 8]; acc += bp[11 - 8]; acc += bp[12 - 8]; @@ -721,10 +743,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc -= bp[15 - 8]; acc -= bp[8 - 8]; acc -= bp[9 - 8]; - rp[3] = (unsigned int)acc; + store_lo32(&rp[3], acc); acc >>= 32; - acc += rp[4]; + acc += load_u32(&rp[4]); acc += bp[12 - 8]; acc += bp[12 - 8]; acc += bp[13 - 8]; @@ -732,10 +754,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc += bp[14 - 8]; acc -= bp[9 - 8]; acc -= bp[10 - 8]; - rp[4] = (unsigned int)acc; + store_lo32(&rp[4], acc); acc >>= 32; - acc += rp[5]; + acc += load_u32(&rp[5]); acc += bp[13 - 8]; acc += bp[13 - 8]; acc += bp[14 - 8]; @@ -743,10 +765,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc += bp[15 - 8]; acc -= bp[10 - 8]; acc -= bp[11 - 8]; - rp[5] = (unsigned int)acc; + store_lo32(&rp[5], acc); acc >>= 32; - acc += rp[6]; + acc += load_u32(&rp[6]); acc += bp[14 - 8]; acc += bp[14 - 8]; acc += bp[15 - 8]; @@ -755,10 +777,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc += bp[13 - 8]; acc -= bp[8 - 8]; acc -= bp[9 - 8]; - rp[6] = (unsigned int)acc; + store_lo32(&rp[6], acc); acc >>= 32; - acc += rp[7]; + acc += load_u32(&rp[7]); acc += bp[15 - 8]; acc += bp[15 - 8]; acc += bp[15 - 8]; @@ -767,7 +789,7 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc -= bp[11 - 8]; acc -= bp[12 - 8]; acc -= bp[13 - 8]; - rp[7] = (unsigned int)acc; + store_lo32(&rp[7], acc); carry = (int)(acc >> 32); } @@ -920,32 +942,32 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, unsigned int *rp = (unsigned int *)r_d; const unsigned int *bp = (const unsigned int *)buf.ui; - acc = rp[0]; + acc = load_u32(&rp[0]); acc += bp[12 - 12]; acc += bp[21 - 12]; acc += bp[20 - 12]; acc -= bp[23 - 12]; - rp[0] = (unsigned int)acc; + store_lo32(&rp[0], acc); acc >>= 32; - acc += rp[1]; + acc += load_u32(&rp[1]); acc += bp[13 - 12]; acc += bp[22 - 12]; acc += bp[23 - 12]; acc -= bp[12 - 12]; acc -= bp[20 - 12]; - rp[1] = (unsigned int)acc; + store_lo32(&rp[1], acc); acc >>= 32; - acc += rp[2]; + acc += load_u32(&rp[2]); acc += bp[14 - 12]; acc += bp[23 - 12]; acc -= bp[13 - 12]; acc -= bp[21 - 12]; - rp[2] = (unsigned int)acc; + store_lo32(&rp[2], acc); acc >>= 32; - acc += rp[3]; + acc += load_u32(&rp[3]); acc += bp[15 - 12]; acc += bp[12 - 12]; acc += bp[20 - 12]; @@ -953,10 +975,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc -= bp[14 - 12]; acc -= bp[22 - 12]; acc -= bp[23 - 12]; - rp[3] = (unsigned int)acc; + store_lo32(&rp[3], acc); acc >>= 32; - acc += rp[4]; + acc += load_u32(&rp[4]); acc += bp[21 - 12]; acc += bp[21 - 12]; acc += bp[16 - 12]; @@ -967,10 +989,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc -= bp[15 - 12]; acc -= bp[23 - 12]; acc -= bp[23 - 12]; - rp[4] = (unsigned int)acc; + store_lo32(&rp[4], acc); acc >>= 32; - acc += rp[5]; + acc += load_u32(&rp[5]); acc += bp[22 - 12]; acc += bp[22 - 12]; acc += bp[17 - 12]; @@ -979,10 +1001,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc += bp[21 - 12]; acc += bp[23 - 12]; acc -= bp[16 - 12]; - rp[5] = (unsigned int)acc; + store_lo32(&rp[5], acc); acc >>= 32; - acc += rp[6]; + acc += load_u32(&rp[6]); acc += bp[23 - 12]; acc += bp[23 - 12]; acc += bp[18 - 12]; @@ -990,48 +1012,48 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, acc += bp[14 - 12]; acc += bp[22 - 12]; acc -= bp[17 - 12]; - rp[6] = (unsigned int)acc; + store_lo32(&rp[6], acc); acc >>= 32; - acc += rp[7]; + acc += load_u32(&rp[7]); acc += bp[19 - 12]; acc += bp[16 - 12]; acc += bp[15 - 12]; acc += bp[23 - 12]; acc -= bp[18 - 12]; - rp[7] = (unsigned int)acc; + store_lo32(&rp[7], acc); acc >>= 32; - acc += rp[8]; + acc += load_u32(&rp[8]); acc += bp[20 - 12]; acc += bp[17 - 12]; acc += bp[16 - 12]; acc -= bp[19 - 12]; - rp[8] = (unsigned int)acc; + store_lo32(&rp[8], acc); acc >>= 32; - acc += rp[9]; + acc += load_u32(&rp[9]); acc += bp[21 - 12]; acc += bp[18 - 12]; acc += bp[17 - 12]; acc -= bp[20 - 12]; - rp[9] = (unsigned int)acc; + store_lo32(&rp[9], acc); acc >>= 32; - acc += rp[10]; + acc += load_u32(&rp[10]); acc += bp[22 - 12]; acc += bp[19 - 12]; acc += bp[18 - 12]; acc -= bp[21 - 12]; - rp[10] = (unsigned int)acc; + store_lo32(&rp[10], acc); acc >>= 32; - acc += rp[11]; + acc += load_u32(&rp[11]); acc += bp[23 - 12]; acc += bp[20 - 12]; acc += bp[19 - 12]; acc -= bp[22 - 12]; - rp[11] = (unsigned int)acc; + store_lo32(&rp[11], acc); carry = (int)(acc >> 32); } diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c index 24f61fbf1593a5505f80520d7e26e73a0cd2918c..eb1be1c98054314e708cae82aa1b144b5e80dffe 100644 --- a/crypto/encode_decode/decoder_pkey.c +++ b/crypto/encode_decode/decoder_pkey.c @@ -721,10 +721,9 @@ int ossl_decoder_cache_flush(OSSL_LIB_CTX *libctx) DECODER_CACHE *cache = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX); - if (cache == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); + if (cache == NULL) return 0; - } + if (!CRYPTO_THREAD_write_lock(cache->lock)) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index 557c697c9aaf688b82bec3ae78bb2f3f71e8ac5f..269c7dcb6d41790cae83de792c446800ea65d5c6 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -260,11 +260,17 @@ int CRYPTO_secure_allocated(const void *ptr) size_t CRYPTO_secure_used(void) { + size_t ret = 0; + #ifndef OPENSSL_NO_SECURE_MEMORY - return secure_mem_used; -#else - return 0; + if (!CRYPTO_THREAD_read_lock(sec_malloc_lock)) + return 0; + + ret = secure_mem_used; + + CRYPTO_THREAD_unlock(sec_malloc_lock); #endif /* OPENSSL_NO_SECURE_MEMORY */ + return ret; } size_t CRYPTO_secure_actual_size(void *ptr) diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 838bcd161c810ee809730cddfda0bbd2cdea20d8..57dacd76f7869f523e3e87766e9aacbc432fae2f 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -970,44 +970,46 @@ static int provider_init(OSSL_PROVIDER *prov) prov->provctx = tmp_provctx; prov->dispatch = provider_dispatch; - for (; provider_dispatch->function_id != 0; provider_dispatch++) { - switch (provider_dispatch->function_id) { - case OSSL_FUNC_PROVIDER_TEARDOWN: - prov->teardown = - OSSL_FUNC_provider_teardown(provider_dispatch); - break; - case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS: - prov->gettable_params = - OSSL_FUNC_provider_gettable_params(provider_dispatch); - break; - case OSSL_FUNC_PROVIDER_GET_PARAMS: - prov->get_params = - OSSL_FUNC_provider_get_params(provider_dispatch); - break; - case OSSL_FUNC_PROVIDER_SELF_TEST: - prov->self_test = - OSSL_FUNC_provider_self_test(provider_dispatch); - break; - case OSSL_FUNC_PROVIDER_GET_CAPABILITIES: - prov->get_capabilities = - OSSL_FUNC_provider_get_capabilities(provider_dispatch); - break; - case OSSL_FUNC_PROVIDER_QUERY_OPERATION: - prov->query_operation = - OSSL_FUNC_provider_query_operation(provider_dispatch); - break; - case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION: - prov->unquery_operation = - OSSL_FUNC_provider_unquery_operation(provider_dispatch); - break; + if (provider_dispatch != NULL) { + for (; provider_dispatch->function_id != 0; provider_dispatch++) { + switch (provider_dispatch->function_id) { + case OSSL_FUNC_PROVIDER_TEARDOWN: + prov->teardown = + OSSL_FUNC_provider_teardown(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_GETTABLE_PARAMS: + prov->gettable_params = + OSSL_FUNC_provider_gettable_params(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_GET_PARAMS: + prov->get_params = + OSSL_FUNC_provider_get_params(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_SELF_TEST: + prov->self_test = + OSSL_FUNC_provider_self_test(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_GET_CAPABILITIES: + prov->get_capabilities = + OSSL_FUNC_provider_get_capabilities(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_QUERY_OPERATION: + prov->query_operation = + OSSL_FUNC_provider_query_operation(provider_dispatch); + break; + case OSSL_FUNC_PROVIDER_UNQUERY_OPERATION: + prov->unquery_operation = + OSSL_FUNC_provider_unquery_operation(provider_dispatch); + break; #ifndef OPENSSL_NO_ERR # ifndef FIPS_MODULE - case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS: - p_get_reason_strings = - OSSL_FUNC_provider_get_reason_strings(provider_dispatch); - break; + case OSSL_FUNC_PROVIDER_GET_REASON_STRINGS: + p_get_reason_strings = + OSSL_FUNC_provider_get_reason_strings(provider_dispatch); + break; # endif #endif + } } } diff --git a/crypto/x509/by_file.c b/crypto/x509/by_file.c index 450bbba0537b6a20adf923e0cae58254804b4f19..5073c137a20b1ca7ccd1ba1e64e716c1db79c734 100644 --- a/crypto/x509/by_file.c +++ b/crypto/x509/by_file.c @@ -128,6 +128,17 @@ int X509_load_cert_file_ex(X509_LOOKUP *ctx, const char *file, int type, count = 0; goto err; } + /* + * X509_STORE_add_cert() added a reference rather than a copy, + * so we need a fresh X509 object. + */ + X509_free(x); + x = X509_new_ex(libctx, propq); + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + count = 0; + goto err; + } count++; } } else if (type == X509_FILETYPE_ASN1) { diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c index d1c3dd5d9ffd21e69bd1c2946b7f11abe0a95d2a..251243b7237320141e5c4fb54650d4d230922ecb 100644 --- a/crypto/x509/v3_asid.c +++ b/crypto/x509/v3_asid.c @@ -169,8 +169,11 @@ int X509v3_asid_add_inherit(ASIdentifiers *asid, int which) if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; - if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) + if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) { + ASIdentifierChoice_free(*choice); + *choice = NULL; return 0; + } (*choice)->type = ASIdentifierChoice_inherit; } return (*choice)->type == ASIdentifierChoice_inherit; @@ -196,18 +199,23 @@ int X509v3_asid_add_id_or_range(ASIdentifiers *asid, default: return 0; } - if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) + if (*choice != NULL && (*choice)->type != ASIdentifierChoice_asIdsOrRanges) return 0; if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); - if ((*choice)->u.asIdsOrRanges == NULL) + if ((*choice)->u.asIdsOrRanges == NULL) { + ASIdentifierChoice_free(*choice); + *choice = NULL; return 0; + } (*choice)->type = ASIdentifierChoice_asIdsOrRanges; } if ((aor = ASIdOrRange_new()) == NULL) return 0; + if (!sk_ASIdOrRange_reserve((*choice)->u.asIdsOrRanges, 1)) + goto err; if (max == NULL) { aor->type = ASIdOrRange_id; aor->u.id = min; @@ -220,7 +228,8 @@ int X509v3_asid_add_id_or_range(ASIdentifiers *asid, ASN1_INTEGER_free(aor->u.range->max); aor->u.range->max = max; } - if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) + /* Cannot fail due to the reservation above */ + if (!ossl_assert(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) goto err; return 1; diff --git a/dev/NEWS-FORMAT.md b/dev/NEWS-FORMAT.md new file mode 100644 index 0000000000000000000000000000000000000000..9807c41bad2899b4fce195e19f533db47b799fbe --- /dev/null +++ b/dev/NEWS-FORMAT.md @@ -0,0 +1,209 @@ +Editorial conventions for NEWS.md +================================= + +With 3.2 onwards we are seeking to make our NEWS.md file more like release +notes, structured to provide useful and pertinent information to those consuming +a release. + +General editorial principles +---------------------------- + +- Use `*` for top-level lists and use a blank line between each list item. + This makes the file more readable when read in raw form, which will commonly + occur when a user examines an unpacked tarball. + +- Cite RFCs with a space: `RFC 9000` + +- Put URLs at the end of the file and reference them rather than giving them + inline. This eases maintenance if a commonly used URL needs to be changed. + +- The blocks within a section for a release line are ordered roughly in + descending order of importance. Equally, list items within a block should be + listed in descending order of significance or severity. + +- Try to develop blog posts to match our wording, especially for the list of + new features. + +- Adopt uniform wording for lists where appropriate but do not insist on + sticking to them where these wordings are unworkable or suboptimal. + +- Everything here is a recommendation, not a requirement. + +- Omit blocks which have no items to list. + +Structure +--------- + +Each release line has a section, which is broken down into the initial and patch +releases within that release line. The most recent releases come first. + +The structure is as follows: + +```text +OpenSSL x.y +----------- + + + + +``` + +### Structure of a release entry + +For each release in a release line, the recommended structure is as follows: + +```text +### Major changes between OpenSSL {PREV_VERSION} and OpenSSL {VERSION} [1 Jan 2023] + + + + + + +``` + +#### Opener paragraph + +For a feature release, the following opener paragraph is suggested: + +```text +OpenSSL x.y.0 is a feature release adding significant new functionality to +OpenSSL. +``` + +For a patch release with no CVEs fixed, the following opener paragraph is +suggested: + +```text +OpenSSL x.y.z is a patch release. +``` + +For a patch release which fixes one or more CVEs, the following opener paragraph +is suggested, to be adjusted as appropriate: + +```text +OpenSSL x.y.z is a security patch release. The most severe CVE fixed in this +release is Medium. +``` + +#### Listing potentially incompatible changes + +If there are any potentially significant or incompatible changes, the following +block should be added: + +```text +This release incorporates the following potentially significant or incompatible +changes: + + * The ... has been changed so that xxx. + + * The ... has been changed so that yyy. + +``` + +Bullet items in this block should be complete sentences with trailing full stops +giving a brief summary. They may optionally be followed by full paragraphs +giving further information if needed. + +#### Listing feature additions + +If there are any feature additions, the following block should be added: + +```text +This release adds the following new features: + + * Support for ... (RFC 1234) + + * Support for ... (RFC 2345) + + This is an elaborating paragraph. + + * Multiple new features and improvements to ... + +``` + +Bullet items in this block should be summary lines without a trailing full stop +giving a brief summary, optionally followed by references to applicable +standards in parentheses. They may optionally be followed by full paragraphs +giving further information if needed. The summary line should not start with a +verb as the opener line for this block provides the verb. + +For consistency, use the wording `Support for ...` as the summary line if +possible and practical. + +List features in descending order of significance (approximately). + +#### Listing known issues + +Known issues can be called out as follows: + +```text +The following known issues are present in this release and will be rectified in +a future release: + + * xxx (#12345) + +``` + +The editorial conventions for this block are similar to those for feature +additions, except that an issue number is listed rather than a reference to a +standard. + +#### Listing documentation enhancements + +Significant documentation enhancements can be called out as follows: + +```text +This release incorporates the following documentation enhancements: + + * Added xyz + + This is an elaborating paragraph, which might for example + provide a link to where this documentation can be viewed. + + * Clarified xyz + +``` + +The editorial conventions for this block are similar to those for feature +additions, except that the verb is part of the summary line. The other rules are +the same. + +For consistency, use the wording `Added ...` or `Clarified ...` as the summary +line if possible. + +#### Listing bug fixes and mitigations + +Significant bug fixes or mitigations can be called out as follows: + +```text +This release incorporates the following bug fixes and mitigations: + + * Mitigated (CVE ID as link and any other + relevant links) + + * Fixed (optional reference link or #issue number as + appropriate) +``` + +The words “bug fixes” or “mitigations” in the leader line should be deleted as +appropriate if inapplicable to a release. + +Fixes for issues with an issue number in the main repository should be given as +`#1234`. Any other issue (for example, a project issue) should be given as a +link, as most users will not know where to find such issues. + +List CVE mitigations first in descending order of severity, followed by bugs in +(very rough) descending order of severity. + +#### Trailing advice + +The following trailer is recommended: + +```text +A more detailed list of changes in this release can be found in the +[CHANGES.md] file. + +As always, bug reports and issues relating to OpenSSL can be [filed on our issue +tracker][issue tracker]. +``` diff --git a/doc/designs/quic-design/glossary.md b/doc/designs/quic-design/glossary.md index fdaa822196712082cdc90db9157e1a0b4de68d0a..a70cfd1ade1019424889752f58ba380848ac666d 100644 --- a/doc/designs/quic-design/glossary.md +++ b/doc/designs/quic-design/glossary.md @@ -84,6 +84,12 @@ may be maintained at a given time. See `quic_record_rx.h` for details. **KU:** Key update. See also TXKU, RXKU. +**LCID:** Local CID. Refers to a CID which will be recognised as identifying a +connection if found in the DCID field of an incoming packet. See also RCID. + +**LCIDM:** Local CID Manager. Tracks LCIDs which have been advertised to a peer. +See also RCIDM. + **Locally-initiated:** Refers to a QUIC stream which was initiated by the local application rather than the remote peer. @@ -121,6 +127,10 @@ in which API calls can be made on different threads. **MSST:** Multi-stream single-thread. Refers to a type of multi-stream QUIC usage in which API calls must not be made concurrently. +**ODCID:** Original Destination CID. This is the DCID found in the first Initial +packet sent by a client, and is used to generate the secrets for encrypting +Initial packets. It is only used temporarily. + **PN:** Packet number. Most QUIC packet types have a packet number (PN); see RFC 9000. @@ -165,6 +175,12 @@ not part of the APL. An XSO wraps a QUIC_STREAM once that stream is exposed as an API object. As such, a `QUIC_CONNECTION` is to a `QUIC_CHANNEL` what a `QUIC_XSO` is to a `QUIC_STREAM`. +**RCID:** Remote CID. Refers to a CID which has been provided to us by a peer +and which we can place in the DCID field of an outgoing packet. See also LCID. + +**RCIDM:** Remote CID Manager. Tracks RCIDs which have been provided to us by a +peer. See also LCIDM. + **REGEN:** A strategy for regenerating lost frames. This strategy regenerates the frame from canonical data sources without having to store a copy of the frame which was transmitted. See FIFM design document for details. diff --git a/doc/man3/SSL_CTX_set_tmp_dh_callback.pod b/doc/man3/SSL_CTX_set_tmp_dh_callback.pod index c0d69f6f6ae99f57bf8a95d5d127774d5a2f7fdf..a14f334cfca8c0d4446c21ce786fb70cafcf5acc 100644 --- a/doc/man3/SSL_CTX_set_tmp_dh_callback.pod +++ b/doc/man3/SSL_CTX_set_tmp_dh_callback.pod @@ -55,7 +55,7 @@ As generating DH parameters is extremely time consuming, an application should not generate the parameters on the fly. DH parameters can be reused, as the actual key is newly generated during the negotiation. -Typically applications should use well know DH parameters that have built-in +Typically applications should use well known DH parameters that have built-in support in OpenSSL. The macros SSL_CTX_set_dh_auto() and SSL_set_dh_auto() configure OpenSSL to use the default built-in DH parameters for the B and B objects respectively. Passing a value of 1 in the I parameter diff --git a/doc/man7/EVP_MD-SHAKE.pod b/doc/man7/EVP_MD-SHAKE.pod index e0395f887b4401d5ef840768afa157059d736e4d..8389539bd8726911f1fa627c68ba6cc53f2ca0f4 100644 --- a/doc/man7/EVP_MD-SHAKE.pod +++ b/doc/man7/EVP_MD-SHAKE.pod @@ -25,14 +25,14 @@ provider, and includes the following varieties: Known names are "KECCAK-KMAC-128" and "KECCAK-KMAC128". This is used by L. Using the notation from NIST FIPS 202 -(Section 6.2), we have KECCAK-KMAC-128(M, d) = KECCAK[256](M || 00, d) +(Section 6.2), we have S = S (see the description of KMAC128 in Appendix A of NIST SP 800-185). =item KECCAK-KMAC-256 Known names are "KECCAK-KMAC-256" and "KECCAK-KMAC256". This is used by L. Using the notation from NIST FIPS 202 -(Section 6.2), we have KECCAK-KMAC-256(M, d) = KECCAK[512](M || 00, d) +(Section 6.2), we have S = S (see the description of KMAC256 in Appendix A of NIST SP 800-185). =item SHAKE-128 diff --git a/doc/man7/EVP_PKEY-RSA.pod b/doc/man7/EVP_PKEY-RSA.pod index 161e9d4d71d16d13818d27be9dd2ed09aa539174..dcd38fcee85bb8eed440afdd32f11bd37230d1d9 100644 --- a/doc/man7/EVP_PKEY-RSA.pod +++ b/doc/man7/EVP_PKEY-RSA.pod @@ -80,7 +80,7 @@ Up to eight additional "r_i" prime factors are supported. =item "rsa-exponent10" (B) RSA CRT (Chinese Remainder Theorem) exponents. The exponents are known -as "dP", "dQ" and "d_i in RFC8017". +as "dP", "dQ" and "d_i" in RFC8017. Up to eight additional "d_i" exponents are supported. =item "rsa-coefficient1" (B) diff --git a/doc/man7/EVP_RAND-SEED-SRC.pod b/doc/man7/EVP_RAND-SEED-SRC.pod index 8bbd5794720e0db0ec4274c435e0fe24b490296d..a00ed328d529065cb7bf531d3914093f2db45bfc 100644 --- a/doc/man7/EVP_RAND-SEED-SRC.pod +++ b/doc/man7/EVP_RAND-SEED-SRC.pod @@ -49,9 +49,10 @@ A context for the seed source can be obtained by calling: OSSL_PARAM params[2], *p = params; unsigned int strength = 128; - /* Create a seed source */ + /* Create and instantiate a seed source */ rand = EVP_RAND_fetch(NULL, "SEED-SRC", NULL); seed = EVP_RAND_CTX_new(rand, NULL); + EVP_RAND_instantiate(seed, strength, 0, NULL, 0, NULL); EVP_RAND_free(rand); /* Feed this into a DRBG */ diff --git a/exporters/cmake/OpenSSLConfig.cmake.in b/exporters/cmake/OpenSSLConfig.cmake.in index 606773ff2726e915ede8f8fae05924d438433bb4..2d2321931de1dad70a4f18720f4238736e67cba3 100644 --- a/exporters/cmake/OpenSSLConfig.cmake.in +++ b/exporters/cmake/OpenSSLConfig.cmake.in @@ -12,10 +12,12 @@ ? platform->sharedlib_simple($_) : undef) // platform->sharedlib($_); - my $lib_shared_import = platform->sharedlib_import($_); $x{static} = $lib_static if $lib_static; $x{shared} = $lib_shared if $lib_shared; - $x{shared_import} = $lib_shared_import if $lib_shared_import; + if (platform->can("sharedlib_import")) { + my $lib_shared_import = platform->sharedlib_import($_); + $x{shared_import} = $lib_shared_import if $lib_shared_import; + } %x ? ( $_ => \%x ) : () } grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} } @{$unified_info{libraries}} diff --git a/fuzz/build.info b/fuzz/build.info index bbbc7c9654a8e5047f81afd4cd49acb370eddf8f..3fc4345a89acaa43214680a43ce0e0f3adf3f37a 100644 --- a/fuzz/build.info +++ b/fuzz/build.info @@ -30,7 +30,7 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] ENDIF IF[{- !$disabled{"quic"} -}] - PROGRAMS{noinst}=quic-client quic-srtm + PROGRAMS{noinst}=quic-client quic-srtm quic-lcidm ENDIF SOURCE[asn1]=asn1.c driver.c fuzz_rand.c @@ -101,6 +101,10 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] INCLUDE[quic-srtm]=../include {- $ex_inc -} DEPEND[quic-srtm]=../libcrypto.a ../libssl.a {- $ex_lib -} + SOURCE[quic-lcidm]=quic-lcidm.c driver.c fuzz_rand.c + INCLUDE[quic-lcidm]=../include {- $ex_inc -} + DEPEND[quic-lcidm]=../libcrypto.a ../libssl.a {- $ex_lib -} + SOURCE[server]=server.c driver.c fuzz_rand.c INCLUDE[server]=../include {- $ex_inc -} DEPEND[server]=../libcrypto ../libssl {- $ex_lib -} @@ -132,7 +136,7 @@ IF[{- !$disabled{tests} -}] ENDIF IF[{- !$disabled{"quic"} -}] - PROGRAMS{noinst}=quic-client-test quic-srtm-test + PROGRAMS{noinst}=quic-client-test quic-srtm-test quic-lcidm-test ENDIF SOURCE[asn1-test]=asn1.c test-corpus.c fuzz_rand.c @@ -204,6 +208,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[quic-srtm-test]=../include DEPEND[quic-srtm-test]=../libcrypto.a ../libssl.a + SOURCE[quic-lcidm-test]=quic-lcidm.c test-corpus.c fuzz_rand.c + INCLUDE[quic-lcidm-test]=../include + DEPEND[quic-lcidm-test]=../libcrypto.a ../libssl.a + SOURCE[server-test]=server.c test-corpus.c fuzz_rand.c INCLUDE[server-test]=../include DEPEND[server-test]=../libcrypto ../libssl diff --git a/fuzz/quic-lcidm.c b/fuzz/quic-lcidm.c new file mode 100644 index 0000000000000000000000000000000000000000..f72f0918600077a8210efe69cb0cd7149d15c007 --- /dev/null +++ b/fuzz/quic-lcidm.c @@ -0,0 +1,180 @@ +/* + * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 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 + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ + +#include +#include +#include +#include "fuzzer.h" +#include "internal/quic_lcidm.h" +#include "internal/packet.h" + +int FuzzerInitialize(int *argc, char ***argv) +{ + FuzzerSetRand(); + OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS | OPENSSL_INIT_ASYNC, NULL); + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); + ERR_clear_error(); + return 1; +} + +/* + * Fuzzer input "protocol": + * Big endian + * u8(LCID length) + * Zero or more of: + * ENROL_ODCID u0(0x00) u64(opaque) u8(cidl):cid + * RETIRE_ODCID u8(0x01) u64(opaque) + * GENERATE_INITIAL u8(0x02) u64(opaque) + * GENERATE u8(0x03) u64(opaque) + * RETIRE u8(0x04) u64(opaque) u64(retire_prior_to) + * CULL u8(0x05) u64(opaque) + * LOOKUP u8(0x06) u8(cidl):cid + */ + +enum { + CMD_ENROL_ODCID, + CMD_RETIRE_ODCID, + CMD_GENERATE_INITIAL, + CMD_GENERATE, + CMD_RETIRE, + CMD_CULL, + CMD_LOOKUP +}; + +static int get_cid(PACKET *pkt, QUIC_CONN_ID *cid) +{ + unsigned int cidl; + + if (!PACKET_get_1(pkt, &cidl) + || cidl > QUIC_MAX_CONN_ID_LEN + || !PACKET_copy_bytes(pkt, cid->id, cidl)) + return 0; + + cid->id_len = (unsigned char)cidl; + return 1; +} + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + int rc = 0; + QUIC_LCIDM *lcidm = NULL; + PACKET pkt; + uint64_t arg_opaque, arg_retire_prior_to, seq_num_out; + unsigned int cmd, lcidl; + QUIC_CONN_ID arg_cid, cid_out; + OSSL_QUIC_FRAME_NEW_CONN_ID ncid_frame; + int did_retire; + void *opaque_out; + + if (!PACKET_buf_init(&pkt, buf, len)) + goto err; + + if (!PACKET_get_1(&pkt, &lcidl) + || lcidl > QUIC_MAX_CONN_ID_LEN) { + rc = -1; + goto err; + } + + if ((lcidm = ossl_quic_lcidm_new(NULL, lcidl)) == NULL) { + rc = -1; + goto err; + } + + while (PACKET_remaining(&pkt) > 0) { + if (!PACKET_get_1(&pkt, &cmd)) + goto err; + + switch (cmd) { + case CMD_ENROL_ODCID: + if (!PACKET_get_net_8(&pkt, &arg_opaque) + || !get_cid(&pkt, &arg_cid)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_enrol_odcid(lcidm, (void *)(uintptr_t)arg_opaque, + &arg_cid); + break; + + case CMD_RETIRE_ODCID: + if (!PACKET_get_net_8(&pkt, &arg_opaque)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_retire_odcid(lcidm, (void *)(uintptr_t)arg_opaque); + break; + + case CMD_GENERATE_INITIAL: + if (!PACKET_get_net_8(&pkt, &arg_opaque)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_generate_initial(lcidm, (void *)(uintptr_t)arg_opaque, + &cid_out); + break; + + case CMD_GENERATE: + if (!PACKET_get_net_8(&pkt, &arg_opaque)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_generate(lcidm, (void *)(uintptr_t)arg_opaque, + &ncid_frame); + break; + + case CMD_RETIRE: + if (!PACKET_get_net_8(&pkt, &arg_opaque) + || !PACKET_get_net_8(&pkt, &arg_retire_prior_to)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_retire(lcidm, (void *)(uintptr_t)arg_opaque, + arg_retire_prior_to, + NULL, &cid_out, + &seq_num_out, &did_retire); + break; + + case CMD_CULL: + if (!PACKET_get_net_8(&pkt, &arg_opaque)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_cull(lcidm, (void *)(uintptr_t)arg_opaque); + break; + + case CMD_LOOKUP: + if (!get_cid(&pkt, &arg_cid)) { + rc = -1; + goto err; + } + + ossl_quic_lcidm_lookup(lcidm, &arg_cid, &seq_num_out, &opaque_out); + break; + + default: + rc = -1; + goto err; + } + } + +err: + ossl_quic_lcidm_free(lcidm); + return rc; +} + +void FuzzerCleanup(void) +{ + FuzzerClearRand(); +} diff --git a/include/crypto/aes_platform.h b/include/crypto/aes_platform.h index eb280e754a6a1c1c741f208616797945abad2228..8a9e7a0535170b42b539229e62ad1f1ec41c0b98 100644 --- a/include/crypto/aes_platform.h +++ b/include/crypto/aes_platform.h @@ -107,17 +107,21 @@ void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); # define HWAES_cbc_encrypt aes_v8_cbc_encrypt # define HWAES_ecb_encrypt aes_v8_ecb_encrypt # if __ARM_MAX_ARCH__>=8 && (defined(__aarch64__) || defined(_M_ARM64)) +# define ARMv8_HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) # define HWAES_xts_encrypt aes_v8_xts_encrypt # define HWAES_xts_decrypt aes_v8_xts_decrypt # endif # define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks +# define HWAES_ctr32_encrypt_blocks_unroll12_eor3 aes_v8_ctr32_encrypt_blocks_unroll12_eor3 # define AES_PMULL_CAPABLE ((OPENSSL_armcap_P & ARMV8_PMULL) && (OPENSSL_armcap_P & ARMV8_AES)) +# define AES_UNROLL12_EOR3_CAPABLE (OPENSSL_armcap_P & ARMV8_UNROLL12_EOR3) # define AES_GCM_ENC_BYTES 512 # define AES_GCM_DEC_BYTES 512 # if __ARM_MAX_ARCH__>=8 && (defined(__aarch64__) || defined(_M_ARM64)) # define AES_gcm_encrypt armv8_aes_gcm_encrypt # define AES_gcm_decrypt armv8_aes_gcm_decrypt -# define AES_GCM_ASM(gctx) ((gctx)->ctr==aes_v8_ctr32_encrypt_blocks && \ +# define AES_GCM_ASM(gctx) (((gctx)->ctr==aes_v8_ctr32_encrypt_blocks_unroll12_eor3 || \ + (gctx)->ctr==aes_v8_ctr32_encrypt_blocks) && \ (gctx)->gcm.funcs.ghash==gcm_ghash_v8) /* The [unroll8_eor3_]aes_gcm_(enc|dec)_(128|192|256)_kernel() functions * take input length in BITS and return number of BYTES processed */ @@ -545,6 +549,11 @@ void HWAES_ecb_encrypt(const unsigned char *in, unsigned char *out, void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, size_t len, const void *key, const unsigned char ivec[16]); +# if defined(AES_UNROLL12_EOR3_CAPABLE) +void HWAES_ctr32_encrypt_blocks_unroll12_eor3(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + const unsigned char ivec[16]); +# endif void HWAES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, const AES_KEY *key1, const AES_KEY *key2, const unsigned char iv[16]); diff --git a/include/internal/quic_lcidm.h b/include/internal/quic_lcidm.h new file mode 100644 index 0000000000000000000000000000000000000000..9b11429814895f97d855d05f4864e5ac44fba2ff --- /dev/null +++ b/include/internal/quic_lcidm.h @@ -0,0 +1,257 @@ +/* +* Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +* +* Licensed under the Apache License 2.0 (the "License"). You may not use +* this file except in compliance with the License. You can obtain a copy +* in the file LICENSE in the source distribution or at +* https://www.openssl.org/source/license.html +*/ + +#ifndef OSSL_INTERNAL_QUIC_LCIDM_H +# define OSSL_INTERNAL_QUIC_LCIDM_H +# pragma once + +# include "internal/e_os.h" +# include "internal/time.h" +# include "internal/quic_types.h" +# include "internal/quic_wire.h" + +# ifndef OPENSSL_NO_QUIC + +/* + * QUIC Local Connection ID Manager + * ================================ + * + * This manages connection IDs for the RX side, which is to say that it issues + * local CIDs (LCIDs) to a peer which that peer can then use to address us via a + * packet DCID. This is as opposed to CID management for the TX side, which + * determines which CIDs we use to transmit based on remote CIDs (RCIDs) the + * peer sent to us. + * + * An opaque pointer can be associated with each LCID. Pointer identity + * (equality) is used to distinguish distinct connections. + * + * LCIDs fall into three categories: + * + * 1. A client's Initial ODCID (1) + * 2. Our local Initial SCID (1) + * 3. A CID issued via a NEW_CONNECTION_ID frame (n) + * 4. A server's Retry SCID (0..1) + * + * (1) is enrolled using ossl_quic_lcidm_enrol_odcid() and retired by the time + * of handshake completion at the latest. It is needed in case the first + * response packet from a server is lost and the client keeps using its Initial + * ODCID. There is never more than one of these, and no sequence number is + * associated with this temporary LCID. + * + * (2) is created by a client when it begins connecting, or by a server when it + * responds to a new connection request. In the latter case, it is generated by + * the server as the preferred DCID for traffic directed towards it. A client + * should switch to using this as a RCID as soon as it receives a valid packet + * from the server. This LCID has a sequence number of 0. + * + * (3) is created when we issue a NEW_CONNECTION_ID frame. Arbitrarily many of + * these can exist. + * + * (4) is a special case. When a server issues a retry it generates a new SCID + * much as it does for (2). However since retries are supposed to be stateless, + * we don't actually register it as an LCID. When the client subsequently + * replies with an Initial packet with token in response to the Retry, the + * server will handle this as a new connection attempt due to not recognising + * the DCID, which is what we want anyway. (The Retry SCID is subsequently + * validated as matching the new Initial ODCID via attestation in the encrypted + * contents of the opaque retry token.) Thus, the LCIDM is not actually involved + * at all here. + * + * Retirement is as follows: + * + * (1) is retired automatically when we know it won't be needed anymore. This is + * when the handshake is completed at the latest, and could potentially be + * earlier. + * + * Both (2) and (3) are retired normally via RETIRE_CONNECTION_ID frames, as it + * has a sequence number of 0. + * + * + * ODCID Peculiarities + * ------------------- + * + * Almost all LCIDs are issued by the receiver responsible for routing them, + * which means that almost all LCIDs will have the same length (specified in + * lcid_len below). The only exception to this is (1); the ODCID is the only + * case where we recognise an LCID we didn't ourselves generate. Since an ODCID + * is chosen by the peer, it can be any length and doesn't necessarily match the + * length we use for LCIDs we generate ourselves. + * + * Since DCID decoding for short-header packets requires an implicitly known + * DCID length, it logically follows that an ODCID can never be used in a 1-RTT + * packet. This is fine as by the time the 1-RTT EL is reached the peer should + * already have switched away from the ODCID to a CID we generated ourselves, + * and if this has not happened we can consider that a protocol violation. + * + * In any case, this means that the LCIDM must necessarily support LCIDs of + * different lengths, even if it always generates LCIDs of a given length. + * + * An ODCID has no sequence number associated with it. It is the only CID to + * lack one. + */ +typedef struct quic_lcidm_st QUIC_LCIDM; + +/* + * Creates a new LCIDM. lcid_len is the length to use for LCIDs in bytes, which + * may be zero. + * + * Returns NULL on failure. + */ +QUIC_LCIDM *ossl_quic_lcidm_new(OSSL_LIB_CTX *libctx, size_t lcid_len); + +/* Frees a LCIDM. */ +void ossl_quic_lcidm_free(QUIC_LCIDM *lcidm); + +/* Gets the local CID length this LCIDM was configured to use. */ +size_t ossl_quic_lcidm_get_lcid_len(const QUIC_LCIDM *lcidm); + +/* + * Determines the number of active LCIDs (i.e,. LCIDs which can be used for + * reception) currently associated with the given opaque pointer. + */ +size_t ossl_quic_lcidm_get_num_active_lcid(const QUIC_LCIDM *lcidm, + void *opaque); + +/* + * Enrol an Initial ODCID sent by the peer. This is the DCID in the first + * Initial packet sent by a client. When we receive a client's first Initial + * packet, we immediately respond with our own SCID (generated using + * ossl_quic_lcidm_generate_initial) to tell the client to switch to using that, + * so ideally the ODCID will only be used for a single packet. However since + * that response might be lost, we also need to accept additional packets using + * the ODCID and need to make sure they get routed to the same connection and + * not interpreted as another new connection attempt. Thus before the CID + * switchover is confirmed, we also have to handle incoming packets addressed to + * the ODCID. This function is used to temporarily enroll the ODCID for a + * connection. Such a LCID is considered to have a sequence number of + * LCIDM_ODCID_SEQ_NUM internally for our purposes. + * + * Note that this is the *only* circumstance where we recognise an LCID we did + * not generate ourselves, or allow an LCID with a different length to lcid_len. + * + * An ODCID MUST be at least 8 bytes in length (RFC 9000 s. 7.2). + * + * This function may only be called once for a given connection. + * Returns 1 on success or 0 on failure. + */ +int ossl_quic_lcidm_enrol_odcid(QUIC_LCIDM *lcidm, void *opaque, + const QUIC_CONN_ID *initial_odcid); + +/* + * Retire a previously enrolled ODCID for a connection. This is generally done + * when we know the peer won't be using it any more (when the handshake is + * completed at the absolute latest, possibly earlier). + * + * Returns 1 if there was an enrolled ODCID which was retired and 0 if there was + * not or on other failure. + */ +int ossl_quic_lcidm_retire_odcid(QUIC_LCIDM *lcidm, void *opaque); + +/* + * Create the first LCID for a given opaque pointer. The generated LCID is + * written to *initial_lcid and associated with the given opaque pointer. + * + * After this function returns successfully, the caller can for example + * register the new LCID with a DEMUX. + * + * May not be called more than once for a given opaque pointer value. + */ +int ossl_quic_lcidm_generate_initial(QUIC_LCIDM *lcidm, + void *opaque, + QUIC_CONN_ID *initial_lcid); + +/* + * Create a subsequent LCID for a given opaque pointer. The information needed + * for a NEW_CONN_ID frame informing the peer of the new LCID, including the + * LCID itself, is written to *ncid_frame. + * + * ncid_frame->stateless_reset is not initialised and the caller is responsible + * for setting it. + * + * After this function returns successfully, the caller can for example + * register the new LCID with a DEMUX and queue the NEW_CONN_ID frame. + */ +int ossl_quic_lcidm_generate(QUIC_LCIDM *lcidm, + void *opaque, + OSSL_QUIC_FRAME_NEW_CONN_ID *ncid_frame); + +/* + * Retire up to one LCID for a given opaque pointer value. Called repeatedly to + * handle a RETIRE_CONN_ID frame. + * + * If containing_pkt_dcid is non-NULL, this function enforces the requirement + * that a CID not be retired by a packet using that CID as the DCID. If + * containing_pkt_dcid is NULL, this check is skipped. + * + * If a LCID is retired as a result of a call to this function, the LCID which + * was retired is written to *retired_lcid, the sequence number of the LCID is + * written to *retired_seq_num and *did_retire is set to 1. Otherwise, + * *did_retire is set to 0. This enables a caller to e.g. unregister the LCID + * from a DEMUX. A caller should call this function repeatedly until the + * function returns with *did_retire set to 0. + * + * This call is likely to cause the value returned by + * ossl_quic_lcidm_get_num_active_lcid() to go down. A caller may wish to call + * ossl_quic_lcidm_generate() repeatedly to bring the number of active LCIDs + * back up to some threshold in response after calling this function. + * + * Returns 1 on success and 0 on failure. If arguments are valid but zero LCIDs + * are retired, this is considered a success condition. + */ +int ossl_quic_lcidm_retire(QUIC_LCIDM *lcidm, + void *opaque, + uint64_t retire_prior_to, + const QUIC_CONN_ID *containing_pkt_dcid, + QUIC_CONN_ID *retired_lcid, + uint64_t *retired_seq_num, + int *did_retire); + +/* + * Cull all LCIDM state relating to a given opaque pointer value. This is useful + * if connection state is spontaneously freed. The caller is responsible for + * e.g. DEMUX state updates. + */ +int ossl_quic_lcidm_cull(QUIC_LCIDM *lcidm, void *opaque); + +/* + * Lookup a LCID. If the LCID is found, writes the associated opaque pointer to + * *opaque and the associated sequence number to *seq_num. Returns 1 on success + * and 0 if an entry is not found. An output argument may be set to NULL if its + * value is not required. + * + * If the LCID is for an Initial ODCID, *seq_num is set to + * LCIDM_ODCID_SEQ_NUM. + */ +#define LCIDM_ODCID_SEQ_NUM UINT64_MAX + +int ossl_quic_lcidm_lookup(QUIC_LCIDM *lcidm, + const QUIC_CONN_ID *lcid, + uint64_t *seq_num, + void **opaque); + +/* + * Debug call to manually remove a specific LCID. Should not be needed in normal + * usage. Returns 1 if the LCID was successfully found and removed and 0 + * otherwise. + */ +int ossl_quic_lcidm_debug_remove(QUIC_LCIDM *lcidm, + const QUIC_CONN_ID *lcid); + +/* + * Debug call to manually add a numbered LCID with a specific CID value and + * sequence number. Should not be needed in normal usage. Returns 1 on success + * and 0 on failure. + */ +int ossl_quic_lcidm_debug_add(QUIC_LCIDM *lcidm, void *opaque, + const QUIC_CONN_ID *lcid, + uint64_t seq_num); + +# endif + +#endif diff --git a/include/internal/quic_types.h b/include/internal/quic_types.h index d42164ba56115dc274504dad1322ca1f4138b962..1d3816a20987226ead56dc573a9a2d25df255507 100644 --- a/include/internal/quic_types.h +++ b/include/internal/quic_types.h @@ -73,6 +73,7 @@ static ossl_unused ossl_inline int ossl_quic_pn_valid(QUIC_PN pn) /* QUIC connection ID representation. */ # define QUIC_MAX_CONN_ID_LEN 20 +# define QUIC_MIN_ODCID_LEN 8 /* RFC 9000 s. 7.2 */ typedef struct quic_conn_id_st { unsigned char id_len, id[QUIC_MAX_CONN_ID_LEN]; diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc index bdcf67071639da7f57d171e8adbf7dc0278a8f63..cc240715003a5876ea55342fc400ade58a8b0915 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -86,8 +86,13 @@ static int armv8_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key, PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx; AES_KEY *ks = &actx->ks.ks; - GCM_HW_SET_KEY_CTR_FN(ks, aes_v8_set_encrypt_key, aes_v8_encrypt, - aes_v8_ctr32_encrypt_blocks); + if (AES_UNROLL12_EOR3_CAPABLE) { + GCM_HW_SET_KEY_CTR_FN(ks, aes_v8_set_encrypt_key, aes_v8_encrypt, + aes_v8_ctr32_encrypt_blocks_unroll12_eor3); + } else { + GCM_HW_SET_KEY_CTR_FN(ks, aes_v8_set_encrypt_key, aes_v8_encrypt, + aes_v8_ctr32_encrypt_blocks); + } return 1; } diff --git a/providers/implementations/ciphers/cipher_aes_hw.c b/providers/implementations/ciphers/cipher_aes_hw.c index 0a1243a5fc031c5fe160754fd1d3aae523024970..e8550a9644f95ac2b0636406886bebf86c2f00b0 100644 --- a/providers/implementations/ciphers/cipher_aes_hw.c +++ b/providers/implementations/ciphers/cipher_aes_hw.c @@ -146,6 +146,8 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aes_##mode(size_t keybits) \ # include "cipher_aes_hw_rv64i.inc" #elif defined(__riscv) && __riscv_xlen == 32 # include "cipher_aes_hw_rv32i.inc" +#elif defined (ARMv8_HWAES_CAPABLE) +# include "cipher_aes_hw_armv8.inc" #else /* The generic case */ # define PROV_CIPHER_HW_declare(mode) diff --git a/providers/implementations/ciphers/cipher_aes_hw_armv8.inc b/providers/implementations/ciphers/cipher_aes_hw_armv8.inc new file mode 100644 index 0000000000000000000000000000000000000000..3f73c79290a8f20b049512989fe0b2e9c2b2a105 --- /dev/null +++ b/providers/implementations/ciphers/cipher_aes_hw_armv8.inc @@ -0,0 +1,34 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Crypto extension support for AES modes ecb, cbc, ofb, cfb, ctr. + * This file is included by cipher_aes_hw.c + */ + +static int cipher_hw_aes_arm_initkey(PROV_CIPHER_CTX *dat, + const unsigned char *key, + size_t keylen) +{ + int ret = cipher_hw_aes_initkey(dat, key, keylen); + if (AES_UNROLL12_EOR3_CAPABLE && dat->mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f)HWAES_ctr32_encrypt_blocks_unroll12_eor3; + + return ret; +} + +#define PROV_CIPHER_HW_declare(mode) \ +static const PROV_CIPHER_HW aes_arm_##mode = { \ + cipher_hw_aes_arm_initkey, \ + ossl_cipher_hw_generic_##mode, \ + cipher_hw_aes_copyctx \ +}; +#define PROV_CIPHER_HW_select(mode) \ +if (ARMv8_HWAES_CAPABLE) \ + return &aes_arm_##mode; diff --git a/providers/implementations/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c index 1b3893598d888b9b128ba750a80ea45361fc5c45..fa0b576b97123d0579e83eb131f474c31b7c6750 100644 --- a/providers/implementations/macs/cmac_prov.c +++ b/providers/implementations/macs/cmac_prov.c @@ -101,8 +101,12 @@ static void *cmac_dup(void *vsrc) static size_t cmac_size(void *vmacctx) { struct cmac_data_st *macctx = vmacctx; + const EVP_CIPHER_CTX *cipherctx = CMAC_CTX_get0_cipher_ctx(macctx->ctx); - return EVP_CIPHER_CTX_get_block_size(CMAC_CTX_get0_cipher_ctx(macctx->ctx)); + if (EVP_CIPHER_CTX_get0_cipher(cipherctx) == NULL) + return 0; + + return EVP_CIPHER_CTX_get_block_size(cipherctx); } static int cmac_setkey(struct cmac_data_st *macctx, diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c index b8648b54bf6062eed7408c4aa845a5c13849cb07..76db37dd02c24d3e0dde58acd642fb21905b4835 100644 --- a/providers/implementations/signature/rsa_sig.c +++ b/providers/implementations/signature/rsa_sig.c @@ -1006,6 +1006,7 @@ static void *rsa_dupctx(void *vprsactx) *dstctx = *srcctx; dstctx->rsa = NULL; dstctx->md = NULL; + dstctx->mgf1_md = NULL; dstctx->mdctx = NULL; dstctx->tbuf = NULL; dstctx->propq = NULL; diff --git a/ssl/quic/build.info b/ssl/quic/build.info index b8d871848c106f0ac829051eca50548b1b5dbad1..e8016dae91fdb60f38c7d59d988e62ad634d9704 100644 --- a/ssl/quic/build.info +++ b/ssl/quic/build.info @@ -15,3 +15,4 @@ SOURCE[$LIBSSL]=quic_tls.c SOURCE[$LIBSSL]=quic_thread_assist.c SOURCE[$LIBSSL]=quic_trace.c SOURCE[$LIBSSL]=quic_srtm.c quic_srt_gen.c +SOURCE[$LIBSSL]=quic_lcidm.c diff --git a/ssl/quic/quic_lcidm.c b/ssl/quic/quic_lcidm.c new file mode 100644 index 0000000000000000000000000000000000000000..a46976a30812c7e93aa61b4732c959b4c12965c6 --- /dev/null +++ b/ssl/quic/quic_lcidm.c @@ -0,0 +1,553 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_lcidm.h" +#include "internal/quic_types.h" +#include "internal/quic_vlint.h" +#include "internal/common.h" +#include +#include +#include + +/* + * QUIC Local Connection ID Manager + * ================================ + */ + +typedef struct quic_lcidm_conn_st QUIC_LCIDM_CONN; + +enum { + LCID_TYPE_ODCID, /* This LCID is the ODCID from the peer */ + LCID_TYPE_INITIAL, /* This is our Initial SCID */ + LCID_TYPE_NCID /* This LCID was issued via a NCID frame */ +}; + +typedef struct quic_lcid_st { + QUIC_CONN_ID cid; + uint64_t seq_num; + + /* Back-pointer to the owning QUIC_LCIDM_CONN structure. */ + QUIC_LCIDM_CONN *conn; + + /* LCID_TYPE_* */ + unsigned int type : 2; +} QUIC_LCID; + +DEFINE_LHASH_OF_EX(QUIC_LCID); +DEFINE_LHASH_OF_EX(QUIC_LCIDM_CONN); + +struct quic_lcidm_conn_st { + size_t num_active_lcid; + LHASH_OF(QUIC_LCID) *lcids; + void *opaque; + QUIC_LCID *odcid_lcid_obj; + uint64_t next_seq_num; + + /* Have we enrolled an ODCID? */ + unsigned int done_odcid : 1; +}; + +struct quic_lcidm_st { + OSSL_LIB_CTX *libctx; + LHASH_OF(QUIC_LCID) *lcids; /* (QUIC_CONN_ID) -> (QUIC_LCID *) */ + LHASH_OF(QUIC_LCIDM_CONN) *conns; /* (void *opaque) -> (QUIC_LCIDM_CONN *) */ + size_t lcid_len; /* Length in bytes for all LCIDs */ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + QUIC_CONN_ID next_lcid; +#endif +}; + +static unsigned long bin_hash(const unsigned char *buf, size_t buf_len) +{ + unsigned long hash = 0; + size_t i; + + for (i = 0; i < buf_len; ++i) + hash ^= ((unsigned long)buf[i]) << (8 * (i % sizeof(unsigned long))); + + return hash; +} + +static unsigned long lcid_hash(const QUIC_LCID *lcid_obj) +{ + return bin_hash(lcid_obj->cid.id, lcid_obj->cid.id_len); +} + +static int lcid_comp(const QUIC_LCID *a, const QUIC_LCID *b) +{ + return !ossl_quic_conn_id_eq(&a->cid, &b->cid); +} + +static unsigned long lcidm_conn_hash(const QUIC_LCIDM_CONN *conn) +{ + return (unsigned long)(uintptr_t)conn->opaque; +} + +static int lcidm_conn_comp(const QUIC_LCIDM_CONN *a, const QUIC_LCIDM_CONN *b) +{ + return a->opaque != b->opaque; +} + +QUIC_LCIDM *ossl_quic_lcidm_new(OSSL_LIB_CTX *libctx, size_t lcid_len) +{ + QUIC_LCIDM *lcidm = NULL; + + if (lcid_len > QUIC_MAX_CONN_ID_LEN) + goto err; + + if ((lcidm = OPENSSL_zalloc(sizeof(*lcidm))) == NULL) + goto err; + + if ((lcidm->lcids = lh_QUIC_LCID_new(lcid_hash, lcid_comp)) == NULL) + goto err; + + if ((lcidm->conns = lh_QUIC_LCIDM_CONN_new(lcidm_conn_hash, + lcidm_conn_comp)) == NULL) + goto err; + + lcidm->libctx = libctx; + lcidm->lcid_len = lcid_len; + return lcidm; + +err: + if (lcidm != NULL) { + lh_QUIC_LCID_free(lcidm->lcids); + lh_QUIC_LCIDM_CONN_free(lcidm->conns); + OPENSSL_free(lcidm); + } + return NULL; +} + +static void lcidm_delete_conn(QUIC_LCIDM *lcidm, QUIC_LCIDM_CONN *conn); + +static void lcidm_delete_conn_(QUIC_LCIDM_CONN *conn, void *arg) +{ + lcidm_delete_conn((QUIC_LCIDM *)arg, conn); +} + +void ossl_quic_lcidm_free(QUIC_LCIDM *lcidm) +{ + if (lcidm == NULL) + return; + + lh_QUIC_LCIDM_CONN_doall_arg(lcidm->conns, lcidm_delete_conn_, lcidm); + + lh_QUIC_LCID_free(lcidm->lcids); + lh_QUIC_LCIDM_CONN_free(lcidm->conns); + OPENSSL_free(lcidm); +} + +static QUIC_LCID *lcidm_get0_lcid(const QUIC_LCIDM *lcidm, const QUIC_CONN_ID *lcid) +{ + QUIC_LCID key; + + key.cid = *lcid; + + if (key.cid.id_len > QUIC_MAX_CONN_ID_LEN) + return NULL; + + return lh_QUIC_LCID_retrieve(lcidm->lcids, &key); +} + +static QUIC_LCIDM_CONN *lcidm_get0_conn(const QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN key; + + key.opaque = opaque; + + return lh_QUIC_LCIDM_CONN_retrieve(lcidm->conns, &key); +} + +static QUIC_LCIDM_CONN *lcidm_upsert_conn(const QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN *conn = lcidm_get0_conn(lcidm, opaque); + + if (conn != NULL) + return conn; + + if ((conn = OPENSSL_zalloc(sizeof(*conn))) == NULL) + goto err; + + if ((conn->lcids = lh_QUIC_LCID_new(lcid_hash, lcid_comp)) == NULL) + goto err; + + conn->opaque = opaque; + + lh_QUIC_LCIDM_CONN_insert(lcidm->conns, conn); + if (lh_QUIC_LCIDM_CONN_error(lcidm->conns)) + goto err; + + return conn; + +err: + if (conn != NULL) { + lh_QUIC_LCID_free(conn->lcids); + OPENSSL_free(conn); + } + return NULL; +} + +static void lcidm_delete_conn_lcid(QUIC_LCIDM *lcidm, QUIC_LCID *lcid_obj) +{ + lh_QUIC_LCID_delete(lcidm->lcids, lcid_obj); + lh_QUIC_LCID_delete(lcid_obj->conn->lcids, lcid_obj); + assert(lcid_obj->conn->num_active_lcid > 0); + --lcid_obj->conn->num_active_lcid; + OPENSSL_free(lcid_obj); +} + +/* doall_arg wrapper */ +static void lcidm_delete_conn_lcid_(QUIC_LCID *lcid_obj, void *arg) +{ + lcidm_delete_conn_lcid((QUIC_LCIDM *)arg, lcid_obj); +} + +static void lcidm_delete_conn(QUIC_LCIDM *lcidm, QUIC_LCIDM_CONN *conn) +{ + lh_QUIC_LCID_doall_arg(conn->lcids, lcidm_delete_conn_lcid_, lcidm); + lh_QUIC_LCIDM_CONN_delete(lcidm->conns, conn); + lh_QUIC_LCID_free(conn->lcids); + OPENSSL_free(conn); +} + +static QUIC_LCID *lcidm_conn_new_lcid(QUIC_LCIDM *lcidm, QUIC_LCIDM_CONN *conn, + const QUIC_CONN_ID *lcid) +{ + QUIC_LCID *lcid_obj = NULL; + + if (lcid->id_len > QUIC_MAX_CONN_ID_LEN) + return NULL; + + if ((lcid_obj = OPENSSL_zalloc(sizeof(*lcid_obj))) == NULL) + goto err; + + lcid_obj->cid = *lcid; + lcid_obj->conn = conn; + + lh_QUIC_LCID_insert(conn->lcids, lcid_obj); + if (lh_QUIC_LCID_error(conn->lcids)) + goto err; + + lh_QUIC_LCID_insert(lcidm->lcids, lcid_obj); + if (lh_QUIC_LCID_error(lcidm->lcids)) { + lh_QUIC_LCID_delete(conn->lcids, lcid_obj); + goto err; + } + + ++conn->num_active_lcid; + return lcid_obj; + +err: + OPENSSL_free(lcid_obj); + return NULL; +} + +size_t ossl_quic_lcidm_get_lcid_len(const QUIC_LCIDM *lcidm) +{ + return lcidm->lcid_len; +} + +size_t ossl_quic_lcidm_get_num_active_lcid(const QUIC_LCIDM *lcidm, + void *opaque) +{ + QUIC_LCIDM_CONN *conn; + + conn = lcidm_get0_conn(lcidm, opaque); + if (conn == NULL) + return 0; + + return conn->num_active_lcid; +} + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + +static int gen_rand_conn_id(OSSL_LIB_CTX *libctx, size_t len, QUIC_CONN_ID *cid) +{ + if (len > QUIC_MAX_CONN_ID_LEN) + return 0; + + cid->id_len = (unsigned char)len; + + if (RAND_bytes_ex(libctx, cid->id, len, len * 8) != 1) { + ERR_raise(ERR_LIB_SSL, ERR_R_RAND_LIB); + cid->id_len = 0; + return 0; + } + + return 1; +} + +#endif + +static int lcidm_generate_cid(QUIC_LCIDM *lcidm, + QUIC_CONN_ID *cid) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + int i; + + lcidm->next_lcid.id_len = (unsigned char)lcidm->lcid_len; + *cid = lcidm->next_lcid; + + for (i = lcidm->lcid_len - 1; i >= 0; --i) + if (++lcidm->next_lcid.id[i] != 0) + break; + + return 1; +#else + return gen_rand_conn_id(lcidm->libctx, lcidm->lcid_len, cid); +#endif +} + +static int lcidm_generate(QUIC_LCIDM *lcidm, + void *opaque, + unsigned int type, + QUIC_CONN_ID *lcid_out, + uint64_t *seq_num) +{ + QUIC_LCIDM_CONN *conn; + QUIC_LCID key, *lcid_obj; + size_t i; +#define MAX_RETRIES 8 + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + if ((type == LCID_TYPE_INITIAL && conn->next_seq_num > 0) + || conn->next_seq_num > OSSL_QUIC_VLINT_MAX) + return 0; + + i = 0; + do { + if (i++ >= MAX_RETRIES) + /* + * Too many retries; should not happen but if it does, don't loop + * endlessly. + */ + return 0; + + if (!lcidm_generate_cid(lcidm, lcid_out)) + return 0; + + key.cid = *lcid_out; + /* If a collision occurs, retry. */ + } while (lh_QUIC_LCID_retrieve(lcidm->lcids, &key) != NULL); + + if ((lcid_obj = lcidm_conn_new_lcid(lcidm, conn, lcid_out)) == NULL) + return 0; + + lcid_obj->seq_num = conn->next_seq_num; + lcid_obj->type = type; + + if (seq_num != NULL) + *seq_num = lcid_obj->seq_num; + + ++conn->next_seq_num; + return 1; +} + +int ossl_quic_lcidm_enrol_odcid(QUIC_LCIDM *lcidm, + void *opaque, + const QUIC_CONN_ID *initial_odcid) +{ + QUIC_LCIDM_CONN *conn; + QUIC_LCID key, *lcid_obj; + + if (initial_odcid == NULL || initial_odcid->id_len < QUIC_MIN_ODCID_LEN + || initial_odcid->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + if (conn->done_odcid) + return 0; + + key.cid = *initial_odcid; + if (lh_QUIC_LCID_retrieve(lcidm->lcids, &key) != NULL) + return 0; + + if ((lcid_obj = lcidm_conn_new_lcid(lcidm, conn, initial_odcid)) == NULL) + return 0; + + lcid_obj->seq_num = LCIDM_ODCID_SEQ_NUM; + lcid_obj->type = LCID_TYPE_ODCID; + + conn->odcid_lcid_obj = lcid_obj; + conn->done_odcid = 1; + return 1; +} + +int ossl_quic_lcidm_generate_initial(QUIC_LCIDM *lcidm, + void *opaque, + QUIC_CONN_ID *initial_lcid) +{ + return lcidm_generate(lcidm, opaque, LCID_TYPE_INITIAL, + initial_lcid, NULL); +} + +int ossl_quic_lcidm_generate(QUIC_LCIDM *lcidm, + void *opaque, + OSSL_QUIC_FRAME_NEW_CONN_ID *ncid_frame) +{ + ncid_frame->seq_num = 0; + ncid_frame->retire_prior_to = 0; + + return lcidm_generate(lcidm, opaque, LCID_TYPE_NCID, + &ncid_frame->conn_id, + &ncid_frame->seq_num); +} + +int ossl_quic_lcidm_retire_odcid(QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN *conn; + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + if (conn->odcid_lcid_obj == NULL) + return 0; + + lcidm_delete_conn_lcid(lcidm, conn->odcid_lcid_obj); + conn->odcid_lcid_obj = NULL; + return 1; +} + +struct retire_args { + QUIC_LCID *earliest_seq_num_lcid_obj; + uint64_t earliest_seq_num, retire_prior_to; +}; + +static void retire_for_conn(QUIC_LCID *lcid_obj, void *arg) +{ + struct retire_args *args = arg; + + /* ODCID LCID cannot be retired via this API */ + if (lcid_obj->type == LCID_TYPE_ODCID + || lcid_obj->seq_num >= args->retire_prior_to) + return; + + if (lcid_obj->seq_num < args->earliest_seq_num) { + args->earliest_seq_num = lcid_obj->seq_num; + args->earliest_seq_num_lcid_obj = lcid_obj; + } +} + +int ossl_quic_lcidm_retire(QUIC_LCIDM *lcidm, + void *opaque, + uint64_t retire_prior_to, + const QUIC_CONN_ID *containing_pkt_dcid, + QUIC_CONN_ID *retired_lcid, + uint64_t *retired_seq_num, + int *did_retire) +{ + QUIC_LCIDM_CONN key, *conn; + struct retire_args args = {0}; + + key.opaque = opaque; + + if (did_retire == NULL) + return 0; + + *did_retire = 0; + if ((conn = lh_QUIC_LCIDM_CONN_retrieve(lcidm->conns, &key)) == NULL) + return 1; + + args.retire_prior_to = retire_prior_to; + args.earliest_seq_num = UINT64_MAX; + lh_QUIC_LCID_doall_arg(conn->lcids, retire_for_conn, &args); + if (args.earliest_seq_num_lcid_obj == NULL) + return 1; + + if (containing_pkt_dcid != NULL + && ossl_quic_conn_id_eq(&args.earliest_seq_num_lcid_obj->cid, + containing_pkt_dcid)) + return 0; + + *did_retire = 1; + if (retired_lcid != NULL) + *retired_lcid = args.earliest_seq_num_lcid_obj->cid; + if (retired_seq_num != NULL) + *retired_seq_num = args.earliest_seq_num_lcid_obj->seq_num; + + lcidm_delete_conn_lcid(lcidm, args.earliest_seq_num_lcid_obj); + return 1; +} + +int ossl_quic_lcidm_cull(QUIC_LCIDM *lcidm, void *opaque) +{ + QUIC_LCIDM_CONN key, *conn; + + key.opaque = opaque; + + if ((conn = lh_QUIC_LCIDM_CONN_retrieve(lcidm->conns, &key)) == NULL) + return 0; + + lcidm_delete_conn(lcidm, conn); + return 1; +} + +int ossl_quic_lcidm_lookup(QUIC_LCIDM *lcidm, + const QUIC_CONN_ID *lcid, + uint64_t *seq_num, + void **opaque) +{ + QUIC_LCID *lcid_obj; + + if (lcid == NULL) + return 0; + + if ((lcid_obj = lcidm_get0_lcid(lcidm, lcid)) == NULL) + return 0; + + if (seq_num != NULL) + *seq_num = lcid_obj->seq_num; + + if (opaque != NULL) + *opaque = lcid_obj->conn->opaque; + + return 1; +} + +int ossl_quic_lcidm_debug_remove(QUIC_LCIDM *lcidm, + const QUIC_CONN_ID *lcid) +{ + QUIC_LCID key, *lcid_obj; + + key.cid = *lcid; + if ((lcid_obj = lh_QUIC_LCID_retrieve(lcidm->lcids, &key)) == NULL) + return 0; + + lcidm_delete_conn_lcid(lcidm, lcid_obj); + return 1; +} + +int ossl_quic_lcidm_debug_add(QUIC_LCIDM *lcidm, void *opaque, + const QUIC_CONN_ID *lcid, + uint64_t seq_num) +{ + QUIC_LCIDM_CONN *conn; + QUIC_LCID key, *lcid_obj; + + if (lcid == NULL || lcid->id_len > QUIC_MAX_CONN_ID_LEN) + return 0; + + if ((conn = lcidm_upsert_conn(lcidm, opaque)) == NULL) + return 0; + + key.cid = *lcid; + if (lh_QUIC_LCID_retrieve(lcidm->lcids, &key) != NULL) + return 0; + + if ((lcid_obj = lcidm_conn_new_lcid(lcidm, conn, lcid)) == NULL) + return 0; + + lcid_obj->seq_num = seq_num; + lcid_obj->type = LCID_TYPE_NCID; + return 1; +} diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index b9858be9372958662acc745ebdd1ec4bd4ff7c42..0150589feae9b55e8aff2fcd903065337fbd6af4 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -340,8 +340,19 @@ static int dane_tlsa_add(SSL_DANE *dane, } if ((DANETLS_USAGE_BIT(usage) & DANETLS_TA_MASK) == 0) { + /* + * The Full(0) certificate decodes to a seemingly valid X.509 + * object with a plausible key, so the TLSA record is well + * formed. However, we don't actually need the certifiate for + * usages PKIX-EE(1) or DANE-EE(3), because at least the EE + * certificate is always presented by the peer. We discard the + * certificate, and just use the TLSA data as an opaque blob + * for matching the raw presented DER octets. + * + * DO NOT FREE `t` here, it will be added to the TLSA record + * list below! + */ X509_free(cert); - tlsa_free(t); break; } diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index e77ab2f3e50efd934e1557a8bb86c95604f1a59b..0a64ca2246987e24f5d8d0d848551417be02f72d 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -1393,8 +1393,7 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) * the client sent a key_share extension * AND * (we are not resuming - * OR (the kex_mode allows key_share resumes - * AND (kex_mode doesn't allow non-dh resumes OR non-dh is not preferred))) + * OR the kex_mode allows key_share resumes) * AND * a shared group exists * THEN @@ -1429,18 +1428,10 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) } } else { /* No suitable key_share */ - - /* Do DHE PSK? */ - int dhe_psk = - /* kex_mode allows key_share resume */ - (((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) != 0) - - /* and psk-only is not available or not explicitly preferred */ - && ((((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0) - || (s->options & SSL_OP_PREFER_NO_DHE_KEX) == 0))); - if (s->hello_retry_request == SSL_HRR_NONE && sent - && (!s->hit || dhe_psk)) { + && (!s->hit + || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) + != 0)) { const uint16_t *pgroups, *clntgroups; size_t num_groups, clnt_num_groups, i; unsigned int group_id = 0; diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 2d28ea3b3d70974af977da293cbc0377fb8e7b64..c4287bd853c1e776d73f029ded79f7572382ac4c 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -573,6 +573,21 @@ int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt, && (s->options & SSL_OP_ALLOW_NO_DHE_KEX) != 0) s->ext.psk_kex_mode |= TLSEXT_KEX_MODE_FLAG_KE; } + + if (((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) != 0) + && (s->options & SSL_OP_PREFER_NO_DHE_KEX) != 0) { + + /* + * If NO_DHE is supported and preferred, then we only remember this + * mode. DHE PSK will not be used for sure, because in any case where + * it would be supported (i.e. if a key share is present), NO_DHE would + * be supported as well. As the latter is preferred it would be + * choosen. By removing DHE PSK here, we don't have to deal with the + * SSL_OP_PREFER_NO_DHE_KEX option in any other place. + */ + s->ext.psk_kex_mode = TLSEXT_KEX_MODE_FLAG_KE; + } + #endif return 1; @@ -1645,25 +1660,15 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, } return EXT_RETURN_NOT_SENT; } - if (s->hit) { - /* PSK ('hit') */ + if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) { /* - * If we're doing PSK ('hit') but the client doesn't support psk-dhe, - * we don't need to send a key share. + * PSK ('hit') and explicitly not doing DHE. If the client sent the + * DHE option, we take it by default, except if non-DHE would be + * preferred by config, but this case would have been handled in + * tls_parse_ctos_psk_kex_modes(). */ - if ((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) - return EXT_RETURN_NOT_SENT; - - /* - * If both, psk_ke and psk_dh_ke are available, we do psk_dh_ke and - * send a key share by default, but not if the server is explicitly - * configured to prefer psk_ke. - */ - if (((s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) != 0) - && ((s->options & SSL_OP_PREFER_NO_DHE_KEX) != 0)) { - return EXT_RETURN_NOT_SENT; - } + return EXT_RETURN_NOT_SENT; } if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_key_share) diff --git a/test/build.info b/test/build.info index a71ee13d1f12457994ca0ecf689234b03ca44641..af43407611de7149415945badd6b48c4809a9fcf 100644 --- a/test/build.info +++ b/test/build.info @@ -63,7 +63,7 @@ IF[{- !$disabled{tests} -}] provfetchtest prov_config_test rand_test ca_internals_test \ bio_tfo_test membio_test bio_dgram_test list_test fips_version_test \ x509_test hpke_test pairwise_fail_test nodefltctxtest \ - evp_xof_test + evp_xof_test x509_load_cert_file_test IF[{- !$disabled{'rpk'} -}] PROGRAMS{noinst}=rpktest @@ -191,6 +191,14 @@ IF[{- !$disabled{tests} -}] SOURCE[evp_extra_test]=evp_extra_test.c fake_rsaprov.c INCLUDE[evp_extra_test]=../include ../apps/include DEPEND[evp_extra_test]=../libcrypto.a libtestutil.a + IF[{- !$disabled{module} && !$disabled{legacy} -}] + DEFINE[evp_extra_test]=STATIC_LEGACY + SOURCE[evp_extra_test]=../providers/legacyprov.c + INCLUDE[evp_extra_test]=../providers/common/include \ + ../providers/implementations/include + DEPEND[evp_extra_test]=../providers/liblegacy.a \ + ../providers/libcommon.a + ENDIF SOURCE[hpke_test]=hpke_test.c INCLUDE[hpke_test]=../include ../apps/include @@ -332,6 +340,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[quic_srtm_test]=../include ../apps/include DEPEND[quic_srtm_test]=../libcrypto.a ../libssl.a libtestutil.a + SOURCE[quic_lcidm_test]=quic_lcidm_test.c + INCLUDE[quic_lcidm_test]=../include ../apps/include + DEPEND[quic_lcidm_test]=../libcrypto.a ../libssl.a libtestutil.a + SOURCE[quic_fifd_test]=quic_fifd_test.c cc_dummy.c INCLUDE[quic_fifd_test]=../include ../apps/include DEPEND[quic_fifd_test]=../libcrypto.a ../libssl.a libtestutil.a @@ -595,6 +607,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[x509_dup_cert_test]=../include ../apps/include DEPEND[x509_dup_cert_test]=../libcrypto libtestutil.a + SOURCE[x509_load_cert_file_test]=x509_load_cert_file_test.c + INCLUDE[x509_load_cert_file_test]=../include ../apps/include + DEPEND[x509_load_cert_file_test]=../libcrypto libtestutil.a + SOURCE[x509_check_cert_pkey_test]=x509_check_cert_pkey_test.c INCLUDE[x509_check_cert_pkey_test]=../include ../apps/include DEPEND[x509_check_cert_pkey_test]=../libcrypto libtestutil.a @@ -1038,6 +1054,13 @@ IF[{- !$disabled{tests} -}] SOURCE[p_test]=p_test.ld GENERATE[p_test.ld]=../util/providers.num ENDIF + MODULES{noinst}=p_minimal + SOURCE[p_minimal]=p_minimal.c + INCLUDE[p_minimal]=../include .. + IF[{- defined $target{shared_defflag} -}] + SOURCE[p_minimal]=p_minimal.ld + GENERATE[p_minimal.ld]=../util/providers.num + ENDIF ENDIF IF[{- $disabled{module} || !$target{dso_scheme} -}] DEFINE[provider_test]=NO_PROVIDER_MODULE @@ -1137,7 +1160,7 @@ ENDIF IF[{- !$disabled{'quic'} -}] PROGRAMS{noinst}=quic_wire_test quic_ackm_test quic_record_test PROGRAMS{noinst}=quic_fc_test quic_stream_test quic_cfq_test quic_txpim_test - PROGRAMS{noinst}=quic_srtm_test + PROGRAMS{noinst}=quic_srtm_test quic_lcidm_test PROGRAMS{noinst}=quic_fifd_test quic_txp_test quic_tserver_test PROGRAMS{noinst}=quic_client_test quic_cc_test quic_multistream_test ENDIF diff --git a/test/cmp_ctx_test.c b/test/cmp_ctx_test.c index 137f67331b068386107b2f9099d74a47c16e2f7c..f38493b33445c5a16c1773139a515ae77f6599eb 100644 --- a/test/cmp_ctx_test.c +++ b/test/cmp_ctx_test.c @@ -405,6 +405,7 @@ execute_CTX_##SETN##_##GETN##_##FIELD(OSSL_CMP_CTX_TEST_FIXTURE *fixture) \ } else { \ if (DUP && val1_read == val1) { \ TEST_error("first set did not dup the value"); \ + val1_read = 0; \ res = 0; \ } \ if (DEFAULT(val1_read)) { \ @@ -433,6 +434,7 @@ execute_CTX_##SETN##_##GETN##_##FIELD(OSSL_CMP_CTX_TEST_FIXTURE *fixture) \ } else { \ if (DUP && val2_read == val2) { \ TEST_error("second set did not dup the value"); \ + val2_read = 0; \ res = 0; \ } \ if (val2 == val1) { \ @@ -462,6 +464,7 @@ execute_CTX_##SETN##_##GETN##_##FIELD(OSSL_CMP_CTX_TEST_FIXTURE *fixture) \ } else { \ if (DUP && val3_read == val2_read) { \ TEST_error("third get did not create a new dup"); \ + val3_read = 0; \ res = 0; \ } \ } \ diff --git a/test/danetest.in b/test/danetest.in index 118da21e75c3eec6deb1e7661a5868be83461c8b..e7aa8c6aba56fe67c14970d37d60f8b37a83bd00 100644 --- a/test/danetest.in +++ b/test/danetest.in @@ -50,7 +50,7 @@ # 1 1 1 1 0 0 -3 0 1 588FD5F414E3327EAFE3169DC040AE161247D1296BF38304AB9CF464850A1365 +3 0 0 3081ec308193a003020102020101300a06082a8648ce3d0403023000301e170d3135313231343030313033345a170d3135313231333030313033345a30003059301306072a8648ce3d020106082a8648ce3d03010703420004c5a4ffa008eebc0369b974799f9479cb47360544fafc02c4204fb3df31e88a1a4f18c85831e93f985c5b231094541b4316b5cb1c9c0c950886fe1143f39f6109300a06082a8648ce3d040302034800304502206ae7b7a870df21081e9a9896020aaf8560984875c812b36d671631abc879f872022100b0889ad2b3814ee64bddd5a7f6a98dea43cb435049469cb50a4404cbdeee1fd6 subject= issuer= notBefore=Dec 14 00:10:34 2015 GMT @@ -65,7 +65,7 @@ yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= # 2 1 1 1 0 0 -3 1 1 05C66146D7909EAE2379825F6D0F5284146B79598DA12E403DC29C33147CF33E +3 1 0 3059301306072a8648ce3d020106082a8648ce3d03010703420004c5a4ffa008eebc0369b974799f9479cb47360544fafc02c4204fb3df31e88a1a4f18c85831e93f985c5b231094541b4316b5cb1c9c0c950886fe1143f39f6109 subject= issuer= notBefore=Dec 14 00:10:34 2015 GMT @@ -80,7 +80,7 @@ yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= # 3 1 1 1 0 0 -3 0 2 42BEE929852C8063A0D619B53D0DD35703BBAD2FC25F2055F737C7A14DDFEA544491F8C00F50FA083BD0AD1B5C98529994FF811BBA5E5170CC6EE9F3ED5563E1 +3 0 1 588FD5F414E3327EAFE3169DC040AE161247D1296BF38304AB9CF464850A1365 subject= issuer= notBefore=Dec 14 00:10:34 2015 GMT @@ -95,7 +95,7 @@ yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= # 4 1 1 1 0 0 -3 1 2 D91A3E5DC34879CD77AD1E989F56FA78FACADF05EF8D445EDF5652BD58EE392C87C02F84C0119D62309041F2D5128A73399DF25D1F47BCD497357EAF1A1009A3 +3 1 1 05C66146D7909EAE2379825F6D0F5284146B79598DA12E403DC29C33147CF33E subject= issuer= notBefore=Dec 14 00:10:34 2015 GMT @@ -109,6 +109,36 @@ yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= -----END CERTIFICATE----- # 5 +1 1 1 0 0 +3 0 2 42BEE929852C8063A0D619B53D0DD35703BBAD2FC25F2055F737C7A14DDFEA544491F8C00F50FA083BD0AD1B5C98529994FF811BBA5E5170CC6EE9F3ED5563E1 +subject= +issuer= +notBefore=Dec 14 00:10:34 2015 GMT +notAfter=Dec 13 00:10:34 2015 GMT +-----BEGIN CERTIFICATE----- +MIHsMIGToAMCAQICAQEwCgYIKoZIzj0EAwIwADAeFw0xNTEyMTQwMDEwMzRaFw0x +NTEyMTMwMDEwMzRaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATFpP+gCO68 +A2m5dHmflHnLRzYFRPr8AsQgT7PfMeiKGk8YyFgx6T+YXFsjEJRUG0MWtcscnAyV +CIb+EUPzn2EJMAoGCCqGSM49BAMCA0gAMEUCIGrnt6hw3yEIHpqYlgIKr4VgmEh1 +yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= +-----END CERTIFICATE----- + +# 6 +1 1 1 0 0 +3 1 2 D91A3E5DC34879CD77AD1E989F56FA78FACADF05EF8D445EDF5652BD58EE392C87C02F84C0119D62309041F2D5128A73399DF25D1F47BCD497357EAF1A1009A3 +subject= +issuer= +notBefore=Dec 14 00:10:34 2015 GMT +notAfter=Dec 13 00:10:34 2015 GMT +-----BEGIN CERTIFICATE----- +MIHsMIGToAMCAQICAQEwCgYIKoZIzj0EAwIwADAeFw0xNTEyMTQwMDEwMzRaFw0x +NTEyMTMwMDEwMzRaMAAwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATFpP+gCO68 +A2m5dHmflHnLRzYFRPr8AsQgT7PfMeiKGk8YyFgx6T+YXFsjEJRUG0MWtcscnAyV +CIb+EUPzn2EJMAoGCCqGSM49BAMCA0gAMEUCIGrnt6hw3yEIHpqYlgIKr4VgmEh1 +yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= +-----END CERTIFICATE----- + +# 7 1 1 1 65 -1 3 0 1 588FD5F414E3327EAFE3169DC040AE161247D1296BF38304AB9CF464850A1366 subject= @@ -123,7 +153,7 @@ CIb+EUPzn2EJMAoGCCqGSM49BAMCA0gAMEUCIGrnt6hw3yEIHpqYlgIKr4VgmEh1 yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= -----END CERTIFICATE----- -# 6 +# 8 1 1 1 65 -1 3 1 1 05C66146D7909EAE2379825F6D0F5284146B79598DA12E403DC29C33147CF33F subject= @@ -138,7 +168,7 @@ CIb+EUPzn2EJMAoGCCqGSM49BAMCA0gAMEUCIGrnt6hw3yEIHpqYlgIKr4VgmEh1 yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= -----END CERTIFICATE----- -# 7 +# 9 1 1 1 65 -1 3 0 2 42BEE929852C8063A0D619B53D0DD35703BBAD2FC25F2055F737C7A14DDFEA544491F8C00F50FA083BD0AD1B5C98529994FF811BBA5E5170CC6EE9F3ED5563E2 subject= @@ -153,7 +183,7 @@ CIb+EUPzn2EJMAoGCCqGSM49BAMCA0gAMEUCIGrnt6hw3yEIHpqYlgIKr4VgmEh1 yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= -----END CERTIFICATE----- -# 8 +# 10 1 1 1 65 -1 3 1 2 D91A3E5DC34879CD77AD1E989F56FA78FACADF05EF8D445EDF5652BD58EE392C87C02F84C0119D62309041F2D5128A73399DF25D1F47BCD497357EAF1A1009A4 subject= @@ -170,7 +200,7 @@ yBKzbWcWMavIefhyAiEAsIia0rOBTuZL3dWn9qmN6kPLQ1BJRpy1CkQEy97uH9Y= ## -- DANE-?? chain tests -- -# 9 +# 11 1 3 0 0 0 3 0 1 BEDC04764CECAE80AEE454D332758F50847DCA424216466E4012E0DEAE1F2E5F subject= /CN=example.com @@ -217,7 +247,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 10 +# 12 1 3 0 0 0 3 1 1 3111668338043DE264D0256A702248696C9484B6221A42740F920187B4C61838 subject= /CN=example.com @@ -264,7 +294,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 11 +# 13 1 3 0 0 0 3 0 2 F756CCD61F3CA50D017653911701CA0052AF0B29E273DD263DD23643D86D4369D03686BD1369EF54BB2DC2DAE3CE4F05AF39D54648F94D54AA86B259AEAD9923 subject= /CN=example.com @@ -311,7 +341,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 12 +# 14 1 3 0 0 0 3 1 2 CB861AF6DDED185EE04472A9092052CCC735120C34785E72C996C94B122EBA6F329BE630B1B4C6E2756E7A75392C21E253C6AEACC31FD45FF4595DED375FAF62 subject= /CN=example.com @@ -358,7 +388,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 13 +# 15 1 3 0 0 1 2 0 1 0DAA76425A1FC398C55A643D5A2485AE4CC2B64B9515A75054722B2E83C31BBD subject= /CN=example.com @@ -405,7 +435,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 14 +# 16 1 3 0 0 1 2 1 1 65A457617072DA3E7F1152471EB3D406526530097D0A9AA34EB47C990A1FCDA3 subject= /CN=example.com @@ -452,7 +482,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 15 +# 17 1 3 0 0 1 2 0 2 6BC0C0F2500320A49392910965263A3EBDD594173D3E36CCE38A003D2EC3FAFBC315EDB776CD3139637DF494FB60359601542A4F821BF0542F926E6270C9762C subject= /CN=example.com @@ -499,7 +529,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 16 +# 18 1 3 0 0 1 2 1 2 1F484106F765B6F1AC483CC509CDAD36486A83D1BA115F562516F407C1109303658408B455824DA0785A252B205DBEECB1AFB5DB869E8AAC242091B63F258F05 subject= /CN=example.com @@ -546,7 +576,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 17 +# 19 1 3 0 0 2 2 0 1 FE7C8E01110627A782765E468D8CB4D2CC7907EAC4BA5974CD92B540ED2AAC3C subject= /CN=example.com @@ -593,7 +623,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 18 +# 20 1 3 0 0 2 2 1 1 91D942E4A2D4226DDAF28CADAA7F13018E4ED0D9A43A529247E51C965188576C subject= /CN=example.com @@ -640,7 +670,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 19 +# 21 1 3 0 0 2 2 0 2 361029F20A3B59DAFAAF05D41811EFC1A9439B972BC6B9D7F13BC5469570E49ACAE0CB0C877C75D58346590EA950AC7A39AED6E8AA8004EA7F5DE3AB9462047E subject= /CN=example.com @@ -687,7 +717,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 20 +# 22 1 3 0 0 2 2 1 2 5F414D4D7BFDF22E39952D9F46C51370FDD050F10C55B4CDB42E40FA98611FDE23EEE9B23315EE1ECDB198C7419E9A2D6742860E4806AF45164507799C3B452E subject= /CN=example.com @@ -736,7 +766,73 @@ vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF ## -- PKIX-?? chain tests -- -# 21 +# 23 +1 2 0 0 0 +1 0 0 308201943082013ba003020102020102300a06082a8648ce3d04030230143112301006035504030c094973737565722043413020170d3135313231333233323335325a180f33303135303431353233323335325a30163114301206035504030c0b6578616d706c652e636f6d3059301306072a8648ce3d020106082a8648ce3d03010703420004664995f47bde35e7b4de48b258e9e8a07adebbdb863b3d06f481a1946c83da9f56cff4d9389b855d2f364b1585b0c734fcfa263026964ff5a4308b3fc879bdb8a37a3078301d0603551d0e041604145b20ca417d9088c7a4c017cb6c0c1c739bb07d8a301f0603551d230418301680147ab75a3cd295ca5df7c5150916e18ff5cc376a1530090603551d130402300030130603551d25040c300a06082b0601050507030130160603551d11040f300d820b6578616d706c652e636f6d300a06082a8648ce3d0403020347003044021f21c9032a5c8a93872d3f4aef321a9574dd956d43bd93c369944c72d6902858022100c8b3290d7af37e571a84d704dbad339d2987d41852dc5936f212947063911181 +subject= /CN=example.com +issuer= /CN=Issuer CA +notBefore=Dec 13 23:23:52 2015 GMT +notAfter=Apr 15 23:23:52 3015 GMT +-----BEGIN CERTIFICATE----- +MIIBlDCCATugAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDDAlJc3N1ZXIg +Q0EwIBcNMTUxMjEzMjMyMzUyWhgPMzAxNTA0MTUyMzIzNTJaMBYxFDASBgNVBAMM +C2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZkmV9HveNee0 +3kiyWOnooHreu9uGOz0G9IGhlGyD2p9Wz/TZOJuFXS82SxWFsMc0/PomMCaWT/Wk +MIs/yHm9uKN6MHgwHQYDVR0OBBYEFFsgykF9kIjHpMAXy2wMHHObsH2KMB8GA1Ud +IwQYMBaAFHq3WjzSlcpd98UVCRbhj/XMN2oVMAkGA1UdEwQCMAAwEwYDVR0lBAww +CgYIKwYBBQUHAwEwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wCgYIKoZIzj0EAwID +RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X +GoTXBNutM50ph9QYUtxZNvISlHBjkRGB +-----END CERTIFICATE----- +subject= /CN=Issuer CA +issuer= /CN=Root CA +notBefore=Dec 13 23:20:09 2015 GMT +notAfter=Apr 15 23:20:09 3015 GMT +-----BEGIN CERTIFICATE----- +MIIBaDCCAQ2gAwIBAgIBAjAKBggqhkjOPQQDAjASMRAwDgYDVQQDDAdSb290IENB +MCAXDTE1MTIxMzIzMjAwOVoYDzMwMTUwNDE1MjMyMDA5WjAUMRIwEAYDVQQDDAlJ +c3N1ZXIgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR9S64YtJ9dxp0KPIXG +aj4hGd6Sz60IH61VwS1RDsl7bADhNpWo2XE1SP5g3xVXM5BDPiob2S20t6oBbsYY +XcWvo1AwTjAdBgNVHQ4EFgQUerdaPNKVyl33xRUJFuGP9cw3ahUwHwYDVR0jBBgw +FoAU5L1AXwUqgg3fmIP5PX0/kKrscj8wDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQD +AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 +GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== +-----END CERTIFICATE----- + +# 24 +1 2 0 0 0 +1 1 0 3059301306072a8648ce3d020106082a8648ce3d03010703420004664995f47bde35e7b4de48b258e9e8a07adebbdb863b3d06f481a1946c83da9f56cff4d9389b855d2f364b1585b0c734fcfa263026964ff5a4308b3fc879bdb8 +subject= /CN=example.com +issuer= /CN=Issuer CA +notBefore=Dec 13 23:23:52 2015 GMT +notAfter=Apr 15 23:23:52 3015 GMT +-----BEGIN CERTIFICATE----- +MIIBlDCCATugAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDDAlJc3N1ZXIg +Q0EwIBcNMTUxMjEzMjMyMzUyWhgPMzAxNTA0MTUyMzIzNTJaMBYxFDASBgNVBAMM +C2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZkmV9HveNee0 +3kiyWOnooHreu9uGOz0G9IGhlGyD2p9Wz/TZOJuFXS82SxWFsMc0/PomMCaWT/Wk +MIs/yHm9uKN6MHgwHQYDVR0OBBYEFFsgykF9kIjHpMAXy2wMHHObsH2KMB8GA1Ud +IwQYMBaAFHq3WjzSlcpd98UVCRbhj/XMN2oVMAkGA1UdEwQCMAAwEwYDVR0lBAww +CgYIKwYBBQUHAwEwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wCgYIKoZIzj0EAwID +RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X +GoTXBNutM50ph9QYUtxZNvISlHBjkRGB +-----END CERTIFICATE----- +subject= /CN=Issuer CA +issuer= /CN=Root CA +notBefore=Dec 13 23:20:09 2015 GMT +notAfter=Apr 15 23:20:09 3015 GMT +-----BEGIN CERTIFICATE----- +MIIBaDCCAQ2gAwIBAgIBAjAKBggqhkjOPQQDAjASMRAwDgYDVQQDDAdSb290IENB +MCAXDTE1MTIxMzIzMjAwOVoYDzMwMTUwNDE1MjMyMDA5WjAUMRIwEAYDVQQDDAlJ +c3N1ZXIgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR9S64YtJ9dxp0KPIXG +aj4hGd6Sz60IH61VwS1RDsl7bADhNpWo2XE1SP5g3xVXM5BDPiob2S20t6oBbsYY +XcWvo1AwTjAdBgNVHQ4EFgQUerdaPNKVyl33xRUJFuGP9cw3ahUwHwYDVR0jBBgw +FoAU5L1AXwUqgg3fmIP5PX0/kKrscj8wDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQD +AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 +GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== +-----END CERTIFICATE----- + +# 25 1 2 0 0 0 1 0 1 BEDC04764CECAE80AEE454D332758F50847DCA424216466E4012E0DEAE1F2E5F subject= /CN=example.com @@ -769,7 +865,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 22 +# 26 1 2 0 0 0 1 1 1 3111668338043DE264D0256A702248696C9484B6221A42740F920187B4C61838 subject= /CN=example.com @@ -802,7 +898,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 23 +# 27 1 3 0 0 0 1 0 2 F756CCD61F3CA50D017653911701CA0052AF0B29E273DD263DD23643D86D4369D03686BD1369EF54BB2DC2DAE3CE4F05AF39D54648F94D54AA86B259AEAD9923 subject= /CN=example.com @@ -849,7 +945,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 24 +# 28 1 3 0 0 0 1 1 2 CB861AF6DDED185EE04472A9092052CCC735120C34785E72C996C94B122EBA6F329BE630B1B4C6E2756E7A75392C21E253C6AEACC31FD45FF4595DED375FAF62 subject= /CN=example.com @@ -896,7 +992,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 25 +# 29 1 2 0 0 1 0 0 1 0DAA76425A1FC398C55A643D5A2485AE4CC2B64B9515A75054722B2E83C31BBD subject= /CN=example.com @@ -929,7 +1025,40 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 26 +# 30 +1 2 0 0 1 +0 1 0 3059301306072a8648ce3d020106082a8648ce3d030107034200047d4bae18b49f5dc69d0a3c85c66a3e2119de92cfad081fad55c12d510ec97b6c00e13695a8d9713548fe60df15573390433e2a1bd92db4b7aa016ec6185dc5af +subject= /CN=example.com +issuer= /CN=Issuer CA +notBefore=Dec 13 23:23:52 2015 GMT +notAfter=Apr 15 23:23:52 3015 GMT +-----BEGIN CERTIFICATE----- +MIIBlDCCATugAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDDAlJc3N1ZXIg +Q0EwIBcNMTUxMjEzMjMyMzUyWhgPMzAxNTA0MTUyMzIzNTJaMBYxFDASBgNVBAMM +C2V4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZkmV9HveNee0 +3kiyWOnooHreu9uGOz0G9IGhlGyD2p9Wz/TZOJuFXS82SxWFsMc0/PomMCaWT/Wk +MIs/yHm9uKN6MHgwHQYDVR0OBBYEFFsgykF9kIjHpMAXy2wMHHObsH2KMB8GA1Ud +IwQYMBaAFHq3WjzSlcpd98UVCRbhj/XMN2oVMAkGA1UdEwQCMAAwEwYDVR0lBAww +CgYIKwYBBQUHAwEwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wCgYIKoZIzj0EAwID +RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X +GoTXBNutM50ph9QYUtxZNvISlHBjkRGB +-----END CERTIFICATE----- +subject= /CN=Issuer CA +issuer= /CN=Root CA +notBefore=Dec 13 23:20:09 2015 GMT +notAfter=Apr 15 23:20:09 3015 GMT +-----BEGIN CERTIFICATE----- +MIIBaDCCAQ2gAwIBAgIBAjAKBggqhkjOPQQDAjASMRAwDgYDVQQDDAdSb290IENB +MCAXDTE1MTIxMzIzMjAwOVoYDzMwMTUwNDE1MjMyMDA5WjAUMRIwEAYDVQQDDAlJ +c3N1ZXIgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR9S64YtJ9dxp0KPIXG +aj4hGd6Sz60IH61VwS1RDsl7bADhNpWo2XE1SP5g3xVXM5BDPiob2S20t6oBbsYY +XcWvo1AwTjAdBgNVHQ4EFgQUerdaPNKVyl33xRUJFuGP9cw3ahUwHwYDVR0jBBgw +FoAU5L1AXwUqgg3fmIP5PX0/kKrscj8wDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQD +AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 +GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== +-----END CERTIFICATE----- + +# 31 1 2 0 0 1 0 1 1 65A457617072DA3E7F1152471EB3D406526530097D0A9AA34EB47C990A1FCDA3 subject= /CN=example.com @@ -962,7 +1091,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 27 +# 32 1 3 0 0 1 0 0 2 6BC0C0F2500320A49392910965263A3EBDD594173D3E36CCE38A003D2EC3FAFBC315EDB776CD3139637DF494FB60359601542A4F821BF0542F926E6270C9762C subject= /CN=example.com @@ -1009,7 +1138,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 28 +# 33 1 3 0 0 1 0 1 2 1F484106F765B6F1AC483CC509CDAD36486A83D1BA115F562516F407C1109303658408B455824DA0785A252B205DBEECB1AFB5DB869E8AAC242091B63F258F05 subject= /CN=example.com @@ -1056,7 +1185,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 29 +# 34 1 2 0 0 2 0 0 1 FE7C8E01110627A782765E468D8CB4D2CC7907EAC4BA5974CD92B540ED2AAC3C subject= /CN=example.com @@ -1089,7 +1218,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 30 +# 35 1 2 0 0 2 0 1 1 91D942E4A2D4226DDAF28CADAA7F13018E4ED0D9A43A529247E51C965188576C subject= /CN=example.com @@ -1122,7 +1251,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 31 +# 36 1 3 0 0 2 0 0 2 361029F20A3B59DAFAAF05D41811EFC1A9439B972BC6B9D7F13BC5469570E49ACAE0CB0C877C75D58346590EA950AC7A39AED6E8AA8004EA7F5DE3AB9462047E subject= /CN=example.com @@ -1169,7 +1298,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 32 +# 37 1 3 0 0 2 0 1 2 5F414D4D7BFDF22E39952D9F46C51370FDD050F10C55B4CDB42E40FA98611FDE23EEE9B23315EE1ECDB198C7419E9A2D6742860E4806AF45164507799C3B452E subject= /CN=example.com @@ -1218,7 +1347,7 @@ vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF ## -- PKIX-?? chain failures -- -# 33 +# 38 # Missing intermediate CA 1 1 0 20 0 1 0 1 BEDC04764CECAE80AEE454D332758F50847DCA424216466E4012E0DEAE1F2E5F @@ -1238,7 +1367,7 @@ RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X GoTXBNutM50ph9QYUtxZNvISlHBjkRGB -----END CERTIFICATE----- -# 34 +# 39 # Missing PKIX intermediate, provided via DNS 2 1 0 0 0 1 1 1 3111668338043DE264D0256A702248696C9484B6221A42740F920187B4C61838 @@ -1259,7 +1388,7 @@ RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X GoTXBNutM50ph9QYUtxZNvISlHBjkRGB -----END CERTIFICATE----- -# 35 +# 40 # Wrong leaf digest 1 3 0 65 -1 1 0 2 F756CCD61F3CA50D017653911701CA0052AF0B29E273DD263DD23643D86D4369D03686BD1369EF54BB2DC2DAE3CE4F05AF39D54648F94D54AA86B259AEAD9924 @@ -1307,7 +1436,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 36 +# 41 # Wrong intermediate digest 1 2 0 65 -1 0 0 1 0DAA76425A1FC398C55A643D5A2485AE4CC2B64B9515A75054722B2E83C31BBE @@ -1341,7 +1470,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 37 +# 42 # Wrong root digest 1 2 0 65 -1 0 0 1 FE7C8E01110627A782765E468D8CB4D2CC7907EAC4BA5974CD92B540ED2AAC3D @@ -1377,7 +1506,7 @@ GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== ## -- Mixed usage cases -# 38 +# 43 # DANE-EE(3) beats DANE-TA(2) 1 3 0 0 0 3 1 2 CB861AF6DDED185EE04472A9092052CCC735120C34785E72C996C94B122EBA6F329BE630B1B4C6E2756E7A75392C21E253C6AEACC31FD45FF4595DED375FAF62 @@ -1426,7 +1555,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 39 +# 44 # DANE-TA(2) depth 1 beats DANE-TA(2) depth 2 1 3 0 0 1 2 1 2 1F484106F765B6F1AC483CC509CDAD36486A83D1BA115F562516F407C1109303658408B455824DA0785A252B205DBEECB1AFB5DB869E8AAC242091B63F258F05 @@ -1475,7 +1604,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 40 +# 45 # DANE-TA(2) depth 2 beats PKIX-TA(0) depth 1 1 3 0 0 2 2 0 1 FE7C8E01110627A782765E468D8CB4D2CC7907EAC4BA5974CD92B540ED2AAC3C @@ -1524,7 +1653,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 41 +# 46 # DANE-TA(2) depth 2 beats PKIX-EE depth 0 1 3 0 0 2 2 0 1 FE7C8E01110627A782765E468D8CB4D2CC7907EAC4BA5974CD92B540ED2AAC3C @@ -1573,7 +1702,7 @@ RwAwRAIgaGnmqp+bTUvzCAkaWnqyww42GbDXXlKIGUaOS7km9MkCIBfxuEWGEZZv vBCcrtNYKWa/JfwFmOq6bHk8WNzDU3zF -----END CERTIFICATE----- -# 42 +# 47 # DANE-TA(2) Full(0) root "from DNS": 1 2 0 0 2 2 0 0 308201643082010BA003020102020101300A06082A8648CE3D04030230123110300E06035504030C07526F6F742043413020170D3135313231333233313330385A180F33303135303431353233313330385A30123110300E06035504030C07526F6F742043413059301306072A8648CE3D020106082A8648CE3D03010703420004D1DA578FD18FB86456B0D91B5656BDD68D4DDBD250E337571127C75E0560F41D0AF91BFAF8805F80C28C026A14D4FE8C30A9673B9EC0C05A84AA810D1341B76CA350304E301D0603551D0E04160414E4BD405F052A820DDF9883F93D7D3F90AAEC723F301F0603551D23041830168014E4BD405F052A820DDF9883F93D7D3F90AAEC723F300C0603551D13040530030101FF300A06082A8648CE3D040302034700304402206869E6AA9F9B4D4BF308091A5A7AB2C30E3619B0D75E528819468E4BB926F4C9022017F1B8458611966FBC109CAED3582966BF25FC0598EABA6C793C58DCC3537CC5 @@ -1607,7 +1736,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 43 +# 48 # DANE-TA(2) Full(0) intermediate "from DNS": 1 1 0 0 1 2 0 0 308201683082010DA003020102020102300A06082A8648CE3D04030230123110300E06035504030C07526F6F742043413020170D3135313231333233323030395A180F33303135303431353233323030395A30143112301006035504030C094973737565722043413059301306072A8648CE3D020106082A8648CE3D030107034200047D4BAE18B49F5DC69D0A3C85C66A3E2119DE92CFAD081FAD55C12D510EC97B6C00E13695A8D9713548FE60DF15573390433E2A1BD92DB4B7AA016EC6185DC5AFA350304E301D0603551D0E041604147AB75A3CD295CA5DF7C5150916E18FF5CC376A15301F0603551D23041830168014E4BD405F052A820DDF9883F93D7D3F90AAEC723F300C0603551D13040530030101FF300A06082A8648CE3D0403020349003046022100831DCD882DA8785D50E41020898C0248879DDDF72D701D1DC1DE6BE08155B43E022100B84B2FB519C4CD3CBC791603D4488F7707597DB7980D9C173E7FDD0ECD7CA308 @@ -1627,7 +1756,7 @@ RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X GoTXBNutM50ph9QYUtxZNvISlHBjkRGB -----END CERTIFICATE----- -# 44 +# 49 # DANE-TA(2) SPKI(1) Full(0) intermediate "from DNS": 1 1 0 0 0 2 1 0 3059301306072A8648CE3D020106082A8648CE3D030107034200047D4BAE18B49F5DC69D0A3C85C66A3E2119DE92CFAD081FAD55C12D510EC97B6C00E13695A8D9713548FE60DF15573390433E2A1BD92DB4B7AA016EC6185DC5AF @@ -1647,7 +1776,7 @@ RwAwRAIfIckDKlyKk4ctP0rvMhqVdN2VbUO9k8NplExy1pAoWAIhAMizKQ16835X GoTXBNutM50ph9QYUtxZNvISlHBjkRGB -----END CERTIFICATE----- -# 45 +# 50 # DANE-TA(2) SPKI(1) Full(0) root "from DNS": 1 2 0 0 1 2 1 0 3059301306072A8648CE3D020106082A8648CE3D03010703420004D1DA578FD18FB86456B0D91B5656BDD68D4DDBD250E337571127C75E0560F41D0AF91BFAF8805F80C28C026A14D4FE8C30A9673B9EC0C05A84AA810D1341B76C @@ -1681,7 +1810,7 @@ AgNJADBGAiEAgx3NiC2oeF1Q5BAgiYwCSIed3fctcB0dwd5r4IFVtD4CIQC4Sy+1 GcTNPLx5FgPUSI93B1l9t5gNnBc+f90OzXyjCA== -----END CERTIFICATE----- -# 46 +# 51 # Mismatched name "example.org", should still succeed given a # DANE-EE(3) match. 1 3 1 0 0 @@ -1730,7 +1859,7 @@ AgNJADBGAiEAumhPWZ37swl10awM/amX+jv0UlUyJBf8RGA6QMG5bwICIQDbinER fEevg+GOsr1P6nNMCAsQd9NwsvTQ+jm+TBArWQ== -----END CERTIFICATE----- -# 47 +# 52 # Mismatched name "example.org", should fail despite a DANE-TA(2) # match for the intermediate CA. 1 3 0 62 1 @@ -1779,7 +1908,7 @@ AgNJADBGAiEAumhPWZ37swl10awM/amX+jv0UlUyJBf8RGA6QMG5bwICIQDbinER fEevg+GOsr1P6nNMCAsQd9NwsvTQ+jm+TBArWQ== -----END CERTIFICATE----- -# 48 +# 53 # Mismatched name "example.org", should fail despite a DANE-TA(2) # match for the root CA. 1 3 0 62 2 @@ -1828,7 +1957,7 @@ AgNJADBGAiEAumhPWZ37swl10awM/amX+jv0UlUyJBf8RGA6QMG5bwICIQDbinER fEevg+GOsr1P6nNMCAsQd9NwsvTQ+jm+TBArWQ== -----END CERTIFICATE----- -# 49 +# 54 # Mismatched name "example.org", should fail when name checks # are not disabled for DANE-EE(3). 1 3 0 62 0 diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 42506303274a64b168c8378e82a9b91cf4840467..f3680a0fb4d95e6e4c150d57e209afd27c2c4d00 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -38,6 +38,10 @@ #include "crypto/evp.h" #include "fake_rsaprov.h" +#ifdef STATIC_LEGACY +OSSL_provider_init_fn ossl_legacy_provider_init; +#endif + static OSSL_LIB_CTX *testctx = NULL; static char *testpropq = NULL; @@ -5437,6 +5441,15 @@ int setup_tests(void) testctx = OSSL_LIB_CTX_new(); if (!TEST_ptr(testctx)) return 0; +#ifdef STATIC_LEGACY + /* + * This test is always statically linked against libcrypto. We must not + * attempt to load legacy.so that might be dynamically linked against + * libcrypto. Instead we use a built-in version of the legacy provider. + */ + if (!OSSL_PROVIDER_add_builtin(testctx, "legacy", ossl_legacy_provider_init)) + return 0; +#endif /* Swap the libctx to test non-default context only */ nullprov = OSSL_PROVIDER_load(NULL, "null"); deflprov = OSSL_PROVIDER_load(testctx, "default"); diff --git a/test/evp_test.c b/test/evp_test.c index d74da09616c502702512111e9649564326f0285f..cef7b1b9e83bcf7dc7082314528d7a94012609b7 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -1514,6 +1514,7 @@ static int mac_test_run_mac(EVP_TEST *t) EVP_MAC_CTX *ctx = NULL; unsigned char *got = NULL; size_t got_len = 0, size = 0; + size_t size_before_init, size_after_init, size_val = 0; int i, block_size = -1, output_size = -1; OSSL_PARAM params[21], sizes[3], *psizes = sizes; size_t params_n = 0; @@ -1610,6 +1611,9 @@ static int mac_test_run_mac(EVP_TEST *t) } params_n++; + if (strcmp(tmpkey, "size") == 0) + size_val = (size_t)strtoul(tmpval, NULL, 0); + OPENSSL_free(tmpkey); } params[params_n] = OSSL_PARAM_construct_end(); @@ -1618,11 +1622,28 @@ static int mac_test_run_mac(EVP_TEST *t) t->err = "MAC_CREATE_ERROR"; goto err; } - + size_before_init = EVP_MAC_CTX_get_mac_size(ctx); if (!EVP_MAC_init(ctx, expected->key, expected->key_len, params)) { t->err = "MAC_INIT_ERROR"; goto err; } + size_after_init = EVP_MAC_CTX_get_mac_size(ctx); + if (!TEST_false(size_before_init == 0 && size_after_init == 0)) { + t->err = "MAC SIZE not set"; + goto err; + } + if (size_before_init != 0) { + /* mac-size not modified by init params */ + if (size_val == 0 && !TEST_size_t_eq(size_before_init, size_after_init)) { + t->err = "MAC SIZE check failed"; + goto err; + } + /* mac-size modified by init params */ + if (size_val != 0 && !TEST_size_t_eq(size_val, size_after_init)) { + t->err = "MAC SIZE check failed"; + goto err; + } + } if (expected->output_size >= 0) *psizes++ = OSSL_PARAM_construct_int(OSSL_MAC_PARAM_SIZE, &output_size); diff --git a/test/p_minimal.c b/test/p_minimal.c new file mode 100644 index 0000000000000000000000000000000000000000..0bff9823f824a294b285058022a823e84c887f57 --- /dev/null +++ b/test/p_minimal.c @@ -0,0 +1,24 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * This is the most minimal provider imaginable. It can be loaded, and does + * absolutely nothing else. + */ + +#include + +OSSL_provider_init_fn OSSL_provider_init; /* Check the function signature */ +int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *oin, + const OSSL_DISPATCH **out, + void **provctx) +{ + return 1; +} diff --git a/test/quic_lcidm_test.c b/test/quic_lcidm_test.c new file mode 100644 index 0000000000000000000000000000000000000000..b5937dfdbffe5ba3bd5221a711fe02af4d3d871e --- /dev/null +++ b/test/quic_lcidm_test.c @@ -0,0 +1,106 @@ +/* + * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/quic_lcidm.h" +#include "testutil.h" + +static char ptrs[8]; + +static const QUIC_CONN_ID cid8_1 = { 8, { 1 } }; +static const QUIC_CONN_ID cid8_2 = { 8, { 2 } }; +static const QUIC_CONN_ID cid8_3 = { 8, { 3 } }; +static const QUIC_CONN_ID cid8_4 = { 8, { 4 } }; +static const QUIC_CONN_ID cid8_5 = { 8, { 5 } }; + +static int test_lcidm(void) +{ + int testresult = 0; + QUIC_LCIDM *lcidm; + size_t lcid_len = 10; /* != ODCID len */ + QUIC_CONN_ID lcid_1, lcid_dummy, lcid_init = {0}; + OSSL_QUIC_FRAME_NEW_CONN_ID ncid_frame_1, ncid_frame_2, ncid_frame_3; + void *opaque = NULL; + uint64_t seq_num = UINT64_MAX; + int did_retire = 0; + + if (!TEST_ptr(lcidm = ossl_quic_lcidm_new(NULL, lcid_len))) + goto err; + + if (!TEST_size_t_eq(ossl_quic_lcidm_get_lcid_len(lcidm), lcid_len)) + goto err; + + if (!TEST_true(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 0, &cid8_1)) + || !TEST_false(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 0, &cid8_2)) + || !TEST_false(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 1, &cid8_1)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 1), 0) + || !TEST_true(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 1, &cid8_3)) + || !TEST_false(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 1, &cid8_4)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 0), 1) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 1), 1) + || !TEST_true(ossl_quic_lcidm_retire_odcid(lcidm, ptrs + 0)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 0), 0) + || !TEST_false(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 0, &cid8_1)) + || !TEST_false(ossl_quic_lcidm_enrol_odcid(lcidm, ptrs + 0, &cid8_5)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 0), 0) + + || !TEST_true(ossl_quic_lcidm_generate_initial(lcidm, ptrs + 2, &lcid_1)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 2), 1) + || !TEST_false(ossl_quic_lcidm_generate_initial(lcidm, ptrs + 2, &lcid_init)) + || !TEST_true(ossl_quic_lcidm_generate(lcidm, ptrs + 2, &ncid_frame_1)) + || !TEST_true(ossl_quic_lcidm_generate(lcidm, ptrs + 2, &ncid_frame_2)) + || !TEST_true(ossl_quic_lcidm_generate(lcidm, ptrs + 2, &ncid_frame_3)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 2), 4) + || !TEST_true(ossl_quic_lcidm_lookup(lcidm, &lcid_1, &seq_num, &opaque)) + || !TEST_ptr_eq(opaque, ptrs + 2) + || !TEST_uint64_t_eq(seq_num, 0) + || !TEST_true(ossl_quic_lcidm_lookup(lcidm, &ncid_frame_1.conn_id, + &seq_num, &opaque)) + || !TEST_ptr_eq(opaque, ptrs + 2) + || !TEST_uint64_t_eq(seq_num, 1) + || !TEST_true(ossl_quic_lcidm_lookup(lcidm, &ncid_frame_2.conn_id, + &seq_num, &opaque)) + || !TEST_ptr_eq(opaque, ptrs + 2) + || !TEST_uint64_t_eq(seq_num, 2) + || !TEST_true(ossl_quic_lcidm_lookup(lcidm, &ncid_frame_3.conn_id, + &seq_num, &opaque)) + || !TEST_ptr_eq(opaque, ptrs + 2) + || !TEST_uint64_t_eq(seq_num, 3) + || !TEST_true(ossl_quic_lcidm_retire(lcidm, ptrs + 2, 2, NULL, + &lcid_dummy, &seq_num, &did_retire)) + || !TEST_true(did_retire) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 2), 3) + || !TEST_true(ossl_quic_lcidm_retire(lcidm, ptrs + 2, 2, NULL, + &lcid_dummy, &seq_num, &did_retire)) + || !TEST_true(did_retire) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 2), 2) + || !TEST_true(ossl_quic_lcidm_retire(lcidm, ptrs + 2, 2, NULL, + &lcid_dummy, &seq_num, &did_retire)) + || !TEST_false(did_retire) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 2), 2) + || !TEST_false(ossl_quic_lcidm_lookup(lcidm, &lcid_init, + &seq_num, &opaque)) + || !TEST_false(ossl_quic_lcidm_lookup(lcidm, &ncid_frame_1.conn_id, + &seq_num, &opaque)) + || !TEST_true(ossl_quic_lcidm_lookup(lcidm, &ncid_frame_2.conn_id, + &seq_num, &opaque)) + || !TEST_true(ossl_quic_lcidm_cull(lcidm, ptrs + 2)) + || !TEST_size_t_eq(ossl_quic_lcidm_get_num_active_lcid(lcidm, ptrs + 2), 0)) + goto err; + + testresult = 1; +err: + ossl_quic_lcidm_free(lcidm); + return testresult; +} + +int setup_tests(void) +{ + ADD_TEST(test_lcidm); + return 1; +} diff --git a/test/recipes/01-test_symbol_presence.t b/test/recipes/01-test_symbol_presence.t index 9efa9f8d2d6eb7a785a7edc5c8ab653164672cbc..222b1886aec01f78d476441575a1dcd85650268b 100644 --- a/test/recipes/01-test_symbol_presence.t +++ b/test/recipes/01-test_symbol_presence.t @@ -114,17 +114,34 @@ foreach (sort keys %stlibname) { my @arrays = ( \@stlib_lines ); push @arrays, \@shlib_lines unless disabled('shared'); foreach (@arrays) { + my %commons; + foreach (@$_) { + if (m|^(.*) C .*|) { + $commons{$1}++; + } + } + foreach (sort keys %commons) { + note "Common symbol: $_"; + } + @$_ = sort - map { - # Drop the first space and everything following it - s| .*||; - # Drop OpenSSL dynamic version information if there is any - s|\@\@.+$||; - # Return the result - $_ - } - grep(m|.* [BCDST] .*|, @$_); + ( map { + # Drop the first space and everything following it + s| .*||; + # Drop OpenSSL dynamic version information if there is any + s|\@\@.+$||; + # Return the result + $_ + } + # Drop any symbol starting with a double underscore, they + # are reserved for the compiler / system ABI and are none + # of our business + grep !m|^__|, + # Only look at external definitions + grep m|.* [BDST] .*|, + @$_ ), + keys %commons; } # Massage the mkdef.pl output to only contain global symbols diff --git a/test/recipes/04-test_provider.t b/test/recipes/04-test_provider.t index 312def775784029aab0dc40555823883ddfc14a5..1233cc4f93a1376adb6c008e688688b21e54ba96 100644 --- a/test/recipes/04-test_provider.t +++ b/test/recipes/04-test_provider.t @@ -12,10 +12,17 @@ use OpenSSL::Test::Utils; setup("test_provider"); -plan tests => 2; +plan tests => 3; ok(run(test(['provider_test'])), "provider_test"); $ENV{"OPENSSL_MODULES"} = bldtop_dir("test"); ok(run(test(['provider_test', '-loaded'])), "provider_test -loaded"); + + SKIP: { + skip "no module support", 1 if disabled("module"); + + ok(run(app(['openssl', 'list', '-provider', 'p_minimal', + '-providers', '-verbose']))); +} diff --git a/test/recipes/60-test_x509_load_cert_file.t b/test/recipes/60-test_x509_load_cert_file.t new file mode 100644 index 0000000000000000000000000000000000000000..75aeac362c2c26aa37ae709438823f1f1c076f12 --- /dev/null +++ b/test/recipes/60-test_x509_load_cert_file.t @@ -0,0 +1,15 @@ +#! /usr/bin/env perl +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test qw/:DEFAULT srctop_file/; + +setup("test_load_cert_file"); + +plan tests => 1; + +ok(run(test(["x509_load_cert_file_test", srctop_file("test", "certs", "leaf-chain.pem")]))); diff --git a/test/recipes/70-test_quic_lcidm.t b/test/recipes/70-test_quic_lcidm.t new file mode 100644 index 0000000000000000000000000000000000000000..b61705beb10e803623ab8cf1da8dfca079161a33 --- /dev/null +++ b/test/recipes/70-test_quic_lcidm.t @@ -0,0 +1,19 @@ +#! /usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test; +use OpenSSL::Test::Utils; + +setup("test_quic_lcidm"); + +plan skip_all => "QUIC protocol is not supported by this OpenSSL build" + if disabled('quic'); + +plan tests => 1; + +ok(run(test(["quic_lcidm_test"]))); diff --git a/test/recipes/99-test_fuzz_quic_lcidm.t b/test/recipes/99-test_fuzz_quic_lcidm.t new file mode 100644 index 0000000000000000000000000000000000000000..2ae61d9190be23ea6794899acf7942d1607727b6 --- /dev/null +++ b/test/recipes/99-test_fuzz_quic_lcidm.t @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +my $fuzzer = "quic-lcidm"; +setup("test_fuzz_${fuzzer}"); + +plan skip_all => "This test requires quic support" + if disabled("quic"); + +plan tests => 2; # one more due to below require_ok(...) + +require_ok(srctop_file('test','recipes','fuzz.pl')); + +fuzz_ok($fuzzer); diff --git a/test/sslapitest.c b/test/sslapitest.c index 61981101bc390cfd162577c62752a0c3ec18e2cd..7ae2f7a4e20e8b5efcb632faecbf4fc69b90e34f 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -5593,6 +5593,119 @@ static int test_tls13_psk(int idx) return testresult; } +#ifndef OSSL_NO_USABLE_TLS1_3 +/* + * Test TLS1.3 connection establishment succeeds with various configurations of + * the options `SSL_OP_ALLOW_NO_DHE_KEX` and `SSL_OP_PREFER_NO_DHE_KEX`. + * The verification of whether the right KEX mode is choosen is not covered by + * this test but by `test_tls13kexmodes`. + * + * Tests (idx & 1): Server has `SSL_OP_ALLOW_NO_DHE_KEX` set. + * Tests (idx & 2): Server has `SSL_OP_PREFER_NO_DHE_KEX` set. + * Tests (idx & 4): Client has `SSL_OP_ALLOW_NO_DHE_KEX` set. + */ +static int test_tls13_no_dhe_kex(const int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; + size_t j; + SSL_SESSION *saved_session; + + int server_allow_no_dhe = (idx & 1) != 0; + int server_prefer_no_dhe = (idx & 2) != 0; + int client_allow_no_dhe = (idx & 4) != 0; + + uint64_t server_options = 0 + | (server_allow_no_dhe ? SSL_OP_ALLOW_NO_DHE_KEX : 0) + | (server_prefer_no_dhe ? SSL_OP_PREFER_NO_DHE_KEX : 0); + + uint64_t client_options = 0 + | (client_allow_no_dhe ? SSL_OP_ALLOW_NO_DHE_KEX : 0); + + new_called = 0; + do_cache = 1; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_3_VERSION, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT + | SSL_SESS_CACHE_NO_INTERNAL_STORE); + + SSL_CTX_set_options(sctx, server_options); + SSL_CTX_set_options(cctx, client_options); + + SSL_CTX_sess_set_new_cb(cctx, new_cachesession_cb); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + /* Check we got the number of tickets we were expecting */ + || !TEST_int_eq(2, new_called)) + goto end; + + /* We'll reuse the last ticket. */ + saved_session = sesscache[new_called - 1]; + + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(cctx); + clientssl = serverssl = NULL; + cctx = NULL; + + /* + * Now we resume with the last ticket we created. + */ + + /* The server context already exists, so we only create the client. */ + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_3_VERSION, 0, + NULL, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_options(cctx, client_options); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL)) + || !TEST_true(SSL_set_session(clientssl, saved_session))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + /* + * Make sure, the session was resumed. + */ + if (!TEST_true(SSL_session_reused(clientssl))) + goto end; + + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + + testresult = 1; + + end: + SSL_free(serverssl); + SSL_free(clientssl); + for (j = 0; j < OSSL_NELEM(sesscache); j++) { + SSL_SESSION_free(sesscache[j]); + sesscache[j] = NULL; + } + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} +#endif /* OSSL_NO_USABLE_TLS1_3 */ + static unsigned char cookie_magic_value[] = "cookie magic"; static int generate_cookie_callback(SSL *ssl, unsigned char *cookie, @@ -11426,6 +11539,9 @@ int setup_tests(void) # else ADD_ALL_TESTS(test_tls13_psk, 4); # endif /* OPENSSL_NO_PSK */ +#ifndef OSSL_NO_USABLE_TLS1_3 + ADD_ALL_TESTS(test_tls13_no_dhe_kex, 8); +#endif /* OSSL_NO_USABLE_TLS1_3 */ # ifndef OPENSSL_NO_TLS1_2 /* Test with both TLSv1.3 and 1.2 versions */ ADD_ALL_TESTS(test_key_exchange, 14); diff --git a/test/x509_load_cert_file_test.c b/test/x509_load_cert_file_test.c new file mode 100644 index 0000000000000000000000000000000000000000..4a736071ae61e57a48838969999755c845914484 --- /dev/null +++ b/test/x509_load_cert_file_test.c @@ -0,0 +1,50 @@ +/* + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +#include "testutil.h" + +static const char *chain; + +static int test_load_cert_file(void) +{ + int ret = 0; + X509_STORE *store = NULL; + X509_LOOKUP *lookup = NULL; + STACK_OF(X509) *certs = NULL; + + if (TEST_ptr(store = X509_STORE_new()) + && TEST_ptr(lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) + && TEST_true(X509_load_cert_file(lookup, chain, X509_FILETYPE_PEM)) + && TEST_ptr(certs = X509_STORE_get1_all_certs(store)) + && TEST_int_eq(sk_X509_num(certs), 4)) + ret = 1; + + OSSL_STACK_OF_X509_free(certs); + X509_STORE_free(store); + return ret; +} + +OPT_TEST_DECLARE_USAGE("cert.pem...\n") + +int setup_tests(void) +{ + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + chain = test_get_argument(0); + if (chain == NULL) + return 0; + + ADD_TEST(test_load_cert_file); + return 1; +} diff --git a/util/perl/OpenSSL/config.pm b/util/perl/OpenSSL/config.pm index cda764b4edcc5f48e5c75b1c5fd3877271cd29a2..970e65dc97e4347f85d282998b43c820d1dcb8c9 100755 --- a/util/perl/OpenSSL/config.pm +++ b/util/perl/OpenSSL/config.pm @@ -82,7 +82,7 @@ my $guess_patterns = [ [ 'HP-UX:.*', sub { my $HPUXVER = $RELEASE; - $HPUXVER = s/[^.]*.[0B]*//; + $HPUXVER =~ s/[^.]*.[0B]*//; # HPUX 10 and 11 targets are unified return "${MACHINE}-hp-hpux1x" if $HPUXVER =~ m@1[0-9]@; return "${MACHINE}-hp-hpux"; @@ -322,6 +322,7 @@ sub determine_compiler_settings { # If we got a version number, process it if ($v) { + $v =~ s/[^.]*.0*// if $SYSTEM eq 'HP-UX'; $CCVENDOR = $k; # The returned version is expected to be one of