Moved dependencies into separate repo
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				/ Build the server (push) Successful in 3m4s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	/ Build the server (push) Successful in 3m4s
				
			This commit is contained in:
		@@ -1,55 +0,0 @@
 | 
			
		||||
Language: Cpp
 | 
			
		||||
Standard: c++20
 | 
			
		||||
 | 
			
		||||
BasedOnStyle: Chromium
 | 
			
		||||
 | 
			
		||||
ColumnLimit: 120
 | 
			
		||||
AccessModifierOffset: -3
 | 
			
		||||
IndentWidth: 3
 | 
			
		||||
ContinuationIndentWidth: 3
 | 
			
		||||
ConstructorInitializerIndentWidth: 6
 | 
			
		||||
 | 
			
		||||
PointerAlignment: Left
 | 
			
		||||
ReferenceAlignment: Left
 | 
			
		||||
QualifierAlignment: Left
 | 
			
		||||
 | 
			
		||||
IncludeBlocks: Preserve
 | 
			
		||||
IncludeCategories:
 | 
			
		||||
  - Regex:           '^<botan/internal/.*\.h>'
 | 
			
		||||
    Priority:        3
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '^<botan/.*\.h>'
 | 
			
		||||
    Priority:        2
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '^<.*'
 | 
			
		||||
    Priority:        4
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '^<.*\.h>'
 | 
			
		||||
    Priority:        3
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '.*'
 | 
			
		||||
    Priority:        1
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
 | 
			
		||||
AttributeMacros: ['BOTAN_FUNC_ISA', 'BOTAN_FUNC_ISA_INLINE', 'BOTAN_FORCE_INLINE']
 | 
			
		||||
 | 
			
		||||
BinPackArguments: false
 | 
			
		||||
BreakStringLiterals: false
 | 
			
		||||
AllowAllArgumentsOnNextLine: true
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: true
 | 
			
		||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
 | 
			
		||||
EmptyLineBeforeAccessModifier: Always
 | 
			
		||||
 | 
			
		||||
BreakConstructorInitializers: AfterColon
 | 
			
		||||
BreakInheritanceList: AfterComma
 | 
			
		||||
AllowShortBlocksOnASingleLine: Empty
 | 
			
		||||
AllowShortFunctionsOnASingleLine: Inline
 | 
			
		||||
SpaceBeforeParens: Never
 | 
			
		||||
IndentPPDirectives: BeforeHash
 | 
			
		||||
FixNamespaceComments: true
 | 
			
		||||
SeparateDefinitionBlocks: Always
 | 
			
		||||
KeepEmptyLinesAtTheStartOfBlocks: false
 | 
			
		||||
IndentAccessModifiers: true
 | 
			
		||||
ReflowComments: false
 | 
			
		||||
RequiresClausePosition: OwnLine
 | 
			
		||||
IndentRequiresClause: true
 | 
			
		||||
@@ -1,54 +0,0 @@
 | 
			
		||||
 | 
			
		||||
# (C) 2022 Jack Lloyd
 | 
			
		||||
# (C) 2022 René Meusel, Rohde & Schwarz Cybersecurity
 | 
			
		||||
#
 | 
			
		||||
# Botan is released under the Simplified BSD License (see license.txt)
 | 
			
		||||
 | 
			
		||||
name: Setup Botan Build Agent
 | 
			
		||||
description: Set up a build agent for building and testing the Botan library
 | 
			
		||||
 | 
			
		||||
inputs:
 | 
			
		||||
  target:
 | 
			
		||||
    description: The ci_build.py target going to be built on this agent
 | 
			
		||||
    required: true
 | 
			
		||||
  cache-key:
 | 
			
		||||
    description: The actions/cache key to be used for this runs, caching will be disabled when no key is provided
 | 
			
		||||
    required: false
 | 
			
		||||
  arch:
 | 
			
		||||
    description: Target CPU architecture
 | 
			
		||||
    required: false
 | 
			
		||||
    default: x64
 | 
			
		||||
 | 
			
		||||
runs:
 | 
			
		||||
  using: composite
 | 
			
		||||
  steps:
 | 
			
		||||
    - name: Setup Build Agent (Windows)
 | 
			
		||||
      run: ${{ github.action_path }}/../../../src/scripts/ci/setup_gh_actions.ps1 "${{ inputs.target }}" "${{ inputs.arch }}"
 | 
			
		||||
      shell: pwsh
 | 
			
		||||
      if: runner.os == 'Windows'
 | 
			
		||||
    - name: Setup Build Agent (Unix-like)
 | 
			
		||||
      run: ${{ github.action_path }}/../../../src/scripts/ci/setup_gh_actions.sh "${{ inputs.target }}" "${{ inputs.arch }}"
 | 
			
		||||
      shell: bash
 | 
			
		||||
      if: runner.os != 'Windows'
 | 
			
		||||
 | 
			
		||||
    - name: Check Availability of Compiler Cache
 | 
			
		||||
      run: print("::warning ::No compiler cache available, build times might suffer")
 | 
			
		||||
      shell: python
 | 
			
		||||
      if: env.COMPILER_CACHE_LOCATION == '' && inputs.cache-key != ''
 | 
			
		||||
    - uses: actions/cache@v3
 | 
			
		||||
      if: env.COMPILER_CACHE_LOCATION != '' && inputs.cache-key != ''
 | 
			
		||||
      with:
 | 
			
		||||
          path: ${{ env.COMPILER_CACHE_LOCATION }}
 | 
			
		||||
          key: ${{ inputs.cache-key }}-${{ github.run_id }}
 | 
			
		||||
          restore-keys: ${{ inputs.cache-key }}
 | 
			
		||||
 | 
			
		||||
    - name: Setup Visual Studio Environment
 | 
			
		||||
      uses: egor-tensin/vs-shell@v2
 | 
			
		||||
      with:
 | 
			
		||||
        arch: ${{ env.VSENV_ARCH }} # set by setup_gh_actions.ps1
 | 
			
		||||
      if: runner.os == 'Windows'
 | 
			
		||||
 | 
			
		||||
    - name: Install Build Dependencies # after setting up Visual Studio Environment
 | 
			
		||||
      run: ${{ github.action_path }}/../../../src/scripts/ci/setup_gh_actions_after_vcvars.ps1 ${{ inputs.target }}
 | 
			
		||||
      shell: pwsh
 | 
			
		||||
      if: runner.os == 'Windows'
 | 
			
		||||
							
								
								
									
										1
									
								
								lib/Botan-3.2.0/.github/codecov.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								lib/Botan-3.2.0/.github/codecov.yml
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
			
		||||
../src/scripts/ci/codecov.yml
 | 
			
		||||
							
								
								
									
										291
									
								
								lib/Botan-3.2.0/.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										291
									
								
								lib/Botan-3.2.0/.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,291 +0,0 @@
 | 
			
		||||
 | 
			
		||||
# (C) 2020,2022 Jack Lloyd
 | 
			
		||||
# (C) 2022      René Meusel, Rohde & Schwarz Cybersecurity
 | 
			
		||||
#
 | 
			
		||||
# Botan is released under the Simplified BSD License (see license.txt)
 | 
			
		||||
 | 
			
		||||
name: ci
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
  # implicitly all other scopes not listed become none
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
 | 
			
		||||
# cancel running workflows when new commits are being pushed in pull requests
 | 
			
		||||
# but not on the master branch
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }} @ ${{ github.head_ref || github.run_id }}
 | 
			
		||||
  cancel-in-progress: true
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  windows:
 | 
			
		||||
    name: "Windows"
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: shared
 | 
			
		||||
            arch: x86_64
 | 
			
		||||
            host_os: windows-2022
 | 
			
		||||
          - target: static
 | 
			
		||||
            arch: x86_64
 | 
			
		||||
            host_os: windows-2022
 | 
			
		||||
          - target: amalgamation
 | 
			
		||||
            arch: x86_64
 | 
			
		||||
            host_os: windows-2022
 | 
			
		||||
          - target: shared
 | 
			
		||||
            arch: x86
 | 
			
		||||
            host_os: windows-2022
 | 
			
		||||
 | 
			
		||||
    runs-on: ${{ matrix.host_os }}
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          cache-key: ${{ matrix.host_os }}-msvc-${{ matrix.arch }}-${{ matrix.target }}
 | 
			
		||||
          arch: ${{ matrix.arch }}
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan
 | 
			
		||||
        run: python3 ./src/scripts/ci_build.py --cc='msvc' --make-tool='ninja' --cpu='${{ matrix.arch }}' --test-results-dir=junit_results ${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
  linux:
 | 
			
		||||
    name: "Linux"
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - compiler: gcc
 | 
			
		||||
            target: shared
 | 
			
		||||
          - compiler: gcc
 | 
			
		||||
            target: amalgamation
 | 
			
		||||
          - compiler: gcc
 | 
			
		||||
            target: static
 | 
			
		||||
          - compiler: clang
 | 
			
		||||
            target: shared
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          cache-key: linux-${{ matrix.compiler }}-x86_64-${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan
 | 
			
		||||
        run: python3 ./src/scripts/ci_build.py --cc='${{ matrix.compiler }}' --test-results-dir=junit_results ${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
  macos:
 | 
			
		||||
    name: "macOS"
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: shared
 | 
			
		||||
            compiler: clang
 | 
			
		||||
          - target: amalgamation
 | 
			
		||||
            compiler: clang
 | 
			
		||||
 | 
			
		||||
    runs-on: macos-13
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          cache-key: macos-${{ matrix.compiler }}-x86_64-${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan
 | 
			
		||||
        run: python3 ./src/scripts/ci_build.py --cc='${{ matrix.compiler }}' --test-results-dir=junit_results ${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
  clang-tidy:
 | 
			
		||||
    name: "Clang Tidy"
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: clang-tidy
 | 
			
		||||
          cache-key: linux-x86_64-clang-tidy
 | 
			
		||||
 | 
			
		||||
      - name: Configure Build
 | 
			
		||||
        run: python3 ./configure.py --cc=clang
 | 
			
		||||
 | 
			
		||||
      - name: Run Clang Tidy
 | 
			
		||||
        run: |
 | 
			
		||||
           ./src/scripts/ci/gh_get_changes_in_pr.py $(git rev-parse HEAD) --api-token=${{ secrets.GITHUB_TOKEN }} | \
 | 
			
		||||
             python3 ./src/scripts/dev_tools/run_clang_tidy.py --verbose --take-file-list-from-stdin --export-fixes-dir=clang_tidy_diagnostics
 | 
			
		||||
 | 
			
		||||
      - name: Display Clang Tidy Results
 | 
			
		||||
        if: failure()
 | 
			
		||||
        run: ./src/scripts/ci/gh_clang_tidy_fixes_in_pr.py clang_tidy_diagnostics
 | 
			
		||||
 | 
			
		||||
  analysis:
 | 
			
		||||
    name: "Analysis"
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: coverage
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: sanitizer
 | 
			
		||||
            compiler: msvc
 | 
			
		||||
            host_os: windows-2022
 | 
			
		||||
            make_tool: ninja
 | 
			
		||||
          - target: sanitizer
 | 
			
		||||
            compiler: clang
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: sanitizer
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: valgrind
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: fuzzers
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: lint
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: format
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
    runs-on: ${{ matrix.host_os }}
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
      COVERALLS_REPO_TOKEN: pbLoTMBxC1DFvbws9WfrzVOvfEdEZTcCS
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
        with:
 | 
			
		||||
          path: ./source
 | 
			
		||||
 | 
			
		||||
      - name: Fetch BoringSSL fork for BoGo tests
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
        with:
 | 
			
		||||
          repository: randombit/boringssl
 | 
			
		||||
          ref: rene/runner-20230705
 | 
			
		||||
          path: ./boringssl
 | 
			
		||||
        if: matrix.target == 'coverage' || matrix.target == 'sanitizer'
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./source/.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          cache-key: ${{ matrix.host_os }}-${{ matrix.compiler }}-x86_64-${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan
 | 
			
		||||
        run: python3 ./source/src/scripts/ci_build.py --root-dir=${{ github.workspace }}/source --build-dir=${{ github.workspace }}/build --boringssl-dir=${{ github.workspace }}/boringssl --cc='${{ matrix.compiler }}' --make-tool='${{ matrix.make_tool }}' --test-results-dir=junit_results ${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
  specials:
 | 
			
		||||
    name: "Special"
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: examples
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: minimized
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: bsi
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
    runs-on: ${{ matrix.host_os }}
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
        with:
 | 
			
		||||
          path: ./source
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./source/.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          cache-key: ${{ matrix.host_os }}-${{ matrix.compiler }}-x86_64-${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan
 | 
			
		||||
        run: python3 ./source/src/scripts/ci_build.py --root-dir=${{ github.workspace }}/source --build-dir=${{ github.workspace }}/build --boringssl-dir=${{ github.workspace }}/boringssl --cc='${{ matrix.compiler }}' --make-tool='${{ matrix.make_tool }}' --test-results-dir=junit_results ${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
  x-compile:
 | 
			
		||||
    name: "Cross"
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: cross-i386
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-arm32
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-arm64
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-ppc64
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-riscv64
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-s390x
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-android-arm32
 | 
			
		||||
            compiler: clang
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: cross-android-arm64
 | 
			
		||||
            compiler: clang
 | 
			
		||||
            host_os: ubuntu-22.04
 | 
			
		||||
          - target: static
 | 
			
		||||
            compiler: gcc
 | 
			
		||||
            host_os: windows-2022
 | 
			
		||||
            make_tool: mingw32-make
 | 
			
		||||
          - target: cross-ios-arm64
 | 
			
		||||
            compiler: clang
 | 
			
		||||
            host_os: macos-13
 | 
			
		||||
          - target: emscripten
 | 
			
		||||
            compiler: emcc
 | 
			
		||||
            host_os: macos-13
 | 
			
		||||
 | 
			
		||||
    runs-on: ${{ matrix.host_os }}
 | 
			
		||||
 | 
			
		||||
    env:
 | 
			
		||||
      ANDROID_NDK: android-ndk-r26
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: ${{ matrix.target }}
 | 
			
		||||
          cache-key: ${{ matrix.host_os }}-${{ matrix.compiler }}-xcompile-${{ matrix.target }}
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan
 | 
			
		||||
        run: python3 ./src/scripts/ci_build.py --cc='${{ matrix.compiler }}' --test-results-dir=junit_results ${{ matrix.target }}
 | 
			
		||||
							
								
								
									
										29
									
								
								lib/Botan-3.2.0/.github/workflows/cifuzz.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								lib/Botan-3.2.0/.github/workflows/cifuzz.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,29 +0,0 @@
 | 
			
		||||
name: CIFuzz
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
  # implicitly all other scopes not listed become none
 | 
			
		||||
 | 
			
		||||
on: [pull_request]
 | 
			
		||||
jobs:
 | 
			
		||||
  Fuzzing:
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
    steps:
 | 
			
		||||
    - name: Build Fuzzers
 | 
			
		||||
      id: build
 | 
			
		||||
      uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
 | 
			
		||||
      with:
 | 
			
		||||
        oss-fuzz-project-name: 'botan'
 | 
			
		||||
        dry-run: false
 | 
			
		||||
    - name: Run Fuzzers
 | 
			
		||||
      uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
 | 
			
		||||
      with:
 | 
			
		||||
        oss-fuzz-project-name: 'botan'
 | 
			
		||||
        fuzz-seconds: 180
 | 
			
		||||
        dry-run: false
 | 
			
		||||
    - name: Upload Crash
 | 
			
		||||
      uses: actions/upload-artifact@v1
 | 
			
		||||
      if: failure() && steps.build.outcome == 'success'
 | 
			
		||||
      with:
 | 
			
		||||
        name: artifacts
 | 
			
		||||
        path: ./out/artifacts
 | 
			
		||||
							
								
								
									
										70
									
								
								lib/Botan-3.2.0/.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										70
									
								
								lib/Botan-3.2.0/.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,70 +0,0 @@
 | 
			
		||||
name: "CodeQL"
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: ["master"]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    # The branches below must be a subset of the branches above
 | 
			
		||||
    branches: ["master"]
 | 
			
		||||
  schedule:
 | 
			
		||||
    # runs every day at 4:23 AM UTC
 | 
			
		||||
    - cron: "23 4 * * *"
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  codeql_cpp:
 | 
			
		||||
    name: C++
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
    permissions:
 | 
			
		||||
      actions: read
 | 
			
		||||
      contents: read
 | 
			
		||||
      security-events: write
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: codeql
 | 
			
		||||
          cache-key: linux-gcc-x86_64-codeql
 | 
			
		||||
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@v2
 | 
			
		||||
        with:
 | 
			
		||||
          languages: cpp
 | 
			
		||||
          config-file: ./src/configs/codeql.yml
 | 
			
		||||
 | 
			
		||||
      - name: Build Library
 | 
			
		||||
        run: ./src/scripts/ci_build.py codeql
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@v2
 | 
			
		||||
        with:
 | 
			
		||||
          category: cpp
 | 
			
		||||
 | 
			
		||||
  codeql_py:
 | 
			
		||||
    name: Python
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
    permissions:
 | 
			
		||||
      actions: read
 | 
			
		||||
      contents: read
 | 
			
		||||
      security-events: write
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@v2
 | 
			
		||||
        with:
 | 
			
		||||
          languages: python
 | 
			
		||||
          config-file: ./src/configs/codeql.yml
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@v2
 | 
			
		||||
        with:
 | 
			
		||||
          category: python
 | 
			
		||||
							
								
								
									
										89
									
								
								lib/Botan-3.2.0/.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										89
									
								
								lib/Botan-3.2.0/.github/workflows/nightly.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,89 +0,0 @@
 | 
			
		||||
 | 
			
		||||
# (C) 2023 Jack Lloyd
 | 
			
		||||
# (C) 2023 Fabian Albert, Rohde & Schwarz Cybersecurity
 | 
			
		||||
#
 | 
			
		||||
# Botan is released under the Simplified BSD License (see license.txt)
 | 
			
		||||
 | 
			
		||||
name: nightly
 | 
			
		||||
 | 
			
		||||
permissions:
 | 
			
		||||
  contents: read
 | 
			
		||||
  # implicitly all other scopes not listed become none
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  schedule:
 | 
			
		||||
    # runs every day at 3:23 AM UTC
 | 
			
		||||
    - cron:  '23 3 * * *'
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  clang_tidy:
 | 
			
		||||
    name: "clang-tidy"
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: clang-tidy
 | 
			
		||||
          cache-key: linux-x86_64-clang-tidy
 | 
			
		||||
 | 
			
		||||
      - name: Install Boost
 | 
			
		||||
        run: sudo apt-get -qq install libboost-dev
 | 
			
		||||
 | 
			
		||||
      - name: Configure Build
 | 
			
		||||
        run: python3 ./configure.py --cc=clang --build-targets=shared,cli,tests,examples,bogo_shim --build-fuzzers=test --with-boost --with-sqlite --with-zlib --with-lzma --with-bzip2
 | 
			
		||||
 | 
			
		||||
      - name: Run Clang Tidy
 | 
			
		||||
        run: python3 ./src/scripts/dev_tools/run_clang_tidy.py --verbose
 | 
			
		||||
 | 
			
		||||
  valgrind:
 | 
			
		||||
    name: "valgrind"
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: valgrind-full
 | 
			
		||||
          cache-key: linux-x86_64-valgrind-full
 | 
			
		||||
 | 
			
		||||
      - name: Valgrind Checks
 | 
			
		||||
        run: python3 ./src/scripts/ci_build.py --cc=gcc --make-tool=make valgrind-full
 | 
			
		||||
 | 
			
		||||
  tls_anvil_server_test:
 | 
			
		||||
    name: "TLS-Anvil (server)"
 | 
			
		||||
 | 
			
		||||
    runs-on: ubuntu-22.04
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Fetch Botan Repository
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Build Agent
 | 
			
		||||
        uses: ./.github/actions/setup-build-agent
 | 
			
		||||
        with:
 | 
			
		||||
          target: tlsanvil
 | 
			
		||||
          cache-key: linux-x86_64-tlsanvil
 | 
			
		||||
 | 
			
		||||
      - name: Build and Test Botan Server with TLS-Anvil
 | 
			
		||||
        run: >
 | 
			
		||||
          python3 ./src/scripts/ci/ci_tlsanvil_test.py
 | 
			
		||||
          --botan-dir .
 | 
			
		||||
          --test-target server
 | 
			
		||||
          --parallel $(nproc)
 | 
			
		||||
 | 
			
		||||
      - uses: actions/upload-artifact@v3
 | 
			
		||||
        with:
 | 
			
		||||
          name: tls-anvil-server-test-results
 | 
			
		||||
          path: |
 | 
			
		||||
            ./TestSuiteResults/
 | 
			
		||||
            ./logs/
 | 
			
		||||
 | 
			
		||||
      - name: Check TLS-Anvil Test Results
 | 
			
		||||
        run: python3 ./src/scripts/ci/ci_tlsanvil_check.py --verbose ./TestSuiteResults
 | 
			
		||||
							
								
								
									
										98
									
								
								lib/Botan-3.2.0/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								lib/Botan-3.2.0/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,98 +0,0 @@
 | 
			
		||||
/Makefile
 | 
			
		||||
CMakeLists.txt*
 | 
			
		||||
build.ninja
 | 
			
		||||
.ninja_log
 | 
			
		||||
libbotan*.so.*
 | 
			
		||||
*.a
 | 
			
		||||
*.so
 | 
			
		||||
*.dylib
 | 
			
		||||
*.exp
 | 
			
		||||
*.lib
 | 
			
		||||
*.pdb
 | 
			
		||||
*.ilk
 | 
			
		||||
*.dll
 | 
			
		||||
*.exe
 | 
			
		||||
*.manifest
 | 
			
		||||
build
 | 
			
		||||
build_deps
 | 
			
		||||
build.log
 | 
			
		||||
botan
 | 
			
		||||
botan-test
 | 
			
		||||
 | 
			
		||||
core.*
 | 
			
		||||
vgcore.*
 | 
			
		||||
 | 
			
		||||
# Text file backups (e.g. gedit, joe)
 | 
			
		||||
*~
 | 
			
		||||
\#*\#
 | 
			
		||||
.\#*
 | 
			
		||||
 | 
			
		||||
# Editor configuration files (top level)
 | 
			
		||||
/*.sublime-project
 | 
			
		||||
/*.sublime-workspace
 | 
			
		||||
/.editorconfig
 | 
			
		||||
 | 
			
		||||
# Archive files
 | 
			
		||||
*.tgz
 | 
			
		||||
*.tar
 | 
			
		||||
 | 
			
		||||
# Logs
 | 
			
		||||
*.log
 | 
			
		||||
 | 
			
		||||
# Patch files
 | 
			
		||||
*.patch
 | 
			
		||||
*.diff
 | 
			
		||||
*.orig
 | 
			
		||||
*.rej
 | 
			
		||||
 | 
			
		||||
# Cache and temporary files
 | 
			
		||||
*.pyc
 | 
			
		||||
.DS_Store
 | 
			
		||||
*.swp
 | 
			
		||||
/*.cache
 | 
			
		||||
 | 
			
		||||
# ctags/etags files
 | 
			
		||||
/TAGS
 | 
			
		||||
/tags
 | 
			
		||||
 | 
			
		||||
# Amalgamation code
 | 
			
		||||
botan_all.h
 | 
			
		||||
botan_all_internal.h
 | 
			
		||||
botan_all.cpp
 | 
			
		||||
botan_all_*.cpp
 | 
			
		||||
 | 
			
		||||
# Coverage output
 | 
			
		||||
coverage.info
 | 
			
		||||
coverage.info.raw
 | 
			
		||||
coverage/
 | 
			
		||||
lcov-out/
 | 
			
		||||
 | 
			
		||||
/fuzzer_corpus
 | 
			
		||||
 | 
			
		||||
# Profiler outputs
 | 
			
		||||
cachegrind.*
 | 
			
		||||
callgrind.*
 | 
			
		||||
 | 
			
		||||
# Ignore stuff in the top level dir that shouldn't be checked in
 | 
			
		||||
/*.c
 | 
			
		||||
/*.cpp
 | 
			
		||||
/*.h
 | 
			
		||||
/*.py
 | 
			
		||||
/*.key
 | 
			
		||||
/*.pem
 | 
			
		||||
/*.der
 | 
			
		||||
/*.ber
 | 
			
		||||
/*.gpg
 | 
			
		||||
/*.pub
 | 
			
		||||
/*.crt
 | 
			
		||||
/*.txt
 | 
			
		||||
/*.rst
 | 
			
		||||
 | 
			
		||||
# Add back files from the toplevel
 | 
			
		||||
!/news.rst
 | 
			
		||||
!/readme.rst
 | 
			
		||||
!/configure.py
 | 
			
		||||
!/license.txt
 | 
			
		||||
 | 
			
		||||
# cscope
 | 
			
		||||
cscope.out
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,21 +0,0 @@
 | 
			
		||||
 | 
			
		||||
ABI Stability
 | 
			
		||||
====================
 | 
			
		||||
 | 
			
		||||
Botan uses semantic versioning for the API; if API features are added the minor
 | 
			
		||||
version increases, whereas if API compatibility breaks occur the major version
 | 
			
		||||
is increased.
 | 
			
		||||
 | 
			
		||||
However no guarantees about ABI are made between releases. Maintaining an ABI
 | 
			
		||||
compatible release in a complex C++ API is exceedingly expensive in development
 | 
			
		||||
time; just adding a single member variable or virtual function is enough to
 | 
			
		||||
cause ABI issues.
 | 
			
		||||
 | 
			
		||||
If ABI changes, the soname revision will increase to prevent applications from
 | 
			
		||||
linking against a potentially incompatible version at runtime.
 | 
			
		||||
 | 
			
		||||
If you are concerned about long-term ABI issues, considering using the C API
 | 
			
		||||
instead; this subset *is* ABI stable.
 | 
			
		||||
 | 
			
		||||
You can review a report on ABI changes to Botan at
 | 
			
		||||
https://abi-laboratory.pro/tracker/timeline/botan/
 | 
			
		||||
@@ -1,279 +0,0 @@
 | 
			
		||||
BigInt
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
``BigInt`` is Botan's implementation of a multiple-precision integer. Thanks to
 | 
			
		||||
C++'s operator overloading features, using ``BigInt`` is often quite similar to
 | 
			
		||||
using a native integer type. The number of functions related to ``BigInt`` is
 | 
			
		||||
quite large, and not all of them are documented here. You can find the complete
 | 
			
		||||
declarations in ``botan/bigint.h`` and ``botan/numthry.h``.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: BigInt
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt()
 | 
			
		||||
 | 
			
		||||
      Create a BigInt with value zero
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt(uint64_t n)
 | 
			
		||||
 | 
			
		||||
      Create a BigInt with value *n*
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt(const std::string& str)
 | 
			
		||||
 | 
			
		||||
      Create a BigInt from a string. By default decimal is expected. With an 0x
 | 
			
		||||
      prefix instead it is treated as hexadecimal.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt(const uint8_t buf[], size_t length)
 | 
			
		||||
 | 
			
		||||
      Create a BigInt from a binary array (big-endian encoding).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt(RandomNumberGenerator& rng, size_t bits, bool set_high_bit = true)
 | 
			
		||||
 | 
			
		||||
      Create a random BigInt of the specified size.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator+(const BigInt& x, const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Add ``x`` and ``y`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator+(const BigInt& x, word y)
 | 
			
		||||
 | 
			
		||||
      Add ``x`` and ``y`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator+(word x, const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Add ``x`` and ``y`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator-(const BigInt& x, const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Subtract ``y`` from ``x`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator-(const BigInt& x, word y)
 | 
			
		||||
 | 
			
		||||
      Subtract ``y`` from ``x`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator*(const BigInt& x, const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Multiply ``x`` and ``y`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator/(const BigInt& x, const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Divide ``x`` by ``y`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator%(const BigInt& x, const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Divide ``x`` by ``y`` and return remainder.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: word operator%(const BigInt& x, word y)
 | 
			
		||||
 | 
			
		||||
      Divide ``x`` by ``y`` and return remainder.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: word operator<<(const BigInt& x, size_t n)
 | 
			
		||||
 | 
			
		||||
      Left shift ``x`` by ``n`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: word operator>>(const BigInt& x, size_t n)
 | 
			
		||||
 | 
			
		||||
      Right shift ``x`` by ``n`` and return result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator+=(const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Add y to ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator+=(word y)
 | 
			
		||||
 | 
			
		||||
      Add y to ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator-=(const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Subtract y from ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator-=(word y)
 | 
			
		||||
 | 
			
		||||
      Subtract y from ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator*=(const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Multiply ``*this`` with y
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator*=(word y)
 | 
			
		||||
 | 
			
		||||
      Multiply ``*this`` with y
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator/=(const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Divide ``*this`` by y
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator%=(const BigInt& y)
 | 
			
		||||
 | 
			
		||||
      Divide ``*this`` by y and set ``*this`` to the remainder.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: word operator%=(word y)
 | 
			
		||||
 | 
			
		||||
      Divide ``*this`` by y and set ``*this`` to the remainder.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: word operator<<=(size_t shift)
 | 
			
		||||
 | 
			
		||||
      Left shift ``*this`` by *shift* bits
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: word operator>>=(size_t shift)
 | 
			
		||||
 | 
			
		||||
      Right shift ``*this`` by *shift* bits
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator++()
 | 
			
		||||
 | 
			
		||||
      Increment ``*this`` by 1
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt& operator--()
 | 
			
		||||
 | 
			
		||||
      Decrement ``*this`` by 1
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator++(int)
 | 
			
		||||
 | 
			
		||||
      Postfix increment ``*this`` by 1
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator--(int)
 | 
			
		||||
 | 
			
		||||
      Postfix decrement ``*this`` by 1
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt operator-() const
 | 
			
		||||
 | 
			
		||||
      Negation operator
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool operator !() const
 | 
			
		||||
 | 
			
		||||
      Return true unless ``*this`` is zero
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void clear()
 | 
			
		||||
 | 
			
		||||
      Set ``*this`` to zero
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: size_t bytes() const
 | 
			
		||||
 | 
			
		||||
      Return number of bytes need to represent value of ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: size_t bits() const
 | 
			
		||||
 | 
			
		||||
      Return number of bits need to represent value of ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_even() const
 | 
			
		||||
 | 
			
		||||
      Return true if ``*this`` is even
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_odd() const
 | 
			
		||||
 | 
			
		||||
      Return true if ``*this`` is odd
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_nonzero() const
 | 
			
		||||
 | 
			
		||||
      Return true if ``*this`` is not zero
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_zero() const
 | 
			
		||||
 | 
			
		||||
      Return true if ``*this`` is zero
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set_bit(size_t n)
 | 
			
		||||
 | 
			
		||||
      Set bit *n* of ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void clear_bit(size_t n)
 | 
			
		||||
 | 
			
		||||
      Clear bit *n* of ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool get_bit(size_t n) const
 | 
			
		||||
 | 
			
		||||
      Get bit *n* of ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: uint32_t to_u32bit() const
 | 
			
		||||
 | 
			
		||||
      Return value of ``*this`` as a 32-bit integer, if possible.
 | 
			
		||||
      If the integer is negative or not in range, an exception is thrown.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_negative() const
 | 
			
		||||
 | 
			
		||||
      Return true if ``*this`` is negative
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_positive() const
 | 
			
		||||
 | 
			
		||||
      Return true if ``*this`` is negative
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt abs() const
 | 
			
		||||
 | 
			
		||||
      Return absolute value of ``*this``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void binary_encode(uint8_t buf[]) const
 | 
			
		||||
 | 
			
		||||
      Encode this BigInt as a big-endian integer. The sign is ignored.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void binary_encode(uint8_t buf[], size_t len) const
 | 
			
		||||
 | 
			
		||||
      Encode this BigInt as a big-endian integer. The sign is ignored.
 | 
			
		||||
      If ``len`` is less than ``bytes()`` then only the low ``len``
 | 
			
		||||
      bytes are output. If ``len`` is greater than ``bytes()`` then
 | 
			
		||||
      the output is padded with leading zeros.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void binary_decode(uint8_t buf[])
 | 
			
		||||
 | 
			
		||||
      Decode this BigInt as a big-endian integer.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::string to_dec_string() const
 | 
			
		||||
 | 
			
		||||
      Encode the integer as a decimal string.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::string to_hex_string() const
 | 
			
		||||
 | 
			
		||||
      Encode the integer as a hexadecimal string.
 | 
			
		||||
 | 
			
		||||
Number Theory
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Number theoretic functions available include:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt gcd(BigInt x, BigInt y)
 | 
			
		||||
 | 
			
		||||
  Returns the greatest common divisor of x and y
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt lcm(BigInt x, BigInt y)
 | 
			
		||||
 | 
			
		||||
  Returns an integer z which is the smallest integer such that z % x
 | 
			
		||||
  == 0 and z % y == 0
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt jacobi(BigInt a, BigInt n)
 | 
			
		||||
 | 
			
		||||
  Return Jacobi symbol of (a|n).
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt inverse_mod(BigInt x, BigInt m)
 | 
			
		||||
 | 
			
		||||
  Returns the modular inverse of x modulo m, that is, an integer
 | 
			
		||||
  y such that (x*y) % m == 1. If no such y exists, returns zero.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt power_mod(BigInt b, BigInt x, BigInt m)
 | 
			
		||||
 | 
			
		||||
  Returns b to the xth power modulo m. If you are doing many
 | 
			
		||||
  exponentiations with a single fixed modulus, it is faster to use a
 | 
			
		||||
  ``Power_Mod`` implementation.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt ressol(BigInt x, BigInt p)
 | 
			
		||||
 | 
			
		||||
  Returns the square root modulo a prime, that is, returns a number y
 | 
			
		||||
  such that (y*y) % p == x. Returns -1 if no such integer exists.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: bool is_prime(BigInt n, RandomNumberGenerator& rng, \
 | 
			
		||||
                                size_t prob = 56, double is_random = false)
 | 
			
		||||
 | 
			
		||||
  Test *n* for primality using a probabilistic algorithm (Miller-Rabin).  With
 | 
			
		||||
  this algorithm, there is some non-zero probability that true will be returned
 | 
			
		||||
  even if *n* is actually composite. Modifying *prob* allows you to decrease the
 | 
			
		||||
  chance of such a false positive, at the cost of increased runtime. Sufficient
 | 
			
		||||
  tests will be run such that the chance *n* is composite is no more than 1 in
 | 
			
		||||
  2\ :sup:`prob`. Set *is_random* to true if (and only if) *n* was randomly
 | 
			
		||||
  chosen (ie, there is no danger it was chosen maliciously) as far fewer tests
 | 
			
		||||
  are needed in that case.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt random_prime(RandomNumberGenerator& rng, \
 | 
			
		||||
                                      size_t bits, \
 | 
			
		||||
                                      BigInt coprime = 1, \
 | 
			
		||||
                                      size_t equiv = 1, \
 | 
			
		||||
                                      size_t equiv_mod = 2)
 | 
			
		||||
 | 
			
		||||
  Return a random prime number of ``bits`` bits long that is
 | 
			
		||||
  relatively prime to ``coprime``, and equivalent to ``equiv`` modulo
 | 
			
		||||
  ``equiv_mod``.
 | 
			
		||||
@@ -1,318 +0,0 @@
 | 
			
		||||
Block Ciphers
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
Block ciphers are a n-bit permutation for some small n, typically 64 or 128
 | 
			
		||||
bits.  They are a cryptographic primitive used to generate higher level
 | 
			
		||||
operations such as authenticated encryption.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   In almost all cases, a bare block cipher is not what you should be using.
 | 
			
		||||
   You probably want an authenticated cipher mode instead (see :ref:`cipher_modes`)
 | 
			
		||||
   This interface is used to build higher level operations (such as cipher
 | 
			
		||||
   modes or MACs), or in the very rare situation where ECB is required,
 | 
			
		||||
   eg for compatibility with an existing system.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: BlockCipher
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::unique_ptr<BlockCipher> create(const std::string& algo_spec, \
 | 
			
		||||
                                                               const std::string& provider = "")
 | 
			
		||||
 | 
			
		||||
      Create a new block cipher object, or else return null.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::unique_ptr<BlockCipher> create_or_throw(const std::string& algo_spec, \
 | 
			
		||||
                                                                        const std::string& provider = "")
 | 
			
		||||
 | 
			
		||||
      Like ``create``, except instead of returning null an exception is thrown
 | 
			
		||||
      if the cipher is not known.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_key(const uint8_t* key, size_t length)
 | 
			
		||||
 | 
			
		||||
      This sets the key to the value specified. Most algorithms only accept keys
 | 
			
		||||
      of certain lengths. If you attempt to call ``set_key`` with a key length
 | 
			
		||||
      that is not supported, the exception ``Invalid_Key_Length`` will be
 | 
			
		||||
      thrown.
 | 
			
		||||
 | 
			
		||||
      In all cases, ``set_key`` must be called on an object before any data
 | 
			
		||||
      processing (encryption, decryption, etc) is done by that object. If this
 | 
			
		||||
      is not done, an exception will be thrown.
 | 
			
		||||
      thrown.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_keylength(size_t length) const
 | 
			
		||||
 | 
			
		||||
     This function returns true if and only if *length* is a valid keylength for
 | 
			
		||||
     this algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t minimum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the smallest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t maximum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the largest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string name() const
 | 
			
		||||
 | 
			
		||||
      Return a human readable name for this algorithm. This is guaranteed to round-trip with
 | 
			
		||||
      ``create`` and ``create_or_throw`` calls, ie create("Foo")->name() == "Foo"
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void clear()
 | 
			
		||||
 | 
			
		||||
     Zero out the key. The key must be reset before the cipher object can be used.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<BlockCipher> new_object() const
 | 
			
		||||
 | 
			
		||||
     Return a newly allocated BlockCipher object of the same type as this one.
 | 
			
		||||
     The new object is unkeyed.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t block_size() const
 | 
			
		||||
 | 
			
		||||
      Return the size (in *bytes*) of the cipher.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t parallelism() const
 | 
			
		||||
 | 
			
		||||
     Return the parallelism underlying this implementation of the cipher. This
 | 
			
		||||
     value can vary across versions and machines. A return value of N means that
 | 
			
		||||
     encrypting or decrypting with N blocks can operate in parallel.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t parallel_bytes() const
 | 
			
		||||
 | 
			
		||||
     Returns ``parallelism`` multiplied by the block size as well as a small
 | 
			
		||||
     fudge factor. That's because even ciphers that have no implicit parallelism
 | 
			
		||||
     typically see a small speedup for being called with several blocks due to
 | 
			
		||||
     caching effects.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string provider() const
 | 
			
		||||
 | 
			
		||||
     Return the provider type. Default value is "base" but can be any arbitrary string.
 | 
			
		||||
     Other example values are "sse2", "avx2", "openssl".
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
 | 
			
		||||
 | 
			
		||||
     Encrypt *blocks* blocks of data, taking the input from the array *in* and
 | 
			
		||||
     placing the ciphertext into *out*. The two pointers may be identical, but
 | 
			
		||||
     should not overlap ranges.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const
 | 
			
		||||
 | 
			
		||||
     Decrypt *blocks* blocks of data, taking the input from the array *in* and
 | 
			
		||||
     placing the plaintext into *out*. The two pointers may be identical, but
 | 
			
		||||
     should not overlap ranges.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void encrypt(const uint8_t in[], uint8_t out[]) const
 | 
			
		||||
 | 
			
		||||
     Encrypt a single block. Equivalent to :cpp:func:`encrypt_n`\ (in, out, 1).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void encrypt(uint8_t block[]) const
 | 
			
		||||
 | 
			
		||||
     Encrypt a single block. Equivalent to :cpp:func:`encrypt_n`\ (block, block, 1)
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void decrypt(const uint8_t in[], uint8_t out[]) const
 | 
			
		||||
 | 
			
		||||
     Decrypt a single block. Equivalent to :cpp:func:`decrypt_n`\ (in, out, 1)
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void decrypt(uint8_t block[]) const
 | 
			
		||||
 | 
			
		||||
     Decrypt a single block. Equivalent to :cpp:func:`decrypt_n`\ (block, block, 1)
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: template<typename Alloc> void encrypt(std::vector<uint8_t, Alloc>& block) const
 | 
			
		||||
 | 
			
		||||
     Assumes ``block`` is of a multiple of the block size.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: template<typename Alloc> void decrypt(std::vector<uint8_t, Alloc>& block) const
 | 
			
		||||
 | 
			
		||||
     Assumes ``block`` is of a multiple of the block size.
 | 
			
		||||
 | 
			
		||||
Code Example
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
For sheer demonstrative purposes, the following code encrypts a provided single
 | 
			
		||||
block of plaintext with AES-256 using two different keys.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/aes.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Available Ciphers
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
Botan includes a number of block ciphers that are specific to particular countries, as
 | 
			
		||||
well as a few that are included mostly due to their use in specific protocols such as PGP
 | 
			
		||||
but not widely used elsewhere. If you are developing new code and have no particular
 | 
			
		||||
opinion, use AES-256. If you desire an alternative to AES, consider Serpent, SHACAL2 or
 | 
			
		||||
Threefish.
 | 
			
		||||
 | 
			
		||||
.. warning:: Avoid any 64-bit block cipher in new designs. There are
 | 
			
		||||
             combinatoric issues that affect any 64-bit cipher that render it
 | 
			
		||||
             insecure when large amounts of data are processed.
 | 
			
		||||
 | 
			
		||||
AES
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Comes in three variants, AES-128, AES-192, and AES-256.
 | 
			
		||||
 | 
			
		||||
The standard 128-bit block cipher. Many modern platforms offer hardware
 | 
			
		||||
acceleration. However, on platforms without hardware support, AES
 | 
			
		||||
implementations typically are vulnerable to side channel attacks. For x86
 | 
			
		||||
systems with SSSE3 but without AES-NI, Botan has an implementation which avoids
 | 
			
		||||
known side channels.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AES`` is defined.
 | 
			
		||||
 | 
			
		||||
ARIA
 | 
			
		||||
~~~~~~
 | 
			
		||||
 | 
			
		||||
South Korean cipher used in industry there. No reason to use it otherwise.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_ARIA`` is defined.
 | 
			
		||||
 | 
			
		||||
Blowfish
 | 
			
		||||
~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A 64-bit cipher popular in the pre-AES era. Very slow key setup. Also used (with
 | 
			
		||||
bcrypt) for password hashing.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_BLOWFISH`` is defined.
 | 
			
		||||
 | 
			
		||||
CAST-128
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A 64-bit cipher, commonly used in OpenPGP.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CAST128`` is defined.
 | 
			
		||||
 | 
			
		||||
Camellia
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Comes in three variants, Camellia-128, Camellia-192, and Camellia-256.
 | 
			
		||||
 | 
			
		||||
A Japanese design standardized by ISO, NESSIE and CRYPTREC.
 | 
			
		||||
Rarely used outside of Japan.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CAMELLIA`` is defined.
 | 
			
		||||
 | 
			
		||||
Cascade
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Creates a block cipher cascade, where each block is encrypted by two ciphers
 | 
			
		||||
with independent keys. Useful if you're very paranoid. In practice any single
 | 
			
		||||
good cipher (such as Serpent, SHACAL2, or AES-256) is more than sufficient.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CASCADE`` is defined.
 | 
			
		||||
 | 
			
		||||
DES and 3DES
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Originally designed by IBM and NSA in the 1970s. Today, DES's 56-bit key renders
 | 
			
		||||
it insecure to any well-resourced attacker. 3DES extends the key length,
 | 
			
		||||
and is still thought to be secure, modulo the limitation of a 64-bit block.
 | 
			
		||||
All are somewhat common in some industries such as finance. Avoid in new code.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_DES`` is defined.
 | 
			
		||||
 | 
			
		||||
GOST-28147-89
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Aka "Magma". An old 64-bit Russian cipher. Possible security issues, avoid
 | 
			
		||||
unless compatibility is needed.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_GOST_28147_89`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Support for this cipher is deprecated and will be removed in a future major release.
 | 
			
		||||
 | 
			
		||||
IDEA
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
An older but still unbroken 64-bit cipher with a 128-bit key. Somewhat common
 | 
			
		||||
due to its use in PGP. Avoid in new designs.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_IDEA`` is defined.
 | 
			
		||||
 | 
			
		||||
Kuznyechik
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 3.2
 | 
			
		||||
 | 
			
		||||
Newer Russian national cipher, also known as GOST R 34.12-2015 or "Grasshopper".
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   The sbox of this cipher is supposedly random, but was found to have a
 | 
			
		||||
   mathematical structure which is exceedingly unlikely to have occured by
 | 
			
		||||
   chance. This may indicate the existence of a backdoor or other issue. Avoid
 | 
			
		||||
   using this cipher unless strictly required.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_KUZNYECHIK`` is defined.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Lion
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A "block cipher construction" which can encrypt blocks of nearly arbitrary
 | 
			
		||||
length.  Built from a stream cipher and a hash function. Useful in certain
 | 
			
		||||
protocols where being able to encrypt large or arbitrary length blocks is
 | 
			
		||||
necessary.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_LION`` is defined.
 | 
			
		||||
 | 
			
		||||
Noekeon
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A fast 128-bit cipher by the designers of AES. Easily secured against side
 | 
			
		||||
channels. Quite obscure however.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_NOEKEON`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Noekeon support is deprecated and will be removed in a future major release.
 | 
			
		||||
 | 
			
		||||
SEED
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A older South Korean cipher, widely used in industry there. No reason to choose it otherwise.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SEED`` is defined.
 | 
			
		||||
 | 
			
		||||
SHACAL2
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
The 256-bit block cipher used inside SHA-256. Accepts up to a 512-bit key.
 | 
			
		||||
Fast, especially when SIMD or SHA-2 acceleration instructions are available.
 | 
			
		||||
Standardized by NESSIE but otherwise obscure.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHACAL2`` is defined.
 | 
			
		||||
 | 
			
		||||
SM4
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A 128-bit Chinese national cipher, required for use in certain commercial
 | 
			
		||||
applications in China. Quite slow. Probably no reason to use it outside of legal
 | 
			
		||||
requirements.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SM4`` is defined.
 | 
			
		||||
 | 
			
		||||
Serpent
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
An AES contender. Widely considered the most conservative design. Fairly slow
 | 
			
		||||
unless SIMD instructions are available.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SERPENT`` is defined.
 | 
			
		||||
 | 
			
		||||
Threefish-512
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A 512-bit tweakable block cipher that was used in the Skein hash function.
 | 
			
		||||
Very fast on 64-bit processors.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_THREEFISH_512`` is defined.
 | 
			
		||||
 | 
			
		||||
Twofish
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A 128-bit block cipher that was one of the AES finalists. Has a somewhat complicated key
 | 
			
		||||
setup and a "kitchen sink" design.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_TWOFISH`` is defined.
 | 
			
		||||
@@ -1,377 +0,0 @@
 | 
			
		||||
.. _cipher_modes:
 | 
			
		||||
 | 
			
		||||
Cipher Modes
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
A block cipher by itself, is only able to securely encrypt a single data block.
 | 
			
		||||
To be able to securely encrypt data of arbitrary length, a mode of operation
 | 
			
		||||
applies the block cipher's single block operation repeatedly to encrypt
 | 
			
		||||
an entire message.
 | 
			
		||||
 | 
			
		||||
All cipher mode implementations are are derived from the base class
 | 
			
		||||
:cpp:class:`Cipher_Mode`, which is declared in ``botan/cipher_mode.h``.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Using an unauthenticted cipher mode without combining it with a
 | 
			
		||||
   :ref:`mac` is insecure. Prefer using an :ref:`aead`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Cipher_Mode
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_key(const uint8_t* key, size_t length)
 | 
			
		||||
 | 
			
		||||
    Set the symmetric key to be used.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_keylength(size_t length) const
 | 
			
		||||
 | 
			
		||||
     This function returns true if and only if *length* is a valid
 | 
			
		||||
     keylength for the algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t minimum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the smallest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t maximum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the largest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t default_nonce_length() const
 | 
			
		||||
 | 
			
		||||
    Return the default (preferable) nonce size for this cipher mode.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_nonce_length(size_t nonce_len) const
 | 
			
		||||
 | 
			
		||||
    Return true if *nonce_len* is a valid length for a nonce with this
 | 
			
		||||
    algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool authenticated() const
 | 
			
		||||
 | 
			
		||||
    Return true if this cipher mode is authenticated
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t tag_size() const
 | 
			
		||||
 | 
			
		||||
    Return the length in bytes of the authentication tag this algorithm
 | 
			
		||||
    generates. If the mode is not authenticated, this will return 0. If the mode
 | 
			
		||||
    is authenticated, it will return some positive value (typically somewhere
 | 
			
		||||
    between 8 and 16).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void clear()
 | 
			
		||||
 | 
			
		||||
    Clear all internal state. The object will act exactly like one which was
 | 
			
		||||
    just allocated.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void reset()
 | 
			
		||||
 | 
			
		||||
    Reset all message state. For example if you called :cpp:func:`start_msg`,
 | 
			
		||||
    then :cpp:func:`process` to process some ciphertext, but then encounter an
 | 
			
		||||
    IO error and must abandon the current message, you can call `reset`. The
 | 
			
		||||
    object will retain the key (unlike calling :cpp:func:`clear` which also
 | 
			
		||||
    resets the key) but the nonce and current message state will be erased.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start_msg(const uint8_t* nonce, size_t nonce_len)
 | 
			
		||||
 | 
			
		||||
    Set up for processing a new message. This function must be called with a new
 | 
			
		||||
    random value for each message. For almost all modes (excepting SIV), if the
 | 
			
		||||
    same nonce is ever used twice with the same key, the encryption scheme loses
 | 
			
		||||
    its confidentiality and/or authenticity properties.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start(const std::vector<uint8_t> nonce)
 | 
			
		||||
 | 
			
		||||
    Acts like :cpp:func:`start_msg`\ (nonce.data(), nonce.size()).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start(const uint8_t* nonce, size_t nonce_len)
 | 
			
		||||
 | 
			
		||||
    Acts like :cpp:func:`start_msg`\ (nonce, nonce_len).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: virtual size_t update_granularity() const
 | 
			
		||||
 | 
			
		||||
    The :cpp:class:`Cipher_Mode` interface requires message processing in multiples of the block size.
 | 
			
		||||
    Returns size of required blocks to update. Will return 1 if the mode implementation
 | 
			
		||||
    does not require buffering.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: virtual size_t ideal_granularity() const
 | 
			
		||||
 | 
			
		||||
    Returns a multiple of update_granularity sized for ideal performance.
 | 
			
		||||
 | 
			
		||||
    In fact this is not truly the "ideal" buffer size but just reflects the
 | 
			
		||||
    smallest possible buffer that can reasonably take advantage of available
 | 
			
		||||
    parallelism (due to SIMD execution, etc). If you are concerned about
 | 
			
		||||
    performance, it may be advisable to take this return value and scale it to
 | 
			
		||||
    approximately 4 KB, and use buffers of that size.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: virtual size_t process(uint8_t* msg, size_t msg_len)
 | 
			
		||||
 | 
			
		||||
    Process msg in place and returns the number of bytes written. *msg* must
 | 
			
		||||
    be a multiple of :cpp:func:`update_granularity`.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(secure_vector<uint8_t>& buffer, size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
    Continue processing a message in the buffer in place. The passed buffer's
 | 
			
		||||
    size must be a multiple of :cpp:func:`update_granularity`.  The first
 | 
			
		||||
    *offset* bytes of the buffer will be ignored.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t minimum_final_size() const
 | 
			
		||||
 | 
			
		||||
    Returns the minimum size needed for :cpp:func:`finish`. This is used for
 | 
			
		||||
    example when processing an AEAD message, to ensure the tag is available. In
 | 
			
		||||
    that case, the encryption side will return 0 (since the tag is generated,
 | 
			
		||||
    rather than being provided) while the decryption mode will return the size
 | 
			
		||||
    of the tag.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void finish(secure_vector<uint8_t>& final_block, size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
    Finalize the message processing with a final block of at least :cpp:func:`minimum_final_size` size.
 | 
			
		||||
    The first *offset* bytes of the passed final block will be ignored.
 | 
			
		||||
 | 
			
		||||
Code Example
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
The following code encrypts the specified plaintext using AES-128/CBC
 | 
			
		||||
with PKCS#7 padding.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   This example ignores the requirement to authenticate the ciphertext
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   Simply replacing the string "AES-128/CBC/PKCS7" string in the example below
 | 
			
		||||
   with "AES-128/GCM" suffices to use authenticated encryption.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/aes_cbc.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Available Unauthenticated Cipher Modes
 | 
			
		||||
-----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   CTR and OFB modes are also implemented, but these are treated as
 | 
			
		||||
   :cpp:class:`Stream_Cipher`\s instead.
 | 
			
		||||
 | 
			
		||||
CBC
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_MODE_CBC`` is defined.
 | 
			
		||||
 | 
			
		||||
CBC requires the plaintext be padded using a reversible rule. The following
 | 
			
		||||
padding schemes are implemented
 | 
			
		||||
 | 
			
		||||
PKCS#7 (RFC5652)
 | 
			
		||||
  The last byte in the padded block defines the padding length p, the remaining padding bytes are set to p as well.
 | 
			
		||||
ANSI X9.23
 | 
			
		||||
  The last byte in the padded block defines the padding length, the remaining padding is filled with 0x00.
 | 
			
		||||
OneAndZeros (ISO/IEC 7816-4)
 | 
			
		||||
  The first padding byte is set to 0x80, the remaining padding bytes are set to 0x00.
 | 
			
		||||
 | 
			
		||||
Ciphertext stealing (CTS) is also implemented. This scheme allows the
 | 
			
		||||
ciphertext to have the same length as the plaintext, however using CTS
 | 
			
		||||
requires the input be at least one full block plus one byte. It is
 | 
			
		||||
also less commonly implemented.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Using CBC with padding without an authentication mode exposes your
 | 
			
		||||
   application to CBC padding oracle attacks, which allow recovering
 | 
			
		||||
   the plaintext of arbitrary messages. Always pair CBC with a MAC such
 | 
			
		||||
   as HMAC (or, preferably, use an AEAD such as GCM).
 | 
			
		||||
 | 
			
		||||
CFB
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_MODE_CFB`` is defined.
 | 
			
		||||
 | 
			
		||||
CFB uses a block cipher to create a self-synchronizing stream cipher. It is used
 | 
			
		||||
for example in the OpenPGP protocol. There is no reason to prefer it, as it has
 | 
			
		||||
worse performance characteristics than modes such as CTR or CBC.
 | 
			
		||||
 | 
			
		||||
XTS
 | 
			
		||||
~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_MODE_XTS`` is defined.
 | 
			
		||||
 | 
			
		||||
XTS is a mode specialized for encrypting disk or database storage
 | 
			
		||||
where ciphertext expansion is not possible. XTS requires all inputs be
 | 
			
		||||
at least one full block (16 bytes for AES), however for any acceptable
 | 
			
		||||
input length, there is no ciphertext expansion.
 | 
			
		||||
 | 
			
		||||
.. _aead:
 | 
			
		||||
 | 
			
		||||
AEAD Mode
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
AEAD (Authenticated Encryption with Associated Data) modes provide message
 | 
			
		||||
encryption, message authentication, and the ability to authenticate additional
 | 
			
		||||
data that is not included in the ciphertext (such as a sequence number or
 | 
			
		||||
header). It is a subclass of :cpp:class:`Cipher_Mode`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: AEAD_Mode
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_key(const SymmetricKey& key)
 | 
			
		||||
 | 
			
		||||
       Set the key
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Key_Length_Specification key_spec() const
 | 
			
		||||
 | 
			
		||||
       Return the key length specification
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_associated_data(const uint8_t ad[], size_t ad_len)
 | 
			
		||||
 | 
			
		||||
       Set any associated data for this message. For maximum portability between
 | 
			
		||||
       different modes, this must be called after :cpp:func:`set_key` and before
 | 
			
		||||
       :cpp:func:`start`.
 | 
			
		||||
 | 
			
		||||
       If the associated data does not change, it is not necessary to call this
 | 
			
		||||
       function more than once, even across multiple calls to :cpp:func:`start`
 | 
			
		||||
       and :cpp:func:`finish`.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start(const uint8_t nonce[], size_t nonce_len)
 | 
			
		||||
 | 
			
		||||
       Start processing a message, using *nonce* as the unique per-message
 | 
			
		||||
       value. It does not need to be random, simply unique (per key).
 | 
			
		||||
 | 
			
		||||
       .. warning::
 | 
			
		||||
          With almost all AEADs, if the same nonce is ever used to encrypt two
 | 
			
		||||
          different messages under the same key, all security is lost. If
 | 
			
		||||
          reliably generating unique nonces is difficult in your environment,
 | 
			
		||||
          use SIV mode which retains security even if nonces are repeated.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(secure_vector<uint8_t>& buffer, size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
       Continue processing a message. The *buffer* is an in/out parameter and
 | 
			
		||||
       may be resized. In particular, some modes require that all input be
 | 
			
		||||
       consumed before any output is produced; with these modes, *buffer* will
 | 
			
		||||
       be returned empty.
 | 
			
		||||
 | 
			
		||||
       On input, the buffer must be sized in blocks of size
 | 
			
		||||
       :cpp:func:`update_granularity`. For instance if the update granularity
 | 
			
		||||
       was 64, then *buffer* could be 64, 128, 192, ... bytes.
 | 
			
		||||
 | 
			
		||||
       The first *offset* bytes of *buffer* will be ignored (this allows in
 | 
			
		||||
       place processing of a buffer that contains an initial plaintext header)
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void finish(secure_vector<uint8_t>& buffer, size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
       Complete processing a message with a final input of *buffer*, which is
 | 
			
		||||
       treated the same as with :cpp:func:`update`. It must contain at least
 | 
			
		||||
       :cpp:func:`final_minimum_size` bytes.
 | 
			
		||||
 | 
			
		||||
       Note that if you have the entire message in hand, calling finish without
 | 
			
		||||
       ever calling update is both efficient and convenient.
 | 
			
		||||
 | 
			
		||||
       .. note::
 | 
			
		||||
 | 
			
		||||
          During decryption, if the supplied authentication tag does not
 | 
			
		||||
          validate, finish will throw an instance of Invalid_Authentication_Tag
 | 
			
		||||
          (aka Integrity_Failure, which was the name for this exception in
 | 
			
		||||
          versions before 2.10, a typedef is included for compatability).
 | 
			
		||||
 | 
			
		||||
          If this occurs, all plaintext previously output via calls to update
 | 
			
		||||
          must be destroyed and not used in any way that an attacker could
 | 
			
		||||
          observe the effects of. This could be anything from echoing the
 | 
			
		||||
          plaintext back (perhaps in an error message), or by making an external
 | 
			
		||||
          RPC whose destination or contents depend on the plaintext. The only
 | 
			
		||||
          thing you can do is buffer it, and in the event of an invalid tag,
 | 
			
		||||
          erase the previously decrypted content from memory.
 | 
			
		||||
 | 
			
		||||
          One simply way to assure this could never happen is to never
 | 
			
		||||
          call update, and instead always marshal the entire message
 | 
			
		||||
          into a single buffer and call finish on it when decrypting.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t update_granularity() const
 | 
			
		||||
 | 
			
		||||
       The AEAD interface requires :cpp:func:`update` be called with blocks of
 | 
			
		||||
       this size. This will be 1, if the mode can process any length inputs.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t final_minimum_size() const
 | 
			
		||||
 | 
			
		||||
       The AEAD interface requires :cpp:func:`finish` be called with at least
 | 
			
		||||
       this many bytes (which may be zero, or greater than
 | 
			
		||||
       :cpp:func:`update_granularity`)
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_nonce_length(size_t nonce_len) const
 | 
			
		||||
 | 
			
		||||
       Returns true if *nonce_len* is a valid nonce length for this scheme. For
 | 
			
		||||
       EAX and GCM, any length nonces are allowed. OCB allows any value between
 | 
			
		||||
       8 and 15 bytes.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t default_nonce_length() const
 | 
			
		||||
 | 
			
		||||
       Returns a reasonable length for the nonce, typically either 96
 | 
			
		||||
       bits, or the only supported length for modes which don't
 | 
			
		||||
       support 96 bit nonces.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Available AEAD Modes
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
If in doubt about what to use, pick ChaCha20Poly1305, AES-256/GCM, or AES-256/SIV.
 | 
			
		||||
Both ChaCha20Poly1305 and AES with GCM are widely implemented. SIV is somewhat
 | 
			
		||||
more obscure (and is slower than either GCM or ChaCha20Poly1305), but has
 | 
			
		||||
excellent security properties.
 | 
			
		||||
 | 
			
		||||
ChaCha20Poly1305
 | 
			
		||||
~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AEAD_CHACHA20_POLY1305`` is defined.
 | 
			
		||||
 | 
			
		||||
Unlike the other AEADs which are based on block ciphers, this mode is based on
 | 
			
		||||
the ChaCha stream cipher and the Poly1305 authentication code. It is very fast
 | 
			
		||||
on all modern platforms.
 | 
			
		||||
 | 
			
		||||
ChaCha20Poly1305 supports 64-bit, 96-bit, and (since 2.8) 192-bit nonces. 64-bit nonces
 | 
			
		||||
are the "classic" ChaCha20Poly1305 design. 96-bit nonces are used by the IETF standard
 | 
			
		||||
version of ChaCha20Poly1305. And 192-bit nonces is the XChaCha20Poly1305 construction,
 | 
			
		||||
which is somewhat less common.
 | 
			
		||||
 | 
			
		||||
For best interop use the IETF version with 96-bit nonces. However 96 bits is small enough
 | 
			
		||||
that it can be dangerous to generate nonces randomly if more than ~ 2^32 messages are
 | 
			
		||||
encrypted under a single key, since if a nonce is ever reused ChaCha20Poly1305 becomes
 | 
			
		||||
insecure. It is better to use a counter for the nonce in this case.
 | 
			
		||||
 | 
			
		||||
If you are encrypting many messages under a single key and cannot maintain a counter for
 | 
			
		||||
the nonce, prefer XChaCha20Poly1305 since a 192 bit nonce is large enough that randomly
 | 
			
		||||
chosen nonces are extremely unlikely to repeat.
 | 
			
		||||
 | 
			
		||||
GCM
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AEAD_GCM`` is defined.
 | 
			
		||||
 | 
			
		||||
NIST standard, commonly used. Requires a 128-bit block cipher. Fairly slow,
 | 
			
		||||
unless hardware support for carryless multiplies is available.
 | 
			
		||||
 | 
			
		||||
OCB
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AEAD_OCB`` is defined.
 | 
			
		||||
 | 
			
		||||
A block cipher based AEAD. Supports 128-bit, 256-bit and 512-bit block ciphers.
 | 
			
		||||
This mode is very fast and easily secured against side channels. Adoption has
 | 
			
		||||
been poor because until 2021 it was patented in the United States. The patent
 | 
			
		||||
was allowed to lapse in early 2021.
 | 
			
		||||
 | 
			
		||||
EAX
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AEAD_EAX`` is defined.
 | 
			
		||||
 | 
			
		||||
A secure composition of CTR mode and CMAC. Supports 128-bit, 256-bit and 512-bit
 | 
			
		||||
block ciphers.
 | 
			
		||||
 | 
			
		||||
SIV
 | 
			
		||||
~~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AEAD_SIV`` is defined.
 | 
			
		||||
 | 
			
		||||
Requires a 128-bit block cipher. Unlike other AEADs, SIV is "misuse resistant";
 | 
			
		||||
if a nonce is repeated, SIV retains security, with the exception that if the
 | 
			
		||||
same nonce is used to encrypt the same message multiple times, an attacker can
 | 
			
		||||
detect the fact that the message was duplicated (this is simply because if both
 | 
			
		||||
the nonce and the message are reused, SIV will output identical ciphertexts).
 | 
			
		||||
 | 
			
		||||
CCM
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_AEAD_CCM`` is defined.
 | 
			
		||||
 | 
			
		||||
A composition of CTR mode and CBC-MAC. Requires a 128-bit block cipher. This is
 | 
			
		||||
a NIST standard mode, but that is about all to recommend it. Prefer EAX.
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
Lossless Data Compression
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Some lossless data compression algorithms are available in botan, currently all
 | 
			
		||||
via third party libraries - these include zlib (including deflate and gzip
 | 
			
		||||
formats), bzip2, and lzma. Support for these must be enabled at build time;
 | 
			
		||||
you can check for them using the macros ``BOTAN_HAS_ZLIB``, ``BOTAN_HAS_BZIP2``,
 | 
			
		||||
and ``BOTAN_HAS_LZMA``.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   You should always compress *before* you encrypt, because encryption seeks to
 | 
			
		||||
   hide the redundancy that compression is supposed to try to find and remove.
 | 
			
		||||
 | 
			
		||||
Compression is done through the ``Compression_Algorithm`` and
 | 
			
		||||
``Decompression_Algorithm`` classes, both defined in `compression.h`
 | 
			
		||||
 | 
			
		||||
Compression and decompression both work in three stages: starting a
 | 
			
		||||
message (``start``), continuing to process it (``update``), and then
 | 
			
		||||
finally completing processing the stream (``finish``).
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Compression_Algorithm
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start(size_t level)
 | 
			
		||||
 | 
			
		||||
       Initialize the compression engine. This must be done before calling
 | 
			
		||||
       ``update`` or ``finish``. The meaning of the `level` parameter varies by
 | 
			
		||||
       the algorithm but generally takes a value between 1 and 9, with higher
 | 
			
		||||
       values implying typically better compression from and more memory and/or
 | 
			
		||||
       CPU time consumed by the compression process. The decompressor can always
 | 
			
		||||
       handle input from any compressor.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function::  void update(secure_vector<uint8_t>& buf, \
 | 
			
		||||
                                 size_t offset = 0, bool flush = false)
 | 
			
		||||
 | 
			
		||||
       Compress the material in the in/out parameter ``buf``. The leading
 | 
			
		||||
       ``offset`` bytes of ``buf`` are ignored and remain untouched; this can be
 | 
			
		||||
       useful for ignoring packet headers.  If ``flush`` is true, the
 | 
			
		||||
       compression state is flushed, allowing the decompressor to recover the
 | 
			
		||||
       entire message up to this point without having the see the rest of the
 | 
			
		||||
       compressed stream.
 | 
			
		||||
 | 
			
		||||
   .. cpp::function:: void finish(secure_vector<uint8_t>& buf, size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
       Finish compressing a message. The ``buf`` and ``offset`` parameters are
 | 
			
		||||
       treated as in ``update``. It is acceptable to call ``start`` followed by
 | 
			
		||||
       ``finish`` with the entire message, without any intervening call to
 | 
			
		||||
       ``update``.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Decompression_Algorithm
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start()
 | 
			
		||||
 | 
			
		||||
       Initialize the decompression engine. This must be done before calling
 | 
			
		||||
       ``update`` or ``finish``. No level is provided here; the decompressor
 | 
			
		||||
       can accept input generated by any compression parameters.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function::  void update(secure_vector<uint8_t>& buf, \
 | 
			
		||||
                                 size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
       Decompress the material in the in/out parameter ``buf``. The leading
 | 
			
		||||
       ``offset`` bytes of ``buf`` are ignored and remain untouched; this can be
 | 
			
		||||
       useful for ignoring packet headers.
 | 
			
		||||
 | 
			
		||||
       This function may throw if the data seems to be invalid.
 | 
			
		||||
 | 
			
		||||
   .. cpp::function:: void finish(secure_vector<uint8_t>& buf, size_t offset = 0)
 | 
			
		||||
 | 
			
		||||
       Finish decompressing a message. The ``buf`` and ``offset`` parameters are
 | 
			
		||||
       treated as in ``update``. It is acceptable to call ``start`` followed by
 | 
			
		||||
       ``finish`` with the entire message, without any intervening call to
 | 
			
		||||
       ``update``.
 | 
			
		||||
 | 
			
		||||
       This function may throw if the data seems to be invalid.
 | 
			
		||||
 | 
			
		||||
The easiest way to get a compressor is via the functions
 | 
			
		||||
``Compression_Algorithm::create`` and
 | 
			
		||||
``Decompression_Algorithm::create`` which both accept a string
 | 
			
		||||
argument which can take values include `zlib` (raw zlib with no
 | 
			
		||||
checksum), `deflate` (zlib's deflate format), `gzip`, `bz2`, and
 | 
			
		||||
`lzma`. A null pointer will be returned if the algorithm is
 | 
			
		||||
unavailable.
 | 
			
		||||
 | 
			
		||||
Two older functions for this are
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Compression_Algorithm* make_compressor(std::string type)
 | 
			
		||||
.. cpp:function:: Decompression_Algorithm* make_decompressor(std::string type)
 | 
			
		||||
 | 
			
		||||
which call the relevant ``create`` function and then ``release`` the
 | 
			
		||||
returned ``unique_ptr``. Avoid these in new code.
 | 
			
		||||
 | 
			
		||||
To use a compression algorithm in a `Pipe` use the adapter types
 | 
			
		||||
`Compression_Filter` and `Decompression_Filter` from `comp_filter.h`. The
 | 
			
		||||
constructors of both filters take a `std::string` argument (passed to
 | 
			
		||||
`make_compressor` or `make_decompressor`), the compression filter also takes a
 | 
			
		||||
`level` parameter. Finally both constructors have a parameter `buf_sz` which
 | 
			
		||||
specifies the size of the internal buffer that will be used - inputs will be
 | 
			
		||||
broken into blocks of this size. The default is 4096.
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
 | 
			
		||||
API Reference
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :maxdepth: 1
 | 
			
		||||
 | 
			
		||||
   footguns
 | 
			
		||||
   versions
 | 
			
		||||
   secmem
 | 
			
		||||
   rng
 | 
			
		||||
   hash
 | 
			
		||||
   block_cipher
 | 
			
		||||
   stream_ciphers
 | 
			
		||||
   message_auth_codes
 | 
			
		||||
   cipher_modes
 | 
			
		||||
   pubkey
 | 
			
		||||
   x509
 | 
			
		||||
   tls
 | 
			
		||||
   credentials_manager
 | 
			
		||||
   bigint
 | 
			
		||||
   kdf
 | 
			
		||||
   pbkdf
 | 
			
		||||
   keywrap
 | 
			
		||||
   passhash
 | 
			
		||||
   cryptobox
 | 
			
		||||
   srp
 | 
			
		||||
   psk_db
 | 
			
		||||
   filters
 | 
			
		||||
   fpe
 | 
			
		||||
   tss
 | 
			
		||||
   ecc
 | 
			
		||||
   compression
 | 
			
		||||
   pkcs11
 | 
			
		||||
   tpm
 | 
			
		||||
   otp
 | 
			
		||||
   roughtime
 | 
			
		||||
   zfec
 | 
			
		||||
   ffi
 | 
			
		||||
   env_vars
 | 
			
		||||
   python
 | 
			
		||||
@@ -1,197 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Credentials Manager
 | 
			
		||||
==================================================
 | 
			
		||||
 | 
			
		||||
A ``Credentials_Manager`` is a way to abstract how the application
 | 
			
		||||
stores credentials. The main user is the :doc:`tls` implementation.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Credentials_Manager
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<Certificate_Store*> \
 | 
			
		||||
         trusted_certificate_authorities( \
 | 
			
		||||
         const std::string& type, \
 | 
			
		||||
         const std::string& context)
 | 
			
		||||
 | 
			
		||||
      Return the list of certificate stores, each of which is assumed
 | 
			
		||||
      to contain (only) trusted certificate authorities. The
 | 
			
		||||
      ``Credentials_Manager`` retains ownership of the
 | 
			
		||||
      Certificate_Store pointers.
 | 
			
		||||
 | 
			
		||||
      .. note::
 | 
			
		||||
 | 
			
		||||
         It would have been a better API to return a vector of
 | 
			
		||||
         ``shared_ptr`` here.  This may change in a future major release.
 | 
			
		||||
 | 
			
		||||
      When *type* is "tls-client", *context* will be the hostname of
 | 
			
		||||
      the server, or empty if the hostname is not known. This allows
 | 
			
		||||
      using a different set of certificate stores in different contexts,
 | 
			
		||||
      for example using the system certificate store unless contacting
 | 
			
		||||
      one particular server which uses a cert issued by an internal CA.
 | 
			
		||||
 | 
			
		||||
      When *type* is "tls-server", the *context* will again be the
 | 
			
		||||
      hostname of the server, or empty if the client did not send a
 | 
			
		||||
      server name indicator. For TLS servers, these CAs are the ones
 | 
			
		||||
      trusted for signing of client certificates. If you do not want
 | 
			
		||||
      the TLS server to ask for a client cert,
 | 
			
		||||
      ``trusted_certificate_authorities`` should return an empty list
 | 
			
		||||
      for *type* "tls-server".
 | 
			
		||||
 | 
			
		||||
      The default implementation returns an empty list.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<X509_Certificate> find_cert_chain( \
 | 
			
		||||
                     const std::vector<std::string>& cert_key_types, \
 | 
			
		||||
                     const std::vector<X509_DN>& acceptable_CAs, \
 | 
			
		||||
                     const std::string& type, \
 | 
			
		||||
                     const std::string& context)
 | 
			
		||||
 | 
			
		||||
      Return the certificate chain to use to identify ourselves. The
 | 
			
		||||
      ``acceptable_CAs`` parameter gives a list of CAs the peer trusts.
 | 
			
		||||
      This may be empty.
 | 
			
		||||
 | 
			
		||||
      .. warning::
 | 
			
		||||
         If this function returns a certificate that is not one of the
 | 
			
		||||
         types given in ``cert_key_types`` confusing handshake
 | 
			
		||||
         failures will result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<X509_Certificate> cert_chain( \
 | 
			
		||||
         const std::vector<std::string>& cert_key_types, \
 | 
			
		||||
         const std::string& type, \
 | 
			
		||||
         const std::string& context)
 | 
			
		||||
 | 
			
		||||
      Return the certificate chain to use to identify ourselves. Starting in
 | 
			
		||||
      2.5, prefer ``find_cert_chain`` which additionally provides the CA list.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<X509_Certificate> cert_chain_single_type( \
 | 
			
		||||
         const std::string& cert_key_type, \
 | 
			
		||||
         const std::string& type, \
 | 
			
		||||
         const std::string& context)
 | 
			
		||||
 | 
			
		||||
      Return the certificate chain to use to identifier ourselves, if
 | 
			
		||||
      we have one of type *cert_key_type* and we would like to use a
 | 
			
		||||
      certificate in this *type*/*context*.
 | 
			
		||||
 | 
			
		||||
      For servers *type* will be "tls-server" and the *context* will
 | 
			
		||||
      be the server name that the client requested via SNI (or empty,
 | 
			
		||||
      if the client did not send SNI).
 | 
			
		||||
 | 
			
		||||
      .. warning::
 | 
			
		||||
 | 
			
		||||
         To avoid cross-protocol attacks it is recommended that if a server
 | 
			
		||||
         receives an SNI request for a name it does not expect, it should close
 | 
			
		||||
         the connection with an alert. This can be done by throwing an exception
 | 
			
		||||
         from the implementation of this function.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::shared_ptr<Private_Key> private_key_for(const X509_Certificate& cert, \
 | 
			
		||||
                                                  const std::string& type, \
 | 
			
		||||
                                                  const std::string& context)
 | 
			
		||||
 | 
			
		||||
      Return a shared pointer to the private key for this certificate. The
 | 
			
		||||
      *cert* will be the leaf cert of a chain returned previously by
 | 
			
		||||
      ``cert_chain`` or ``cert_chain_single_type``.
 | 
			
		||||
 | 
			
		||||
In versions before 1.11.34, there was an additional function on `Credentials_Manager`
 | 
			
		||||
 | 
			
		||||
   .. cpp::function:: void verify_certificate_chain( \
 | 
			
		||||
         const std::string& type, \
 | 
			
		||||
         const std::string& hostname, \
 | 
			
		||||
         const std::vector<X509_Certificate>& cert_chain)
 | 
			
		||||
 | 
			
		||||
This function has been replaced by `TLS::Callbacks::tls_verify_cert_chain`.
 | 
			
		||||
 | 
			
		||||
SRP Authentication
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
``Credentials_Manager`` contains the hooks used by TLS clients and
 | 
			
		||||
servers for SRP authentication.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Support for TLS-SRP is deprecated, and will be removed in a future
 | 
			
		||||
   major release. When that occurs these APIs will be removed. Prefer
 | 
			
		||||
   instead performing a standard TLS handshake, then perform a PAKE
 | 
			
		||||
   authentication inside of (and cryptographically bound to) the TLS
 | 
			
		||||
   channel.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: bool attempt_srp(const std::string& type, \
 | 
			
		||||
                                   const std::string& context)
 | 
			
		||||
 | 
			
		||||
   Returns if we should consider using SRP for authentication
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string srp_identifier(const std::string& type, \
 | 
			
		||||
                                             const std::string& context)
 | 
			
		||||
 | 
			
		||||
   Returns the SRP identifier we'd like to use (used by client)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string srp_password(const std::string& type, \
 | 
			
		||||
                                           const std::string& context, \
 | 
			
		||||
                                           const std::string& identifier)
 | 
			
		||||
 | 
			
		||||
   Returns the password for *identifier* (used by client)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: bool srp_verifier(const std::string& type, \
 | 
			
		||||
                                    const std::string& context, \
 | 
			
		||||
                                    const std::string& identifier, \
 | 
			
		||||
                                    std::string& group_name, \
 | 
			
		||||
                                    BigInt& verifier, \
 | 
			
		||||
                                    std::vector<uint8_t>& salt, \
 | 
			
		||||
                                    bool generate_fake_on_unknown)
 | 
			
		||||
 | 
			
		||||
    Returns the SRP verifier information for *identifier* (used by server)
 | 
			
		||||
 | 
			
		||||
Preshared Keys
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
TLS supports the use of pre shared keys for authentication.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: SymmetricKey psk(const std::string& type, \
 | 
			
		||||
                                   const std::string& context, \
 | 
			
		||||
                                   const std::string& identity)
 | 
			
		||||
 | 
			
		||||
    Return a symmetric key for use with *identity*
 | 
			
		||||
 | 
			
		||||
    One important special case for ``psk`` is where *type* is
 | 
			
		||||
    "tls-server", *context* is "session-ticket" and *identity* is an
 | 
			
		||||
    empty string. If a key is returned for this case, a TLS server
 | 
			
		||||
    will offer session tickets to clients who can use them, and the
 | 
			
		||||
    returned key will be used to encrypt the ticket. The server is
 | 
			
		||||
    allowed to change the key at any time (though changing the key
 | 
			
		||||
    means old session tickets can no longer be used for resumption,
 | 
			
		||||
    forcing a full re-handshake when the client next connects). One
 | 
			
		||||
    simple approach to add support for session tickets in your server
 | 
			
		||||
    is to generate a random key the first time ``psk`` is called to
 | 
			
		||||
    retrieve the session ticket key, cache it for later use in the
 | 
			
		||||
    ``Credentials_Manager``, and simply let it be thrown away when the
 | 
			
		||||
    process terminates. See :rfc:`4507` for more information about TLS
 | 
			
		||||
    session tickets.
 | 
			
		||||
 | 
			
		||||
    A similar special case exists for DTLS cookie verification. In
 | 
			
		||||
    this case *type* will be "tls-server" and *context* is
 | 
			
		||||
    "dtls-cookie-secret". If no key is returned, then DTLS cookies are
 | 
			
		||||
    not used. Similar to the session ticket key, the DTLS cookie
 | 
			
		||||
    secret can be chosen during server startup and rotated at any time
 | 
			
		||||
    with no ill effect.
 | 
			
		||||
 | 
			
		||||
    .. warning::
 | 
			
		||||
 | 
			
		||||
       If DTLS cookies are not used then the server is prone to be
 | 
			
		||||
       abused as a DoS amplifier, where the attacker sends a
 | 
			
		||||
       relatively small client hello in a UDP packet with a forged
 | 
			
		||||
       return address, and then the server replies to the victim with
 | 
			
		||||
       several messages that are larger. This not only hides the
 | 
			
		||||
       attackers address from the victim, but increases their
 | 
			
		||||
       effective bandwidth. This is not an issue when using DTLS over
 | 
			
		||||
       SCTP or TCP.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string psk_identity_hint(const std::string& type, \
 | 
			
		||||
                                                const std::string& context)
 | 
			
		||||
 | 
			
		||||
    Returns an identity hint which may be provided to the client. This
 | 
			
		||||
    can help a client understand what PSK to use.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string psk_identity(const std::string& type, \
 | 
			
		||||
                                           const std::string& context, \
 | 
			
		||||
                                           const std::string& identity_hint)
 | 
			
		||||
 | 
			
		||||
    Returns the identity we would like to use given this *type* and
 | 
			
		||||
    *context* and the optional *identity_hint*. Not all servers or
 | 
			
		||||
    protocols will provide a hint.
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Cryptobox
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Encryption using a passphrase
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.8.6
 | 
			
		||||
 | 
			
		||||
.. deprecated:: 3.0
 | 
			
		||||
 | 
			
		||||
This is a set of simple routines that encrypt some data using a
 | 
			
		||||
passphrase. There are defined in the header `cryptobox.h`, inside
 | 
			
		||||
namespace `Botan::CryptoBox`.
 | 
			
		||||
 | 
			
		||||
It generates cipher and MAC keys using 8192 iterations of PBKDF2 with
 | 
			
		||||
HMAC(SHA-512), then encrypts using Serpent in CTR mode and authenticates using a
 | 
			
		||||
HMAC(SHA-512) mac of the ciphertext, truncated to 160 bits.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::string encrypt(const uint8_t input[], size_t input_len, \
 | 
			
		||||
                                       const std::string& passphrase, \
 | 
			
		||||
                                       RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
    Encrypt the contents using *passphrase*.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::string decrypt(const uint8_t input[], size_t input_len, \
 | 
			
		||||
                                       const std::string& passphrase)
 | 
			
		||||
 | 
			
		||||
    Decrypts something encrypted with encrypt.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::string decrypt(const std::string& input, \
 | 
			
		||||
                                       const std::string& passphrase)
 | 
			
		||||
 | 
			
		||||
    Decrypts something encrypted with encrypt.
 | 
			
		||||
@@ -1,284 +0,0 @@
 | 
			
		||||
Elliptic Curve Operations
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
In addition to high level operations for signatures, key agreement,
 | 
			
		||||
and message encryption using elliptic curve cryptography, the library
 | 
			
		||||
contains lower level interfaces for performing operations such as
 | 
			
		||||
elliptic curve point multiplication.
 | 
			
		||||
 | 
			
		||||
Only curves over prime fields are supported.
 | 
			
		||||
 | 
			
		||||
Many of these functions take a workspace, either a vector of words or
 | 
			
		||||
a vector of BigInts. These are used to minimize memory allocations
 | 
			
		||||
during common operations.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   You should only use these interfaces if you know what you are doing.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: EC_Group
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Group(const OID& oid)
 | 
			
		||||
 | 
			
		||||
         Initialize an ``EC_Group`` using an OID referencing the curve
 | 
			
		||||
         parameters.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Group(const std::string& name)
 | 
			
		||||
 | 
			
		||||
         Initialize an ``EC_Group`` using a name or OID (for example
 | 
			
		||||
         "secp256r1", or "1.2.840.10045.3.1.7")
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Group(const BigInt& p, \
 | 
			
		||||
               const BigInt& a, \
 | 
			
		||||
               const BigInt& b, \
 | 
			
		||||
               const BigInt& base_x, \
 | 
			
		||||
               const BigInt& base_y, \
 | 
			
		||||
               const BigInt& order, \
 | 
			
		||||
               const BigInt& cofactor, \
 | 
			
		||||
               const OID& oid = OID())
 | 
			
		||||
 | 
			
		||||
          Initialize an elliptic curve group from the relevant parameters. This
 | 
			
		||||
          is used for example to create custom (application-specific) curves.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Group(const std::vector<uint8_t>& ber_encoding)
 | 
			
		||||
 | 
			
		||||
         Initialize an ``EC_Group`` by decoding a DER encoded parameter block.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: std::vector<uint8_t> DER_encode(EC_Group_Encoding form) const
 | 
			
		||||
 | 
			
		||||
         Return the DER encoding of this group.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: std::string PEM_encode() const
 | 
			
		||||
 | 
			
		||||
         Return the PEM encoding of this group (base64 of DER encoding plus
 | 
			
		||||
         header/trailer).
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: bool a_is_minus_3() const
 | 
			
		||||
 | 
			
		||||
         Return true if the ``a`` parameter is congruent to -3 mod p.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: bool a_is_zero() const
 | 
			
		||||
 | 
			
		||||
         Return true if the ``a`` parameter is congruent to 0 mod p.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: size_t get_p_bits() const
 | 
			
		||||
 | 
			
		||||
         Return size of the prime in bits.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: size_t get_p_bytes() const
 | 
			
		||||
 | 
			
		||||
         Return size of the prime in bytes.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: size_t get_order_bits() const
 | 
			
		||||
 | 
			
		||||
         Return size of the group order in bits.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: size_t get_order_bytes() const
 | 
			
		||||
 | 
			
		||||
         Return size of the group order in bytes.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_p() const
 | 
			
		||||
 | 
			
		||||
         Return the prime modulus.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_a() const
 | 
			
		||||
 | 
			
		||||
         Return the ``a`` parameter of the elliptic curve equation.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_b() const
 | 
			
		||||
 | 
			
		||||
         Return the ``b`` parameter of the elliptic curve equation.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const EC_Point& get_base_point() const
 | 
			
		||||
 | 
			
		||||
         Return the groups base point element.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_g_x() const
 | 
			
		||||
 | 
			
		||||
         Return the x coordinate of the base point element.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_g_y() const
 | 
			
		||||
 | 
			
		||||
         Return the y coordinate of the base point element.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_order() const
 | 
			
		||||
 | 
			
		||||
         Return the order of the group generated by the base point.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const BigInt& get_cofactor() const
 | 
			
		||||
 | 
			
		||||
         Return the cofactor of the curve. In most cases this will be 1.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: BigInt mod_order(const BigInt& x) const
 | 
			
		||||
 | 
			
		||||
         Reduce argument ``x`` modulo the curve order.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: BigInt inverse_mod_order(const BigInt& x) const
 | 
			
		||||
 | 
			
		||||
         Return inverse of argument ``x`` modulo the curve order.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: BigInt multiply_mod_order(const BigInt& x, const BigInt& y) const
 | 
			
		||||
 | 
			
		||||
         Multiply ``x`` and ``y`` and reduce the result modulo the curve order.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: bool verify_public_element(const EC_Point& y) const
 | 
			
		||||
 | 
			
		||||
         Return true if ``y`` seems to be a valid group element.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: const OID& get_curve_oid() const
 | 
			
		||||
 | 
			
		||||
         Return the OID used to identify the curve. May be empty.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Point point(const BigInt& x, const BigInt& y) const
 | 
			
		||||
 | 
			
		||||
         Create and return a point with affine elements ``x`` and ``y``. Note
 | 
			
		||||
         this function *does not* verify that ``x`` and ``y`` satisfy the curve
 | 
			
		||||
         equation.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Point point_multiply(const BigInt& x, const EC_Point& pt, const BigInt& y) const
 | 
			
		||||
 | 
			
		||||
         Multi-exponentiation. Returns base_point*x + pt*y. Not constant time.
 | 
			
		||||
         (Ordinarily used for signature verification.)
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Point blinded_base_point_multiply(const BigInt& k, \
 | 
			
		||||
                                            RandomNumberGenerator& rng, \
 | 
			
		||||
                                            std::vector<BigInt>& ws) const
 | 
			
		||||
 | 
			
		||||
         Return ``base_point*k`` in a way that attempts to resist side channels.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: BigInt blinded_base_point_multiply_x(const BigInt& k, \
 | 
			
		||||
                                           RandomNumberGenerator& rng, \
 | 
			
		||||
                                           std::vector<BigInt>& ws) const
 | 
			
		||||
 | 
			
		||||
         Like `blinded_base_point_multiply` but returns only the x coordinate.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Point blinded_var_point_multiply(const EC_Point& point, \
 | 
			
		||||
                                          const BigInt& k, \
 | 
			
		||||
                                          RandomNumberGenerator& rng, \
 | 
			
		||||
                                          std::vector<BigInt>& ws) const
 | 
			
		||||
 | 
			
		||||
         Return ``point*k`` in a way that attempts to resist side channels.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: BigInt random_scalar(RandomNumberGenerator& rng) const
 | 
			
		||||
 | 
			
		||||
         Return a random scalar (ie an integer between 1 and the group order).
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Point zero_point() const
 | 
			
		||||
 | 
			
		||||
         Return the zero point (aka the point at infinity).
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: EC_Point OS2ECP(const uint8_t bits[], size_t len) const
 | 
			
		||||
 | 
			
		||||
         Decode a point from the binary encoding. This function verifies that
 | 
			
		||||
         the decoded point is a valid element on the curve.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: bool verify_group(RandomNumberGenerator& rng, bool strong = false) const
 | 
			
		||||
 | 
			
		||||
         Attempt to verify the group seems valid.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: static const std::set<std::string>& known_named_groups()
 | 
			
		||||
 | 
			
		||||
         Return a list of known groups, ie groups for which ``EC_Group(name)``
 | 
			
		||||
         will succeed.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: EC_Point
 | 
			
		||||
 | 
			
		||||
   Stores elliptic curve points in Jacobian representation.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<uint8_t> encode(EC_Point::Compression_Type format) const
 | 
			
		||||
 | 
			
		||||
      Encode a point in a way that can later be decoded with `EC_Group::OS2ECP`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point& operator+=(const EC_Point& rhs)
 | 
			
		||||
 | 
			
		||||
      Point addition.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point& operator-=(const EC_Point& rhs)
 | 
			
		||||
 | 
			
		||||
      Point subtraction.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point& operator*=(const BigInt& scalar)
 | 
			
		||||
 | 
			
		||||
      Point multiplication using Montgomery ladder.
 | 
			
		||||
 | 
			
		||||
      .. warning::
 | 
			
		||||
         Prefer the blinded functions in ``EC_Group``
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point& negate()
 | 
			
		||||
 | 
			
		||||
      Negate this point.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt get_affine_x() const
 | 
			
		||||
 | 
			
		||||
      Return the affine ``x`` coordinate of the point.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt get_affine_y() const
 | 
			
		||||
 | 
			
		||||
      Return the affine ``y`` coordinate of the point.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void force_affine()
 | 
			
		||||
 | 
			
		||||
      Convert the point to its equivalent affine coordinates. Throws
 | 
			
		||||
      if this is the point at infinity.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: static void force_all_affine(std::vector<EC_Point>& points, \
 | 
			
		||||
                                                  secure_vector<word>& ws)
 | 
			
		||||
 | 
			
		||||
      Force several points to be affine at once. Uses Montgomery's
 | 
			
		||||
      trick to reduce number of inversions required, so this is much
 | 
			
		||||
      faster than calling ``force_affine`` on each point in sequence.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_affine() const
 | 
			
		||||
 | 
			
		||||
      Return true if this point is in affine coordinates.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_zero() const
 | 
			
		||||
 | 
			
		||||
      Return true if this point is zero (aka point at infinity).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool on_the_curve() const
 | 
			
		||||
 | 
			
		||||
      Return true if this point is on the curve.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void randomize_repr(RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
      Randomize the point representation.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool operator==(const EC_Point& other) const
 | 
			
		||||
 | 
			
		||||
      Point equality. This compares the affine representations.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void add(const EC_Point& other, std::vector<BigInt>& workspace)
 | 
			
		||||
 | 
			
		||||
      Point addition, taking a workspace.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void add_affine(const EC_Point& other, std::vector<BigInt>& workspace)
 | 
			
		||||
 | 
			
		||||
      Mixed (Jacobian+affine) addition, taking a workspace.
 | 
			
		||||
 | 
			
		||||
      .. warning::
 | 
			
		||||
 | 
			
		||||
         This function assumes that ``other`` is affine, if this is
 | 
			
		||||
         not correct the result will be invalid.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void mult2(std::vector<BigInt>& workspace)
 | 
			
		||||
 | 
			
		||||
      Point doubling.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void mult2i(size_t i, std::vector<BigInt>& workspace)
 | 
			
		||||
 | 
			
		||||
      Repeated point doubling.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point plus(const EC_Point& other, std::vector<BigInt>& workspace) const
 | 
			
		||||
 | 
			
		||||
      Point addition, returning the result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point double_of(std::vector<BigInt>& workspace) const
 | 
			
		||||
 | 
			
		||||
      Point doubling, returning the result.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: EC_Point zero() const
 | 
			
		||||
 | 
			
		||||
      Return the point at infinity
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
.. _env_vars:
 | 
			
		||||
 | 
			
		||||
Environment Variables
 | 
			
		||||
======================
 | 
			
		||||
 | 
			
		||||
Certain environment variables can affect or tune the behavior of the
 | 
			
		||||
library. The variables and their behavior are described here.
 | 
			
		||||
 | 
			
		||||
* ``BOTAN_THREAD_POOL_SIZE`` controls the number of threads which will be
 | 
			
		||||
  created for a thread pool used for some purposes within the library. If not
 | 
			
		||||
  set, or set to 0, then it defaults to the number of CPUs available on the
 | 
			
		||||
  system. If it is set to the string "none" then the thread pool is disabled;
 | 
			
		||||
  instead all work passed to the thread pool will be executed immediately
 | 
			
		||||
  by the calling thread.
 | 
			
		||||
 | 
			
		||||
  As of version 3.2.0, on MinGW the thread pool is by default disabled, due to a
 | 
			
		||||
  bug which causes deadlock on application shutdown. Enabling the pool can be
 | 
			
		||||
  explicitly requested by setting ``BOTAN_THREAD_POOL_SIZE`` to an integer
 | 
			
		||||
  value.
 | 
			
		||||
 | 
			
		||||
* ``BOTAN_MLOCK_POOL_SIZE`` controls the total amount of memory, in bytes, which
 | 
			
		||||
  will be locked in memory using ``mlock`` or ``VirtualLock`` and managed in a
 | 
			
		||||
  memory pool. This should be a multiple of the system page size. If set to
 | 
			
		||||
  ``0``, then the memory pool is disabled.
 | 
			
		||||
 | 
			
		||||
* ``BOTAN_FFI_PRINT_EXCEPTIONS`` if this variable is set (to any value), then
 | 
			
		||||
  if an exception is caught by the FFI layer, before returning an error code, it
 | 
			
		||||
  will print the text message of the exception to stderr. This is primarily
 | 
			
		||||
  intended for debugging.
 | 
			
		||||
 | 
			
		||||
* ``BOTAN_CLEAR_CPUID``: this variable can be set to a comma-separated list of
 | 
			
		||||
  CPUID fields to ignore. For example setting ``BOTAN_CLEAR_CPUID=avx2,avx512``
 | 
			
		||||
  will cause AVX2 and AVX-512 codepaths to be avoided. Note that disabling basic
 | 
			
		||||
  features (notably NEON or SSE2/SSSE3) can cause other higher level features
 | 
			
		||||
  like AES-NI to also become disabled.
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,733 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Pipe/Filter Message Processing
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    The system described below provides a message processing system with a
 | 
			
		||||
    straightforward API. However it makes many extra memory copies and
 | 
			
		||||
    allocations than would otherwise be required, and also tends to make
 | 
			
		||||
    applications using it somewhat opaque because it is not obvious what this or
 | 
			
		||||
    that Pipe& object actually does (type of operation, number of messages
 | 
			
		||||
    output (if any!), and so on), whereas using say a HashFunction or AEAD_Mode
 | 
			
		||||
    provides a much better idea in the code of what operation is occurring.
 | 
			
		||||
 | 
			
		||||
    This filter interface is no longer used within the library itself
 | 
			
		||||
    (outside a few dusty corners) and will likely not see any further major
 | 
			
		||||
    development. However it will remain included because the API is often
 | 
			
		||||
    convenient and many applications use it.
 | 
			
		||||
 | 
			
		||||
Many common uses of cryptography involve processing one or more
 | 
			
		||||
streams of data. Botan provides services that make setting up data
 | 
			
		||||
flows through various operations, such as compression, encryption, and
 | 
			
		||||
base64 encoding. Each of these operations is implemented in what are
 | 
			
		||||
called *filters* in Botan. A set of filters are created and placed into
 | 
			
		||||
a *pipe*, and information "flows" through the pipe until it reaches
 | 
			
		||||
the end, where the output is collected for retrieval. If you're
 | 
			
		||||
familiar with the Unix shell environment, this design will sound quite
 | 
			
		||||
familiar.
 | 
			
		||||
 | 
			
		||||
Here is an example that uses a pipe to base64 encode some strings::
 | 
			
		||||
 | 
			
		||||
  Pipe pipe(new Base64_Encoder); // pipe owns the pointer
 | 
			
		||||
  pipe.start_msg();
 | 
			
		||||
  pipe.write("message 1");
 | 
			
		||||
  pipe.end_msg(); // flushes buffers, increments message number
 | 
			
		||||
 | 
			
		||||
  // process_msg(x) is start_msg() && write(x) && end_msg()
 | 
			
		||||
  pipe.process_msg("message2");
 | 
			
		||||
 | 
			
		||||
  std::string m1 = pipe.read_all_as_string(0); // "message1"
 | 
			
		||||
  std::string m2 = pipe.read_all_as_string(1); // "message2"
 | 
			
		||||
 | 
			
		||||
Byte streams in the pipe are grouped into messages; blocks of data that
 | 
			
		||||
are processed in an identical fashion (ie, with the same sequence of
 | 
			
		||||
filter operations). Messages are delimited by calls to ``start_msg``
 | 
			
		||||
and ``end_msg``. Each message in a pipe has its own identifier, which
 | 
			
		||||
currently is an integer that increments up from zero.
 | 
			
		||||
 | 
			
		||||
The ``Base64_Encoder`` was allocated using ``new``; but where was it
 | 
			
		||||
deallocated?  When a filter object is passed to a ``Pipe``, the pipe
 | 
			
		||||
takes ownership of the object, and will deallocate it when it is no
 | 
			
		||||
longer needed.
 | 
			
		||||
 | 
			
		||||
There are two different ways to make use of messages. One is to send
 | 
			
		||||
several messages through a ``Pipe`` without changing the ``Pipe``
 | 
			
		||||
configuration, so you end up with a sequence of messages; one use of
 | 
			
		||||
this would be to send a sequence of identically encrypted UDP packets,
 | 
			
		||||
for example (note that the *data* need not be identical; it is just
 | 
			
		||||
that each is encrypted, encoded, signed, etc in an identical
 | 
			
		||||
fashion). Another is to change the filters that are used in the
 | 
			
		||||
``Pipe`` between each message, by adding or removing filters;
 | 
			
		||||
functions that let you do this are documented in the Pipe API section.
 | 
			
		||||
 | 
			
		||||
Botan has about 40 filters that perform different operations on data.
 | 
			
		||||
Here's code that uses one of them to encrypt a string with AES::
 | 
			
		||||
 | 
			
		||||
  AutoSeeded_RNG rng,
 | 
			
		||||
  SymmetricKey key(rng, 16); // a random 128-bit key
 | 
			
		||||
  InitializationVector iv(rng, 16); // a random 128-bit IV
 | 
			
		||||
 | 
			
		||||
  // The algorithm we want is specified by a string
 | 
			
		||||
  Pipe pipe(get_cipher("AES-128/CBC", key, iv, Cipher_Dir::Encryption));
 | 
			
		||||
 | 
			
		||||
  pipe.process_msg("secrets");
 | 
			
		||||
  pipe.process_msg("more secrets");
 | 
			
		||||
 | 
			
		||||
  secure_vector<uint8_t> c1 = pipe.read_all(0);
 | 
			
		||||
 | 
			
		||||
  uint8_t c2[4096] = { 0 };
 | 
			
		||||
  size_t got_out = pipe.read(c2, sizeof(c2), 1);
 | 
			
		||||
  // use c2[0...got_out]
 | 
			
		||||
 | 
			
		||||
Note the use of ``AutoSeeded_RNG``, which is a random number
 | 
			
		||||
generator. If you want to, you can explicitly set up the random number
 | 
			
		||||
generators and entropy sources you want to, however for 99% of cases
 | 
			
		||||
``AutoSeeded_RNG`` is preferable.
 | 
			
		||||
 | 
			
		||||
``Pipe`` also has convenience methods for dealing with ``std::iostream``.
 | 
			
		||||
Here is an example of this, using the bzip2 compression filter::
 | 
			
		||||
 | 
			
		||||
  std::ifstream in("data.bin", std::ios::binary)
 | 
			
		||||
  std::ofstream out("data.bin.bz2", std::ios::binary)
 | 
			
		||||
 | 
			
		||||
  Pipe pipe(new Compression_Filter("bzip2", 9));
 | 
			
		||||
 | 
			
		||||
  pipe.start_msg();
 | 
			
		||||
  in >> pipe;
 | 
			
		||||
  pipe.end_msg();
 | 
			
		||||
  out << pipe;
 | 
			
		||||
 | 
			
		||||
However there is a hitch to the code above; the complete contents of
 | 
			
		||||
the compressed data will be held in memory until the entire message
 | 
			
		||||
has been compressed, at which time the statement ``out << pipe`` is
 | 
			
		||||
executed, and the data is freed as it is read from the pipe and
 | 
			
		||||
written to the file. But if the file is very large, we might not have
 | 
			
		||||
enough physical memory (or even enough virtual memory!) for that to be
 | 
			
		||||
practical. So instead of storing the compressed data in the pipe for
 | 
			
		||||
reading it out later, we divert it directly to the file::
 | 
			
		||||
 | 
			
		||||
  std::ifstream in("data.bin", std::ios::binary)
 | 
			
		||||
  std::ofstream out("data.bin.bz2", std::ios::binary)
 | 
			
		||||
 | 
			
		||||
  Pipe pipe(new Compression_Filter("bzip2", 9), new DataSink_Stream(out));
 | 
			
		||||
 | 
			
		||||
  pipe.start_msg();
 | 
			
		||||
  in >> pipe;
 | 
			
		||||
  pipe.end_msg();
 | 
			
		||||
 | 
			
		||||
This is the first code we've seen so far that uses more than one
 | 
			
		||||
filter in a pipe. The output of the compressor is sent to the
 | 
			
		||||
``DataSink_Stream``. Anything written to a ``DataSink_Stream`` is
 | 
			
		||||
written to a file; the filter produces no output. As soon as the
 | 
			
		||||
compression algorithm finishes up a block of data, it will send it
 | 
			
		||||
along to the sink filter, which will immediately write it to the
 | 
			
		||||
stream; if you were to call ``pipe.read_all()`` after
 | 
			
		||||
``pipe.end_msg()``, you'd get an empty vector out. This is
 | 
			
		||||
particularly useful for cases where you are processing a large amount
 | 
			
		||||
of data, as it means you don't have to store everything in memory at
 | 
			
		||||
once.
 | 
			
		||||
 | 
			
		||||
Here's an example using two computational filters::
 | 
			
		||||
 | 
			
		||||
   AutoSeeded_RNG rng,
 | 
			
		||||
   SymmetricKey key(rng, 32);
 | 
			
		||||
   InitializationVector iv(rng, 16);
 | 
			
		||||
 | 
			
		||||
   Pipe encryptor(get_cipher("AES/CBC/PKCS7", key, iv, Cipher_Dir::Encryption),
 | 
			
		||||
                  new Base64_Encoder);
 | 
			
		||||
 | 
			
		||||
   encryptor.start_msg();
 | 
			
		||||
   file >> encryptor;
 | 
			
		||||
   encryptor.end_msg(); // flush buffers, complete computations
 | 
			
		||||
   std::cout << encryptor;
 | 
			
		||||
 | 
			
		||||
You can read from a pipe while you are still writing to it, which
 | 
			
		||||
allows you to bound the amount of memory that is in use at any one
 | 
			
		||||
time. A common idiom for this is::
 | 
			
		||||
 | 
			
		||||
   pipe.start_msg();
 | 
			
		||||
   std::vector<uint8_t> buffer(4096); // arbitrary size
 | 
			
		||||
   while(infile.good())
 | 
			
		||||
      {
 | 
			
		||||
      infile.read((char*)&buffer[0], buffer.size());
 | 
			
		||||
      const size_t got_from_infile = infile.gcount();
 | 
			
		||||
      pipe.write(buffer, got_from_infile);
 | 
			
		||||
 | 
			
		||||
      if(infile.eof())
 | 
			
		||||
         pipe.end_msg();
 | 
			
		||||
 | 
			
		||||
      while(pipe.remaining() > 0)
 | 
			
		||||
         {
 | 
			
		||||
         const size_t buffered = pipe.read(buffer, buffer.size());
 | 
			
		||||
         outfile.write((const char*)&buffer[0], buffered);
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
   if(infile.bad() || (infile.fail() && !infile.eof()))
 | 
			
		||||
      throw Some_Exception();
 | 
			
		||||
 | 
			
		||||
Fork
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
It is common that you might receive some data and want to perform more
 | 
			
		||||
than one operation on it (ie, encrypt it with Serpent and calculate
 | 
			
		||||
the SHA-256 hash of the plaintext at the same time). That's where
 | 
			
		||||
``Fork`` comes in. ``Fork`` is a filter that takes input and passes it
 | 
			
		||||
on to *one or more* filters that are attached to it. ``Fork`` changes
 | 
			
		||||
the nature of the pipe system completely: instead of being a linked
 | 
			
		||||
list, it becomes a tree or acyclic graph.
 | 
			
		||||
 | 
			
		||||
Each filter in the fork is given its own output buffer, and thus its
 | 
			
		||||
own message. For example, if you had previously written two messages
 | 
			
		||||
into a pipe, then you start a new one with a fork that has three
 | 
			
		||||
paths of filter's inside it, you add three new messages to the
 | 
			
		||||
pipe. The data you put into the pipe is duplicated and sent
 | 
			
		||||
into each set of filter and the eventual output is placed into a
 | 
			
		||||
dedicated message slot in the pipe.
 | 
			
		||||
 | 
			
		||||
Messages in the pipe are allocated in a depth-first manner. This is only
 | 
			
		||||
interesting if you are using more than one fork in a single pipe.
 | 
			
		||||
As an example, consider the following::
 | 
			
		||||
 | 
			
		||||
   Pipe pipe(new Fork(
 | 
			
		||||
                new Fork(
 | 
			
		||||
                   new Base64_Encoder,
 | 
			
		||||
                   new Fork(
 | 
			
		||||
                      NULL,
 | 
			
		||||
                      new Base64_Encoder
 | 
			
		||||
                      )
 | 
			
		||||
                   ),
 | 
			
		||||
                new Hex_Encoder
 | 
			
		||||
                )
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
In this case, message 0 will be the output of the first
 | 
			
		||||
``Base64_Encoder``, message 1 will be a copy of the input (see below
 | 
			
		||||
for how fork interprets NULL pointers), message 2 will be the output
 | 
			
		||||
of the second ``Base64_Encoder``, and message 3 will be the output of
 | 
			
		||||
the ``Hex_Encoder``. This results in message numbers being allocated
 | 
			
		||||
in a top to bottom fashion, when looked at on the screen. However,
 | 
			
		||||
note that there could be potential for bugs if this is not
 | 
			
		||||
anticipated. For example, if your code is passed a filter, and you
 | 
			
		||||
assume it is a "normal" one that only uses one message, your message
 | 
			
		||||
offsets would be wrong, leading to some confusion during output.
 | 
			
		||||
 | 
			
		||||
If Fork's first argument is a null pointer, but a later argument is
 | 
			
		||||
not, then Fork will feed a copy of its input directly through. Here's
 | 
			
		||||
a case where that is useful::
 | 
			
		||||
 | 
			
		||||
   // have std::string ciphertext, auth_code, key, iv, mac_key;
 | 
			
		||||
 | 
			
		||||
   Pipe pipe(new Base64_Decoder,
 | 
			
		||||
             get_cipher("AES-128", key, iv, Cipher_Dir::Decryption),
 | 
			
		||||
             new Fork(
 | 
			
		||||
                0, // this message gets plaintext
 | 
			
		||||
                new MAC_Filter("HMAC(SHA-1)", mac_key)
 | 
			
		||||
             )
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
   pipe.process_msg(ciphertext);
 | 
			
		||||
   std::string plaintext = pipe.read_all_as_string(0);
 | 
			
		||||
   secure_vector<uint8_t> mac = pipe.read_all(1);
 | 
			
		||||
 | 
			
		||||
   if(mac != auth_code)
 | 
			
		||||
      error();
 | 
			
		||||
 | 
			
		||||
Here we wanted to not only decrypt the message, but send the decrypted
 | 
			
		||||
text through an additional computation, in order to compute the
 | 
			
		||||
authentication code.
 | 
			
		||||
 | 
			
		||||
Any filters that are attached to the pipe after the fork are
 | 
			
		||||
implicitly attached onto the first branch created by the fork. For
 | 
			
		||||
example, let's say you created this pipe::
 | 
			
		||||
 | 
			
		||||
  Pipe pipe(new Fork(new Hash_Filter("SHA-256"),
 | 
			
		||||
                     new Hash_Filter("SHA-512")),
 | 
			
		||||
            new Hex_Encoder);
 | 
			
		||||
 | 
			
		||||
And then called ``start_msg``, inserted some data, then
 | 
			
		||||
``end_msg``. Then ``pipe`` would contain two messages. The first one
 | 
			
		||||
(message number 0) would contain the SHA-256 sum of the input in hex
 | 
			
		||||
encoded form, and the other would contain the SHA-512 sum of the input
 | 
			
		||||
in raw binary. In many situations you'll want to perform a sequence of
 | 
			
		||||
operations on multiple branches of the fork; in which case, use
 | 
			
		||||
the filter described in :ref:`chain`.
 | 
			
		||||
 | 
			
		||||
There is also a ``Threaded_Fork`` which acts the same as ``Fork``,
 | 
			
		||||
except it runs each of the filters in its own thread.
 | 
			
		||||
 | 
			
		||||
.. _chain:
 | 
			
		||||
 | 
			
		||||
Chain
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
A ``Chain`` filter creates a chain of filters and encapsulates them
 | 
			
		||||
inside a single filter (itself). This allows a sequence of filters to
 | 
			
		||||
become a single filter, to be passed into or out of a function, or to
 | 
			
		||||
a ``Fork`` constructor.
 | 
			
		||||
 | 
			
		||||
You can call ``Chain``'s constructor with up to four ``Filter``
 | 
			
		||||
pointers (they will be added in order), or with an array of filter
 | 
			
		||||
pointers and a ``size_t`` that tells ``Chain`` how many filters are in
 | 
			
		||||
the array (again, they will be attached in order). Here's the example
 | 
			
		||||
from the last section, using chain instead of relying on the implicit
 | 
			
		||||
pass through the other version used::
 | 
			
		||||
 | 
			
		||||
  Pipe pipe(new Fork(
 | 
			
		||||
                new Chain(new Hash_Filter("SHA-256"), new Hex_Encoder),
 | 
			
		||||
                new Hash_Filter("SHA-512")
 | 
			
		||||
                )
 | 
			
		||||
           );
 | 
			
		||||
 | 
			
		||||
Sources and Sinks
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Data Sources
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
A ``DataSource`` is a simple abstraction for a thing that stores
 | 
			
		||||
bytes. This type is used heavily in the areas of the API related to
 | 
			
		||||
ASN.1 encoding/decoding. The following types are ``DataSource``:
 | 
			
		||||
``Pipe``, ``SecureQueue``, and a couple of special purpose ones:
 | 
			
		||||
``DataSource_Memory`` and ``DataSource_Stream``.
 | 
			
		||||
 | 
			
		||||
You can create a ``DataSource_Memory`` with an array of bytes and a
 | 
			
		||||
length field. The object will make a copy of the data, so you don't
 | 
			
		||||
have to worry about keeping that memory allocated. This is mostly for
 | 
			
		||||
internal use, but if it comes in handy, feel free to use it.
 | 
			
		||||
 | 
			
		||||
A ``DataSource_Stream`` is probably more useful than the memory based
 | 
			
		||||
one. Its constructors take either a ``std::istream`` or a
 | 
			
		||||
``std::string``. If it's a stream, the data source will use the
 | 
			
		||||
``istream`` to satisfy read requests (this is particularly useful to
 | 
			
		||||
use with ``std::cin``). If the string version is used, it will attempt
 | 
			
		||||
to open up a file with that name and read from it.
 | 
			
		||||
 | 
			
		||||
Data Sinks
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
A ``DataSink`` (in ``data_snk.h``) is a ``Filter`` that takes
 | 
			
		||||
arbitrary amounts of input, and produces no output. This means it's
 | 
			
		||||
doing something with the data outside the realm of what
 | 
			
		||||
``Filter``/``Pipe`` can handle, for example, writing it to a file
 | 
			
		||||
(which is what the ``DataSink_Stream`` does). There is no need for
 | 
			
		||||
``DataSink``s that write to a ``std::string`` or memory buffer,
 | 
			
		||||
because ``Pipe`` can handle that by itself.
 | 
			
		||||
 | 
			
		||||
Here's a quick example of using a ``DataSink``, which encrypts
 | 
			
		||||
``in.txt`` and sends the output to ``out.txt``. There is
 | 
			
		||||
no explicit output operation; the writing of ``out.txt`` is
 | 
			
		||||
implicit::
 | 
			
		||||
 | 
			
		||||
   DataSource_Stream in("in.txt");
 | 
			
		||||
   Pipe pipe(get_cipher("AES-128/CTR-BE", key, iv),
 | 
			
		||||
             new DataSink_Stream("out.txt"));
 | 
			
		||||
   pipe.process_msg(in);
 | 
			
		||||
 | 
			
		||||
A real advantage of this is that even if "in.txt" is large, only as
 | 
			
		||||
much memory is needed for internal I/O buffers will be used.
 | 
			
		||||
 | 
			
		||||
The Pipe API
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
Initializing Pipe
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
By default, ``Pipe`` will do nothing at all; any input placed into the
 | 
			
		||||
``Pipe`` will be read back unchanged. Obviously, this has limited
 | 
			
		||||
utility, and presumably you want to use one or more filters to somehow
 | 
			
		||||
process the data. First, you can choose a set of filters to initialize
 | 
			
		||||
the ``Pipe`` via the constructor. You can pass it either a set of up
 | 
			
		||||
to four filter pointers, or a pre-defined array and a length::
 | 
			
		||||
 | 
			
		||||
   Pipe pipe1(new Filter1(/*args*/), new Filter2(/*args*/),
 | 
			
		||||
              new Filter3(/*args*/), new Filter4(/*args*/));
 | 
			
		||||
   Pipe pipe2(new Filter1(/*args*/), new Filter2(/*args*/));
 | 
			
		||||
 | 
			
		||||
   Filter* filters[5] = {
 | 
			
		||||
     new Filter1(/*args*/), new Filter2(/*args*/), new Filter3(/*args*/),
 | 
			
		||||
     new Filter4(/*args*/), new Filter5(/*args*/) /* more if desired... */
 | 
			
		||||
   };
 | 
			
		||||
   Pipe pipe3(filters, 5);
 | 
			
		||||
 | 
			
		||||
This is by far the most common way to initialize a ``Pipe``. However,
 | 
			
		||||
occasionally a more flexible initialization strategy is necessary;
 | 
			
		||||
this is supported by 4 member functions. These functions may only be
 | 
			
		||||
used while the pipe in question is not in use; that is, either before
 | 
			
		||||
calling ``start_msg``, or after ``end_msg`` has been called (and no
 | 
			
		||||
new calls to ``start_msg`` have been made yet).
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::prepend(Filter* filter)
 | 
			
		||||
 | 
			
		||||
  Calling ``prepend`` will put the passed filter first in the list of
 | 
			
		||||
  transformations. For example, if you prepend a filter implementing
 | 
			
		||||
  encryption, and the pipe already had a filter that hex encoded the
 | 
			
		||||
  input, then the next message processed would be first encrypted,
 | 
			
		||||
  and *then* hex encoded.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::append(Filter* filter)
 | 
			
		||||
 | 
			
		||||
  Like ``prepend``, but places the filter at the end of the message
 | 
			
		||||
  flow. This doesn't always do what you expect if there is a fork.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::pop()
 | 
			
		||||
 | 
			
		||||
  Removes the first filter in the flow.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::reset()
 | 
			
		||||
 | 
			
		||||
  Removes all the filters that the pipe currently holds - it is reset
 | 
			
		||||
  to an empty/no-op state.  Any data that is being retained by the
 | 
			
		||||
  pipe is retained after a ``reset``, and ``reset`` does not affect
 | 
			
		||||
  message numbers (discussed later).
 | 
			
		||||
 | 
			
		||||
Giving Data to a Pipe
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Input to a ``Pipe`` is delimited into messages, which can be read from
 | 
			
		||||
independently (ie, you can read 5 bytes from one message, and then all of
 | 
			
		||||
another message, without either read affecting any other messages).
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::start_msg()
 | 
			
		||||
 | 
			
		||||
  Starts a new message; if a message was already running, an exception is
 | 
			
		||||
  thrown. After this function returns, you can call ``write``.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::write(const uint8_t* input, size_t length)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::write(const std::vector<uint8_t>& input)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::write(const std::string& input)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::write(DataSource& input)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::write(uint8_t input)
 | 
			
		||||
 | 
			
		||||
  All versions of ``write`` write the input into the filter sequence.
 | 
			
		||||
  If a message is not currently active, an exception is thrown.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Pipe::end_msg()
 | 
			
		||||
 | 
			
		||||
  End the currently active message
 | 
			
		||||
 | 
			
		||||
Sometimes, you may want to do only a single write per message. In this
 | 
			
		||||
case, you can use the ``process_msg`` series of functions, which start
 | 
			
		||||
a message, write their argument into the pipe, and then end the
 | 
			
		||||
message. In this case you would not make any explicit calls to
 | 
			
		||||
``start_msg``/``end_msg``.
 | 
			
		||||
 | 
			
		||||
Pipes can also be used with the ``>>`` operator, and will accept a
 | 
			
		||||
``std::istream``, or on Unix systems with the ``fd_unix`` module, a
 | 
			
		||||
Unix file descriptor. In either case, the entire contents of the file
 | 
			
		||||
will be read into the pipe.
 | 
			
		||||
 | 
			
		||||
Getting Output from a Pipe
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Retrieving the processed data from a pipe is a bit more complicated,
 | 
			
		||||
for various reasons. The pipe will separate each message into a
 | 
			
		||||
separate buffer, and you have to retrieve data from each message
 | 
			
		||||
independently. Each of the reader functions has a final parameter that
 | 
			
		||||
specifies what message to read from. If this parameter is set to
 | 
			
		||||
``Pipe::DEFAULT_MESSAGE``, it will read the current default message
 | 
			
		||||
(``DEFAULT_MESSAGE`` is also the default value of this parameter).
 | 
			
		||||
 | 
			
		||||
Functions in ``Pipe`` related to reading include:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: size_t Pipe::read(uint8_t* out, size_t len)
 | 
			
		||||
 | 
			
		||||
  Reads up to ``len`` bytes into ``out``, and returns the number of
 | 
			
		||||
  bytes actually read.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: size_t Pipe::peek(uint8_t* out, size_t len)
 | 
			
		||||
 | 
			
		||||
  Acts exactly like `read`, except the data is not actually read; the
 | 
			
		||||
  next read will return the same data.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: secure_vector<uint8_t> Pipe::read_all()
 | 
			
		||||
 | 
			
		||||
  Reads the entire message into a buffer and returns it
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string Pipe::read_all_as_string()
 | 
			
		||||
 | 
			
		||||
  Like ``read_all``, but it returns the data as a ``std::string``.
 | 
			
		||||
  No encoding is done; if the message contains raw binary, so will
 | 
			
		||||
  the string.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: size_t Pipe::remaining()
 | 
			
		||||
 | 
			
		||||
  Returns how many bytes are left in the message
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Pipe::message_id Pipe::default_msg()
 | 
			
		||||
 | 
			
		||||
  Returns the current default message number
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Pipe::message_id Pipe::message_count()
 | 
			
		||||
 | 
			
		||||
  Returns the total number of messages currently in the pipe
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Pipe::set_default_msg(Pipe::message_id msgno)
 | 
			
		||||
 | 
			
		||||
  Sets the default message number (which must be a valid message
 | 
			
		||||
  number for that pipe). The ability to set the default message number
 | 
			
		||||
  is particularly important in the case of using the file output
 | 
			
		||||
  operations (``<<`` with a ``std::ostream`` or Unix file descriptor),
 | 
			
		||||
  because there is no way to specify the message explicitly when using
 | 
			
		||||
  the output operator.
 | 
			
		||||
 | 
			
		||||
Pipe I/O for Unix File Descriptors
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This is a minor feature, but it comes in handy sometimes. In all
 | 
			
		||||
installations of the library, Botan's ``Pipe`` object overloads the
 | 
			
		||||
``<<`` and ``>>`` operators for C++ iostream objects,
 | 
			
		||||
which is usually more than sufficient for doing I/O.
 | 
			
		||||
 | 
			
		||||
However, there are cases where the iostream hierarchy does not map well to
 | 
			
		||||
local 'file types', so there is also the ability to do I/O directly with Unix
 | 
			
		||||
file descriptors. This is most useful when you want to read from or write to
 | 
			
		||||
something like a TCP or Unix-domain socket, or a pipe, since for simple file
 | 
			
		||||
access it's usually easier to just use C++'s file streams.
 | 
			
		||||
 | 
			
		||||
If ``BOTAN_EXT_PIPE_UNIXFD_IO`` is defined, then you can use the
 | 
			
		||||
overloaded I/O operators with Unix file descriptors. For an example of this,
 | 
			
		||||
check out the ``hash_fd`` example, included in the Botan distribution.
 | 
			
		||||
 | 
			
		||||
Filter Catalog
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
This section documents most of the useful filters included in the
 | 
			
		||||
library.
 | 
			
		||||
 | 
			
		||||
Keyed Filters
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
A few sections ago, it was mentioned that ``Pipe`` can process
 | 
			
		||||
multiple messages, treating each of them the same. Well, that was a
 | 
			
		||||
bit of a lie. There are some algorithms (in particular, block ciphers
 | 
			
		||||
not in ECB mode, and all stream ciphers) that change their state as
 | 
			
		||||
data is put through them.
 | 
			
		||||
 | 
			
		||||
Naturally, you might well want to reset the keys or (in the case of
 | 
			
		||||
block cipher modes) IVs used by such filters, so multiple messages can
 | 
			
		||||
be processed using completely different keys, or new IVs, or new keys
 | 
			
		||||
and IVs, or whatever.  And in fact, even for a MAC or an ECB block
 | 
			
		||||
cipher, you might well want to change the key used from message to
 | 
			
		||||
message.
 | 
			
		||||
 | 
			
		||||
Enter ``Keyed_Filter``, which acts as an abstract interface for any
 | 
			
		||||
filter that is uses keys: block cipher modes, stream ciphers, MACs,
 | 
			
		||||
and so on. It has two functions, ``set_key`` and ``set_iv``. Calling
 | 
			
		||||
``set_key`` will set (or reset) the key used by the algorithm. Setting
 | 
			
		||||
the IV only makes sense in certain algorithms -- a call to ``set_iv``
 | 
			
		||||
on an object that doesn't support IVs will cause an exception. You
 | 
			
		||||
must call ``set_key`` *before* calling ``set_iv``.
 | 
			
		||||
 | 
			
		||||
Here's a example::
 | 
			
		||||
 | 
			
		||||
   Keyed_Filter *aes, *hmac;
 | 
			
		||||
   Pipe pipe(new Base64_Decoder,
 | 
			
		||||
             // Note the assignments to the cast and hmac variables
 | 
			
		||||
             aes = get_cipher("AES-128/CBC", aes_key, iv),
 | 
			
		||||
             new Fork(
 | 
			
		||||
                0, // Read the section 'Fork' to understand this
 | 
			
		||||
                new Chain(
 | 
			
		||||
                   hmac = new MAC_Filter("HMAC(SHA-1)", mac_key, 12),
 | 
			
		||||
                   new Base64_Encoder
 | 
			
		||||
                   )
 | 
			
		||||
                )
 | 
			
		||||
      );
 | 
			
		||||
   pipe.start_msg();
 | 
			
		||||
   // use pipe for a while, decrypt some stuff, derive new keys and IVs
 | 
			
		||||
   pipe.end_msg();
 | 
			
		||||
 | 
			
		||||
   aes->set_key(aes_key2);
 | 
			
		||||
   aes->set_iv(iv2);
 | 
			
		||||
   hmac->set_key(mac_key2);
 | 
			
		||||
 | 
			
		||||
   pipe.start_msg();
 | 
			
		||||
   // use pipe for some other things
 | 
			
		||||
   pipe.end_msg();
 | 
			
		||||
 | 
			
		||||
There are some requirements to using ``Keyed_Filter`` that you must
 | 
			
		||||
follow. If you call ``set_key`` or ``set_iv`` on a filter that is
 | 
			
		||||
owned by a ``Pipe``, you must do so while the ``Pipe`` is
 | 
			
		||||
"unlocked". This refers to the times when no messages are being
 | 
			
		||||
processed by ``Pipe`` -- either before ``Pipe``'s ``start_msg`` is
 | 
			
		||||
called, or after ``end_msg`` is called (and no new call to
 | 
			
		||||
``start_msg`` has happened yet). Doing otherwise will result in
 | 
			
		||||
undefined behavior, probably silently getting invalid output.
 | 
			
		||||
 | 
			
		||||
And remember: if you're resetting both values, reset the key *first*.
 | 
			
		||||
 | 
			
		||||
Cipher Filters
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Getting a hold of a ``Filter`` implementing a cipher is very
 | 
			
		||||
easy. Make sure you're including the header ``lookup.h``, and
 | 
			
		||||
then call ``get_cipher``. You will pass the return value
 | 
			
		||||
directly into a ``Pipe``. There are a couple different functions
 | 
			
		||||
which do varying levels of initialization:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Keyed_Filter* get_cipher(std::string cipher_spec, \
 | 
			
		||||
   SymmetricKey key, InitializationVector iv, Cipher_Dir dir)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Keyed_Filter* get_cipher(std::string cipher_spec, \
 | 
			
		||||
   SymmetricKey key, Cipher_Dir dir)
 | 
			
		||||
 | 
			
		||||
The version that doesn't take an IV is useful for things that don't
 | 
			
		||||
use them, like block ciphers in ECB mode, or most stream ciphers. If
 | 
			
		||||
you specify a cipher spec that does want a IV, and you use the version
 | 
			
		||||
that doesn't take one, an exception will be thrown. The ``dir``
 | 
			
		||||
argument can be either ``Cipher_Dir::Encryption`` or ``Cipher_Dir::Decryption``.
 | 
			
		||||
 | 
			
		||||
The cipher_spec is a string that specifies what cipher is to be
 | 
			
		||||
used. The general syntax for "cipher_spec" is "STREAM_CIPHER",
 | 
			
		||||
"BLOCK_CIPHER/MODE", or "BLOCK_CIPHER/MODE/PADDING". In the case of
 | 
			
		||||
stream ciphers, no mode is necessary, so just the name is
 | 
			
		||||
sufficient. A block cipher requires a mode of some sort, which can be
 | 
			
		||||
"ECB", "CBC", "CFB(n)", "OFB", "CTR-BE", or "EAX(n)". The argument to
 | 
			
		||||
CFB mode is how many bits of feedback should be used. If you just use
 | 
			
		||||
"CFB" with no argument, it will default to using a feedback equal to
 | 
			
		||||
the block size of the cipher. EAX mode also takes an optional bit
 | 
			
		||||
argument, which tells EAX how large a tag size to use~--~generally
 | 
			
		||||
this is the size of the block size of the cipher, which is the default
 | 
			
		||||
if you don't specify any argument.
 | 
			
		||||
 | 
			
		||||
In the case of the ECB and CBC modes, a padding method can also be
 | 
			
		||||
specified. If it is not supplied, ECB defaults to not padding, and CBC
 | 
			
		||||
defaults to using PKCS #5/#7 compatible padding. The padding methods
 | 
			
		||||
currently available are "NoPadding", "PKCS7", "OneAndZeros", and
 | 
			
		||||
"CTS". CTS padding is currently only available for CBC mode, but the
 | 
			
		||||
others can also be used in ECB mode.
 | 
			
		||||
 | 
			
		||||
Some example "cipher_spec arguments are: "AES-128/CBC",
 | 
			
		||||
"Blowfish/CTR-BE", "Serpent/XTS", and "AES-256/EAX".
 | 
			
		||||
 | 
			
		||||
"CTR-BE" refers to counter mode where the counter is incremented as if
 | 
			
		||||
it were a big-endian encoded integer. This is compatible with most
 | 
			
		||||
other implementations, but it is possible some will use the
 | 
			
		||||
incompatible little endian convention. This version would be denoted
 | 
			
		||||
as "CTR-LE" if it were supported.
 | 
			
		||||
 | 
			
		||||
"EAX" is a new cipher mode designed by Wagner, Rogaway, and
 | 
			
		||||
Bellare. It is an authenticated cipher mode (that is, no separate
 | 
			
		||||
authentication is needed), has provable security, and is free from
 | 
			
		||||
patent entanglements. It runs about half as fast as most of the other
 | 
			
		||||
cipher modes (like CBC, OFB, or CTR), which is not bad considering you
 | 
			
		||||
don't need to use an authentication code.
 | 
			
		||||
 | 
			
		||||
Hashes and MACs
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Hash functions and MACs don't need anything special when it comes to
 | 
			
		||||
filters. Both just take their input and produce no output until
 | 
			
		||||
``end_msg`` is called, at which time they complete the hash or MAC and
 | 
			
		||||
send that as output.
 | 
			
		||||
 | 
			
		||||
These filters take a string naming the type to be used. If for some
 | 
			
		||||
reason you name something that doesn't exist, an exception will be thrown.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Hash_Filter::Hash_Filter(std::string hash, size_t outlen = 0)
 | 
			
		||||
 | 
			
		||||
  This constructor creates a filter that hashes its input with
 | 
			
		||||
  ``hash``. When ``end_msg`` is called on the owning pipe, the hash is
 | 
			
		||||
  completed and the digest is sent on to the next filter in the
 | 
			
		||||
  pipeline. The parameter ``outlen`` specifies how many bytes of the
 | 
			
		||||
  hash output will be passed along to the next filter when ``end_msg``
 | 
			
		||||
  is called. By default, it will pass the entire hash.
 | 
			
		||||
 | 
			
		||||
  Examples of names for ``Hash_Filter`` are "SHA-1" and "Whirlpool".
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: MAC_Filter::MAC_Filter(std::string mac, SymmetricKey key, size_t outlen = 0)
 | 
			
		||||
 | 
			
		||||
  This constructor takes a name for a mac, such as "HMAC(SHA-1)" or
 | 
			
		||||
  "CMAC(AES-128)", along with a key to use. The optional ``outlen``
 | 
			
		||||
  works the same as in ``Hash_Filter``.
 | 
			
		||||
 | 
			
		||||
Encoders
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Often you want your data to be in some form of text (for sending over
 | 
			
		||||
channels that aren't 8-bit clean, printing it, etc). The filters
 | 
			
		||||
``Hex_Encoder`` and ``Base64_Encoder`` will convert arbitrary binary
 | 
			
		||||
data into hex or base64 formats. Not surprisingly, you can use
 | 
			
		||||
``Hex_Decoder`` and ``Base64_Decoder`` to convert it back into its
 | 
			
		||||
original form.
 | 
			
		||||
 | 
			
		||||
Both of the encoders can take a few options about how the data should
 | 
			
		||||
be formatted (all of which have defaults). The first is a ``bool``
 | 
			
		||||
which says if the encoder should insert line breaks. This defaults to
 | 
			
		||||
false. Line breaks don't matter either way to the decoder, but it
 | 
			
		||||
makes the output a bit more appealing to the human eye, and a few
 | 
			
		||||
transport mechanisms (notably some email systems) limit the maximum
 | 
			
		||||
line length.
 | 
			
		||||
 | 
			
		||||
The second encoder option is an integer specifying how long such lines
 | 
			
		||||
will be (obviously this will be ignored if line-breaking isn't being
 | 
			
		||||
used). The default tends to be in the range of 60-80 characters, but
 | 
			
		||||
is not specified. If you want a specific value, set it. Otherwise the
 | 
			
		||||
default should be fine.
 | 
			
		||||
 | 
			
		||||
Lastly, ``Hex_Encoder`` takes an argument of type ``Case``, which can
 | 
			
		||||
be ``Uppercase`` or ``Lowercase`` (default is ``Uppercase``). This
 | 
			
		||||
specifies what case the characters A-F should be output as. The base64
 | 
			
		||||
encoder has no such option, because it uses both upper and lower case
 | 
			
		||||
letters for its output.
 | 
			
		||||
 | 
			
		||||
You can find the declarations for these types in ``hex_filt.h`` and
 | 
			
		||||
``b64_filt.h``.
 | 
			
		||||
 | 
			
		||||
Writing New Filters
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
The system of filters and pipes was designed in an attempt to make it
 | 
			
		||||
as simple as possible to write new filter types. There are four
 | 
			
		||||
functions that need to be implemented by a class deriving from
 | 
			
		||||
``Filter``:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string Filter::name() const
 | 
			
		||||
 | 
			
		||||
  This should just return a useful decription of the filter object.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Filter::write(const uint8_t* input, size_t length)
 | 
			
		||||
 | 
			
		||||
  This function is what is called when a filter receives input for it
 | 
			
		||||
  to process. The filter is not required to process the data right
 | 
			
		||||
  away; many filters buffer their input before producing any output. A
 | 
			
		||||
  filter will usually have ``write`` called many times during its
 | 
			
		||||
  lifetime.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Filter::send(uint8_t* output, size_t length)
 | 
			
		||||
 | 
			
		||||
  Eventually, a filter will want to produce some output to send along
 | 
			
		||||
  to the next filter in the pipeline. It does so by calling ``send``
 | 
			
		||||
  with whatever it wants to send along to the next filter. There is
 | 
			
		||||
  also a version of ``send`` taking a single byte argument, as a
 | 
			
		||||
  convenience.
 | 
			
		||||
 | 
			
		||||
  .. note::
 | 
			
		||||
 | 
			
		||||
     Normally a filter does not need to override ``send``, though it
 | 
			
		||||
     can for special handling. It does however need to call this
 | 
			
		||||
     function whenever it wants to produce output.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Filter::start_msg()
 | 
			
		||||
 | 
			
		||||
  Implementing this function is optional. Implement it if your filter
 | 
			
		||||
  would like to do some processing or setup at the start of each
 | 
			
		||||
  message, such as allocating a data structure.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Filter::end_msg()
 | 
			
		||||
 | 
			
		||||
  Implementing this function is optional. It is called when it has
 | 
			
		||||
  been requested that filters finish up their computations. The filter
 | 
			
		||||
  should finish up with whatever computation it is working on (for
 | 
			
		||||
  example, a compressing filter would flush the compressor and
 | 
			
		||||
  ``send`` the final block), and empty any buffers in preparation for
 | 
			
		||||
  processing a fresh new set of input.
 | 
			
		||||
 | 
			
		||||
Additionally, if necessary, filters can define a constructor that
 | 
			
		||||
takes any needed arguments, and a destructor to deal with deallocating
 | 
			
		||||
memory, closing files, etc.
 | 
			
		||||
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
========================================
 | 
			
		||||
Footguns
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
This section notes areas where certain usages can cause confusing bugs or problems.
 | 
			
		||||
 | 
			
		||||
Static Objects
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
If you maintain ``static`` variables which hold Botan objects, you will perhaps
 | 
			
		||||
find that in some circumstances your application crashes in strange ways on
 | 
			
		||||
shutdown. That is because, at least on some operating systems, Botan uses a
 | 
			
		||||
locked memory pool as backing storage for the ``secure_vector`` type. This pool
 | 
			
		||||
allocates out of pages which have been locked into memory using ``mlock`` or
 | 
			
		||||
``VirtualLock`` system calls.
 | 
			
		||||
 | 
			
		||||
If your variable happens to be destroyed before the pool, all is well. If the
 | 
			
		||||
pool happens to be destroyed before the variable, then when the object goes to
 | 
			
		||||
free its memory, a crash will occur.
 | 
			
		||||
 | 
			
		||||
This is basically the famous C++ "Static Initialization Order Fiasco", except
 | 
			
		||||
in reverse.
 | 
			
		||||
 | 
			
		||||
The best course of action is to avoid ``static`` variables. If that is
 | 
			
		||||
impossible or inconvenient, one option is to disable the pool, either at build
 | 
			
		||||
time (disable the ``locking_allocator`` module) or at runtime. Unfortunately the
 | 
			
		||||
runtime setting requires setting an environment variable (see :ref:`env_vars`),
 | 
			
		||||
and doing so consistently *prior to static intialization* is not trivial, due to
 | 
			
		||||
the previously mentioned fiasco. One option might be to use GCC's
 | 
			
		||||
``constructor`` function attribute.
 | 
			
		||||
 | 
			
		||||
Another approach is to use the utility class ``Allocator_Initializer`` (declared
 | 
			
		||||
in ``mem_ops.h``) as an associated ``static`` variable in your code. As long as
 | 
			
		||||
the ``Allocator_Initializer`` is created *before* your static variables, that
 | 
			
		||||
means the allocator is created before your object, and thus will be destroyed
 | 
			
		||||
after your object is destroyed.
 | 
			
		||||
 | 
			
		||||
Ideally a more satisfactory solution to this issue could be found, especially
 | 
			
		||||
given the difficulty of disabling the pool at runtime.
 | 
			
		||||
 | 
			
		||||
Multithreaded Access
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
It is perfectly safe to use the library from multiple threads.
 | 
			
		||||
 | 
			
		||||
It is *not* safe to use the same object from multiple threads, without some form
 | 
			
		||||
of external serialization or locking.
 | 
			
		||||
 | 
			
		||||
There are a few exceptions to this rule, where the type itself maintains an
 | 
			
		||||
internal mutexes. This will be noted in the respective documentation for that type.
 | 
			
		||||
 | 
			
		||||
Use of `fork`
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
If you use the `fork` syscall in your code, and attempt to use the library in
 | 
			
		||||
both processes, likely bad things will happen due to internal locks. You can
 | 
			
		||||
avoid this problem by either at build time disabling the features associated
 | 
			
		||||
with these locks (namely ``locking_allocator`` and ``thread_utils``) or
 | 
			
		||||
disabling them at runtime using :ref:`env_vars`, ideally at the very start of
 | 
			
		||||
`main`.
 | 
			
		||||
@@ -1,98 +0,0 @@
 | 
			
		||||
Format Preserving Encryption
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Format preserving encryption (FPE) refers to a set of techniques for
 | 
			
		||||
encrypting data such that the ciphertext has the same format as the
 | 
			
		||||
plaintext. For instance, you can use FPE to encrypt credit card
 | 
			
		||||
numbers with valid checksums such that the ciphertext is also an
 | 
			
		||||
credit card number with a valid checksum, or similarly for bank
 | 
			
		||||
account numbers, US Social Security numbers, or even more general
 | 
			
		||||
mappings like English words onto other English words.
 | 
			
		||||
 | 
			
		||||
The scheme currently implemented in botan is called FE1, and described
 | 
			
		||||
in the paper `Format Preserving Encryption
 | 
			
		||||
<https://eprint.iacr.org/2009/251>`_ by Mihir Bellare, Thomas
 | 
			
		||||
Ristenpart, Phillip Rogaway, and Till Stegers. FPE is an area of
 | 
			
		||||
ongoing standardization and it is likely that other schemes will be
 | 
			
		||||
included in the future.
 | 
			
		||||
 | 
			
		||||
To encrypt an arbitrary value using FE1, you need to use a ranking
 | 
			
		||||
method. Basically, the idea is to assign an integer to every value you
 | 
			
		||||
might encrypt. For instance, a 16 digit credit card number consists of
 | 
			
		||||
a 15 digit code plus a 1 digit checksum. So to encrypt a credit card
 | 
			
		||||
number, you first remove the checksum, encrypt the 15 digit value
 | 
			
		||||
modulo 10\ :sup:`15`, and then calculate what the checksum is for the
 | 
			
		||||
new (ciphertext) number. Or, if you were encrypting words in a
 | 
			
		||||
dictionary, you could rank the words by their lexicographical order,
 | 
			
		||||
and choose the modulus to be the number of words in the dictionary.
 | 
			
		||||
 | 
			
		||||
The interfaces for FE1 are defined in the header ``fpe_fe1.h``:
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.5.0
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: FPE_FE1
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: FPE_FE1(const BigInt& n, size_t rounds = 5, \
 | 
			
		||||
                             bool compat_mode = false,           \
 | 
			
		||||
                             std::string mac_algo = "HMAC(SHA-256)")
 | 
			
		||||
 | 
			
		||||
      Initialize an FPE operation to encrypt/decrypt integers less
 | 
			
		||||
      than *n*. It is expected that *n* is trivially factorable into
 | 
			
		||||
      small integers. Common usage would be n to be a power of 10.
 | 
			
		||||
 | 
			
		||||
      Note that the default parameters to this constructor are
 | 
			
		||||
      **incompatible** with the ``fe1_encrypt`` and ``fe1_decrypt``
 | 
			
		||||
      function originally added in 1.9.17. For compatibility, use
 | 
			
		||||
      3 rounds and set ``compat_mode`` to true.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt encrypt(const BigInt& x, const uint8_t tweak[], size_t tweak_len) const
 | 
			
		||||
 | 
			
		||||
      Encrypts the value *x* modulo the value *n* using the *key* and *tweak*
 | 
			
		||||
      specified. Returns an integer less than *n*. The *tweak* is a value that
 | 
			
		||||
      does not need to be secret that parameterizes the encryption function. For
 | 
			
		||||
      instance, if you were encrypting a database column with a single key, you
 | 
			
		||||
      could use a per-row-unique integer index value as the tweak. The same
 | 
			
		||||
      tweak value must be used during decryption.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt decrypt(const BigInt& x, const uint8_t tweak[], size_t tweak_len) const
 | 
			
		||||
 | 
			
		||||
      Decrypts an FE1 ciphertext. The *tweak* must be the same as that provided
 | 
			
		||||
      to the encryption function. Returns the plaintext integer.
 | 
			
		||||
 | 
			
		||||
      Note that there is not any implicit authentication or checking of data in
 | 
			
		||||
      FE1, so if you provide an incorrect key or tweak the result is simply a
 | 
			
		||||
      random integer.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt encrypt(const BigInt& x, uint64_t tweak)
 | 
			
		||||
 | 
			
		||||
      Convenience version of encrypt taking an integer tweak.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt decrypt(const BigInt& x, uint64_t tweak)
 | 
			
		||||
 | 
			
		||||
      Convenience version of decrypt taking an integer tweak.
 | 
			
		||||
 | 
			
		||||
There are two functions that handle the entire FE1 encrypt/decrypt operation.
 | 
			
		||||
These are the original interface to FE1, first added in 1.9.17. However because
 | 
			
		||||
they do the entire setup cost for each operation, they are significantly slower
 | 
			
		||||
than the class-based API presented above.
 | 
			
		||||
 | 
			
		||||
.. warning:: These functions are hardcoded to use 3 rounds, which may be
 | 
			
		||||
             insufficient depending on the chosen modulus.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt FPE::fe1_encrypt(const BigInt& n, const BigInt& X, \
 | 
			
		||||
             const SymmetricKey& key, const std::vector<uint8_t>& tweak)
 | 
			
		||||
 | 
			
		||||
    This creates an FPE_FE1 object, sets the key, and encrypts *X* using
 | 
			
		||||
    the provided tweak.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt FPE::fe1_decrypt(const BigInt& n, const BigInt& X, \
 | 
			
		||||
             const SymmetricKey& key, const std::vector<uint8_t>& tweak)
 | 
			
		||||
 | 
			
		||||
    This creates an FPE_FE1 object, sets the key, and decrypts *X* using
 | 
			
		||||
    the provided tweak.
 | 
			
		||||
 | 
			
		||||
This example encrypts a credit card number with a valid `Luhn checksum
 | 
			
		||||
<https://en.wikipedia.org/wiki/Luhn_algorithm>`_ to another number with the same
 | 
			
		||||
format, including a correct checksum.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: ../../src/cli/cc_enc.cpp
 | 
			
		||||
@@ -1,312 +0,0 @@
 | 
			
		||||
Hash Functions and Checksums
 | 
			
		||||
=============================
 | 
			
		||||
 | 
			
		||||
Hash functions are one-way functions, which map data of arbitrary size to a
 | 
			
		||||
fixed output length. Most of the hash functions in Botan are designed to be
 | 
			
		||||
cryptographically secure, which means that it is computationally infeasible to
 | 
			
		||||
create a collision (finding two inputs with the same hash) or preimages (given a
 | 
			
		||||
hash output, generating an arbitrary input with the same hash). But note that
 | 
			
		||||
not all such hash functions meet their goals, in particular MD4 and MD5 are
 | 
			
		||||
trivially broken. However they are still included due to their wide adoption in
 | 
			
		||||
various protocols.
 | 
			
		||||
 | 
			
		||||
The class :cpp:class:`HashFunction` is defined in `botan/hash.h`.
 | 
			
		||||
 | 
			
		||||
Using a hash function is typically split into three stages: initialization,
 | 
			
		||||
update, and finalization (often referred to as a IUF interface). The
 | 
			
		||||
initialization stage is implicit: after creating a hash function object, it is
 | 
			
		||||
ready to process data. Then update is called one or more times. Calling update
 | 
			
		||||
several times is equivalent to calling it once with all of the arguments
 | 
			
		||||
concatenated. After completing a hash computation (eg using ``final``), the
 | 
			
		||||
internal state is reset to begin hashing a new message.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: HashFunction
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::unique_ptr<HashFunction> create(const std::string& name)
 | 
			
		||||
 | 
			
		||||
    Return a newly allocated hash function object, or nullptr if the
 | 
			
		||||
    name is not recognized.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::unique_ptr<HashFunction> create_or_throw(const std::string& name)
 | 
			
		||||
 | 
			
		||||
    Like ``create`` except that it will throw an exception instead of
 | 
			
		||||
    returning nullptr.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t output_length()
 | 
			
		||||
 | 
			
		||||
    Return the size (in *bytes*) of the output of this function.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(const uint8_t* input, size_t length)
 | 
			
		||||
 | 
			
		||||
    Updates the computation with *input*.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(uint8_t input)
 | 
			
		||||
 | 
			
		||||
    Updates the computation with *input*.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(const std::vector<uint8_t>& input)
 | 
			
		||||
 | 
			
		||||
    Updates the computation with *input*.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(const std::string& input)
 | 
			
		||||
 | 
			
		||||
    Updates the computation with *input*.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void final(uint8_t* out)
 | 
			
		||||
 | 
			
		||||
    Finalize the calculation and place the result into ``out``.
 | 
			
		||||
    For the argument taking an array, exactly ``output_length`` bytes will
 | 
			
		||||
    be written. After you call ``final``, the algorithm is reset to
 | 
			
		||||
    its initial state, so it may be reused immediately.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> final()
 | 
			
		||||
 | 
			
		||||
    Similar to the other function of the same name, except it returns
 | 
			
		||||
    the result in a newly allocated vector.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> process(const uint8_t in[], size_t length)
 | 
			
		||||
 | 
			
		||||
     Equivalent to calling ``update`` followed by ``final``.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> process(const std::string& in)
 | 
			
		||||
 | 
			
		||||
     Equivalent to calling ``update`` followed by ``final``.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<HashFunction> new_object()
 | 
			
		||||
 | 
			
		||||
     Return a newly allocated HashFunction object of the same type as this one.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<HashFunction> copy_state()
 | 
			
		||||
 | 
			
		||||
     Return a newly allocated HashFunction object of the same type as this one,
 | 
			
		||||
     whose internal state matches the current state of this.
 | 
			
		||||
 | 
			
		||||
Code Example
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
Assume we want to calculate the SHA-256, SHA-384, and SHA-3 hash digests of the STDIN stream using the Botan library.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/hash.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Available Hash Functions
 | 
			
		||||
------------------------------
 | 
			
		||||
 | 
			
		||||
The following cryptographic hash functions are implemented. If in doubt,
 | 
			
		||||
any of SHA-384, SHA-3, or BLAKE2b are fine choices.
 | 
			
		||||
 | 
			
		||||
BLAKE2b
 | 
			
		||||
^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_BLAKE2B`` is defined.
 | 
			
		||||
 | 
			
		||||
A recently designed hash function. Very fast on 64-bit processors. Can output a
 | 
			
		||||
hash of any length between 1 and 64 bytes, this is specified by passing a value
 | 
			
		||||
to the constructor with the desired length.
 | 
			
		||||
 | 
			
		||||
Named like "Blake2b" which selects default 512-bit output, or as
 | 
			
		||||
"Blake2b(256)" to select 256 bits of output.
 | 
			
		||||
 | 
			
		||||
GOST-34.11
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. deprecated:: 2.11
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_GOST_34_11`` is defined.
 | 
			
		||||
 | 
			
		||||
Russian national standard hash. It is old, slow, and has some weaknesses. Avoid
 | 
			
		||||
it unless you must.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   As this hash function is no longer approved by the latest Russian standards,
 | 
			
		||||
   support for GOST 34.11 hash is deprecated and will be removed in a future
 | 
			
		||||
   major release.
 | 
			
		||||
 | 
			
		||||
Keccak-1600
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_KECCAK`` is defined.
 | 
			
		||||
 | 
			
		||||
An older (and incompatible) variant of SHA-3, but sometimes used. Prefer SHA-3 in
 | 
			
		||||
new code.
 | 
			
		||||
 | 
			
		||||
MD4
 | 
			
		||||
^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
An old and now broken hash function. Available if ``BOTAN_HAS_MD4`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   MD4 collisions can be easily created. There is no safe cryptographic use
 | 
			
		||||
   for this function.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Support for MD4 is deprecated and will be removed in a future major release.
 | 
			
		||||
 | 
			
		||||
MD5
 | 
			
		||||
^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
An old and now broken hash function. Available if ``BOTAN_HAS_MD5`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   MD5 collisions can be easily created. MD5 should never be used for signatures.
 | 
			
		||||
 | 
			
		||||
RIPEMD-160
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_RIPEMD160`` is defined.
 | 
			
		||||
 | 
			
		||||
A 160 bit hash function, quite old but still thought to be secure (up to the
 | 
			
		||||
limit of 2**80 computation required for a collision which is possible with any
 | 
			
		||||
160 bit hash function). Somewhat deprecated these days. Prefer SHA-2 or SHA-3
 | 
			
		||||
in new code.
 | 
			
		||||
 | 
			
		||||
SHA-1
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHA1`` is defined.
 | 
			
		||||
 | 
			
		||||
Widely adopted NSA designed hash function. Use SHA-2 or SHA-3 in new code.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   SHA-1 collisions can now be created by moderately resourced attackers. It
 | 
			
		||||
   must never be used for signatures.
 | 
			
		||||
 | 
			
		||||
SHA-256
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHA2_32`` is defined.
 | 
			
		||||
 | 
			
		||||
Relatively fast 256 bit hash function, thought to be secure.
 | 
			
		||||
 | 
			
		||||
Also includes the variant SHA-224. There is no real reason to use SHA-224.
 | 
			
		||||
 | 
			
		||||
SHA-512
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHA2_64`` is defined.
 | 
			
		||||
 | 
			
		||||
SHA-512 is faster than SHA-256 on 64-bit processors. Also includes the
 | 
			
		||||
truncated variants SHA-384 and SHA-512/256, which have the advantage
 | 
			
		||||
of avoiding message extension attacks.
 | 
			
		||||
 | 
			
		||||
SHA-3
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHA3`` is defined.
 | 
			
		||||
 | 
			
		||||
The new NIST standard hash. Fairly slow.
 | 
			
		||||
 | 
			
		||||
Supports 224, 256, 384 or 512 bit outputs. SHA-3 is faster with
 | 
			
		||||
smaller outputs.  Use as "SHA-3(256)" or "SHA-3(512)". Plain "SHA-3"
 | 
			
		||||
selects default 512 bit output.
 | 
			
		||||
 | 
			
		||||
SHAKE (SHAKE-128, SHAKE-256)
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHAKE`` is defined.
 | 
			
		||||
 | 
			
		||||
These are actually XOFs (extensible output functions) based on SHA-3, which can
 | 
			
		||||
output a value of any byte length. For example "SHAKE-128(1024)" will produce
 | 
			
		||||
1024 bits of output. The specified length must be a multiple of 8.
 | 
			
		||||
 | 
			
		||||
SM3
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SM3`` is defined.
 | 
			
		||||
 | 
			
		||||
Chinese national hash function, 256 bit output. Widely used in industry there.
 | 
			
		||||
Fast and seemingly secure, but no reason to prefer it over SHA-2 or SHA-3 unless
 | 
			
		||||
required.
 | 
			
		||||
 | 
			
		||||
Skein-512
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SKEIN_512`` is defined.
 | 
			
		||||
 | 
			
		||||
A contender for the NIST SHA-3 competition. Very fast on 64-bit systems.  Can
 | 
			
		||||
output a hash of any length between 1 and 64 bytes. It also accepts an optional
 | 
			
		||||
"personalization string" which can create variants of the hash. This is useful
 | 
			
		||||
for domain separation.
 | 
			
		||||
 | 
			
		||||
To set a personalization string set the second param to any value,
 | 
			
		||||
typically ASCII strings are used. Examples "Skein-512(256)" or
 | 
			
		||||
"Skein-512(384,personalization_string)".
 | 
			
		||||
 | 
			
		||||
Streebog (Streebog-256, Streebog-512)
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_STREEBOG`` is defined.
 | 
			
		||||
 | 
			
		||||
Newly designed Russian national hash function. Due to use of input-dependent
 | 
			
		||||
table lookups, it is vulnerable to side channels. There is no reason to use it
 | 
			
		||||
unless compatibility is needed.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   The Streebog Sbox has recently been revealed to have a hidden structure which
 | 
			
		||||
   interacts with its linear layer in a way which may provide a backdoor when
 | 
			
		||||
   used in certain ways. Avoid Streebog if at all possible.
 | 
			
		||||
 | 
			
		||||
Whirlpool
 | 
			
		||||
^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_WHIRLPOOL`` is defined.
 | 
			
		||||
 | 
			
		||||
A 512-bit hash function standardized by ISO and NESSIE. Relatively slow, and due
 | 
			
		||||
to the table based implementation it is potentially vulnerable to cache based
 | 
			
		||||
side channels.
 | 
			
		||||
 | 
			
		||||
Hash Function Combiners
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
These are functions which combine multiple hash functions to create a new hash
 | 
			
		||||
function. They are typically only used in specialized applications.
 | 
			
		||||
 | 
			
		||||
Parallel
 | 
			
		||||
^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_PARALLEL_HASH`` is defined.
 | 
			
		||||
 | 
			
		||||
Parallel simply concatenates multiple hash functions. For example
 | 
			
		||||
"Parallel(SHA-256,SHA-512)" outputs a 256+512 bit hash created by hashing the
 | 
			
		||||
input with both SHA-256 and SHA-512 and concatenating the outputs.
 | 
			
		||||
 | 
			
		||||
Note that due to the "multicollision attack" it turns out that generating a
 | 
			
		||||
collision for multiple parallel hash functions is no harder than generating a
 | 
			
		||||
collision for the strongest hash function.
 | 
			
		||||
 | 
			
		||||
Comp4P
 | 
			
		||||
^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_COMB4P`` is defined.
 | 
			
		||||
 | 
			
		||||
This combines two cryptographic hashes in such a way that preimage and collision
 | 
			
		||||
attacks are provably at least as hard as a preimage or collision attack on the
 | 
			
		||||
strongest hash.
 | 
			
		||||
 | 
			
		||||
Checksums
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
.. note:: Checksums are not suitable for cryptographic use, but can be used for
 | 
			
		||||
          error checking purposes.
 | 
			
		||||
 | 
			
		||||
Adler32
 | 
			
		||||
^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_ADLER32`` is defined.
 | 
			
		||||
 | 
			
		||||
The Adler32 checksum is used in the zlib format. 32 bit output.
 | 
			
		||||
 | 
			
		||||
CRC24
 | 
			
		||||
^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CRC24`` is defined.
 | 
			
		||||
 | 
			
		||||
This is the CRC function used in OpenPGP. 24 bit output.
 | 
			
		||||
 | 
			
		||||
CRC32
 | 
			
		||||
^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CRC32`` is defined.
 | 
			
		||||
 | 
			
		||||
This is the 32-bit CRC used in protocols such as Ethernet, gzip, PNG, etc.
 | 
			
		||||
@@ -1,153 +0,0 @@
 | 
			
		||||
 | 
			
		||||
.. _key_derivation_function:
 | 
			
		||||
 | 
			
		||||
Key Derivation Functions (KDF)
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Key derivation functions are used to turn some amount of shared secret material
 | 
			
		||||
into uniform random keys suitable for use with symmetric algorithms. An example
 | 
			
		||||
of an input which is useful for a KDF is a shared secret created using
 | 
			
		||||
Diffie-Hellman key agreement.
 | 
			
		||||
 | 
			
		||||
Typically a KDF is also used with a *salt* and a *label*. The *salt* should be
 | 
			
		||||
some random information which is available to all of the parties that would need
 | 
			
		||||
to use the KDF; this could be performed by setting the salt to some kind of
 | 
			
		||||
session identifier, or by having one of the parties generate a random salt and
 | 
			
		||||
including it in a message.
 | 
			
		||||
 | 
			
		||||
The *label* is used to bind the KDF output to some specific context. For
 | 
			
		||||
instance if you were using the KDF to derive a specific key referred to as the
 | 
			
		||||
"message key" in the protocol description, you might use a label of "FooProtocol
 | 
			
		||||
v2 MessageKey". This labeling ensures that if you accidentally use the same
 | 
			
		||||
input key and salt in some other context, you still use different keys in the
 | 
			
		||||
two contexts.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: KDF
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<KDF> KDF::create(const std::string& algo)
 | 
			
		||||
 | 
			
		||||
      Create a new KDF object. Returns nullptr if the named key derivation
 | 
			
		||||
      function was not available
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<KDF> KDF::create_or_throw(const std::string& algo)
 | 
			
		||||
 | 
			
		||||
      Create a new KDF object. Throws an exception if the named key derivation
 | 
			
		||||
      function was not available
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: template<concepts::resizable_byte_buffer T = secure_vector<uint8_t>> \
 | 
			
		||||
      T derive_key(size_t key_len, \
 | 
			
		||||
                   std::span<const uint8_t> secret, \
 | 
			
		||||
                   std::span<const uint8_t> salt, \
 | 
			
		||||
                   std::span<const uint8_t> label) const
 | 
			
		||||
 | 
			
		||||
      This version is parameterized to the output buffer type, so it can be used
 | 
			
		||||
      to return a ``std::vector``, a ``secure_vector``, or anything else
 | 
			
		||||
      satisfying the ``resizable_byte_buffer`` concept.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> derive_key( \
 | 
			
		||||
                                    const uint8_t secret[], \
 | 
			
		||||
                                    size_t secret_len, \
 | 
			
		||||
                                    const uint8_t salt[], \
 | 
			
		||||
                                    size_t salt_len, \
 | 
			
		||||
                                    const uint8_t label[], \
 | 
			
		||||
                                    size_t label_len) const
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> derive_key( \
 | 
			
		||||
     size_t key_len, const std::vector<uint8_t>& secret, \
 | 
			
		||||
     const std::vector<uint8_t>& salt, \
 | 
			
		||||
     const std::vector<uint8_t>& label) const
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> derive_key( \
 | 
			
		||||
     size_t key_len, const std::vector<uint8_t>& secret, \
 | 
			
		||||
     const uint8_t* salt, size_t salt_len) const
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> derive_key( \
 | 
			
		||||
     size_t key_len, const uint8_t* secret, size_t secret_len, \
 | 
			
		||||
     const std::string& salt) const
 | 
			
		||||
 | 
			
		||||
   All variations on the same theme. Deterministically creates a
 | 
			
		||||
   uniform random value from *secret*, *salt*, and *label*, whose
 | 
			
		||||
   meaning is described above.
 | 
			
		||||
 | 
			
		||||
Code Example
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
An example demonstrating using the API to hash a secret using HKDF
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/kdf.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Available KDFs
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
Botan includes many different KDFs simply because different protocols and.
 | 
			
		||||
standards have created subtly different approaches to this problem. For new
 | 
			
		||||
code, use HKDF which is conservative, well studied, widely implemented and NIST
 | 
			
		||||
approved. There is no technical reason (besides compatability) to choose any
 | 
			
		||||
other KDF.
 | 
			
		||||
 | 
			
		||||
HKDF
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
Defined in RFC 5869, HKDF uses HMAC to process inputs. Also available
 | 
			
		||||
are variants HKDF-Extract and HKDF-Expand. HKDF is the combined
 | 
			
		||||
Extract+Expand operation. Use the combined HKDF unless you need
 | 
			
		||||
compatibility with some other system.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_HKDF`` is defined.
 | 
			
		||||
 | 
			
		||||
KDF2
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
KDF2 comes from IEEE 1363. It uses a hash function.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_KDF2`` is defined.
 | 
			
		||||
 | 
			
		||||
KDF1-18033
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
KDF1 from ISO 18033-2. Very similar to (but incompatible with) KDF2.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_KDF1_18033`` is defined.
 | 
			
		||||
 | 
			
		||||
KDF1
 | 
			
		||||
~~~~~~
 | 
			
		||||
 | 
			
		||||
KDF1 from IEEE 1363. It can only produce an output at most the length
 | 
			
		||||
of the hash function used.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_KDF1`` is defined.
 | 
			
		||||
 | 
			
		||||
X9.42 PRF
 | 
			
		||||
~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A KDF from ANSI X9.42. Sometimes used for Diffie-Hellman. However it is
 | 
			
		||||
overly complicated and is fixed to use only SHA-1.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_X942_PRF`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   X9.42 PRF is deprecated and will be removed in a future major release.
 | 
			
		||||
 | 
			
		||||
SP800-108
 | 
			
		||||
~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
KDFs from NIST SP 800-108. Variants include "SP800-108-Counter",
 | 
			
		||||
"SP800-108-Feedback" and "SP800-108-Pipeline".
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SP800_108`` is defined.
 | 
			
		||||
 | 
			
		||||
SP800-56A
 | 
			
		||||
~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
KDF from NIST SP 800-56A.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SP800_56A`` is defined.
 | 
			
		||||
 | 
			
		||||
SP800-56C
 | 
			
		||||
~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
KDF from NIST SP 800-56C.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SP800_56C`` is defined.
 | 
			
		||||
@@ -1,60 +0,0 @@
 | 
			
		||||
AES Key Wrapping
 | 
			
		||||
=================================
 | 
			
		||||
 | 
			
		||||
NIST specifies two mechanisms for wrapping (encrypting) symmetric keys using
 | 
			
		||||
another key. The first (and older, more widely supported) method requires the
 | 
			
		||||
input be a multiple of 8 bytes long. The other allows any length input, though
 | 
			
		||||
only up to 2**32 bytes.
 | 
			
		||||
 | 
			
		||||
These algorithms are described in NIST SP 800-38F, and RFCs 3394 and 5649.
 | 
			
		||||
 | 
			
		||||
This API, defined in ``nist_keywrap.h``, first became available in version 2.4.0
 | 
			
		||||
 | 
			
		||||
These functions take an arbitrary 128-bit block cipher object, which must
 | 
			
		||||
already have been keyed with the key encryption key. NIST only allows these
 | 
			
		||||
functions with AES, but any 128-bit cipher will do and some other implementations
 | 
			
		||||
(such as in OpenSSL) do also allow other ciphers.  Use AES for best interop.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::vector<uint8_t> nist_key_wrap(const uint8_t input[], \
 | 
			
		||||
                  size_t input_len, const BlockCipher& bc)
 | 
			
		||||
 | 
			
		||||
   This performs KW (key wrap) mode. The input must be a multiple of 8 bytes long.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: secure_vector<uint8_t> nist_key_unwrap(const uint8_t input[], \
 | 
			
		||||
                  size_t input_len,  const BlockCipher& bc)
 | 
			
		||||
 | 
			
		||||
   This unwraps the result of nist_key_wrap, or throw Invalid_Authentication_Tag on error.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::vector<uint8_t> nist_key_wrap_padded(const uint8_t input[], \
 | 
			
		||||
                  size_t input_len, const BlockCipher& bc)
 | 
			
		||||
 | 
			
		||||
   This performs KWP (key wrap with padding) mode. The input can be any length.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: secure_vector<uint8_t> nist_key_unwrap_padded(const uint8_t input[], \
 | 
			
		||||
                  size_t input_len, const BlockCipher& bc)
 | 
			
		||||
 | 
			
		||||
   This unwraps the result of nist_key_wrap_padded, or throws Invalid_Authentication_Tag
 | 
			
		||||
   on error.
 | 
			
		||||
 | 
			
		||||
RFC 3394 Interface
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
This is an older interface that was first available (with slight changes) in
 | 
			
		||||
1.10, and available in its current form since 2.0 release. It uses a 128-bit,
 | 
			
		||||
192-bit, or 256-bit key to encrypt an input key. AES is always used. The input
 | 
			
		||||
must be a multiple of 8 bytes; if not an exception is thrown.
 | 
			
		||||
 | 
			
		||||
This interface is defined in ``rfc3394.h``.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: secure_vector<uint8_t> rfc3394_keywrap(const secure_vector<uint8_t>& key, \
 | 
			
		||||
                                                         const SymmetricKey& kek)
 | 
			
		||||
 | 
			
		||||
  Wrap the input key using kek (the key encryption key), and return the result. It will
 | 
			
		||||
  be 8 bytes longer than the input key.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: secure_vector<uint8_t> rfc3394_keyunwrap(const secure_vector<uint8_t>& key, \
 | 
			
		||||
                                                           const SymmetricKey& kek)
 | 
			
		||||
 | 
			
		||||
  Unwrap a key wrapped with rfc3394_keywrap.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,195 +0,0 @@
 | 
			
		||||
 | 
			
		||||
.. _mac:
 | 
			
		||||
 | 
			
		||||
Message Authentication Codes (MAC)
 | 
			
		||||
===================================
 | 
			
		||||
 | 
			
		||||
A Message Authentication Code algorithm computes a tag over a message utilizing
 | 
			
		||||
a shared secret key. Thus a valid tag confirms the authenticity and integrity of
 | 
			
		||||
the message. Only entities in possession of the shared secret key are able to
 | 
			
		||||
verify the tag.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
    When combining a MAC with unauthenticated encryption mode, prefer to first
 | 
			
		||||
    encrypt the message and then MAC the ciphertext. The alternative is to MAC
 | 
			
		||||
    the plaintext, which depending on exact usage can suffer serious security
 | 
			
		||||
    issues. For a detailed discussion of this issue see the paper "The Order of
 | 
			
		||||
    Encryption and Authentication for Protecting Communications" by Hugo
 | 
			
		||||
    Krawczyk
 | 
			
		||||
 | 
			
		||||
The Botan MAC computation is split into five stages.
 | 
			
		||||
 | 
			
		||||
#. Instantiate the MAC algorithm.
 | 
			
		||||
#. Set the secret key.
 | 
			
		||||
#. Process IV.
 | 
			
		||||
#. Process data.
 | 
			
		||||
#. Finalize the MAC computation.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: MessageAuthenticationCode
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string name() const
 | 
			
		||||
 | 
			
		||||
     Returns a human-readable string of the name of this algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void clear()
 | 
			
		||||
 | 
			
		||||
     Clear the key.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<MessageAuthenticationCode> new_object() const
 | 
			
		||||
 | 
			
		||||
     Return a newly allocated object of the same type as this one.
 | 
			
		||||
     The new object is unkeyed.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_key(const uint8_t* key, size_t length)
 | 
			
		||||
 | 
			
		||||
    Set the shared MAC key for the calculation. This function has to be called before the data is processed.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_keylength(size_t length) const
 | 
			
		||||
 | 
			
		||||
     This function returns true if and only if *length* is a valid
 | 
			
		||||
     keylength for the algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t minimum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the smallest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t maximum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the largest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void start(const uint8_t* nonce, size_t nonce_len)
 | 
			
		||||
 | 
			
		||||
    Set the IV for the MAC calculation. Note that not all MAC algorithms require an IV.
 | 
			
		||||
    If an IV is required, the function has to be called before the data is processed.
 | 
			
		||||
    For algorithms that don't require it, the call can be omitted, or else called
 | 
			
		||||
    with ``nonce_len`` of zero.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(const uint8_t* input, size_t length)
 | 
			
		||||
 | 
			
		||||
     Process the passed data.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(const secure_vector<uint8_t>& in)
 | 
			
		||||
 | 
			
		||||
    Process the passed data.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void update(uint8_t in)
 | 
			
		||||
 | 
			
		||||
    Process a single byte.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void final(uint8_t* out)
 | 
			
		||||
 | 
			
		||||
    Complete the MAC computation and write the calculated tag to the passed byte array.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: secure_vector<uint8_t> final()
 | 
			
		||||
 | 
			
		||||
    Complete the MAC computation and return the calculated tag.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool verify_mac(const uint8_t* mac, size_t length)
 | 
			
		||||
 | 
			
		||||
    Finalize the current MAC computation and compare the result to the passed
 | 
			
		||||
    ``mac``. Returns ``true``, if the verification is successful and false
 | 
			
		||||
    otherwise.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Code Examples
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
The following example computes an HMAC with a random key then verifies the tag.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/hmac.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
The following example code computes a AES-256 GMAC and subsequently verifies the
 | 
			
		||||
tag.  Unlike most other MACs, GMAC requires a nonce *which must not repeat or
 | 
			
		||||
all security is lost*.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/gmac.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
The following example code computes a valid AES-128 CMAC tag and modifies the
 | 
			
		||||
data to demonstrate a MAC verification failure.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/cmac.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Available MACs
 | 
			
		||||
------------------------------------------
 | 
			
		||||
 | 
			
		||||
Currently the following MAC algorithms are available in Botan. In new code,
 | 
			
		||||
default to HMAC with a strong hash like SHA-256 or SHA-384.
 | 
			
		||||
 | 
			
		||||
CMAC
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A modern CBC-MAC variant that avoids the security problems of plain CBC-MAC.
 | 
			
		||||
Approved by NIST. Also sometimes called OMAC.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CMAC`` is defined.
 | 
			
		||||
 | 
			
		||||
GMAC
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
GMAC is related to the GCM authenticated cipher mode. It is quite slow unless
 | 
			
		||||
hardware support for carryless multiplications is available. A new nonce
 | 
			
		||||
must be used with **each** message authenticated, or otherwise all security is
 | 
			
		||||
lost.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_GMAC`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Due to the nonce requirement, GMAC is exceptionally fragile. Avoid it unless
 | 
			
		||||
   absolutely required.
 | 
			
		||||
 | 
			
		||||
HMAC
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A message authentication code based on a hash function. Very commonly used.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_HMAC`` is defined.
 | 
			
		||||
 | 
			
		||||
KMAC
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 3.2
 | 
			
		||||
 | 
			
		||||
A SHA-3 derived message authentication code defined by NIST in SP 800-185.
 | 
			
		||||
 | 
			
		||||
There are two variants, ``KMAC-128`` and ``KMAC-256``. Both take a parameter
 | 
			
		||||
which specifies the output length in bits, for example ``KMAC-128(256)``.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_KMAC`` is defined.
 | 
			
		||||
 | 
			
		||||
Poly1305
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A polynomial mac (similar to GMAC). Very fast, but tricky to use safely. Forms
 | 
			
		||||
part of the ChaCha20Poly1305 AEAD mode. A new key must be used for **each**
 | 
			
		||||
message, or all security is lost.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_POLY1305`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   Due to the nonce requirement, Poly1305 is exceptionally fragile. Avoid it unless
 | 
			
		||||
   absolutely required.
 | 
			
		||||
 | 
			
		||||
SipHash
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A modern and very fast PRF. Produces only a 64-bit output. Defaults to
 | 
			
		||||
"SipHash(2,4)" which is the recommended configuration, using 2 rounds for each
 | 
			
		||||
input block and 4 rounds for finalization.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SIPHASH`` is defined.
 | 
			
		||||
 | 
			
		||||
X9.19-MAC
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A CBC-MAC variant sometimes used in finance. Always uses DES.
 | 
			
		||||
Sometimes called the "DES retail MAC", also standardized in ISO 9797-1.
 | 
			
		||||
 | 
			
		||||
It is slow and has known attacks. Avoid unless required.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_X919_MAC`` is defined.
 | 
			
		||||
@@ -1,98 +0,0 @@
 | 
			
		||||
One Time Passwords
 | 
			
		||||
========================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.2.0
 | 
			
		||||
 | 
			
		||||
One time password schemes are a user authentication method that relies on a
 | 
			
		||||
fixed secret key which is used to derive a sequence of short passwords, each of
 | 
			
		||||
which is accepted only once. Commonly this is used to implement two-factor
 | 
			
		||||
authentication (2FA), where the user authenticates using both a conventional
 | 
			
		||||
password (or a public key signature) and an OTP generated by a small device such
 | 
			
		||||
as a mobile phone.
 | 
			
		||||
 | 
			
		||||
Botan implements the HOTP and TOTP schemes from RFC 4226 and 6238.
 | 
			
		||||
 | 
			
		||||
Since the range of possible OTPs is quite small, applications must rate limit
 | 
			
		||||
OTP authentication attempts to some small number per second. Otherwise an attacker
 | 
			
		||||
could quickly try all 1000000 6-digit OTPs in a brief amount of time.
 | 
			
		||||
 | 
			
		||||
HOTP
 | 
			
		||||
^^^^^^
 | 
			
		||||
 | 
			
		||||
HOTP generates OTPs that are a short numeric sequence, between 6 and 8 digits
 | 
			
		||||
(most applications use 6 digits), created using the HMAC of a 64-bit counter
 | 
			
		||||
value. If the counter ever repeats the OTP will also repeat, thus both parties
 | 
			
		||||
must assure the counter only increments and is never repeated or
 | 
			
		||||
decremented. Thus both client and server must keep track of the next counter
 | 
			
		||||
expected.
 | 
			
		||||
 | 
			
		||||
Anyone with access to the client-specific secret key can authenticate as that
 | 
			
		||||
client, so it should be treated with the same security consideration as would be
 | 
			
		||||
given to any other symmetric key or plaintext password.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: HOTP
 | 
			
		||||
 | 
			
		||||
    Implement counter-based OTP
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: HOTP(const SymmetricKey& key, const std::string& hash_algo = "SHA-1", size_t digits = 6)
 | 
			
		||||
 | 
			
		||||
       Initialize an HOTP instance with a secret key (specific to each client),
 | 
			
		||||
       a hash algorithm (must be SHA-1, SHA-256, or SHA-512), and the number of
 | 
			
		||||
       digits with each OTP (must be 6, 7, or 8).
 | 
			
		||||
 | 
			
		||||
       In RFC 4226, HOTP is only defined with SHA-1, but many HOTP
 | 
			
		||||
       implementations support SHA-256 as an extension. The collision attacks
 | 
			
		||||
       on SHA-1 do not have any known effect on HOTP's security.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: uint32_t generate_hotp(uint64_t counter)
 | 
			
		||||
 | 
			
		||||
       Return the OTP associated with a specific counter value.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: std::pair<bool,uint64_t> verify_hotp(uint32_t otp, \
 | 
			
		||||
                      uint64_t starting_counter, size_t resync_range = 0)
 | 
			
		||||
 | 
			
		||||
       Check if a provided OTP matches the one that should be generated for
 | 
			
		||||
       the specified counter.
 | 
			
		||||
 | 
			
		||||
       The *starting_counter* should be the counter of the last successful
 | 
			
		||||
       authentication plus 1. If *resync_resync* is greater than 0, some number
 | 
			
		||||
       of counter values above *starting_counter* will also be checked if
 | 
			
		||||
       necessary. This is useful for instance when a client mistypes an OTP on
 | 
			
		||||
       entry; the authentication will fail so the server will not update its
 | 
			
		||||
       counter, but the client device will subsequently show the OTP for the
 | 
			
		||||
       next counter. Depending on the environment a *resync_range* of 3 to 10
 | 
			
		||||
       might be appropriate.
 | 
			
		||||
 | 
			
		||||
       Returns a pair of (is_valid,next_counter_to_use). If the OTP is invalid
 | 
			
		||||
       then always returns (false,starting_counter), since the last successful
 | 
			
		||||
       authentication counter has not changed.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TOTP
 | 
			
		||||
^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
TOTP is based on the same algorithm as HOTP, but instead of a counter a
 | 
			
		||||
timestamp is used.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: TOTP
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: TOTP(const SymmetricKey& key, const std::string& hash_algo = "SHA-1", \
 | 
			
		||||
                          size_t digits = 6, size_t time_step = 30)
 | 
			
		||||
 | 
			
		||||
      Setup to perform TOTP authentication using secret key *key*.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: uint32_t generate_totp(std::chrono::system_clock::time_point time_point)
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: uint32_t generate_totp(uint64_t unix_time)
 | 
			
		||||
 | 
			
		||||
      Generate and return a TOTP code based on a timestamp.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool verify_totp(uint32_t otp, std::chrono::system_clock::time_point time, \
 | 
			
		||||
                                      size_t clock_drift_accepted = 0)
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool verify_totp(uint32_t otp, uint64_t unix_time, \
 | 
			
		||||
                                      size_t clock_drift_accepted = 0)
 | 
			
		||||
 | 
			
		||||
      Return true if the provided OTP code is correct for the provided
 | 
			
		||||
      timestamp. If required, use *clock_drift_accepted* to deal with
 | 
			
		||||
      the client and server having slightly different clocks.
 | 
			
		||||
@@ -1,215 +0,0 @@
 | 
			
		||||
Password Hashing
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Storing passwords for user authentication purposes in plaintext is the
 | 
			
		||||
simplest but least secure method; when an attacker compromises the
 | 
			
		||||
database in which the passwords are stored, they immediately gain
 | 
			
		||||
access to all of them. Often passwords are reused among multiple
 | 
			
		||||
services or machines, meaning once a password to a single service is
 | 
			
		||||
known an attacker has a substantial head start on attacking other
 | 
			
		||||
machines.
 | 
			
		||||
 | 
			
		||||
The general approach is to store, instead of the password, the output
 | 
			
		||||
of a one way function of the password. Upon receiving an
 | 
			
		||||
authentication request, the authenticating party can recompute the one way
 | 
			
		||||
function and compare the value just computed with the one that was
 | 
			
		||||
stored. If they match, then the authentication request succeeds. But
 | 
			
		||||
when an attacker gains access to the database, they only have the
 | 
			
		||||
output of the one way function, not the original password.
 | 
			
		||||
 | 
			
		||||
Common hash functions such as SHA-256 are one way, but used alone they
 | 
			
		||||
have problems for this purpose. What an attacker can do, upon gaining
 | 
			
		||||
access to such a stored password database, is hash common dictionary
 | 
			
		||||
words and other possible passwords, storing them in a list. Then he
 | 
			
		||||
can search through his list; if a stored hash and an entry in his list
 | 
			
		||||
match, then he has found the password. Even worse, this can happen
 | 
			
		||||
*offline*: an attacker can begin hashing common passwords days,
 | 
			
		||||
months, or years before ever gaining access to the database. In
 | 
			
		||||
addition, if two users choose the same password, the one way function
 | 
			
		||||
output will be the same for both of them, which will be visible upon
 | 
			
		||||
inspection of the database.
 | 
			
		||||
 | 
			
		||||
There are two solutions to these problems: salting and
 | 
			
		||||
iteration. Salting refers to including, along with the password, a
 | 
			
		||||
randomly chosen value which perturbs the one way function. Salting can
 | 
			
		||||
reduce the effectiveness of offline dictionary generation, because for
 | 
			
		||||
each potential password, an attacker would have to compute the one way
 | 
			
		||||
function output for all possible salts. It also prevents the same
 | 
			
		||||
password from producing the same output, as long as the salts do not
 | 
			
		||||
collide. Choosing n-bit salts randomly, salt collisions become likely
 | 
			
		||||
only after about 2\ :sup:\ `(n/2)` salts have been generated. Choosing a
 | 
			
		||||
large salt (say 80 to 128 bits) ensures this is very unlikely. Note
 | 
			
		||||
that in password hashing salt collisions are unfortunate, but not
 | 
			
		||||
fatal - it simply allows the attacker to attack those two passwords in
 | 
			
		||||
parallel easier than they would otherwise be able to.
 | 
			
		||||
 | 
			
		||||
The other approach, iteration, refers to the general technique of
 | 
			
		||||
forcing multiple one way function evaluations when computing the
 | 
			
		||||
output, to slow down the operation. For instance if hashing a single
 | 
			
		||||
password requires running SHA-256 100,000 times instead of just once,
 | 
			
		||||
that will slow down user authentication by a factor of 100,000, but
 | 
			
		||||
user authentication happens quite rarely, and usually there are more
 | 
			
		||||
expensive operations that need to occur anyway (network and database
 | 
			
		||||
I/O, etc). On the other hand, an attacker who is attempting to break a
 | 
			
		||||
database full of stolen password hashes will be seriously
 | 
			
		||||
inconvenienced by a factor of 100,000 slowdown; they will be able to
 | 
			
		||||
only test at a rate of .0001% of what they would without iterations
 | 
			
		||||
(or, equivalently, will require 100,000 times as many zombie botnet
 | 
			
		||||
hosts).
 | 
			
		||||
 | 
			
		||||
Memory usage while checking a password is also a consideration; if the
 | 
			
		||||
computation requires using a certain minimum amount of memory, then an
 | 
			
		||||
attacker can become memory-bound, which may in particular make
 | 
			
		||||
customized cracking hardware more expensive. Some password hashing
 | 
			
		||||
designs, such as scrypt, explicitly attempt to provide this. The
 | 
			
		||||
bcrypt approach requires over 4 KiB of RAM (for the Blowfish key
 | 
			
		||||
schedule) and may also make some hardware attacks more expensive.
 | 
			
		||||
 | 
			
		||||
Botan provides three techniques for password hashing: Argon2, bcrypt, and
 | 
			
		||||
passhash9 (based on PBKDF2).
 | 
			
		||||
 | 
			
		||||
Argon2
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.11.0
 | 
			
		||||
 | 
			
		||||
Argon2 is the winner of the PHC (Password Hashing Competition) and provides
 | 
			
		||||
a tunable memory hard password hash. It has a standard string encoding, which looks like::
 | 
			
		||||
 | 
			
		||||
  "$argon2i$v=19$m=8192,t=10,p=3$YWFhYWFhYWE$itkWB9ODqTd85wUsoib7pfpVTNGMOu0ZJan1odl25V8"
 | 
			
		||||
 | 
			
		||||
Argon2 has three tunable parameters: ``M``, ``p``, and ``t``. ``M`` gives the
 | 
			
		||||
total memory consumption of the algorithm in kilobytes. Increasing ``p``
 | 
			
		||||
increases the available parallelism of the computation. The ``t`` parameter
 | 
			
		||||
gives the number of passes which are made over the data.
 | 
			
		||||
 | 
			
		||||
There are three variants of Argon2, namely Argon2d, Argon2i and Argon2id.
 | 
			
		||||
Argon2d uses data dependent table lookups with may leak information about the
 | 
			
		||||
password via side channel attacks, and is **not recommended** for password
 | 
			
		||||
hashing. Argon2i uses data independent table lookups and is immune to these
 | 
			
		||||
attacks, but at the cost of requiring higher ``t`` for security. Argon2id uses a
 | 
			
		||||
hybrid approach which is thought to be highly secure. The algorithm designers
 | 
			
		||||
recommend using Argon2id with ``t`` and ``p`` both equal to 1 and ``M`` set to
 | 
			
		||||
the largest amount of memory usable in your environment.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string argon2_generate_pwhash(const char* password, size_t password_len, \
 | 
			
		||||
                          RandomNumberGenerator& rng, \
 | 
			
		||||
                          size_t p, size_t M, size_t t, \
 | 
			
		||||
                          size_t y = 2, size_t salt_len = 16, size_t output_len = 32)
 | 
			
		||||
 | 
			
		||||
   Generate an Argon2 hash of the specified password. The ``y`` parameter specifies
 | 
			
		||||
   the variant: 0 for Argon2d, 1 for Argon2i, and 2 for Argon2id.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: bool argon2_check_pwhash(const char* password, size_t password_len, \
 | 
			
		||||
                                           const std::string& hash)
 | 
			
		||||
 | 
			
		||||
   Verify an Argon2 password hash against the provided password. Returns false if
 | 
			
		||||
   the input hash seems malformed or if the computed hash does not match.
 | 
			
		||||
 | 
			
		||||
Bcrypt
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
`Bcrypt <https://www.usenix.org/legacy/event/usenix99/provos/provos.pdf>`_ is a
 | 
			
		||||
password hashing scheme originally designed for use in OpenBSD, but numerous
 | 
			
		||||
other implementations exist. It is made available by including ``bcrypt.h``.
 | 
			
		||||
 | 
			
		||||
It has the advantage that it requires a small amount (4K) of fast RAM
 | 
			
		||||
to compute, which can make hardware password cracking somewhat more
 | 
			
		||||
expensive.
 | 
			
		||||
 | 
			
		||||
Bcrypt provides outputs that look like this::
 | 
			
		||||
 | 
			
		||||
  "$2a$12$7KIYdyv8Bp32WAvc.7YvI.wvRlyVn0HP/EhPmmOyMQA4YKxINO0p2"
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Due to the design of bcrypt, the password is effectively truncated at 72
 | 
			
		||||
   characters; further characters are ignored and do not change the hash. To
 | 
			
		||||
   support longer passwords, one common approach is to pre-hash the password
 | 
			
		||||
   with SHA-256, then run bcrypt using the hex or base64 encoding of the hash as
 | 
			
		||||
   the password. (Many bcrypt implementations truncate the password at the first
 | 
			
		||||
   NULL character, so hashing the raw binary SHA-256 may cause problems. Botan's
 | 
			
		||||
   bcrypt implementation will hash whatever values are given in the
 | 
			
		||||
   ``std::string`` including any embedded NULLs so this is not an issue, but
 | 
			
		||||
   might cause interop problems if another library needs to validate the
 | 
			
		||||
   password hashes.)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string generate_bcrypt(const std::string& password, \
 | 
			
		||||
                    RandomNumberGenerator& rng, \
 | 
			
		||||
                    uint16_t work_factor = 12, \
 | 
			
		||||
                    char bcrypt_version = "a")
 | 
			
		||||
 | 
			
		||||
   Takes the password to hash, a rng, and a work factor.
 | 
			
		||||
   The resulting password hash is returned as a string.
 | 
			
		||||
 | 
			
		||||
   Higher work factors increase the amount of time the algorithm runs,
 | 
			
		||||
   increasing the cost of cracking attempts. The increase is exponential, so a
 | 
			
		||||
   work factor of 12 takes roughly twice as long as work factor 11. The default
 | 
			
		||||
   work factor was set to 10 up until the 2.8.0 release.
 | 
			
		||||
 | 
			
		||||
   It is recommended to set the work factor as high as your system can tolerate
 | 
			
		||||
   (from a performance and latency perspective) since higher work factors greatly
 | 
			
		||||
   improve the security against GPU-based attacks.  For example, for protecting
 | 
			
		||||
   high value administrator passwords, consider using work factor 15 or 16; at
 | 
			
		||||
   these work factors each bcrypt computation takes several seconds. Since admin
 | 
			
		||||
   logins will be relatively uncommon, it might be acceptable for each login
 | 
			
		||||
   attempt to take some time. As of 2018, a good password cracking rig (with 8
 | 
			
		||||
   NVIDIA 1080 cards) can attempt about 1 billion bcrypt computations per month
 | 
			
		||||
   for work factor 13. For work factor 12, it can do twice as many.  For work
 | 
			
		||||
   factor 15, it can do only one quarter as many attempts.
 | 
			
		||||
 | 
			
		||||
   Due to bugs affecting various implementations of bcrypt, several different
 | 
			
		||||
   variants of the algorithm are defined. As of 2.7.0 Botan supports generating
 | 
			
		||||
   (or checking) the 2a, 2b, and 2y variants.  Since Botan has never been
 | 
			
		||||
   affected by any of the bugs which necessitated these version upgrades, all
 | 
			
		||||
   three versions are identical beyond the version identifier. Which variant to
 | 
			
		||||
   use is controlled by the ``bcrypt_version`` argument.
 | 
			
		||||
 | 
			
		||||
   The bcrypt work factor must be at least 4 (though at this work factor bcrypt
 | 
			
		||||
   is not very secure). The bcrypt format allows up to 31, but Botan currently
 | 
			
		||||
   rejects all work factors greater than 18 since even that work factor requires
 | 
			
		||||
   roughly 15 seconds of computation on a fast machine.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: bool check_bcrypt(const std::string& password, \
 | 
			
		||||
   const std::string& hash)
 | 
			
		||||
 | 
			
		||||
   Takes a password and a bcrypt output and returns true if the
 | 
			
		||||
   password is the same as the one that was used to generate the
 | 
			
		||||
   bcrypt hash.
 | 
			
		||||
 | 
			
		||||
.. _passhash9:
 | 
			
		||||
 | 
			
		||||
Passhash9
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Botan also provides a password hashing technique called passhash9, in
 | 
			
		||||
``passhash9.h``, which is based on PBKDF2.
 | 
			
		||||
 | 
			
		||||
Passhash9 hashes look like::
 | 
			
		||||
 | 
			
		||||
  "$9$AAAKxwMGNPSdPkOKJS07Xutm3+1Cr3ytmbnkjO6LjHzCMcMQXvcT"
 | 
			
		||||
 | 
			
		||||
This function should be secure with the proper parameters, and will remain in
 | 
			
		||||
the library for the foreseeable future, but it is specific to Botan rather than
 | 
			
		||||
being a widely used password hash. Prefer bcrypt or Argon2.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   This password format string ("$9$") conflicts with the format used
 | 
			
		||||
   for scrypt password hashes on Cisco systems.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string generate_passhash9(const std::string& password, \
 | 
			
		||||
   RandomNumberGenerator& rng, uint16_t work_factor = 15, uint8_t alg_id = 4)
 | 
			
		||||
 | 
			
		||||
   Functions much like ``generate_bcrypt``. The last parameter,
 | 
			
		||||
   ``alg_id``, specifies which PRF to use. Currently defined values are
 | 
			
		||||
   0: HMAC(SHA-1), 1: HMAC(SHA-256), 2: CMAC(Blowfish), 3: HMAC(SHA-384), 4: HMAC(SHA-512)
 | 
			
		||||
 | 
			
		||||
   The work factor must be greater than zero and less than 512. This performs
 | 
			
		||||
   10000 * ``work_factor`` PBKDF2 iterations, using 96 bits of salt taken from
 | 
			
		||||
   ``rng``. Using work factor of 10 or more is recommended.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: bool check_passhash9(const std::string& password, \
 | 
			
		||||
   const std::string& hash)
 | 
			
		||||
 | 
			
		||||
   Functions much like ``check_bcrypt``
 | 
			
		||||
@@ -1,294 +0,0 @@
 | 
			
		||||
 | 
			
		||||
.. _pbkdf:
 | 
			
		||||
 | 
			
		||||
Password Based Key Derivation
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Often one needs to convert a human readable password into a cryptographic
 | 
			
		||||
key. It is useful to slow down the computation of these computations in order to
 | 
			
		||||
reduce the speed of brute force search, thus they are parameterized in some
 | 
			
		||||
way which allows their required computation to be tuned.
 | 
			
		||||
 | 
			
		||||
PasswordHash
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.8.0
 | 
			
		||||
 | 
			
		||||
This API, declared in ``pwdhash.h``, has two classes, ``PasswordHashFamily``
 | 
			
		||||
representing the general algorithm, such as "PBKDF2(SHA-256)", or "Scrypt", and
 | 
			
		||||
``PasswordHash`` representing a specific instance of the problem which is fully
 | 
			
		||||
specified with all parameters (say "Scrypt" with ``N`` = 8192, ``r`` = 64, and
 | 
			
		||||
``p`` = 8) and which can be used to derive keys.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PasswordHash
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void hash(std::span<uint8_t> out, \
 | 
			
		||||
                               std::string_view password, \
 | 
			
		||||
                               std::span<uint8> salt)
 | 
			
		||||
 | 
			
		||||
      Derive a key from the specified *password* and *salt*, placing it into *out*.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void hash(std::span<uint8_t> out, \
 | 
			
		||||
                               std::string_view password, \
 | 
			
		||||
                               std::span<const uint8> salt, \
 | 
			
		||||
                               std::span<const uint8> ad, \
 | 
			
		||||
                               std::span<const uint8> key)
 | 
			
		||||
 | 
			
		||||
      Derive a key from the specified *password*, *salt*, associated data (*ad*), and
 | 
			
		||||
      secret *key*, placing it into *out*. The *ad* and *key* are both allowed
 | 
			
		||||
      to be empty. Currently non-empty AD/key is only supported with Argon2.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void derive_key(uint8_t out[], size_t out_len, \
 | 
			
		||||
                     const char* password, const size_t password_len, \
 | 
			
		||||
                     const uint8_t salt[], size_t salt_len) const
 | 
			
		||||
 | 
			
		||||
      Same functionality as the 3 argument variant of :cpp:func:`PasswordHash::hash`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void derive_key(uint8_t out[], size_t out_len, \
 | 
			
		||||
                     const char* password, const size_t password_len, \
 | 
			
		||||
                     const uint8_t salt[], size_t salt_len, \
 | 
			
		||||
                     const uint8_t ad[], size_t ad_len, \
 | 
			
		||||
                     const uint8_t key[], size_t key_len) const
 | 
			
		||||
 | 
			
		||||
       Same functionality as the 5 argument variant of :cpp:func:`PasswordHash::hash`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::string to_string() const
 | 
			
		||||
 | 
			
		||||
      Return a descriptive string including the parameters (iteration count, etc)
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: size_t iterations() const
 | 
			
		||||
 | 
			
		||||
      Return the iteration parameter
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: size_t memory_param() const
 | 
			
		||||
 | 
			
		||||
      Return the memory usage parameter, or 0 if the algorithm does not offer
 | 
			
		||||
      a memory usage option.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: size_t parallelism() const
 | 
			
		||||
 | 
			
		||||
      Returns the parallelism parameter, or 0 if the algorithm does not offer a
 | 
			
		||||
      parallelism option.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: size_t total_memory_usage() const
 | 
			
		||||
 | 
			
		||||
      Return a guesstimate of the total number of bytes of memory consumed when
 | 
			
		||||
      running this algorithm. If the function is not intended to be memory-hard
 | 
			
		||||
      and uses an effictively fixed amount of memory when running, this function
 | 
			
		||||
      returns 0.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool supports_keyed_operation() const
 | 
			
		||||
 | 
			
		||||
      Returns true if this password hash supports supplying a secret key
 | 
			
		||||
      to :cpp:func:`PasswordHash::hash`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool supports_associated_data() const
 | 
			
		||||
 | 
			
		||||
      Returns true if this password hash supports supplying associated data
 | 
			
		||||
      to :cpp:func:`PasswordHash::hash`.
 | 
			
		||||
 | 
			
		||||
The ``PasswordHashFamily`` creates specific instances of ``PasswordHash``:
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PasswordHashFamily
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: static std::unique_ptr<PasswordHashFamily> create(const std::string& what)
 | 
			
		||||
 | 
			
		||||
      For example "PBKDF2(SHA-256)", "Scrypt", "Argon2id". Returns null if the
 | 
			
		||||
      algorithm is not available.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::unique_ptr<PasswordHash> default_params() const
 | 
			
		||||
 | 
			
		||||
      Create a default instance of the password hashing algorithm. Be warned the
 | 
			
		||||
      value returned here may change from release to release.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::unique_ptr<PasswordHash> tune( \
 | 
			
		||||
                     size_t output_len, \
 | 
			
		||||
                     std::chrono::milliseconds msec, \
 | 
			
		||||
                     size_t max_memory_usage_mb = 0, \
 | 
			
		||||
                     std::chrono::milliseconds tuning_msec = std::chrono::milliseconds(10)) const
 | 
			
		||||
 | 
			
		||||
      Return a password hash instance tuned to run for approximately ``msec``
 | 
			
		||||
      milliseconds when producing an output of length ``output_len``. (Accuracy
 | 
			
		||||
      may vary, use the command line utility ``botan pbkdf_tune`` to check.)
 | 
			
		||||
 | 
			
		||||
      The parameters will be selected to use at most *max_memory_usage_mb* megabytes
 | 
			
		||||
      of memory, or if left as zero any size is allowed.
 | 
			
		||||
 | 
			
		||||
      This function works by runing a short tuning loop to estimate the
 | 
			
		||||
      performance of the algorithm, then scaling the parameters appropriately to
 | 
			
		||||
      hit the target size. The length of time the tuning loop runs can be
 | 
			
		||||
      controlled using the *tuning_msec* parameter.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::unique_ptr<PasswordHash> from_params( \
 | 
			
		||||
         size_t i1, size_t i2 = 0, size_t i3 = 0) const
 | 
			
		||||
 | 
			
		||||
      Create a password hash using some scheme specific format. Parameters are as follows:
 | 
			
		||||
 | 
			
		||||
      * For PBKDF2, PGP-S2K, and Bcrypt-PBKDF, ``i1`` is iterations
 | 
			
		||||
      * Scrypt uses ``i1`` == ``N``, ``i2`` == ``r``, and ``i3`` == ``p``
 | 
			
		||||
      * Argon2 family uses ``i1`` == ``M``, ``i2`` == ``t``, and ``i3`` == ``p``
 | 
			
		||||
 | 
			
		||||
      All unneeded parameters should be set to 0 or left blank.
 | 
			
		||||
 | 
			
		||||
Code Example
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
An example demonstrating using the API to hash a password using Argon2i:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pwdhash.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Available Schemes
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
General Recommendations
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
If you need wide interoperability use PBKDF2 with HMAC-SHA256 and at least 50K
 | 
			
		||||
iterations. If you don't, use Argon2id with p=1, t=3 and M as large as you
 | 
			
		||||
can reasonably set (say 1 gigabyte).
 | 
			
		||||
 | 
			
		||||
You can test how long a particular PBKDF takes to execute using the cli tool
 | 
			
		||||
``pbkdf_tune``::
 | 
			
		||||
 | 
			
		||||
  $ ./botan pbkdf_tune --algo=Argon2id 500 --max-mem=192 --check
 | 
			
		||||
  For 500 ms selected Argon2id(196608,3,1) using 192 MiB took 413.159 msec to compute
 | 
			
		||||
 | 
			
		||||
This returns the parameters chosen by the fast auto-tuning algorithm, and
 | 
			
		||||
because ``--check`` was supplied the hash is also executed with the full set of
 | 
			
		||||
parameters and timed.
 | 
			
		||||
 | 
			
		||||
PBKDF2
 | 
			
		||||
^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
PBKDF2 is the "standard" password derivation scheme, widely implemented in many
 | 
			
		||||
different libraries. It uses HMAC internally and requires choosing a hash
 | 
			
		||||
function to use. (If in doubt use SHA-256 or SHA-512). It also requires choosing
 | 
			
		||||
an iteration count, which makes brute force attacks more expensive. Use *at
 | 
			
		||||
least* 50000 and preferably much more. Using 250,000 would not be unreasonable.
 | 
			
		||||
 | 
			
		||||
Scrypt
 | 
			
		||||
^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.7.0
 | 
			
		||||
 | 
			
		||||
Scrypt is a relatively newer design which is "memory hard" - in
 | 
			
		||||
addition to requiring large amounts of CPU power it uses a large block
 | 
			
		||||
of memory to compute the hash. This makes brute force attacks using
 | 
			
		||||
ASICs substantially more expensive.
 | 
			
		||||
 | 
			
		||||
Scrypt has three parameters, usually termed ``N``, ``r``, and ``p``.  ``N`` is
 | 
			
		||||
the primary control of the workfactor, and must be a power of 2. For interactive
 | 
			
		||||
logins use 32768, for protection of secret keys or backups use 1048576.
 | 
			
		||||
 | 
			
		||||
The ``r`` parameter controls how 'wide' the internal hashing operation is. It
 | 
			
		||||
also increases the amount of memory that is used. Values from 1 to 8 are
 | 
			
		||||
reasonable.
 | 
			
		||||
 | 
			
		||||
Setting ``p`` parameter to greater than 1 splits up the work in a way that up
 | 
			
		||||
to p processors can work in parallel.
 | 
			
		||||
 | 
			
		||||
As a general recommendation, use ``N`` = 32768, ``r`` = 8, ``p`` = 1
 | 
			
		||||
 | 
			
		||||
Argon2
 | 
			
		||||
^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.11.0
 | 
			
		||||
 | 
			
		||||
Argon2 is the winner of the PHC (Password Hashing Competition) and
 | 
			
		||||
provides a tunable memory hard PBKDF. There are three minor variants
 | 
			
		||||
of Argon2 - Argon2d, Argon2i, and Argon2id. All three are implemented.
 | 
			
		||||
 | 
			
		||||
Bcrypt
 | 
			
		||||
^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.11.0
 | 
			
		||||
 | 
			
		||||
Bcrypt-PBKDF is a variant of the well known ``bcrypt`` password hashing
 | 
			
		||||
function.  Like ``bcrypt`` it is based around using Blowfish for the key
 | 
			
		||||
expansion, which requires 4 KiB of fast random access memory, making hardware
 | 
			
		||||
based attacks more expensive. Unlike Argon2 or Scrypt, the memory usage is not
 | 
			
		||||
tunable.
 | 
			
		||||
 | 
			
		||||
This function is relatively obscure but is used for example in OpenSSH.
 | 
			
		||||
Prefer Argon2 or Scrypt in new systems.
 | 
			
		||||
 | 
			
		||||
OpenPGP S2K
 | 
			
		||||
^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   The OpenPGP algorithm is weak and strange, and should be avoided unless
 | 
			
		||||
   implementing OpenPGP.
 | 
			
		||||
 | 
			
		||||
There are some oddities about OpenPGP's S2K algorithms that are documented
 | 
			
		||||
here. For one thing, it uses the iteration count in a strange manner; instead of
 | 
			
		||||
specifying how many times to iterate the hash, it tells how many *bytes* should
 | 
			
		||||
be hashed in total (including the salt). So the exact iteration count will
 | 
			
		||||
depend on the size of the salt (which is fixed at 8 bytes by the OpenPGP
 | 
			
		||||
standard, though the implementation will allow any salt size) and the size of
 | 
			
		||||
the passphrase.
 | 
			
		||||
 | 
			
		||||
To get what OpenPGP calls "Simple S2K", set iterations to 0, and do not specify
 | 
			
		||||
a salt. To get "Salted S2K", again leave the iteration count at 0, but give an
 | 
			
		||||
8-byte salt. "Salted and Iterated S2K" requires an 8-byte salt and some
 | 
			
		||||
iteration count (this should be significantly larger than the size of the
 | 
			
		||||
longest passphrase that might reasonably be used; somewhere from 1024 to 65536
 | 
			
		||||
would probably be about right). Using both a reasonably sized salt and a large
 | 
			
		||||
iteration count is highly recommended to prevent password guessing attempts.
 | 
			
		||||
 | 
			
		||||
PBKDF
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
:cpp:class:`PBKDF` is the older API for this functionality, presented in header
 | 
			
		||||
``pbkdf.h``. It only supports PBKDF2 and the PGP S2K algorithm, not
 | 
			
		||||
Scrypt, Argon2, or bcrypt. This interface is deprecated and will be removed
 | 
			
		||||
in a future major release.
 | 
			
		||||
 | 
			
		||||
In addition, this API requires the passphrase be entered as a
 | 
			
		||||
``std::string``, which means the secret will be stored in memory that
 | 
			
		||||
will not be zeroed.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PBKDF
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: static std::unique_ptr<PBKDF> create(const std::string& algo_spec, \
 | 
			
		||||
                                                          const std::string& provider = "")
 | 
			
		||||
 | 
			
		||||
      Return a newly created PBKDF object. The name should be in the
 | 
			
		||||
      format "PBKDF2(HASHNAME)", "PBKDF2(HMAC(HASHNAME))", or
 | 
			
		||||
      "OpenPGP-S2K".  Returns null if the algorithm is not available.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void pbkdf_iterations(uint8_t out[], size_t out_len, \
 | 
			
		||||
                            const std::string& passphrase, \
 | 
			
		||||
                            const uint8_t salt[], size_t salt_len, \
 | 
			
		||||
                            size_t iterations) const
 | 
			
		||||
 | 
			
		||||
      Run the PBKDF algorithm for the specified number of iterations,
 | 
			
		||||
      with the given salt, and write output to the buffer.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void pbkdf_timed(uint8_t out[], size_t out_len, \
 | 
			
		||||
                         const std::string& passphrase, \
 | 
			
		||||
                         const uint8_t salt[], size_t salt_len, \
 | 
			
		||||
                         std::chrono::milliseconds msec, \
 | 
			
		||||
                         size_t& iterations) const
 | 
			
		||||
 | 
			
		||||
      Choose (via short run-time benchmark) how many iterations to perform
 | 
			
		||||
      in order to run for roughly msec milliseconds. Writes the number
 | 
			
		||||
      of iterations used to reference argument.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: OctetString derive_key( \
 | 
			
		||||
               size_t output_len, const std::string& passphrase, \
 | 
			
		||||
               const uint8_t* salt, size_t salt_len, \
 | 
			
		||||
               size_t iterations) const
 | 
			
		||||
 | 
			
		||||
   Computes a key from *passphrase* and the *salt* (of length
 | 
			
		||||
   *salt_len* bytes) using an algorithm-specific interpretation of
 | 
			
		||||
   *iterations*, producing a key of length *output_len*.
 | 
			
		||||
 | 
			
		||||
   Use an iteration count of at least 10000. The salt should be
 | 
			
		||||
   randomly chosen by a good random number generator (see
 | 
			
		||||
   :ref:`random_number_generators` for how), or at the very least
 | 
			
		||||
   unique to this usage of the passphrase.
 | 
			
		||||
 | 
			
		||||
   If you call this function again with the same parameters, you will
 | 
			
		||||
   get the same key.
 | 
			
		||||
@@ -1,944 +0,0 @@
 | 
			
		||||
.. _pkcs11:
 | 
			
		||||
 | 
			
		||||
PKCS#11
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.11.31
 | 
			
		||||
 | 
			
		||||
|
 | 
			
		||||
 | 
			
		||||
PKCS#11 is a platform-independent interface for accessing smart cards and
 | 
			
		||||
hardware security modules (HSM). Vendors of PKCS#11 compatible devices usually
 | 
			
		||||
provide a so called middleware or "PKCS#11 module" which implements the PKCS#11
 | 
			
		||||
standard. This middleware translates calls from the platform-independent PKCS#11
 | 
			
		||||
API to device specific calls. So application developers don't have to write smart card
 | 
			
		||||
or HSM specific code for each device they want to support.
 | 
			
		||||
 | 
			
		||||
   .. note::
 | 
			
		||||
 | 
			
		||||
     The Botan PKCS#11 interface is implemented against version v2.40 of the standard.
 | 
			
		||||
 | 
			
		||||
Botan wraps the C PKCS#11 API to provide a C++ PKCS#11 interface. This is done
 | 
			
		||||
in two levels of abstraction: a low level API (see :ref:`pkcs11_low_level`) and
 | 
			
		||||
a high level API (see :ref:`pkcs11_high_level`). The low level API provides
 | 
			
		||||
access to all functions that are specified by the standard. The high level API
 | 
			
		||||
represents an object oriented approach to use PKCS#11 compatible devices but
 | 
			
		||||
only provides a subset of the functions described in the standard.
 | 
			
		||||
 | 
			
		||||
To use the PKCS#11 implementation the ``pkcs11`` module has to be enabled.
 | 
			
		||||
 | 
			
		||||
   .. note::
 | 
			
		||||
 | 
			
		||||
      Both PKCS#11 APIs live in the namespace ``Botan::PKCS11``
 | 
			
		||||
 | 
			
		||||
.. _pkcs11_low_level:
 | 
			
		||||
 | 
			
		||||
Low Level API
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
The PKCS#11 standards committee provides header files (``pkcs11.h``, ``pkcs11f.h`` and
 | 
			
		||||
``pkcs11t.h``) which define the PKCS#11 API in the C programming language. These
 | 
			
		||||
header files could be used directly to access PKCS#11 compatible smart cards or
 | 
			
		||||
HSMs. The external header files are shipped with Botan in version v2.4 of the standard. The PKCS#11 low
 | 
			
		||||
level API wraps the original PKCS#11 API, but still allows to access all functions described in the
 | 
			
		||||
standard and has the advantage that it is a C++ interface with features like RAII, exceptions
 | 
			
		||||
and automatic memory management.
 | 
			
		||||
 | 
			
		||||
The low level API is implemented by the :cpp:class:`LowLevel` class and can be accessed by
 | 
			
		||||
including the header ``botan/p11.h``.
 | 
			
		||||
 | 
			
		||||
Preface
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
All constants that belong together in the PKCS#11 standard are grouped into C++
 | 
			
		||||
enum classes. For example the different user types are grouped in the
 | 
			
		||||
:cpp:enum:`UserType` enumeration:
 | 
			
		||||
 | 
			
		||||
.. cpp:enum-class:: UserType : CK_USER_TYPE
 | 
			
		||||
 | 
			
		||||
   .. cpp:enumerator:: UserType::SO = CKU_SO
 | 
			
		||||
   .. cpp:enumerator:: UserType::User = CKU_USER
 | 
			
		||||
   .. cpp:enumerator:: UserType::ContextSpecific = CKU_CONTEXT_SPECIFIC
 | 
			
		||||
 | 
			
		||||
Additionally, all types that are used by the low or high level API are mapped by
 | 
			
		||||
type aliases to more C++ like names. For instance:
 | 
			
		||||
 | 
			
		||||
.. cpp:type:: FunctionListPtr = CK_FUNCTION_LIST_PTR
 | 
			
		||||
 | 
			
		||||
.. rubric:: C-API Wrapping
 | 
			
		||||
 | 
			
		||||
There is at least one method in the :cpp:class:`LowLevel` class that corresponds to a PKCS#11
 | 
			
		||||
function. For example the :cpp:func:`C_GetSlotList` method in the :cpp:class:`LowLevel` class is defined as follows:
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: LowLevel
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool C_GetSlotList(Bbool token_present, SlotId* slot_list_ptr, Ulong* count_ptr, ReturnValue* return_value = ThrowException) const
 | 
			
		||||
 | 
			
		||||
The :cpp:class:`LowLevel` class calls the PKCS#11 function from the function list of the PKCS#11 module:
 | 
			
		||||
 | 
			
		||||
   .. code-block:: c
 | 
			
		||||
 | 
			
		||||
      CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList,
 | 
			
		||||
                                                CK_ULONG_PTR pulCount )
 | 
			
		||||
 | 
			
		||||
Where it makes sense there is also an overload of the :cpp:class:`LowLevel` method to make usage easier and safer:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool C_GetSlotList( bool token_present, std::vector<SlotId>& slot_ids, ReturnValue* return_value = ThrowException ) const
 | 
			
		||||
 | 
			
		||||
With this overload the user of this API just has to pass a vector of :cpp:type:`SlotId` instead of pointers
 | 
			
		||||
to preallocated memory for the slot list and the number of elements. Additionally, there is no need
 | 
			
		||||
to call the method twice in order to determine the number of elements first.
 | 
			
		||||
 | 
			
		||||
Another example is the :cpp:func:`C_InitPIN` overload:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename Talloc> bool C_InitPIN( SessionHandle session, const std::vector<uint8_t, TAlloc>& pin, ReturnValue* return_value = ThrowException ) const
 | 
			
		||||
 | 
			
		||||
The templated ``pin`` parameter allows to pass the PIN as a ``std::vector<uint8_t>`` or a ``secure_vector<uint8_t>``.
 | 
			
		||||
If used with a ``secure_vector`` it is assured that the memory is securely erased when the ``pin`` object is no longer needed.
 | 
			
		||||
 | 
			
		||||
Error Handling
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
All possible PKCS#11 return values are represented by the enum class:
 | 
			
		||||
 | 
			
		||||
.. cpp:enum-class:: ReturnValue : CK_RV
 | 
			
		||||
 | 
			
		||||
All methods of the :cpp:class:`LowLevel` class have a default parameter ``ReturnValue* return_value = ThrowException``.
 | 
			
		||||
This parameter controls the error handling of all :cpp:class:`LowLevel` methods. The default
 | 
			
		||||
behavior ``return_value = ThrowException`` is to throw an exception if the method does
 | 
			
		||||
not complete successfully. If a non-``NULL`` pointer is passed, ``return_value`` receives the
 | 
			
		||||
return value of the PKCS#11 function and no exception is thrown. In case ``nullptr`` is
 | 
			
		||||
passed as ``return_value``, the exact return value is ignored and the method just returns
 | 
			
		||||
``true`` if the function succeeds and ``false`` otherwise.
 | 
			
		||||
 | 
			
		||||
Getting started
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
An object of this class can be accessed by the ``Module::operator->()`` method.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code Example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_low_level.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
.. _pkcs11_high_level:
 | 
			
		||||
 | 
			
		||||
High Level API
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
The high level API provides access to the most commonly used PKCS#11 functionality in an
 | 
			
		||||
object oriented manner. Functionality of the high level API includes:
 | 
			
		||||
 | 
			
		||||
* Loading/unloading of PKCS#11 modules
 | 
			
		||||
* Initialization of tokens
 | 
			
		||||
* Change of PIN/SO-PIN
 | 
			
		||||
* Session management
 | 
			
		||||
* Random number generation
 | 
			
		||||
* Enumeration of objects on the token (certificates, public keys, private keys)
 | 
			
		||||
* Import/export/deletion of certificates
 | 
			
		||||
* Generation/import/export/deletion of RSA and EC public and private keys
 | 
			
		||||
* Encryption/decryption using RSA with support for OAEP and PKCS1-v1_5 (and raw)
 | 
			
		||||
* Signature generation/verification using RSA with support for PSS and PKCS1-v1_5 (and raw)
 | 
			
		||||
* Signature generation/verification using ECDSA
 | 
			
		||||
* Key derivation using ECDH
 | 
			
		||||
 | 
			
		||||
Module
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The :cpp:class:`Module` class represents a PKCS#11 shared library (module) and is defined in
 | 
			
		||||
``botan/p11_module.h``.
 | 
			
		||||
 | 
			
		||||
It is constructed from a a file path to a PKCS#11 module and optional :cpp:type:`C_InitializeArgs`:
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Module
 | 
			
		||||
 | 
			
		||||
   .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
      Module(const std::string& file_path, C_InitializeArgs init_args =
 | 
			
		||||
         { nullptr, nullptr, nullptr, nullptr, static_cast<CK_FLAGS>(Flag::OsLockingOk), nullptr })
 | 
			
		||||
 | 
			
		||||
   It loads the shared library and calls :cpp:func:`C_Initialize` with the provided :cpp:type:`C_InitializeArgs`.
 | 
			
		||||
   On destruction of the object :cpp:func:`C_Finalize` is called.
 | 
			
		||||
 | 
			
		||||
There are two more methods in this class. One is for reloading the shared library
 | 
			
		||||
and reinitializing the PKCS#11 module:
 | 
			
		||||
 | 
			
		||||
   .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
      void reload(C_InitializeArgs init_args =
 | 
			
		||||
         { nullptr, nullptr, nullptr, nullptr, static_cast< CK_FLAGS >(Flag::OsLockingOk), nullptr });
 | 
			
		||||
 | 
			
		||||
The other one is for getting general information about the PKCS#11 module:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Info get_info() const
 | 
			
		||||
 | 
			
		||||
      This function calls :cpp:func:`C_GetInfo` internally.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_module.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Slot
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The :cpp:class:`Slot` class represents a PKCS#11 slot and is defined in
 | 
			
		||||
``botan/p11_slot.h``.
 | 
			
		||||
 | 
			
		||||
A PKCS#11 slot is usually a smart card reader that potentially contains a token.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Slot
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Slot(Module& module, SlotId slot_id)
 | 
			
		||||
 | 
			
		||||
      To instantiate this class a reference to a :cpp:class:`Module` object and a ``slot_id`` have to be passed
 | 
			
		||||
      to the constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: static std::vector<SlotId> get_available_slots(Module& module, bool token_present)
 | 
			
		||||
 | 
			
		||||
      Retrieve available slot ids by calling this static method.
 | 
			
		||||
 | 
			
		||||
      The parameter ``token_present`` controls whether all slots or only slots with a
 | 
			
		||||
      token attached are returned by this method. This method calls :cpp:func:`C_GetSlotList()`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: SlotInfo get_slot_info() const
 | 
			
		||||
 | 
			
		||||
      Returns information about the slot. Calls :cpp:func:`C_GetSlotInfo`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: TokenInfo get_token_info() const
 | 
			
		||||
 | 
			
		||||
      Obtains information about a particular token in the system. Calls :cpp:func:`C_GetTokenInfo`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<MechanismType> get_mechanism_list() const
 | 
			
		||||
 | 
			
		||||
      Obtains a list of mechanism types supported by the slot. Calls :cpp:func:`C_GetMechanismList`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: MechanismInfo get_mechanism_info(MechanismType mechanism_type) const
 | 
			
		||||
 | 
			
		||||
      Obtains information about a particular mechanism possibly supported by a slot.
 | 
			
		||||
      Calls :cpp:func:`C_GetMechanismInfo`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void initialize(const std::string& label, const secure_string& so_pin) const
 | 
			
		||||
 | 
			
		||||
      Calls :cpp:func:`C_InitToken` to initialize the token. The ``label`` must not exceed 32 bytes.
 | 
			
		||||
      The current PIN of the security officer must be passed in ``so_pin`` if the token
 | 
			
		||||
      is reinitialized or if it's a factory new token, the ``so_pin`` that is passed will initially be set.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_slot.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Session
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The :cpp:class:`Session` class represents a PKCS#11 session and is defined in ``botan/p11_session.h``.
 | 
			
		||||
 | 
			
		||||
A session is a logical connection between an application and a token.
 | 
			
		||||
 | 
			
		||||
The session is passed to most other PKCS#11 operations, and must remain alive
 | 
			
		||||
as long as any other PKCS#11 object which the session was passed to is still
 | 
			
		||||
alive, otherwise errors or even an application crash are possible.
 | 
			
		||||
In the future,
 | 
			
		||||
the API may change to using ``shared_ptr`` to remove this problem.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Session
 | 
			
		||||
 | 
			
		||||
   There are two constructors to create a new session and one constructor to
 | 
			
		||||
   take ownership of an existing session. The destructor calls
 | 
			
		||||
   :cpp:func:`C_Logout` if a user is logged in to this session and always
 | 
			
		||||
   :cpp:func:`C_CloseSession`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Session(Slot& slot, bool read_only)
 | 
			
		||||
 | 
			
		||||
      To initialize a session object a :cpp:class:`Slot` has to be specified on which the session
 | 
			
		||||
      should operate. ``read_only`` specifies whether the session should be read only or read write.
 | 
			
		||||
      Calls :cpp:func:`C_OpenSession`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Session(Slot& slot, Flags flags, VoidPtr callback_data, Notify notify_callback)
 | 
			
		||||
 | 
			
		||||
      Creates a new session by passing a :cpp:class:`Slot`, session ``flags``, ``callback_data`` and a
 | 
			
		||||
      ``notify_callback``. Calls :cpp:func:`C_OpenSession`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Session(Slot& slot, SessionHandle handle)
 | 
			
		||||
 | 
			
		||||
      Takes ownership of an existing session by passing :cpp:class:`Slot` and a session ``handle``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: SessionHandle release()
 | 
			
		||||
 | 
			
		||||
      Returns the released :cpp:type:`SessionHandle`
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void login(UserType userType, const secure_string& pin)
 | 
			
		||||
 | 
			
		||||
      Login to this session by passing :cpp:enum:`UserType` and ``pin``. Calls :cpp:func:`C_Login`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void logoff()
 | 
			
		||||
 | 
			
		||||
      Logout from this session. Not mandatory because on destruction of the :cpp:class:`Session` object
 | 
			
		||||
      this is done automatically.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: SessionInfo get_info() const
 | 
			
		||||
 | 
			
		||||
      Returns information about this session. Calls :cpp:func:`C_GetSessionInfo`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set_pin(const secure_string& old_pin, const secure_string& new_pin) const
 | 
			
		||||
 | 
			
		||||
      Calls :cpp:func:`C_SetPIN` to change the PIN of the logged in user using the ``old_pin``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void init_pin(const secure_string& new_pin)
 | 
			
		||||
 | 
			
		||||
      Calls :cpp:func:`C_InitPIN` to change or initialize the PIN using the SO_PIN (requires a logged in session).
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_session.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Objects
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
PKCS#11 objects consist of various attributes (:c:type:`CK_ATTRIBUTE`). For example :c:macro:`CKA_TOKEN`
 | 
			
		||||
describes if a PKCS#11 object is a session object or a token object. The helper class :cpp:class:`AttributeContainer`
 | 
			
		||||
helps with storing these attributes. The class is defined in ``botan/p11_object.h``.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: AttributeContainer
 | 
			
		||||
 | 
			
		||||
Attributes can be set in an :cpp:class:`AttributeContainer` by various ``add_`` methods:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void add_class(ObjectClass object_class)
 | 
			
		||||
 | 
			
		||||
      Add a class attribute (:c:macro:`CKA_CLASS` / :cpp:enumerator:`AttributeType::Class`)
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void add_string(AttributeType attribute, const std::string& value)
 | 
			
		||||
 | 
			
		||||
      Add a string attribute (e.g. :c:macro:`CKA_LABEL` / :cpp:enumerator:`AttributeType::Label`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void AttributeContainer::add_binary(AttributeType attribute, const uint8_t* value, size_t length)
 | 
			
		||||
 | 
			
		||||
      Add a binary attribute (e.g. :c:macro:`CKA_ID` / :cpp:enumerator:`AttributeType::Id`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename TAlloc> void AttributeContainer::add_binary(AttributeType attribute, const std::vector<uint8_t, TAlloc>& binary)
 | 
			
		||||
 | 
			
		||||
      Add a binary attribute by passing a ``vector``/``secure_vector`` (e.g. :c:macro:`CKA_ID` / :cpp:enumerator:`AttributeType::Id`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void AttributeContainer::add_bool(AttributeType attribute, bool value)
 | 
			
		||||
 | 
			
		||||
      Add a bool attribute (e.g. :c:macro:`CKA_SENSITIVE` / :cpp:enumerator:`AttributeType::Sensitive`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename T> void AttributeContainer::add_numeric(AttributeType attribute, T value)
 | 
			
		||||
 | 
			
		||||
       Add a numeric attribute (e.g. :c:macro:`CKA_MODULUS_BITS` / :cpp:enumerator:`AttributeType::ModulusBits`).
 | 
			
		||||
 | 
			
		||||
.. rubric:: Object Properties
 | 
			
		||||
 | 
			
		||||
The PKCS#11 standard defines the mandatory and optional attributes for each object class.
 | 
			
		||||
The mandatory and optional attribute requirements are mapped in so called property classes.
 | 
			
		||||
Mandatory attributes are set in the constructor, optional attributes can be set via ``set_`` methods.
 | 
			
		||||
 | 
			
		||||
In the top hierarchy is the :cpp:class:`ObjectProperties` class which inherits from the :cpp:class:`AttributeContainer`.
 | 
			
		||||
This class represents the common attributes of all PKCS#11 objects.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: ObjectProperties : public AttributeContainer
 | 
			
		||||
 | 
			
		||||
The constructor is defined as follows:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ObjectProperties::ObjectProperties(ObjectClass object_class)
 | 
			
		||||
 | 
			
		||||
      Every PKCS#11 object needs an object class attribute.
 | 
			
		||||
 | 
			
		||||
The next level defines the :cpp:class:`StorageObjectProperties` class which inherits from
 | 
			
		||||
:cpp:class:`ObjectProperties`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: StorageObjectProperties : public ObjectProperties
 | 
			
		||||
 | 
			
		||||
The only mandatory attribute is the object class, so the constructor is
 | 
			
		||||
defined as follows:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: StorageObjectProperties::StorageObjectProperties(ObjectClass object_class)
 | 
			
		||||
 | 
			
		||||
But in contrast to the :cpp:class:`ObjectProperties` class there are various setter methods. For example to
 | 
			
		||||
set the :cpp:enumerator:`AttributeType::Label`:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set_label(const std::string& label)
 | 
			
		||||
 | 
			
		||||
      Sets the label description of the object (RFC2279 string).
 | 
			
		||||
 | 
			
		||||
The remaining hierarchy is defined as follows:
 | 
			
		||||
 | 
			
		||||
* :cpp:class:`DataObjectProperties` inherits from :cpp:class:`StorageObjectProperties`
 | 
			
		||||
* :cpp:class:`CertificateProperties` inherits from :cpp:class:`StorageObjectProperties`
 | 
			
		||||
* :cpp:class:`DomainParameterProperties` inherits from :cpp:class:`StorageObjectProperties`
 | 
			
		||||
* :cpp:class:`KeyProperties` inherits from :cpp:class:`StorageObjectProperties`
 | 
			
		||||
* :cpp:class:`PublicKeyProperties` inherits from :cpp:class:`KeyProperties`
 | 
			
		||||
* :cpp:class:`PrivateKeyProperties` inherits from :cpp:class:`KeyProperties`
 | 
			
		||||
* :cpp:class:`SecretKeyProperties` inherits from :cpp:class:`KeyProperties`
 | 
			
		||||
 | 
			
		||||
PKCS#11 objects themselves are represented by the :cpp:class:`Object` class.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Object
 | 
			
		||||
 | 
			
		||||
Following constructors are defined:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Object::Object(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Takes ownership over an existing object.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Object::Object(Session& session, const ObjectProperties& obj_props)
 | 
			
		||||
 | 
			
		||||
      Creates a new object with the :cpp:class:`ObjectProperties` provided in ``obj_props``.
 | 
			
		||||
 | 
			
		||||
The other methods are:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: secure_vector<uint8_t> get_attribute_value(AttributeType attribute) const
 | 
			
		||||
 | 
			
		||||
      Returns the value of the given attribute (using :cpp:func:`C_GetAttributeValue`)
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set_attribute_value(AttributeType attribute, const secure_vector<uint8_t>& value) const
 | 
			
		||||
 | 
			
		||||
      Sets the given value for the attribute (using :cpp:func:`C_SetAttributeValue`)
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void destroy() const
 | 
			
		||||
 | 
			
		||||
      Destroys the object.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ObjectHandle copy(const AttributeContainer& modified_attributes) const
 | 
			
		||||
 | 
			
		||||
      Allows to copy the object with modified attributes.
 | 
			
		||||
 | 
			
		||||
And static methods to search for objects:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::vector<Attribute>& search_template)
 | 
			
		||||
 | 
			
		||||
      Searches for all objects of the given type that match ``search_template``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::string& label)
 | 
			
		||||
 | 
			
		||||
      Searches for all objects of the given type using the label (:c:macro:`CKA_LABEL`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::vector<uint8_t>& id)
 | 
			
		||||
 | 
			
		||||
      Searches for all objects of the given type using the id (:c:macro:`CKA_ID`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename T> static std::vector<T> search(Session& session, const std::string& label, const std::vector<uint8_t>& id)
 | 
			
		||||
 | 
			
		||||
      Searches for all objects of the given type using the label (:c:macro:`CKA_LABEL`) and id (:c:macro:`CKA_ID`).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename T> static std::vector<T> search(Session& session)
 | 
			
		||||
 | 
			
		||||
      Searches for all objects of the given type.
 | 
			
		||||
 | 
			
		||||
.. rubric:: The ObjectFinder
 | 
			
		||||
 | 
			
		||||
Another way for searching objects is to use the :cpp:class:`ObjectFinder` class. This class
 | 
			
		||||
manages calls to the ``C_FindObjects*`` functions: :cpp:func:`C_FindObjectsInit`, :cpp:func:`C_FindObjects`
 | 
			
		||||
and :cpp:func:`C_FindObjectsFinal`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: ObjectFinder
 | 
			
		||||
 | 
			
		||||
The constructor has the following signature:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ObjectFinder::ObjectFinder(Session& session, const std::vector<Attribute>& search_template)
 | 
			
		||||
 | 
			
		||||
      A search can be prepared with an :cpp:class:`ObjectSearcher` by passing a :cpp:class:`Session` and a ``search_template``.
 | 
			
		||||
 | 
			
		||||
The actual search operation is started by calling the :cpp:func:`find` method:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::vector<ObjectHandle> find(std::uint32_t max_count = 100) const
 | 
			
		||||
 | 
			
		||||
      Starts or continues a search for token and session objects that match a template. ``max_count``
 | 
			
		||||
      specifies the maximum number of search results (object handles) that are returned.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void finish()
 | 
			
		||||
 | 
			
		||||
      Finishes the search operation manually to allow a new :cpp:class:`ObjectFinder` to exist.
 | 
			
		||||
      Otherwise the search is finished by the destructor.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_objects.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
RSA
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
PKCS#11 RSA support is implemented in ``<botan/p11_rsa.h>``.
 | 
			
		||||
 | 
			
		||||
.. rubric:: RSA Public Keys
 | 
			
		||||
 | 
			
		||||
PKCS#11 RSA public keys are provided by the class :cpp:class:`PKCS11_RSA_PublicKey`. This class
 | 
			
		||||
inherits from :cpp:class:`RSA_PublicKey` and :cpp:class:`Object`. Furthermore there are two property classes defined
 | 
			
		||||
to generate and import RSA public keys analogous to the other property classes described
 | 
			
		||||
before: :cpp:class:`RSA_PublicKeyGenerationProperties` and :cpp:class:`RSA_PublicKeyImportProperties`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_RSA_PublicKey : public RSA_PublicKey, public Object
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RSA_PublicKey(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Existing PKCS#11 RSA public keys can be used by providing an :cpp:type:`ObjectHandle` to the
 | 
			
		||||
      constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RSA_PublicKey(Session& session, const RSA_PublicKeyImportProperties& pubkey_props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to import an existing RSA public key with the :cpp:class:`RSA_PublicKeyImportProperties`
 | 
			
		||||
      passed in ``pubkey_props`` to the token.
 | 
			
		||||
 | 
			
		||||
.. rubric:: RSA Private Keys
 | 
			
		||||
 | 
			
		||||
The support for PKCS#11 RSA private keys is implemented in a similar way. There are two property
 | 
			
		||||
classes: :cpp:class:`RSA_PrivateKeyGenerationProperties` and :cpp:class:`RSA_PrivateKeyImportProperties`. The :cpp:class:`PKCS11_RSA_PrivateKey`
 | 
			
		||||
class implements the actual support for PKCS#11 RSA private keys. This class inherits from :cpp:class:`Private_Key`,
 | 
			
		||||
:cpp:class:`RSA_PublicKey` and :cpp:class:`Object`. In contrast to the public key class there is a third constructor
 | 
			
		||||
to generate private keys directly on the token or in the session and one method to export private keys.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_RSA_PrivateKey : public Private_Key, public RSA_PublicKey, public Object
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RSA_PrivateKey(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Existing PKCS#11 RSA private keys can be used by providing an :cpp:type:`ObjectHandle` to the
 | 
			
		||||
      constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RSA_PrivateKey(Session& session, const RSA_PrivateKeyImportProperties& priv_key_props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to import an existing RSA private key with the :cpp:class:`RSA_PrivateKeyImportProperties`
 | 
			
		||||
      passed in ``priv_key_props`` to the token.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RSA_PrivateKey(Session& session, uint32_t bits, const RSA_PrivateKeyGenerationProperties& priv_key_props)
 | 
			
		||||
 | 
			
		||||
      Generates a new PKCS#11 RSA private key with bit length provided in ``bits`` and the :cpp:class:`RSA_PrivateKeyGenerationProperties`
 | 
			
		||||
      passed in ``priv_key_props``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: RSA_PrivateKey export_key() const
 | 
			
		||||
 | 
			
		||||
      Returns the exported :cpp:class:`RSA_PrivateKey`.
 | 
			
		||||
 | 
			
		||||
PKCS#11 RSA key pairs can be generated with the following free function:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RSA_KeyPair PKCS11::generate_rsa_keypair(Session& session, const RSA_PublicKeyGenerationProperties& pub_props, const RSA_PrivateKeyGenerationProperties& priv_props)
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_rsa.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
ECDSA
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
PKCS#11 ECDSA support is implemented in ``<botan/p11_ecdsa.h>``.
 | 
			
		||||
 | 
			
		||||
.. rubric:: ECDSA Public Keys
 | 
			
		||||
 | 
			
		||||
PKCS#11 ECDSA public keys are provided by the class :cpp:class:`PKCS11_ECDSA_PublicKey`. This class
 | 
			
		||||
inherits from :cpp:class:`PKCS11_EC_PublicKey` and :cpp:class:`ECDSA_PublicKey`. The necessary property classes
 | 
			
		||||
are defined in ``<botan/p11_ecc_key.h>``. For public keys there are :cpp:class:`EC_PublicKeyGenerationProperties`
 | 
			
		||||
and :cpp:class:`EC_PublicKeyImportProperties`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_ECDSA_PublicKey : public PKCS11_EC_PublicKey, public virtual ECDSA_PublicKey
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDSA_PublicKey(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Existing PKCS#11 ECDSA private keys can be used by providing an :cpp:type:`ObjectHandle` to the
 | 
			
		||||
      constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDSA_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to import an existing ECDSA public key with the :cpp:class:`EC_PublicKeyImportProperties`
 | 
			
		||||
      passed in ``props`` to the token.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ECDSA_PublicKey PKCS11_ECDSA_PublicKey::export_key() const
 | 
			
		||||
 | 
			
		||||
      Returns the exported :cpp:class:`ECDSA_PublicKey`.
 | 
			
		||||
 | 
			
		||||
.. rubric:: ECDSA Private Keys
 | 
			
		||||
 | 
			
		||||
The class :cpp:class:`PKCS11_ECDSA_PrivateKey` inherits from :cpp:class:`PKCS11_EC_PrivateKey` and implements support
 | 
			
		||||
for PKCS#11 ECDSA private keys. There are two property classes for key generation
 | 
			
		||||
and import: :cpp:class:`EC_PrivateKeyGenerationProperties` and :cpp:class:`EC_PrivateKeyImportProperties`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_ECDSA_PrivateKey : public PKCS11_EC_PrivateKey
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDSA_PrivateKey(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Existing PKCS#11 ECDSA private keys can be used by providing an :cpp:type:`ObjectHandle` to the
 | 
			
		||||
      constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDSA_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to import an existing ECDSA private key with the :cpp:class:`EC_PrivateKeyImportProperties`
 | 
			
		||||
      passed in ``props`` to the token.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDSA_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params, const EC_PrivateKeyGenerationProperties& props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to generate a new ECDSA private key with the :cpp:class:`EC_PrivateKeyGenerationProperties`
 | 
			
		||||
      passed in ``props`` on the token. The ``ec_params`` parameter is the DER-encoding of an
 | 
			
		||||
      ANSI X9.62 Parameters value.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ECDSA_PrivateKey export_key() const
 | 
			
		||||
 | 
			
		||||
      Returns the exported :cpp:class:`ECDSA_PrivateKey`.
 | 
			
		||||
 | 
			
		||||
PKCS#11 ECDSA key pairs can be generated with the following free function:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDSA_KeyPair PKCS11::generate_ecdsa_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props)
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_ecdsa.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
ECDH
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
PKCS#11 ECDH support is implemented in ``<botan/p11_ecdh.h>``.
 | 
			
		||||
 | 
			
		||||
.. rubric:: ECDH Public Keys
 | 
			
		||||
 | 
			
		||||
PKCS#11 ECDH public keys are provided by the class :cpp:class:`PKCS11_ECDH_PublicKey`. This class
 | 
			
		||||
inherits from :cpp:class:`PKCS11_EC_PublicKey`. The necessary property classes
 | 
			
		||||
are defined in ``<botan/p11_ecc_key.h>``. For public keys there are :cpp:class:`EC_PublicKeyGenerationProperties`
 | 
			
		||||
and :cpp:class:`EC_PublicKeyImportProperties`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_ECDH_PublicKey : public PKCS11_EC_PublicKey
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDH_PublicKey(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Existing PKCS#11 ECDH private keys can be used by providing an :cpp:type:`ObjectHandle` to the
 | 
			
		||||
      constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDH_PublicKey(Session& session, const EC_PublicKeyImportProperties& props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to import an existing ECDH public key with the :cpp:class:`EC_PublicKeyImportProperties`
 | 
			
		||||
      passed in ``props`` to the token.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ECDH_PublicKey export_key() const
 | 
			
		||||
 | 
			
		||||
      Returns the exported :cpp:class:`ECDH_PublicKey`.
 | 
			
		||||
 | 
			
		||||
.. rubric:: ECDH Private Keys
 | 
			
		||||
 | 
			
		||||
The class :cpp:class:`PKCS11_ECDH_PrivateKey` inherits from :cpp:class:`PKCS11_EC_PrivateKey` and :cpp:class:`PK_Key_Agreement_Key`
 | 
			
		||||
and implements support for PKCS#11 ECDH private keys. There are two
 | 
			
		||||
property classes. One for key generation and one for import: :cpp:class:`EC_PrivateKeyGenerationProperties` and
 | 
			
		||||
:cpp:class:`EC_PrivateKeyImportProperties`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_ECDH_PrivateKey : public virtual PKCS11_EC_PrivateKey, public virtual PK_Key_Agreement_Key
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDH_PrivateKey(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Existing PKCS#11 ECDH private keys can be used by providing an :cpp:type:`ObjectHandle` to the
 | 
			
		||||
      constructor.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDH_PrivateKey(Session& session, const EC_PrivateKeyImportProperties& props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to import an existing ECDH private key with the :cpp:class:`EC_PrivateKeyImportProperties`
 | 
			
		||||
      passed in ``props`` to the token.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_ECDH_PrivateKey(Session& session, const std::vector<uint8_t>& ec_params, const EC_PrivateKeyGenerationProperties& props)
 | 
			
		||||
 | 
			
		||||
      This constructor can be used to generate a new ECDH private key with the :cpp:class:`EC_PrivateKeyGenerationProperties`
 | 
			
		||||
      passed in ``props`` on the token. The ``ec_params`` parameter is the DER-encoding of an
 | 
			
		||||
      ANSI X9.62 Parameters value.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: ECDH_PrivateKey export_key() const
 | 
			
		||||
 | 
			
		||||
      Returns the exported :cpp:class:`ECDH_PrivateKey`.
 | 
			
		||||
 | 
			
		||||
PKCS#11 ECDH key pairs can be generated with the following free function:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: PKCS11_ECDH_KeyPair PKCS11::generate_ecdh_keypair(Session& session, const EC_PublicKeyGenerationProperties& pub_props, const EC_PrivateKeyGenerationProperties& priv_props)
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_ecdh.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The PKCS#11 RNG is defined in ``<botan/p11_randomgenerator.h>``. The class :cpp:class:`PKCS11_RNG`
 | 
			
		||||
implements the :cpp:class:`Hardware_RNG` interface.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_RNG : public Hardware_RNG
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_RNG(Session& session)
 | 
			
		||||
 | 
			
		||||
      A PKCS#11 :cpp:class:`Session` must be passed to instantiate a ``PKCS11_RNG``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void randomize(uint8_t output[], std::size_t length) override
 | 
			
		||||
 | 
			
		||||
      Calls :cpp:func:`C_GenerateRandom` to generate random data.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void add_entropy(const uint8_t in[], std::size_t length) override
 | 
			
		||||
 | 
			
		||||
      Calls :cpp:func:`C_SeedRandom` to add entropy to the random generation function of the token/middleware.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_rng.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Token Management Functions
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The header file ``<botan/p11.h>`` also defines some free functions for token management:
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void initialize_token(Slot& slot, const std::string& label, const secure_string& so_pin, const secure_string& pin)
 | 
			
		||||
 | 
			
		||||
      Initializes a token by passing a :cpp:class:`Slot`, a ``label`` and the ``so_pin`` of the security officer.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void change_pin(Slot& slot, const secure_string& old_pin, const secure_string& new_pin)
 | 
			
		||||
 | 
			
		||||
      Change PIN with ``old_pin`` to ``new_pin``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void change_so_pin(Slot& slot, const secure_string& old_so_pin, const secure_string& new_so_pin)
 | 
			
		||||
 | 
			
		||||
      Change SO_PIN with ``old_so_pin`` to new ``new_so_pin``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set_pin(Slot& slot, const secure_string& so_pin, const secure_string& pin)
 | 
			
		||||
 | 
			
		||||
      Sets user ``pin`` with ``so_pin``.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_token_management.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
X.509
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The header file ``<botan/p11_x509.h>`` defines the property class :cpp:class:`X509_CertificateProperties`
 | 
			
		||||
and the class :cpp:class:`PKCS11_X509_Certificate`.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PKCS11_X509_Certificate : public Object, public X509_Certificate
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_X509_Certificate(Session& session, ObjectHandle handle)
 | 
			
		||||
 | 
			
		||||
      Allows to use existing certificates on the token by passing a valid :cpp:type:`ObjectHandle`.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: PKCS11_X509_Certificate(Session& session, const X509_CertificateProperties& props)
 | 
			
		||||
 | 
			
		||||
      Allows to import an existing X.509 certificate to the token with the :cpp:class:`X509_CertificateProperties`
 | 
			
		||||
      passed in ``props``.
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Code example:
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/pkcs11_x509.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Tests
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The PKCS#11 tests are not executed automatically because the depend on an external
 | 
			
		||||
PKCS#11 module/middleware. The test tool has to be executed with ``--pkcs11-lib=``
 | 
			
		||||
followed with the path of the PKCS#11 module and a second argument which controls the
 | 
			
		||||
PKCS#11 tests that are executed. Passing ``pkcs11`` will execute all PKCS#11 tests but it's
 | 
			
		||||
also possible to execute only a subset with the following arguments:
 | 
			
		||||
 | 
			
		||||
- pkcs11-ecdh
 | 
			
		||||
- pkcs11-ecdsa
 | 
			
		||||
- pkcs11-lowlevel
 | 
			
		||||
- pkcs11-manage
 | 
			
		||||
- pkcs11-module
 | 
			
		||||
- pkcs11-object
 | 
			
		||||
- pkcs11-rng
 | 
			
		||||
- pkcs11-rsa
 | 
			
		||||
- pkcs11-session
 | 
			
		||||
- pkcs11-slot
 | 
			
		||||
- pkcs11-x509
 | 
			
		||||
 | 
			
		||||
The following PIN and SO-PIN/PUK values are used in tests:
 | 
			
		||||
 | 
			
		||||
- PIN 123456
 | 
			
		||||
- SO-PIN/PUK 12345678
 | 
			
		||||
 | 
			
		||||
 .. warning::
 | 
			
		||||
 | 
			
		||||
   Unlike the CardOS (4.4, 5.0, 5.3), the aforementioned SO-PIN/PUK is
 | 
			
		||||
   inappropriate for Gemalto (IDPrime MD 3840) cards, as it must be a byte array
 | 
			
		||||
   of length 24. For this reason some of the tests for Gemalto card involving
 | 
			
		||||
   SO-PIN will fail.  You run into a risk of exceding login attempts and as a
 | 
			
		||||
   result locking your card!  Currently, specifying pin via command-line option
 | 
			
		||||
   is not implemented, and therefore the desired PIN must be modified in the
 | 
			
		||||
   header src/tests/test_pkcs11.h:
 | 
			
		||||
 | 
			
		||||
   .. code-block:: cpp
 | 
			
		||||
 | 
			
		||||
      // SO PIN is expected to be set to "12345678" prior to running the tests
 | 
			
		||||
      const std::string SO_PIN = "12345678";
 | 
			
		||||
      const auto SO_PIN_SECVEC = Botan::PKCS11::secure_string(SO_PIN.begin(), SO_PIN.end());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Tested/Supported Smartcards
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
You are very welcome to contribute your own test results for other testing environments or other cards.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Test results
 | 
			
		||||
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
|  Smartcard                          | Status                                    | OS                                                | Midleware                                         |   Botan                                           | Errors                                            |
 | 
			
		||||
+=====================================+===========================================+===================================================+===================================================+===================================================+===================================================+
 | 
			
		||||
| CardOS 4.4                          | mostly works                              | Windows 10, 64-bit, version 1709                  | API Version 5.4.9.77 (Cryptoki v2.11)             |  2.4.0, Cryptoki v2.40                            | [50]_                                             |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
| CardOS 5.0                          | mostly works                              | Windows 10, 64-bit, version 1709                  | API Version 5.4.9.77 (Cryptoki v2.11)             |  2.4.0, Cryptoki v2.40                            | [51]_                                             |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
| CardOS 5.3                          | mostly works                              | Windows 10, 64-bit, version 1709                  | API Version 5.4.9.77 (Cryptoki v2.11)             |  2.4.0, Cryptoki v2.40                            | [52]_                                             |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
| CardOS 5.3                          | mostly works                              | Windows 10, 64-bit, version 1903                  | API Version 5.5.1 (Cryptoki v2.11)                |  2.12.0 unreleased, Cryptoki v2.40                | [53]_                                             |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
| Gemalto IDPrime MD 3840             | mostly works                              | Windows 10, 64-bit, version 1709                  | IDGo 800, v1.2.4 (Cryptoki v2.20)                 |  2.4.0, Cryptoki v2.40                            | [54]_                                             |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
| SoftHSM 2.3.0 (OpenSSL 1.0.2g)      | works                                     | Windows 10, 64-bit, version 1709                  | Cryptoki v2.40                                    |  2.4.0, Cryptoki v2.40                            |                                                   |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
| SoftHSM 2.5.0 (OpenSSL 1.1.1)       | works                                     | Windows 10, 64-bit, version 1803                  | Cryptoki v2.40                                    |  2.11.0, Cryptoki v2.40                           |                                                   |
 | 
			
		||||
+-------------------------------------+-------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+---------------------------------------------------+
 | 
			
		||||
 | 
			
		||||
.. [50] Failing operations for CardOS 4.4:
 | 
			
		||||
 | 
			
		||||
 - object_copy [20]_
 | 
			
		||||
 | 
			
		||||
 - rsa_privkey_export [21]_
 | 
			
		||||
 - rsa_generate_private_key [22]_
 | 
			
		||||
 - rsa_sign_verify [23]_
 | 
			
		||||
 | 
			
		||||
 - ecdh_privkey_import [3]_
 | 
			
		||||
 - ecdh_privkey_export [2]_
 | 
			
		||||
 - ecdh_pubkey_import [4]_
 | 
			
		||||
 - ecdh_pubkey_export [4]_
 | 
			
		||||
 - ecdh_generate_private_key [3]_
 | 
			
		||||
 - ecdh_generate_keypair [3]_
 | 
			
		||||
 - ecdh_derive [3]_
 | 
			
		||||
 | 
			
		||||
 - ecdsa_privkey_import [3]_
 | 
			
		||||
 - ecdsa_privkey_export [2]_
 | 
			
		||||
 - ecdsa_pubkey_import [4]_
 | 
			
		||||
 - ecdsa_pubkey_export [4]_
 | 
			
		||||
 - ecdsa_generate_private_key  [3]_
 | 
			
		||||
 - ecdsa_generate_keypair  [3]_
 | 
			
		||||
 - ecdsa_sign_verify  [3]_
 | 
			
		||||
 | 
			
		||||
 - rng_add_entropy [5]_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. [51] Failing operations for CardOS 5.0
 | 
			
		||||
 | 
			
		||||
 - object_copy [20]_
 | 
			
		||||
 | 
			
		||||
 - rsa_privkey_export [21]_
 | 
			
		||||
 - rsa_generate_private_key [22]_
 | 
			
		||||
 - rsa_sign_verify [23]_
 | 
			
		||||
 | 
			
		||||
 - ecdh_privkey_export [2]_
 | 
			
		||||
 - ecdh_pubkey_import [4]_
 | 
			
		||||
 - ecdh_generate_private_key [32]_
 | 
			
		||||
 - ecdh_generate_keypair [3]_
 | 
			
		||||
 - ecdh_derive [33]_
 | 
			
		||||
 | 
			
		||||
 - ecdsa_privkey_export [2]_
 | 
			
		||||
 - ecdsa_generate_private_key  [30]_
 | 
			
		||||
 - ecdsa_generate_keypair  [30]_
 | 
			
		||||
 - ecdsa_sign_verify  [30]_
 | 
			
		||||
 | 
			
		||||
 - rng_add_entropy [5]_
 | 
			
		||||
 | 
			
		||||
.. [52] Failing operations for CardOS 5.3
 | 
			
		||||
 | 
			
		||||
 - object_copy [20]_
 | 
			
		||||
 | 
			
		||||
 - rsa_privkey_export [21]_
 | 
			
		||||
 - rsa_generate_private_key [22]_
 | 
			
		||||
 - rsa_sign_verify [23]_
 | 
			
		||||
 | 
			
		||||
 - ecdh_privkey_export [2]_
 | 
			
		||||
 - ecdh_pubkey_import [6]_
 | 
			
		||||
 - ecdh_pubkey_export [6]_
 | 
			
		||||
 - ecdh_generate_private_key [30]_
 | 
			
		||||
 - ecdh_generate_keypair [31]_
 | 
			
		||||
 - ecdh_derive [30]_
 | 
			
		||||
 | 
			
		||||
 - ecdsa_privkey_export [2]_
 | 
			
		||||
 - ecdsa_pubkey_import [6]_
 | 
			
		||||
 - ecdsa_pubkey_export [6]_
 | 
			
		||||
 - ecdsa_generate_private_key  [31]_
 | 
			
		||||
 - ecdsa_generate_keypair  [31]_
 | 
			
		||||
 - ecdsa_sign_verify  [34]_
 | 
			
		||||
 | 
			
		||||
 - rng_add_entropy [5]_
 | 
			
		||||
 | 
			
		||||
.. [53] Failing operations for CardOS 5.3 (middelware 5.5.1)
 | 
			
		||||
 | 
			
		||||
 - ecdh_privkey_export [2]_
 | 
			
		||||
 - ecdh_generate_private_key [35]_
 | 
			
		||||
 - ecdsa_privkey_export [2]_
 | 
			
		||||
 - ecdsa_generate_private_key [36]_
 | 
			
		||||
 - c_copy_object [4]_
 | 
			
		||||
 | 
			
		||||
 - object_copy [4]_
 | 
			
		||||
 | 
			
		||||
 - rng_add_entropy [5]_
 | 
			
		||||
 | 
			
		||||
 - rsa_sign_verify [3]_
 | 
			
		||||
 - rsa_privkey_export [2]_
 | 
			
		||||
 - rsa_generate_private_key [9]_
 | 
			
		||||
 | 
			
		||||
.. [54] Failing operations for Gemalto IDPrime MD 3840
 | 
			
		||||
 | 
			
		||||
 - session_login_logout [2]_
 | 
			
		||||
 - session_info [2]_
 | 
			
		||||
 - set_pin [2]_
 | 
			
		||||
 - initialize [2]_
 | 
			
		||||
 - change_so_pin [2]_
 | 
			
		||||
 | 
			
		||||
 - object_copy [20]_
 | 
			
		||||
 | 
			
		||||
 - rsa_generate_private_key [7]_
 | 
			
		||||
 - rsa_encrypt_decrypt [8]_
 | 
			
		||||
 - rsa_sign_verify [2]_
 | 
			
		||||
 | 
			
		||||
 - rng_add_entropy [5]_
 | 
			
		||||
 | 
			
		||||
Error descriptions
 | 
			
		||||
 | 
			
		||||
.. [2] CKR_ARGUMENTS_BAD (0x7=7)
 | 
			
		||||
.. [3] CKR_MECHANISM_INVALID (0x70=112)
 | 
			
		||||
.. [4] CKR_FUNCTION_NOT_SUPPORTED (0x54=84)
 | 
			
		||||
.. [5] CKR_RANDOM_SEED_NOT_SUPPORTED (0x120=288)
 | 
			
		||||
.. [6] CKM_X9_42_DH_KEY_PAIR_GEN | CKR_DEVICE_ERROR (0x30=48)
 | 
			
		||||
.. [7] CKR_TEMPLATE_INCONSISTENT (0xD1=209)
 | 
			
		||||
.. [8] CKR_ENCRYPTED_DATA_INVALID | CKM_SHA256_RSA_PKCS (0x40=64)
 | 
			
		||||
.. [9] CKR_TEMPLATE_INCOMPLETE (0xD0=208)
 | 
			
		||||
 | 
			
		||||
.. [20] Test fails due to unsupported copy function (CKR_FUNCTION_NOT_SUPPORTED)
 | 
			
		||||
.. [21] Generating private key for extraction with property extractable fails (CKR_ARGUMENTS_BAD)
 | 
			
		||||
.. [22] Generate rsa private key operation fails (CKR_TEMPLATE_INCOMPLETE)
 | 
			
		||||
.. [23] Raw RSA sign-verify fails (CKR_MECHANISM_INVALID)
 | 
			
		||||
 | 
			
		||||
.. [30] Invalid argument Decoding error: BER: Value truncated
 | 
			
		||||
.. [31] Invalid argument Decoding error: BER: Length field is to large
 | 
			
		||||
.. [32] Invalid argument OS2ECP: Unknown format type 155
 | 
			
		||||
.. [33] Invalid argument OS2ECP: Unknown format type 92
 | 
			
		||||
.. [34] Invalid argument OS2ECP: Unknown format type 57
 | 
			
		||||
.. [35] Invalid argument OS2ECP: Unknown format type 82
 | 
			
		||||
.. [36] Invalid argument OS2ECP: Unknown format type 102
 | 
			
		||||
@@ -1,110 +0,0 @@
 | 
			
		||||
PSK Database
 | 
			
		||||
======================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.4.0
 | 
			
		||||
 | 
			
		||||
Many applications need to store pre-shared keys (hereafter PSKs) for
 | 
			
		||||
authentication purposes.
 | 
			
		||||
 | 
			
		||||
An abstract interface to PSK stores, along with some implementations
 | 
			
		||||
of same, are provided in ``psk_db.h``
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: PSK_Database
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool is_encrypted() const
 | 
			
		||||
 | 
			
		||||
      Returns true if (at least) the PSKs themselves are encrypted. Returns
 | 
			
		||||
      false if PSKs are stored in plaintext.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: std::set<std::string> list_names() const
 | 
			
		||||
 | 
			
		||||
      Return the set of valid names stored in the database, ie values for which
 | 
			
		||||
      ``get`` will return a value.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set(const std::string& name, const uint8_t psk[], size_t psk_len)
 | 
			
		||||
 | 
			
		||||
      Save a PSK. If ``name`` already exists, the current value will be
 | 
			
		||||
      overwritten.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: secure_vector<uint8_t> get(const std::string& name) const
 | 
			
		||||
 | 
			
		||||
      Return a value saved with ``set``. Throws an exception if ``name`` doesn't
 | 
			
		||||
      exist.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void remove(const std::string& name)
 | 
			
		||||
 | 
			
		||||
      Remove ``name`` from the database. If ``name`` doesn't exist, ignores the request.
 | 
			
		||||
 | 
			
		||||
   .. cpp::function:: std::string get_str(const std::string& name) const
 | 
			
		||||
 | 
			
		||||
      Like ``get`` but casts the return value to a string.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void set_str(const std::string& name, const std::string& psk)
 | 
			
		||||
 | 
			
		||||
      Like ``set`` but accepts the psk as a string (eg for a password).
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: template<typename Alloc> void set_vec(const std::string& name, \
 | 
			
		||||
                                              const std::vector<uint8_t, Alloc>& psk)
 | 
			
		||||
 | 
			
		||||
      Like ``set`` but accepting a vector.
 | 
			
		||||
 | 
			
		||||
The same header also provides a specific instantiation of ``PSK_Database`` which
 | 
			
		||||
encrypts both names and PSKs. It must be subclassed to provide the storage.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Encrypted_PSK_Database : public PSK_Database
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: Encrypted_PSK_Database(const secure_vector<uint8_t>& master_key)
 | 
			
		||||
 | 
			
		||||
      Initializes or opens a PSK database. The master key is used the secure the
 | 
			
		||||
      contents. It may be of any length. If encrypting PSKs under a passphrase,
 | 
			
		||||
      use a suitable key derivation scheme (such as PBKDF2) to derive the secret
 | 
			
		||||
      key. If the master key is lost, all PSKs stored are unrecoverable.
 | 
			
		||||
 | 
			
		||||
      Both names and values are encrypted using NIST key wrapping (see NIST
 | 
			
		||||
      SP800-38F) with AES-256. First the master key is used with HMAC(SHA-256)
 | 
			
		||||
      to derive two 256-bit keys, one for encrypting all names and the other to
 | 
			
		||||
      key an instance of HMAC(SHA-256). Values are each encrypted under an
 | 
			
		||||
      individual key created by hashing the encrypted name with HMAC. This
 | 
			
		||||
      associates the encrypted key with the name, and prevents an attacker with
 | 
			
		||||
      write access to the data store from taking an encrypted key associated
 | 
			
		||||
      with one entity and copying it to another entity.
 | 
			
		||||
 | 
			
		||||
      Names and PSKs are both padded to the next multiple of 8 bytes, providing
 | 
			
		||||
      some obfuscation of the length.
 | 
			
		||||
 | 
			
		||||
      One artifact of the names being encrypted is that is is possible to use
 | 
			
		||||
      multiple different master keys with the same underlying storage. Each
 | 
			
		||||
      master key will be responsible for a subset of the keys. An attacker who
 | 
			
		||||
      knows one of the keys will be able to tell there are other values
 | 
			
		||||
      encrypted under another key, but will not be able to tell how many other
 | 
			
		||||
      master keys are in use.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: virtual void kv_set(const std::string& index, const std::string& value) = 0
 | 
			
		||||
 | 
			
		||||
      Save an encrypted value. Both ``index`` and ``value`` will be non-empty
 | 
			
		||||
      base64 encoded strings.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: virtual std::string kv_get(const std::string& index) const = 0
 | 
			
		||||
 | 
			
		||||
      Return a value saved with ``kv_set``, or return the empty string.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: virtual void kv_del(const std::string& index) = 0
 | 
			
		||||
 | 
			
		||||
      Remove a value saved with ``kv_set``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: virtual std::set<std::string> kv_get_all() const = 0
 | 
			
		||||
 | 
			
		||||
      Return all active names (ie values for which ``kv_get`` will return a
 | 
			
		||||
      non-empty string).
 | 
			
		||||
 | 
			
		||||
A subclass of ``Encrypted_PSK_Database`` which stores data in a SQL database
 | 
			
		||||
is also available.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Encrypted_PSK_Database_SQL : public Encrypted_PSK_Database
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Encrypted_PSK_Database_SQL(const secure_vector<uint8_t>& master_key, \
 | 
			
		||||
                                 std::shared_ptr<SQL_Database> db, \
 | 
			
		||||
                                 const std::string& table_name)
 | 
			
		||||
 | 
			
		||||
     Creates or uses the named table in ``db``. The SQL schema of the table is
 | 
			
		||||
     ``(psk_name TEXT PRIMARY KEY, psk_value TEXT)``.
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,667 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Python Binding
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.11.14
 | 
			
		||||
 | 
			
		||||
.. highlight:: python
 | 
			
		||||
 | 
			
		||||
.. py:module:: botan3
 | 
			
		||||
 | 
			
		||||
The Python binding is based on the `ffi` module of botan and the
 | 
			
		||||
`ctypes` module of the Python standard library.
 | 
			
		||||
 | 
			
		||||
The versioning of the Python module follows the major versioning of
 | 
			
		||||
the C++ library. So for Botan 2, the module is named ``botan2`` while
 | 
			
		||||
for Botan 3 it is ``botan3``.
 | 
			
		||||
 | 
			
		||||
Versioning
 | 
			
		||||
----------------------------------------
 | 
			
		||||
.. py:function:: version_major()
 | 
			
		||||
 | 
			
		||||
   Returns the major number of the library version.
 | 
			
		||||
 | 
			
		||||
.. py:function:: version_minor()
 | 
			
		||||
 | 
			
		||||
   Returns the minor number of the library version.
 | 
			
		||||
 | 
			
		||||
.. py:function:: version_patch()
 | 
			
		||||
 | 
			
		||||
   Returns the patch number of the library version.
 | 
			
		||||
 | 
			
		||||
.. py:function:: version_string()
 | 
			
		||||
 | 
			
		||||
   Returns a free form version string for the library
 | 
			
		||||
 | 
			
		||||
Random Number Generators
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: RandomNumberGenerator(rng_type = 'system')
 | 
			
		||||
 | 
			
		||||
     Previously ``rng``
 | 
			
		||||
 | 
			
		||||
     Type 'user' also allowed (userspace HMAC_DRBG seeded from system
 | 
			
		||||
     rng). The system RNG is very cheap to create, as just a single file
 | 
			
		||||
     handle or CSP handle is kept open, from first use until shutdown,
 | 
			
		||||
     no matter how many 'system' rng instances are created. Thus it is
 | 
			
		||||
     easy to use the RNG in a one-off way, with `botan.RandomNumberGenerator().get(32)`.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: get(length)
 | 
			
		||||
 | 
			
		||||
      Return some bytes
 | 
			
		||||
 | 
			
		||||
   .. py:method:: reseed(bits = 256)
 | 
			
		||||
 | 
			
		||||
      Meaningless on system RNG, on userspace RNG causes a reseed/rekey
 | 
			
		||||
 | 
			
		||||
   .. py:method:: reseed_from_rng(source_rng, bits = 256)
 | 
			
		||||
 | 
			
		||||
      Take bits from the source RNG and use it to seed ``self``
 | 
			
		||||
 | 
			
		||||
   .. py:method:: add_entropy(seed)
 | 
			
		||||
 | 
			
		||||
      Add some unpredictable seed data to the RNG
 | 
			
		||||
 | 
			
		||||
Hash Functions
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: HashFunction(algo)
 | 
			
		||||
 | 
			
		||||
    Previously ``hash_function``
 | 
			
		||||
 | 
			
		||||
    The ``algo`` param is a string (eg 'SHA-1', 'SHA-384', 'BLAKE2b')
 | 
			
		||||
 | 
			
		||||
    .. py:method:: algo_name()
 | 
			
		||||
 | 
			
		||||
       Returns the name of this algorithm
 | 
			
		||||
 | 
			
		||||
    .. py:method:: clear()
 | 
			
		||||
 | 
			
		||||
       Clear state
 | 
			
		||||
 | 
			
		||||
    .. py:method:: output_length()
 | 
			
		||||
 | 
			
		||||
       Return output length in bytes
 | 
			
		||||
 | 
			
		||||
    .. py:method:: update(x)
 | 
			
		||||
 | 
			
		||||
       Add some input
 | 
			
		||||
 | 
			
		||||
    .. py:method:: final()
 | 
			
		||||
 | 
			
		||||
       Returns the hash of all input provided, resets
 | 
			
		||||
       for another message.
 | 
			
		||||
 | 
			
		||||
Message Authentication Codes
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: MsgAuthCode(algo)
 | 
			
		||||
 | 
			
		||||
    Previously ``message_authentication_code``
 | 
			
		||||
 | 
			
		||||
    Algo is a string (eg 'HMAC(SHA-256)', 'Poly1305', 'CMAC(AES-256)')
 | 
			
		||||
 | 
			
		||||
    .. py:method:: algo_name()
 | 
			
		||||
 | 
			
		||||
       Returns the name of this algorithm
 | 
			
		||||
 | 
			
		||||
    .. py:method:: clear()
 | 
			
		||||
 | 
			
		||||
       Clear internal state including the key
 | 
			
		||||
 | 
			
		||||
    .. py:method:: output_length()
 | 
			
		||||
 | 
			
		||||
       Return the output length in bytes
 | 
			
		||||
 | 
			
		||||
    .. py:method:: set_key(key)
 | 
			
		||||
 | 
			
		||||
       Set the key
 | 
			
		||||
 | 
			
		||||
    .. py:method:: update(x)
 | 
			
		||||
 | 
			
		||||
       Add some input
 | 
			
		||||
 | 
			
		||||
    .. py:method:: final()
 | 
			
		||||
 | 
			
		||||
       Returns the MAC of all input provided, resets
 | 
			
		||||
       for another message with the same key.
 | 
			
		||||
 | 
			
		||||
Ciphers
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: SymmetricCipher(object, algo, encrypt = True)
 | 
			
		||||
 | 
			
		||||
       Previously ``cipher``
 | 
			
		||||
 | 
			
		||||
       The algorithm is spcified as a string (eg 'AES-128/GCM',
 | 
			
		||||
       'Serpent/OCB(12)', 'Threefish-512/EAX').
 | 
			
		||||
 | 
			
		||||
       Set the second param to False for decryption
 | 
			
		||||
 | 
			
		||||
    .. py:method:: algo_name()
 | 
			
		||||
 | 
			
		||||
       Returns the name of this algorithm
 | 
			
		||||
 | 
			
		||||
    .. py:method:: tag_length()
 | 
			
		||||
 | 
			
		||||
       Returns the tag length (0 for unauthenticated modes)
 | 
			
		||||
 | 
			
		||||
    .. py:method:: default_nonce_length()
 | 
			
		||||
 | 
			
		||||
       Returns default nonce length
 | 
			
		||||
 | 
			
		||||
    .. py:method:: update_granularity()
 | 
			
		||||
 | 
			
		||||
       Returns update block size. Call to update() must provide input
 | 
			
		||||
       of exactly this many bytes
 | 
			
		||||
 | 
			
		||||
    .. py:method:: is_authenticated()
 | 
			
		||||
 | 
			
		||||
       Returns True if this is an AEAD mode
 | 
			
		||||
 | 
			
		||||
    .. py:method:: valid_nonce_length(nonce_len)
 | 
			
		||||
 | 
			
		||||
       Returns True if nonce_len is a valid nonce len for this mode
 | 
			
		||||
 | 
			
		||||
    .. py:method:: clear()
 | 
			
		||||
 | 
			
		||||
       Resets all state
 | 
			
		||||
 | 
			
		||||
    .. py:method:: set_key(key)
 | 
			
		||||
 | 
			
		||||
       Set the key
 | 
			
		||||
 | 
			
		||||
    .. py:method:: set_assoc_data(ad)
 | 
			
		||||
 | 
			
		||||
       Sets the associated data. Fails if this is not an AEAD mode
 | 
			
		||||
 | 
			
		||||
    .. py:method:: start(nonce)
 | 
			
		||||
 | 
			
		||||
       Start processing a message using nonce
 | 
			
		||||
 | 
			
		||||
    .. py:method:: update(txt)
 | 
			
		||||
 | 
			
		||||
       Consumes input text and returns output. Input text must be of
 | 
			
		||||
       update_granularity() length.  Alternately, always call finish
 | 
			
		||||
       with the entire message, avoiding calls to update entirely
 | 
			
		||||
 | 
			
		||||
    .. py:method:: finish(txt = None)
 | 
			
		||||
 | 
			
		||||
       Finish processing (with an optional final input). May throw if
 | 
			
		||||
       message authentication checks fail, in which case all plaintext
 | 
			
		||||
       previously processed must be discarded. You may call finish()
 | 
			
		||||
       with the entire message
 | 
			
		||||
 | 
			
		||||
Bcrypt
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:function:: bcrypt(passwd, rng, work_factor = 10)
 | 
			
		||||
 | 
			
		||||
   Provided the password and an RNG object, returns a bcrypt string
 | 
			
		||||
 | 
			
		||||
.. py:function:: check_bcrypt(passwd, bcrypt)
 | 
			
		||||
 | 
			
		||||
   Check a bcrypt hash against the provided password, returning True
 | 
			
		||||
   iff the password matches.
 | 
			
		||||
 | 
			
		||||
PBKDF
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:function:: pbkdf(algo, password, out_len, iterations = 100000, salt = None)
 | 
			
		||||
 | 
			
		||||
   Runs a PBKDF2 algo specified as a string (eg 'PBKDF2(SHA-256)',
 | 
			
		||||
   'PBKDF2(CMAC(Blowfish))').  Runs with specified iterations, with
 | 
			
		||||
   meaning depending on the algorithm.  The salt can be provided or
 | 
			
		||||
   otherwise is randomly chosen. In any case it is returned from the
 | 
			
		||||
   call.
 | 
			
		||||
 | 
			
		||||
   Returns out_len bytes of output (or potentially less depending on
 | 
			
		||||
   the algorithm and the size of the request).
 | 
			
		||||
 | 
			
		||||
   Returns tuple of salt, iterations, and psk
 | 
			
		||||
 | 
			
		||||
.. py:function:: pbkdf_timed(algo, password, out_len, ms_to_run = 300, salt = rng().get(12))
 | 
			
		||||
 | 
			
		||||
   Runs for as many iterations as needed to consumed ms_to_run
 | 
			
		||||
   milliseconds on whatever we're running on. Returns tuple of salt,
 | 
			
		||||
   iterations, and psk
 | 
			
		||||
 | 
			
		||||
Scrypt
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.8.0
 | 
			
		||||
 | 
			
		||||
.. py:function:: scrypt(out_len, password, salt, N=1024, r=8, p=8)
 | 
			
		||||
 | 
			
		||||
   Runs Scrypt key derivation function over the specified password
 | 
			
		||||
   and salt using Scrypt parameters N, r, p.
 | 
			
		||||
 | 
			
		||||
KDF
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:function:: kdf(algo, secret, out_len, salt)
 | 
			
		||||
 | 
			
		||||
   Performs a key derviation function (such as "HKDF(SHA-384)") over
 | 
			
		||||
   the provided secret and salt values. Returns a value of the
 | 
			
		||||
   specified length.
 | 
			
		||||
 | 
			
		||||
Public Key
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: PublicKey(object)
 | 
			
		||||
 | 
			
		||||
  Previously ``public_key``
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load(val)
 | 
			
		||||
 | 
			
		||||
     Load a public key. The value should be a PEM or DER blob.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_rsa(n, e)
 | 
			
		||||
 | 
			
		||||
     Load an RSA public key giving the modulus and public exponent
 | 
			
		||||
     as integers.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_dsa(p, q, g, y)
 | 
			
		||||
 | 
			
		||||
     Load an DSA public key giving the parameters and public value
 | 
			
		||||
     as integers.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_dh(p, g, y)
 | 
			
		||||
 | 
			
		||||
     Load an Diffie-Hellman public key giving the parameters and
 | 
			
		||||
     public value as integers.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_elgamal(p, q, g, y)
 | 
			
		||||
 | 
			
		||||
     Load an ElGamal public key giving the parameters and
 | 
			
		||||
     public value as integers.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_ecdsa(curve, pub_x, pub_y)
 | 
			
		||||
 | 
			
		||||
     Load an ECDSA public key giving the curve as a string
 | 
			
		||||
     (like "secp256r1") and the public point as a pair of
 | 
			
		||||
     integers giving the affine coordinates.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_ecdh(curve, pub_x, pub_y)
 | 
			
		||||
 | 
			
		||||
     Load an ECDH public key giving the curve as a string
 | 
			
		||||
     (like "secp256r1") and the public point as a pair of
 | 
			
		||||
     integers giving the affine coordinates.
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_sm2(curve, pub_x, pub_y)
 | 
			
		||||
 | 
			
		||||
     Load a SM2 public key giving the curve as a string (like
 | 
			
		||||
     "sm2p256v1") and the public point as a pair of integers giving
 | 
			
		||||
     the affine coordinates.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: check_key(rng_obj, strong=True):
 | 
			
		||||
 | 
			
		||||
     Test the key for consistency. If ``strong`` is ``True`` then
 | 
			
		||||
     more expensive tests are performed.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: export(pem=False)
 | 
			
		||||
 | 
			
		||||
     Exports the public key using the usual X.509 SPKI representation.
 | 
			
		||||
     If ``pem`` is True, the result is a PEM encoded string. Otherwise
 | 
			
		||||
     it is a binary DER value.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: to_der()
 | 
			
		||||
 | 
			
		||||
     Like ``self.export(False)``
 | 
			
		||||
 | 
			
		||||
  .. py:method:: to_pem()
 | 
			
		||||
 | 
			
		||||
     Like ``self.export(True)``
 | 
			
		||||
 | 
			
		||||
  .. py:method:: get_field(field_name)
 | 
			
		||||
 | 
			
		||||
     Return an integer field related to the public key. The valid field names
 | 
			
		||||
     vary depending on the algorithm. For example RSA public modulus can be
 | 
			
		||||
     extracted with ``rsa_key.get_field("n")``.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: fingerprint(hash = 'SHA-256')
 | 
			
		||||
 | 
			
		||||
     Returns a hash of the public key
 | 
			
		||||
 | 
			
		||||
  .. py:method:: algo_name()
 | 
			
		||||
 | 
			
		||||
     Returns the algorithm name
 | 
			
		||||
 | 
			
		||||
  .. py:method:: estimated_strength()
 | 
			
		||||
 | 
			
		||||
     Returns the estimated strength of this key against known attacks
 | 
			
		||||
     (NFS, Pollard's rho, etc)
 | 
			
		||||
 | 
			
		||||
Private Key
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: PrivateKey
 | 
			
		||||
 | 
			
		||||
  Previously ``private_key``
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: create(algo, param, rng)
 | 
			
		||||
 | 
			
		||||
     Creates a new private key. The parameter type/value depends on
 | 
			
		||||
     the algorithm. For "rsa" is is the size of the key in bits.
 | 
			
		||||
     For "ecdsa" and "ecdh" it is a group name (for instance
 | 
			
		||||
     "secp256r1"). For "ecdh" there is also a special case for group
 | 
			
		||||
     "curve25519" (which is actually a completely distinct key type
 | 
			
		||||
     with a non-standard encoding).
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load(val, passphrase="")
 | 
			
		||||
 | 
			
		||||
     Return a private key (DER or PEM formats accepted)
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_rsa(p, q, e)
 | 
			
		||||
 | 
			
		||||
     Return a private RSA key
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_dsa(p, q, g, x)
 | 
			
		||||
 | 
			
		||||
     Return a private DSA key
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_dh(p, g, x)
 | 
			
		||||
 | 
			
		||||
     Return a private DH key
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_elgamal(p, q, g, x)
 | 
			
		||||
 | 
			
		||||
     Return a private ElGamal key
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_ecdsa(curve, x)
 | 
			
		||||
 | 
			
		||||
     Return a private ECDSA key
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_ecdh(curve, x)
 | 
			
		||||
 | 
			
		||||
     Return a private ECDH key
 | 
			
		||||
 | 
			
		||||
  .. py:classmethod:: load_sm2(curve, x)
 | 
			
		||||
 | 
			
		||||
     Return a private SM2 key
 | 
			
		||||
 | 
			
		||||
  .. py:method:: get_public_key()
 | 
			
		||||
 | 
			
		||||
     Return a public_key object
 | 
			
		||||
 | 
			
		||||
  .. py:method:: to_pem()
 | 
			
		||||
 | 
			
		||||
     Return the PEM encoded private key (unencrypted). Like ``self.export(True)``
 | 
			
		||||
 | 
			
		||||
  .. py:method:: to_der()
 | 
			
		||||
 | 
			
		||||
     Return the PEM encoded private key (unencrypted). Like ``self.export(False)``
 | 
			
		||||
 | 
			
		||||
  .. py:method:: check_key(rng_obj, strong=True):
 | 
			
		||||
 | 
			
		||||
     Test the key for consistency. If ``strong`` is ``True`` then
 | 
			
		||||
     more expensive tests are performed.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: algo_name()
 | 
			
		||||
 | 
			
		||||
     Returns the algorithm name
 | 
			
		||||
 | 
			
		||||
  .. py:method:: export(pem=False)
 | 
			
		||||
 | 
			
		||||
     Exports the private key in PKCS8 format. If ``pem`` is True, the
 | 
			
		||||
     result is a PEM encoded string. Otherwise it is a binary DER
 | 
			
		||||
     value. The key will not be encrypted.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: export_encrypted(passphrase, rng, pem=False, msec=300, cipher=None, pbkdf=None)
 | 
			
		||||
 | 
			
		||||
     Exports the private key in PKCS8 format, encrypted using the
 | 
			
		||||
     provided passphrase. If ``pem`` is True, the result is a PEM
 | 
			
		||||
     encoded string. Otherwise it is a binary DER value.
 | 
			
		||||
 | 
			
		||||
  .. py:method:: get_field(field_name)
 | 
			
		||||
 | 
			
		||||
     Return an integer field related to the public key. The valid field names
 | 
			
		||||
     vary depending on the algorithm. For example first RSA secret prime can be
 | 
			
		||||
     extracted with ``rsa_key.get_field("p")``. This function can also be
 | 
			
		||||
     used to extract the public parameters.
 | 
			
		||||
 | 
			
		||||
Public Key Operations
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: PKEncrypt(pubkey, padding)
 | 
			
		||||
 | 
			
		||||
    Previously ``pk_op_encrypt``
 | 
			
		||||
 | 
			
		||||
    .. py:method:: encrypt(msg, rng)
 | 
			
		||||
 | 
			
		||||
.. py:class:: PKDecrypt(privkey, padding)
 | 
			
		||||
 | 
			
		||||
    Previously ``pk_op_decrypt``
 | 
			
		||||
 | 
			
		||||
    .. py:method:: decrypt(msg)
 | 
			
		||||
 | 
			
		||||
.. py:class:: PKSign(privkey, hash_w_padding)
 | 
			
		||||
 | 
			
		||||
    Previously ``pk_op_sign``
 | 
			
		||||
 | 
			
		||||
    .. py:method:: update(msg)
 | 
			
		||||
    .. py:method:: finish(rng)
 | 
			
		||||
 | 
			
		||||
.. py:class:: PKVerify(pubkey, hash_w_padding)
 | 
			
		||||
 | 
			
		||||
    Previously ``pk_op_verify``
 | 
			
		||||
 | 
			
		||||
    .. py:method:: update(msg)
 | 
			
		||||
    .. py:method:: check_signature(signature)
 | 
			
		||||
 | 
			
		||||
.. py:class:: PKKeyAgreement(privkey, kdf)
 | 
			
		||||
 | 
			
		||||
    Previously ``pk_op_key_agreement``
 | 
			
		||||
 | 
			
		||||
    .. py:method:: public_value()
 | 
			
		||||
 | 
			
		||||
    Returns the public value to be passed to the other party
 | 
			
		||||
 | 
			
		||||
    .. py:method:: agree(other, key_len, salt)
 | 
			
		||||
 | 
			
		||||
    Returns a key derived by the KDF.
 | 
			
		||||
 | 
			
		||||
Multiple Precision Integers (MPI)
 | 
			
		||||
-------------------------------------
 | 
			
		||||
.. versionadded:: 2.8.0
 | 
			
		||||
 | 
			
		||||
.. py:class:: MPI(initial_value=None, radix=None)
 | 
			
		||||
 | 
			
		||||
   Initialize an MPI object with specified value, left as zero otherwise.  The
 | 
			
		||||
   ``initial_value`` should be an ``int``, ``str``, or ``MPI``.
 | 
			
		||||
   The ``radix`` value should be set to 16 when initializing from a base 16 `str` value.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   Most of the usual arithmetic operators (``__add__``, ``__mul__``, etc) are
 | 
			
		||||
   defined.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: inverse_mod(modulus)
 | 
			
		||||
 | 
			
		||||
      Return the inverse of ``self`` modulo ``modulus``, or zero if no inverse exists
 | 
			
		||||
 | 
			
		||||
   .. py:method:: is_prime(rng, prob=128)
 | 
			
		||||
 | 
			
		||||
      Test if ``self`` is prime
 | 
			
		||||
 | 
			
		||||
   .. py:method:: pow_mod(exponent, modulus):
 | 
			
		||||
 | 
			
		||||
      Return ``self`` to the ``exponent`` power modulo ``modulus``
 | 
			
		||||
 | 
			
		||||
   .. py:method:: mod_mul(other, modulus):
 | 
			
		||||
 | 
			
		||||
      Return the multiplication product of ``self`` and ``other`` modulo ``modulus``
 | 
			
		||||
 | 
			
		||||
   .. py:method:: gcd(other):
 | 
			
		||||
 | 
			
		||||
      Return the greatest common divisor of ``self`` and ``other``
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Format Preserving Encryption (FE1 scheme)
 | 
			
		||||
-----------------------------------------
 | 
			
		||||
.. versionadded:: 2.8.0
 | 
			
		||||
 | 
			
		||||
.. py:class:: FormatPreservingEncryptionFE1(modulus, key, rounds=5, compat_mode=False)
 | 
			
		||||
 | 
			
		||||
   Initialize an instance for format preserving encryption
 | 
			
		||||
 | 
			
		||||
   .. py:method:: encrypt(msg, tweak)
 | 
			
		||||
 | 
			
		||||
      The msg should be a botan3.MPI or an object which can be converted to one
 | 
			
		||||
 | 
			
		||||
   .. py:method:: decrypt(msg, tweak)
 | 
			
		||||
 | 
			
		||||
      The msg should be a botan3.MPI or an object which can be converted to one
 | 
			
		||||
 | 
			
		||||
HOTP
 | 
			
		||||
-----------------------------------------
 | 
			
		||||
.. versionadded:: 2.8.0
 | 
			
		||||
 | 
			
		||||
.. py:class:: HOTP(key, hash="SHA-1", digits=6)
 | 
			
		||||
 | 
			
		||||
   .. py:method:: generate(counter)
 | 
			
		||||
 | 
			
		||||
      Generate an HOTP code for the provided counter
 | 
			
		||||
 | 
			
		||||
   .. py:method:: check(code, counter, resync_range=0)
 | 
			
		||||
 | 
			
		||||
      Check if provided ``code`` is the correct code for ``counter``.
 | 
			
		||||
      If ``resync_range`` is greater than zero, HOTP also checks
 | 
			
		||||
      up to ``resync_range`` following counter values.
 | 
			
		||||
 | 
			
		||||
      Returns a tuple of (bool,int) where the boolean indicates if the
 | 
			
		||||
      code was valid, and the int indicates the next counter value
 | 
			
		||||
      that should be used. If the code did not verify, the next
 | 
			
		||||
      counter value is always identical to the counter that was passed
 | 
			
		||||
      in. If the code did verify and resync_range was zero, then the
 | 
			
		||||
      next counter will always be counter+1.
 | 
			
		||||
 | 
			
		||||
X509Cert
 | 
			
		||||
-----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: X509Cert(filename=None, buf=None) 
 | 
			
		||||
 | 
			
		||||
   .. py:method:: time_starts()
 | 
			
		||||
 | 
			
		||||
      Return the time the certificate becomes valid, as a string in form
 | 
			
		||||
      "YYYYMMDDHHMMSSZ" where Z is a literal character reflecting that this time is
 | 
			
		||||
      relative to UTC.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: time_expires()
 | 
			
		||||
 | 
			
		||||
      Return the time the certificate expires, as a string in form
 | 
			
		||||
      "YYYYMMDDHHMMSSZ" where Z is a literal character reflecting that this time is
 | 
			
		||||
      relative to UTC.      
 | 
			
		||||
 | 
			
		||||
   .. py:method:: to_string()
 | 
			
		||||
 | 
			
		||||
      Format the certificate as a free-form string.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: fingerprint(hash_algo='SHA-256')
 | 
			
		||||
 | 
			
		||||
      Return a fingerprint for the certificate, which is basically just a hash
 | 
			
		||||
      of the binary contents. Normally SHA-1 or SHA-256 is used, but any hash
 | 
			
		||||
      function is allowed.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: serial_number()
 | 
			
		||||
 | 
			
		||||
      Return the serial number of the certificate.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: authority_key_id()
 | 
			
		||||
 | 
			
		||||
      Return the authority key ID set in the certificate, which may be empty.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: subject_key_id()
 | 
			
		||||
 | 
			
		||||
      Return the subject key ID set in the certificate, which may be empty.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: subject_public_key_bits()
 | 
			
		||||
 | 
			
		||||
      Get the serialized representation of the public key included in this certificate.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: subject_public_key()
 | 
			
		||||
 | 
			
		||||
      Get the public key included in this certificate as an object of class ``PublicKey``.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: subject_dn(key, index)
 | 
			
		||||
 | 
			
		||||
      Get a value from the subject DN field.
 | 
			
		||||
 | 
			
		||||
      ``key`` specifies a value to get, for instance ``"Name"`` or `"Country"`.  
 | 
			
		||||
 | 
			
		||||
   .. py:method:: issuer_dn(key, index)
 | 
			
		||||
 | 
			
		||||
      Get a value from the issuer DN field.
 | 
			
		||||
 | 
			
		||||
      ``key`` specifies a value to get, for instance ``"Name"`` or `"Country"`.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: hostname_match(hostname)
 | 
			
		||||
 | 
			
		||||
      Return True if the Common Name (CN) field of the certificate matches a given ``hostname``.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: not_before()
 | 
			
		||||
 | 
			
		||||
      Return the time the certificate becomes valid, as seconds since epoch.   
 | 
			
		||||
 | 
			
		||||
   .. py:method:: not_after()
 | 
			
		||||
 | 
			
		||||
      Return the time the certificate expires, as seconds since epoch.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: allowed_usage(usage_list)
 | 
			
		||||
 | 
			
		||||
      Return True if the certificates Key Usage extension contains all constraints given in ``usage_list``.
 | 
			
		||||
      Also return True if the certificate doesn't have this extension.
 | 
			
		||||
      Example usage constraints are: ``"DIGITAL_SIGNATURE"``, ``"KEY_CERT_SIGN"``, ``"CRL_SIGN"``.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: verify(intermediates=None, \
 | 
			
		||||
                  trusted=None, \
 | 
			
		||||
                  trusted_path=None, \
 | 
			
		||||
                  required_strength=0, \
 | 
			
		||||
                  hostname=None, \
 | 
			
		||||
                  reference_time=0 \
 | 
			
		||||
                  crls=None)
 | 
			
		||||
 | 
			
		||||
      Verify a certificate. Returns 0 if validation was successful, returns a positive error code 
 | 
			
		||||
      if the validation was unsuccesful.
 | 
			
		||||
 | 
			
		||||
      ``intermediates`` is a list of untrusted subauthorities.
 | 
			
		||||
 | 
			
		||||
      ``trusted`` is a list of trusted root CAs.
 | 
			
		||||
 | 
			
		||||
      The `trusted_path` refers to a directory where one or more trusted CA
 | 
			
		||||
      certificates are stored.
 | 
			
		||||
 | 
			
		||||
      Set ``required_strength`` to indicate the minimum key and hash strength
 | 
			
		||||
      that is allowed. For instance setting to 80 allows 1024-bit RSA and SHA-1.
 | 
			
		||||
      Setting to 110 requires 2048-bit RSA and SHA-256 or higher. Set to zero
 | 
			
		||||
      to accept a default.
 | 
			
		||||
 | 
			
		||||
      If ``hostname`` is given, it will be checked against the certificates CN field.
 | 
			
		||||
 | 
			
		||||
      Set ``reference_time`` to be the time which the certificate chain is
 | 
			
		||||
      validated against. Use zero (default) to use the current system clock.
 | 
			
		||||
 | 
			
		||||
      ``crls`` is a list of CRLs issued by either trusted or untrusted authorities.
 | 
			
		||||
 | 
			
		||||
   .. py:classmethod:: validation_status(error_code)
 | 
			
		||||
 | 
			
		||||
      Return an informative string associated with the verification return code.
 | 
			
		||||
 | 
			
		||||
   .. py:method:: is_revoked(self, crl)
 | 
			
		||||
 | 
			
		||||
      Check if the certificate (``self``) is revoked on the given ``crl``.
 | 
			
		||||
 | 
			
		||||
X509CRL
 | 
			
		||||
-----------------------------------------
 | 
			
		||||
 | 
			
		||||
.. py:class:: X509CRL(filename=None, buf=None)
 | 
			
		||||
 | 
			
		||||
   Class representing an X.509 Certificate Revocation List.
 | 
			
		||||
 | 
			
		||||
   A CRL in PEM or DER format can be loaded from a file, with the ``filename`` argument,
 | 
			
		||||
   or from a bytestring, with the ``buf`` argument.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,289 +0,0 @@
 | 
			
		||||
.. _random_number_generators:
 | 
			
		||||
 | 
			
		||||
Random Number Generators
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: RandomNumberGenerator
 | 
			
		||||
 | 
			
		||||
   The base class for all RNG objects, is declared in ``rng.h``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void randomize(uint8_t* output_array, size_t length)
 | 
			
		||||
 | 
			
		||||
      Places *length* random bytes into the provided buffer.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void randomize_with_input(uint8_t* data, size_t length, \
 | 
			
		||||
                     const uint8_t* extra_input, size_t extra_input_len)
 | 
			
		||||
 | 
			
		||||
      Like randomize, but first incorporates the additional input field into the
 | 
			
		||||
      state of the RNG. The additional input could be anything which
 | 
			
		||||
      parameterizes this request. Not all RNG types accept additional inputs,
 | 
			
		||||
      the value will be silently ignored when not supported.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void randomize_with_ts_input(uint8_t* data, size_t length)
 | 
			
		||||
 | 
			
		||||
      Creates a buffer with some timestamp values and calls ``randomize_with_input``
 | 
			
		||||
 | 
			
		||||
      .. note::
 | 
			
		||||
 | 
			
		||||
         When RDRAND is enabled and available at runtime, instead of timestamps
 | 
			
		||||
         the output of RDRAND is used as the additional data.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: uint8_t next_byte()
 | 
			
		||||
 | 
			
		||||
      Generates a single random byte and returns it. Note that calling this
 | 
			
		||||
      function several times is much slower than calling ``randomize`` once to
 | 
			
		||||
      produce multiple bytes at a time.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void add_entropy(const uint8_t* data, size_t length)
 | 
			
		||||
 | 
			
		||||
      Incorporates provided data into the state of the PRNG, if at all possible.
 | 
			
		||||
      This works for most RNG types, including the system and TPM RNGs. But if
 | 
			
		||||
      the RNG doesn't support this operation, the data is dropped, no error is
 | 
			
		||||
      indicated.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: bool accepts_input() const
 | 
			
		||||
 | 
			
		||||
      This function returns ``false`` if it is known that this RNG object cannot
 | 
			
		||||
      accept external inputs. In this case, any calls to
 | 
			
		||||
      :cpp:func:`RandomNumberGenerator::add_entropy` will be ignored.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: void reseed_from_rng(RandomNumberGenerator& rng, \
 | 
			
		||||
                     size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS)
 | 
			
		||||
 | 
			
		||||
      Reseed by calling ``rng`` to acquire ``poll_bits`` data.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
RNG Types
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Several different RNG types are implemented. Some access hardware RNGs, which
 | 
			
		||||
are only available on certain platforms. Others are mostly useful in specific
 | 
			
		||||
situations.
 | 
			
		||||
 | 
			
		||||
Generally prefer using ``System_RNG``, or if not available use ``AutoSeeded_RNG``
 | 
			
		||||
which is intended to provide best possible behavior in a userspace PRNG.
 | 
			
		||||
 | 
			
		||||
System_RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
On systems which support it, in ``system_rng.h`` you can access a shared
 | 
			
		||||
reference to a process global instance of the system PRNG (using interfaces such
 | 
			
		||||
as ``/dev/urandom``, ``getrandom``, ``arc4random``, ``BCryptGenRandom``,
 | 
			
		||||
or ``RtlGenRandom``):
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: RandomNumberGenerator& system_rng()
 | 
			
		||||
 | 
			
		||||
   Returns a reference to the system RNG
 | 
			
		||||
 | 
			
		||||
There is also a wrapper class ``System_RNG`` which simply invokes on
 | 
			
		||||
the return value of ``system_rng()``. This is useful in situations where
 | 
			
		||||
you may sometimes want to use the system RNG and a userspace RNG in others,
 | 
			
		||||
for example::
 | 
			
		||||
 | 
			
		||||
  std::unique_ptr<Botan::RandomNumberGenerator> rng;
 | 
			
		||||
  #if defined(BOTAN_HAS_SYSTEM_RNG)
 | 
			
		||||
  rng.reset(new System_RNG);
 | 
			
		||||
  #else
 | 
			
		||||
  rng.reset(new AutoSeeded_RNG);
 | 
			
		||||
  #endif
 | 
			
		||||
 | 
			
		||||
Unlike nearly any other object in Botan it is acceptable to share a single
 | 
			
		||||
instance of ``System_RNG`` between threads without locking, because the underlying
 | 
			
		||||
RNG is itself thread safe due to being serialized by a mutex in the kernel itself.
 | 
			
		||||
 | 
			
		||||
AutoSeeded_RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
AutoSeeded_RNG is type naming a 'best available' userspace PRNG. The
 | 
			
		||||
exact definition of this has changed over time and may change again in the
 | 
			
		||||
future. Fortunately there is no compatibility concerns when changing
 | 
			
		||||
any RNG since the only expectation is it produces bits
 | 
			
		||||
indistinguishable from random.
 | 
			
		||||
 | 
			
		||||
.. note:: Starting in 2.16.0, AutoSeeded_RNG uses an internal lock and so is
 | 
			
		||||
          safe to share among threads. However if possible it is still better to
 | 
			
		||||
          use a RNG per thread as otherwise the RNG object needlessly creates a
 | 
			
		||||
          point of contention. In previous versions, the RNG does not have an
 | 
			
		||||
          internal lock and all access to it must be serialized.
 | 
			
		||||
 | 
			
		||||
The current version uses HMAC_DRBG with either SHA-384 or SHA-256. The
 | 
			
		||||
initial seed is generated either by the system PRNG (if available) or
 | 
			
		||||
a default set of entropy sources. These are also used for periodic
 | 
			
		||||
reseeding of the RNG state.
 | 
			
		||||
 | 
			
		||||
HMAC_DRBG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
HMAC-DRBG is a random number generator designed by NIST and specified
 | 
			
		||||
in SP 800-90A. It seems to be the most conservative generator of the
 | 
			
		||||
NIST approved options.
 | 
			
		||||
 | 
			
		||||
It can be instantiated with any HMAC but is typically used with
 | 
			
		||||
SHA-256, SHA-384, or SHA-512, as these are the hash functions approved
 | 
			
		||||
for this use by NIST.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   There is no reason to use this class directly unless your application
 | 
			
		||||
   requires HMAC-DRBG with specific parameters or options. Usually this
 | 
			
		||||
   would be for some standards conformance reason. If you just want a
 | 
			
		||||
   userspace RNG, use ``AutoSeeded_RNG``.
 | 
			
		||||
 | 
			
		||||
``HMAC_DRBG``'s constructors are:
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: HMAC_DRBG
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \
 | 
			
		||||
                        RandomNumberGenerator& underlying_rng, \
 | 
			
		||||
                        size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \
 | 
			
		||||
                        size_t max_number_of_bytes_per_request = 64 * 1024)
 | 
			
		||||
 | 
			
		||||
         Creates a DRBG which will automatically reseed as required by making
 | 
			
		||||
         calls to ``underlying_rng`` either after being invoked
 | 
			
		||||
         ``reseed_interval`` times, or if use of ``fork`` system call is
 | 
			
		||||
         detected.
 | 
			
		||||
 | 
			
		||||
         You can disable automatic reseeding by setting ``reseed_interval`` to
 | 
			
		||||
         zero, in which case ``underlying_rng`` will only be invoked in the case
 | 
			
		||||
         of ``fork``.
 | 
			
		||||
 | 
			
		||||
         The specification of HMAC DRBG requires that each invocation produce no
 | 
			
		||||
         more than 64 kibibytes of data. However, the RNG interface allows
 | 
			
		||||
         producing arbitrary amounts of data in a single request. To accommodate
 | 
			
		||||
         this, ``HMAC_DRBG`` treats requests for more data as if they were
 | 
			
		||||
         multiple requests each of (at most) the maximum size. You can specify a
 | 
			
		||||
         smaller maximum size with ``max_number_of_bytes_per_request``. There is
 | 
			
		||||
         normally no reason to do this.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \
 | 
			
		||||
                        Entropy_Sources& entropy_sources, \
 | 
			
		||||
                        size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \
 | 
			
		||||
                        size_t max_number_of_bytes_per_request = 64 * 1024)
 | 
			
		||||
 | 
			
		||||
         Like above function, but instead of an RNG taking a set of entropy
 | 
			
		||||
         sources to seed from as required.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf, \
 | 
			
		||||
                        RandomNumberGenerator& underlying_rng, \
 | 
			
		||||
                        Entropy_Sources& entropy_sources, \
 | 
			
		||||
                        size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL, \
 | 
			
		||||
                        size_t max_number_of_bytes_per_request = 64 * 1024)
 | 
			
		||||
 | 
			
		||||
         Like above function, but taking both an RNG and a set of entropy
 | 
			
		||||
         sources to seed from as required.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf)
 | 
			
		||||
 | 
			
		||||
         Creates an unseeded DRBG. You must explicitly provide seed data later
 | 
			
		||||
         on in order to use this RNG. This is primarily useful for deterministic
 | 
			
		||||
         key generation.
 | 
			
		||||
 | 
			
		||||
         Since no source of data is available to automatically reseed, automatic
 | 
			
		||||
         reseeding is disabled when this constructor is used. If the RNG object
 | 
			
		||||
         detects that ``fork`` system call was used without it being
 | 
			
		||||
         subsequently reseeded, it will throw an exception.
 | 
			
		||||
 | 
			
		||||
      .. cpp:function:: HMAC_DRBG(const std::string& hmac_hash)
 | 
			
		||||
 | 
			
		||||
         Like the constructor just taking a PRF, except instead of a PRF object,
 | 
			
		||||
         a string specifying what hash to use with HMAC is provided.
 | 
			
		||||
 | 
			
		||||
ChaCha_RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This is a very fast userspace PRNG based on ChaCha20 and HMAC(SHA-256). The key
 | 
			
		||||
for ChaCha is derived by hashing entropy inputs with HMAC. Then the ChaCha
 | 
			
		||||
keystream generator is run, first to generate the new HMAC key (used for any
 | 
			
		||||
future entropy additions), then the desired RNG outputs.
 | 
			
		||||
 | 
			
		||||
This RNG composes two primitives thought to be secure (ChaCha and HMAC) in a
 | 
			
		||||
simple and well studied way (the extract-then-expand paradigm), but is still an
 | 
			
		||||
ad-hoc and non-standard construction. It is included because it is roughly 20x
 | 
			
		||||
faster then HMAC_DRBG (basically running as fast as ChaCha can generate
 | 
			
		||||
keystream bits), and certain applications need access to a very fast RNG.
 | 
			
		||||
 | 
			
		||||
One thing applications using ``ChaCha_RNG`` need to be aware of is that for
 | 
			
		||||
performance reasons, no backtracking resistance is implemented in the RNG
 | 
			
		||||
design. An attacker who recovers the ``ChaCha_RNG`` state can recover the output
 | 
			
		||||
backwards in time to the last rekey and forwards to the next rekey.
 | 
			
		||||
 | 
			
		||||
An explicit reseeding (:cpp:func:`RandomNumberGenerator::add_entropy`) or
 | 
			
		||||
providing any input to the RNG
 | 
			
		||||
(:cpp:func:`RandomNumberGenerator::randomize_with_ts_input`,
 | 
			
		||||
:cpp:func:`RandomNumberGenerator::randomize_with_input`) is sufficient to cause
 | 
			
		||||
a reseeding. Or, if a RNG or entropy source was provided to the ``ChaCha_RNG``
 | 
			
		||||
constructor, then reseeding will be performed automatically after a certain
 | 
			
		||||
interval of requests.
 | 
			
		||||
 | 
			
		||||
Processor_RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This RNG type directly invokes a CPU instruction capable of generating
 | 
			
		||||
a cryptographically secure random number. On x86 it uses ``rdrand``,
 | 
			
		||||
on POWER ``darn``. If the relevant instruction is not available, the
 | 
			
		||||
constructor of the class will throw at runtime. You can test
 | 
			
		||||
beforehand by checking the result of ``Processor_RNG::available()``.
 | 
			
		||||
 | 
			
		||||
TPM_RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This RNG type allows using the RNG exported from a TPM chip.
 | 
			
		||||
 | 
			
		||||
PKCS11_RNG
 | 
			
		||||
^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This RNG type allows using the RNG exported from a hardware token accessed via PKCS11.
 | 
			
		||||
 | 
			
		||||
Entropy Sources
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
An ``EntropySource`` is an abstract representation of some method of
 | 
			
		||||
gather "real" entropy. This tends to be very system dependent. The
 | 
			
		||||
*only* way you should use an ``EntropySource`` is to pass it to a PRNG
 | 
			
		||||
that will extract entropy from it -- never use the output directly for
 | 
			
		||||
any kind of key or nonce generation!
 | 
			
		||||
 | 
			
		||||
``EntropySource`` has a pair of functions for getting entropy from
 | 
			
		||||
some external source, called ``fast_poll`` and ``slow_poll``. These
 | 
			
		||||
pass a buffer of bytes to be written; the functions then return how
 | 
			
		||||
many bytes of entropy were gathered.
 | 
			
		||||
 | 
			
		||||
Note for writers of ``EntropySource`` subclasses: it isn't necessary
 | 
			
		||||
to use any kind of cryptographic hash on your output. The data
 | 
			
		||||
produced by an EntropySource is only used by an application after it
 | 
			
		||||
has been hashed by the ``RandomNumberGenerator`` that asked for the
 | 
			
		||||
entropy, thus any hashing you do will be wasteful of both CPU cycles
 | 
			
		||||
and entropy.
 | 
			
		||||
 | 
			
		||||
The following entropy sources are currently used:
 | 
			
		||||
 | 
			
		||||
 * The system RNG (``/dev/urandom``, ``getrandom``, ``arc4random``,
 | 
			
		||||
   ``BCryptGenRandom``, or ``RtlGenRandom``).
 | 
			
		||||
 * Processor provided RNG outputs (RDRAND, RDSEED, DARN) are used if available,
 | 
			
		||||
   but not counted as contributing entropy
 | 
			
		||||
 * The ``getentropy`` call is used on OpenBSD, FreeBSD, and macOS
 | 
			
		||||
 * ``/proc`` walk: read files in ``/proc``. Last ditch protection against
 | 
			
		||||
   flawed system RNG.
 | 
			
		||||
 * Win32 stats: takes snapshot of current system processes. Last ditch
 | 
			
		||||
   protection against flawed system RNG.
 | 
			
		||||
 | 
			
		||||
Fork Safety
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
On Unix platforms, the ``fork()`` and ``clone()`` system calls can
 | 
			
		||||
be used to spawn a new child process. Fork safety ensures that the
 | 
			
		||||
child process doesn't see the same output of random bytes as the
 | 
			
		||||
parent process. Botan tries to ensure fork safety by feeding the
 | 
			
		||||
process ID into the internal state of the random generator and by
 | 
			
		||||
automatically reseeding the random generator if the process ID
 | 
			
		||||
changed between two requests of random bytes. However, this does
 | 
			
		||||
not protect against PID wrap around. The process ID is usually
 | 
			
		||||
implemented as a 16 bit integer. In this scenario, a process will
 | 
			
		||||
spawn a new child process, which exits the parent process and
 | 
			
		||||
spawns a new child process himself. If the PID wrapped around, the
 | 
			
		||||
second child process may get assigned the process ID of it's 
 | 
			
		||||
grandparent and the fork safety can not be ensured.
 | 
			
		||||
 | 
			
		||||
Therefore, it is strongly recommended to explicitly reseed any
 | 
			
		||||
userspace random generators after forking a new process. If this is
 | 
			
		||||
not possible in your application, prefer using the system PRNG
 | 
			
		||||
instead.
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
Roughtime
 | 
			
		||||
===========
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 2.13.0
 | 
			
		||||
 | 
			
		||||
Botan includes a Roughtime client, available in ``botan/roughtime.h``
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Memory container
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
A major concern with mixing modern multi-user OSes and cryptographic
 | 
			
		||||
code is that at any time the code (including secret keys) could be
 | 
			
		||||
swapped to disk, where it can later be read by an attacker, or left
 | 
			
		||||
floating around in memory for later retrieval.
 | 
			
		||||
 | 
			
		||||
For this reason the library uses a ``std::vector`` with a custom
 | 
			
		||||
allocator that will zero memory before deallocation, named via typedef
 | 
			
		||||
as ``secure_vector``. Because it is simply a STL vector with a custom
 | 
			
		||||
allocator, it has an identical API to the ``std::vector`` you know and
 | 
			
		||||
love.
 | 
			
		||||
 | 
			
		||||
Some operating systems offer the ability to lock memory into RAM,
 | 
			
		||||
preventing swapping from occurring. Typically this operation is
 | 
			
		||||
restricted to privileged users (root or admin), however some OSes
 | 
			
		||||
including Linux and FreeBSD allow normal users to lock a small amount
 | 
			
		||||
of memory. On these systems, allocations first attempt to allocate out
 | 
			
		||||
of this small locked pool, and then if that fails will fall back to
 | 
			
		||||
normal heap allocations.
 | 
			
		||||
 | 
			
		||||
The ``secure_vector`` template is only meant for primitive data types
 | 
			
		||||
(bytes or ints): if you want a container of higher level Botan
 | 
			
		||||
objects, you can just use a ``std::vector``, since these objects know
 | 
			
		||||
how to clear themselves when they are destroyed. You cannot, however,
 | 
			
		||||
have a ``std::vector`` (or any other container) of ``Pipe`` objects or
 | 
			
		||||
filters, because these types have pointers to other filters, and
 | 
			
		||||
implementing copy constructors for these types would be both hard and
 | 
			
		||||
quite expensive (vectors of pointers to such objects is fine, though).
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
Secure Remote Password
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
The library contains an implementation of the
 | 
			
		||||
`SRP6-a <http://srp.stanford.edu/design.html>`_ password authenticated
 | 
			
		||||
key exchange protocol in ``srp6.h``.
 | 
			
		||||
 | 
			
		||||
A SRP client provides what is called a SRP *verifier* to the server.
 | 
			
		||||
This verifier is based on a password, but the password cannot be
 | 
			
		||||
easily derived from the verifier (however brute force attacks are
 | 
			
		||||
possible). Later, the client and server can perform an SRP exchange,
 | 
			
		||||
which results in a shared secret key. This key can be used for mutual
 | 
			
		||||
authentication and/or encryption.
 | 
			
		||||
 | 
			
		||||
SRP works in a discrete logarithm group. Special parameter sets for
 | 
			
		||||
SRP6 are defined, denoted in the library as "modp/srp/<size>", for
 | 
			
		||||
example "modp/srp/2048".
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
     While knowledge of the verifier does not easily allow an attacker
 | 
			
		||||
     to get the raw password, they could still use the verifier to
 | 
			
		||||
     impersonate the server to the client, so verifiers should be
 | 
			
		||||
     protected as carefully as a plaintext password would be.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: BigInt generate_srp6_verifier( \
 | 
			
		||||
          const std::string& username, \
 | 
			
		||||
          const std::string& password, \
 | 
			
		||||
          const std::vector<uint8_t>& salt, \
 | 
			
		||||
          const std::string& group_id, \
 | 
			
		||||
          const std::string& hash_id)
 | 
			
		||||
 | 
			
		||||
    Generates a new verifier using the specified password and salt.
 | 
			
		||||
    This is stored by the server. The salt must also be stored. Later,
 | 
			
		||||
    the given username and password are used to by the client during
 | 
			
		||||
    the key agreement step.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string srp6_group_identifier( \
 | 
			
		||||
            const BigInt& N, const BigInt& g)
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: SRP6_Server_Session
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: BigInt step1(const BigInt& v, \
 | 
			
		||||
                     const std::string& group_id, \
 | 
			
		||||
                     const std::string& hash_id, \
 | 
			
		||||
                     RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
       Takes a verifier (generated by generate_srp6_verifier) along
 | 
			
		||||
       with the group_id, and output a value `B` which is provided to
 | 
			
		||||
       the client.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: SymmetricKey step2(const BigInt& A)
 | 
			
		||||
 | 
			
		||||
      Takes the parameter A generated by srp6_client_agree,
 | 
			
		||||
      and return the shared secret key.
 | 
			
		||||
 | 
			
		||||
      In the event of an impersonation attack (or wrong username/password, etc)
 | 
			
		||||
      no error occurs, but the key returned will be different on the two sides.
 | 
			
		||||
      The two sides must verify each other, for example by using the shared
 | 
			
		||||
      secret to key an HMAC and then exchanging authenticated messages.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::pair<BigInt,SymmetricKey> srp6_client_agree( \
 | 
			
		||||
               const std::string& username, \
 | 
			
		||||
               const std::string& password, \
 | 
			
		||||
               const std::string& group_id, \
 | 
			
		||||
               const std::string& hash_id, \
 | 
			
		||||
               const std::vector<uint8_t>& salt, \
 | 
			
		||||
               const BigInt& B, \
 | 
			
		||||
               RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
    The client receives these parameters from the server, except for
 | 
			
		||||
    the username and password which are provided by the user. The
 | 
			
		||||
    parameter B is the output of `step1`.
 | 
			
		||||
 | 
			
		||||
    The client agreement step outputs a shared symmetric key along
 | 
			
		||||
    with the parameter A which is returned to the server (and allows
 | 
			
		||||
    it the compute the shared key).
 | 
			
		||||
@@ -1,194 +0,0 @@
 | 
			
		||||
Stream Ciphers
 | 
			
		||||
========================
 | 
			
		||||
 | 
			
		||||
In contrast to block ciphers, stream ciphers operate on a plaintext stream
 | 
			
		||||
instead of blocks. Thus encrypting data results in changing the internal state
 | 
			
		||||
of the cipher and encryption of plaintext with arbitrary length is possible in
 | 
			
		||||
one go (in byte amounts). All implemented stream ciphers derive from the base
 | 
			
		||||
class :cpp:class:`StreamCipher` (`botan/stream_cipher.h`).
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   Using a stream cipher without an authentication code is extremely insecure,
 | 
			
		||||
   because an attacker can trivially modify messages. Prefer using an
 | 
			
		||||
   authenticated cipher mode such as GCM or SIV.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   Encrypting more than one message with the same key requires careful management
 | 
			
		||||
   of initialization vectors. Otherwise the keystream will be reused, which causes
 | 
			
		||||
   the security of the cipher to completely fail.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: StreamCipher
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string name() const
 | 
			
		||||
 | 
			
		||||
     Returns a human-readable string of the name of this algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void clear()
 | 
			
		||||
 | 
			
		||||
     Clear the key.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<StreamCipher> new_object() const
 | 
			
		||||
 | 
			
		||||
     Return a newly allocated object of the same type as this one.
 | 
			
		||||
     The new object is unkeyed.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_key(const uint8_t* key, size_t length)
 | 
			
		||||
 | 
			
		||||
     Set the stream cipher key. If the length is not accepted, an
 | 
			
		||||
     ``Invalid_Key_Length`` exception is thrown.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_keylength(size_t length) const
 | 
			
		||||
 | 
			
		||||
     This function returns true if and only if *length* is a valid
 | 
			
		||||
     keylength for the algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t minimum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the smallest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t maximum_keylength() const
 | 
			
		||||
 | 
			
		||||
     Return the largest key length (in bytes) that is acceptable for the
 | 
			
		||||
     algorithm.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool valid_iv_length(size_t iv_len) const
 | 
			
		||||
 | 
			
		||||
     This function returns true if and only if *length* is a valid IV length for
 | 
			
		||||
     the stream cipher. Some ciphers do not support IVs at all, and will return
 | 
			
		||||
     false for any value except zero.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t default_iv_length() const
 | 
			
		||||
 | 
			
		||||
     Returns some default IV size, normally the largest IV supported by the cipher.
 | 
			
		||||
     If this function returns zero, then IVs are not supported and any call to
 | 
			
		||||
     ``set_iv`` with a non-empty value will fail.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void set_iv(const uint8_t*, size_t len)
 | 
			
		||||
 | 
			
		||||
     Load IV into the stream cipher state. This should happen after the key is
 | 
			
		||||
     set and before any operation (encrypt/decrypt/seek) is called.
 | 
			
		||||
 | 
			
		||||
     If the cipher does not support IVs, then a call with ``len`` equal to zero
 | 
			
		||||
     will be accepted and any other length will cause a ``Invalid_IV_Length``
 | 
			
		||||
     exception.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void seek(uint64_t offset)
 | 
			
		||||
 | 
			
		||||
     Sets the state of the stream cipher and keystream according to the passed
 | 
			
		||||
     *offset*, exactly as if *offset* bytes had first been encrypted. The key
 | 
			
		||||
     and (if required) the IV have to be set before this can be called. Not all
 | 
			
		||||
     ciphers support seeking; such objects will throw ``Not_Implemented`` in
 | 
			
		||||
     this case.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void cipher(const uint8_t* in, uint8_t* out, size_t n)
 | 
			
		||||
 | 
			
		||||
     Processes *n* bytes plain/ciphertext from *in* and writes the result to *out*.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void cipher1(uint8_t* inout, size_t n)
 | 
			
		||||
 | 
			
		||||
     Processes *n* bytes plain/ciphertext in place. Acts like :cpp:func:`cipher`\ (inout, inout, n).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void encipher(std::vector<uint8_t> inout)
 | 
			
		||||
  .. cpp:function:: void encrypt(std::vector<uint8_t> inout)
 | 
			
		||||
  .. cpp:function:: void decrypt(std::vector<uint8_t> inout)
 | 
			
		||||
 | 
			
		||||
     Processes plain/ciphertext *inout* in place. Acts like :cpp:func:`cipher`\ (inout.data(), inout.data(), inout.size()).
 | 
			
		||||
 | 
			
		||||
Code Example
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
The following code encrypts a provided plaintext using ChaCha20.
 | 
			
		||||
 | 
			
		||||
.. literalinclude:: /../src/examples/chacha.cpp
 | 
			
		||||
   :language: cpp
 | 
			
		||||
 | 
			
		||||
Available Stream Ciphers
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
Botan provides the following stream ciphers. If in doubt, pick ChaCha20 or CTR(AES-256).
 | 
			
		||||
 | 
			
		||||
CTR-BE
 | 
			
		||||
~~~~~~~
 | 
			
		||||
 | 
			
		||||
Counter mode converts a block cipher into a stream cipher. It offers
 | 
			
		||||
parallel execution and can seek within the output stream, both useful
 | 
			
		||||
properties.
 | 
			
		||||
 | 
			
		||||
CTR mode requires a nonce, which can be any length up to the block size of the
 | 
			
		||||
underlying cipher. If it is shorter than the block size, sufficient zero bytes
 | 
			
		||||
are appended.
 | 
			
		||||
 | 
			
		||||
It is possible to choose the width of the counter portion, which can improve
 | 
			
		||||
performance somewhat, but limits the maximum number of bytes that can safely be
 | 
			
		||||
encrypted. Different protocols have different conventions for the width of the
 | 
			
		||||
counter portion. This is done by specifying the width (which must be at least 4
 | 
			
		||||
bytes, allowing to encrypt 2\ :sup:`32` blocks of data) for example using
 | 
			
		||||
"CTR(AES-256,8)" will select a 64-bit (8 byte) counter.
 | 
			
		||||
 | 
			
		||||
(The ``-BE`` suffix refers to big-endian convention for the counter.
 | 
			
		||||
Little-endian counter mode is rarely used and not currently implemented.)
 | 
			
		||||
 | 
			
		||||
OFB
 | 
			
		||||
~~~~~
 | 
			
		||||
 | 
			
		||||
Another stream cipher based on a block cipher. Unlike CTR mode, it does not
 | 
			
		||||
allow parallel execution or seeking within the output stream. Prefer CTR.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_OFB`` is defined.
 | 
			
		||||
 | 
			
		||||
ChaCha
 | 
			
		||||
~~~~~~~~
 | 
			
		||||
 | 
			
		||||
A very fast cipher, now widely deployed in TLS as part of the ChaCha20Poly1305
 | 
			
		||||
AEAD. Can be used with 8 (fast but dangerous), 12 (balance), or 20 rounds
 | 
			
		||||
(conservative). Even with 20 rounds, ChaCha is very fast. Use 20 rounds.
 | 
			
		||||
 | 
			
		||||
ChaCha supports an optional IV (which defaults to all zeros). It can be of
 | 
			
		||||
length 64, 96 or (since 2.8) 192 bits. Using ChaCha with a 192 bit nonce is also
 | 
			
		||||
known as XChaCha.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_CHACHA`` is defined.
 | 
			
		||||
 | 
			
		||||
Salsa20
 | 
			
		||||
~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
An earlier iteration of the ChaCha design, this cipher is popular due to its use
 | 
			
		||||
in the libsodium library. Prefer ChaCha.
 | 
			
		||||
 | 
			
		||||
Salsa supports an optional IV (which defaults to all zeros). It can be of length
 | 
			
		||||
64 or 192 bits. Using Salsa with a 192 bit nonce is also known as XSalsa.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SALSA20`` is defined.
 | 
			
		||||
 | 
			
		||||
SHAKE-128
 | 
			
		||||
~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
This is the SHAKE-128 XOF exposed as a stream cipher. It is slower
 | 
			
		||||
than ChaCha and somewhat obscure, and was primarily implemented to
 | 
			
		||||
support a particular post-quantum scheme which is no longer supported.
 | 
			
		||||
 | 
			
		||||
SHAKE does not support IVs, nor seeking within the cipher stream.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_SHAKE_CIPHER`` is defined.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
  SHAKE support (as a stream cipher) is deprecated and will be removed
 | 
			
		||||
  in a future major release.
 | 
			
		||||
 | 
			
		||||
RC4
 | 
			
		||||
~~~~
 | 
			
		||||
 | 
			
		||||
An old and very widely deployed stream cipher notable for its simplicity. It
 | 
			
		||||
does not support IVs or seeking within the cipher stream. Compared to modern
 | 
			
		||||
algorithms like ChaCha20, it is also quite slow.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   RC4 is prone to numerous attacks. **Avoid in new code** and use only if
 | 
			
		||||
   required for compatibility with existing systems.
 | 
			
		||||
 | 
			
		||||
Available if ``BOTAN_HAS_RC4`` is defined.
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,113 +0,0 @@
 | 
			
		||||
Trusted Platform Module (TPM)
 | 
			
		||||
==========================================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.11.26
 | 
			
		||||
 | 
			
		||||
Some computers come with a TPM, which is a small side processor which can
 | 
			
		||||
perform certain operations which include RSA key generation and signing, a
 | 
			
		||||
random number generator, accessing a small amount of NVRAM, and a set of PCRs
 | 
			
		||||
which can be used to measure software state (this is TPMs most famous use, for
 | 
			
		||||
authenticating a boot sequence).
 | 
			
		||||
 | 
			
		||||
The TPM NVRAM and PCR APIs are not supported by Botan at this time, patches welcome.
 | 
			
		||||
 | 
			
		||||
Currently only v1.2 TPMs are supported, and the only TPM library supported is
 | 
			
		||||
TrouSerS (http://trousers.sourceforge.net/). Hopefully both of these limitations
 | 
			
		||||
will be removed in a future release, in order to support newer TPM v2.0 systems.
 | 
			
		||||
The current code has been tested with an ST TPM running in a Lenovo laptop.
 | 
			
		||||
 | 
			
		||||
Test for TPM support with the macro ``BOTAN_HAS_TPM``, include ``<botan/tpm.h>``.
 | 
			
		||||
 | 
			
		||||
First, create a connection to the TPM with a ``TPM_Context``. The context is
 | 
			
		||||
passed to all other TPM operations, and should remain alive as long as any other
 | 
			
		||||
TPM object which the context was passed to is still alive, otherwise errors or
 | 
			
		||||
even an application crash are possible. In the future, the API may change to
 | 
			
		||||
using ``shared_ptr`` to remove this problem.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: TPM_Context
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: TPM_Context(pin_cb cb, const char* srk_password)
 | 
			
		||||
 | 
			
		||||
     The (somewhat improperly named) pin_cb callback type takes a std::string as
 | 
			
		||||
     an argument, which is an informative message for the user. It should return
 | 
			
		||||
     a string containing the password entered by the user.
 | 
			
		||||
 | 
			
		||||
     Normally the SRK password is null. Use nullptr to signal this.
 | 
			
		||||
 | 
			
		||||
The TPM contains a RNG of unknown design or quality. If that doesn't scare you
 | 
			
		||||
off, you can use it with ``TPM_RNG`` which implements the standard
 | 
			
		||||
``RandomNumberGenerator`` interface.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: TPM_RNG
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: TPM_RNG(TPM_Context& ctx)
 | 
			
		||||
 | 
			
		||||
      Initialize a TPM RNG object. After initialization, reading from
 | 
			
		||||
      this RNG reads from the hardware? RNG on the TPM.
 | 
			
		||||
 | 
			
		||||
The v1.2 TPM uses only RSA, but because this key is implemented completely in
 | 
			
		||||
hardware it uses a different private key type, with a somewhat different API to
 | 
			
		||||
match the TPM's behavior.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: TPM_PrivateKey
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: TPM_PrivateKey(TPM_Context& ctx, size_t bits, const char* key_password)
 | 
			
		||||
 | 
			
		||||
        Create a new RSA key stored on the TPM. The bits should be either 1024
 | 
			
		||||
        or 2048; the TPM interface hypothetically allows larger keys but in
 | 
			
		||||
        practice no v1.2 TPM hardware supports them.
 | 
			
		||||
 | 
			
		||||
        The TPM processor is not fast, be prepared for this to take a while.
 | 
			
		||||
 | 
			
		||||
        The key_password is the password to the TPM key ?
 | 
			
		||||
 | 
			
		||||
   .. cpp:function::  std::string register_key(TPM_Storage_Type storage_type)
 | 
			
		||||
 | 
			
		||||
        Registers a key with the TPM. The storage_type can be either
 | 
			
		||||
        `TPM_Storage_Type::User` or `TPM_Storage_Type::System`. If System, the
 | 
			
		||||
        key is stored on the TPM itself. If User, it is stored on the local hard
 | 
			
		||||
        drive in a database maintained by an intermediate piece of system
 | 
			
		||||
        software (which actual interacts with the physical TPM on behalf of any
 | 
			
		||||
        number of applications calling the TPM API).
 | 
			
		||||
 | 
			
		||||
        The TPM has only some limited space to store private keys and may reject
 | 
			
		||||
        requests to store the key.
 | 
			
		||||
 | 
			
		||||
        In either case the key is encrypted with an RSA key which was generated
 | 
			
		||||
        on the TPM and which it will not allow to be exported. Thus (so goes the
 | 
			
		||||
        theory) without physically attacking the TPM
 | 
			
		||||
 | 
			
		||||
        Returns a UUID which can be passed back to constructor below.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function::  TPM_PrivateKey(TPM_Context& ctx, const std::string& uuid, \
 | 
			
		||||
                                      TPM_Storage_Type storage_type)
 | 
			
		||||
 | 
			
		||||
        Load a registered key. The UUID was returned by the ``register_key`` function.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function::  std::vector<uint8_t> export_blob() const
 | 
			
		||||
 | 
			
		||||
        Export the key as an encrypted blob. This blob can later be presented
 | 
			
		||||
        back to the same TPM to load the key.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: TPM_PrivateKey(TPM_Context& ctx, const std::vector<uint8_t>& blob)
 | 
			
		||||
 | 
			
		||||
        Load a TPM key previously exported as a blob with ``export_blob``.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function::  std::unique_ptr<Public_Key> public_key() const
 | 
			
		||||
 | 
			
		||||
         Return the public key associated with this TPM private key.
 | 
			
		||||
 | 
			
		||||
         TPM does not store public keys, nor does it support signature verification.
 | 
			
		||||
 | 
			
		||||
   .. cpp:function:: TSS_HKEY handle() const
 | 
			
		||||
 | 
			
		||||
        Returns the bare TSS key handle. Use if you need to call the raw TSS API.
 | 
			
		||||
 | 
			
		||||
A ``TPM_PrivateKey`` can be passed to a ``PK_Signer`` constructor and used to
 | 
			
		||||
sign messages just like any other key. Only PKCS #1 v1.5 signatures are supported
 | 
			
		||||
by the v1.2 TPM.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::vector<std::string> TPM_PrivateKey::registered_keys(TPM_Context& ctx)
 | 
			
		||||
 | 
			
		||||
      This static function returns the list of all keys (in URL format)
 | 
			
		||||
      registered with the system
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
Threshold Secret Sharing
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 1.9.1
 | 
			
		||||
 | 
			
		||||
Threshold secret sharing allows splitting a secret into ``N`` shares such that
 | 
			
		||||
``M`` (for specified ``M`` <= ``N``) is sufficient to recover the secret, but an
 | 
			
		||||
attacker with ``M - 1`` shares cannot derive any information about the secret.
 | 
			
		||||
 | 
			
		||||
The implementation in Botan follows an expired Internet draft
 | 
			
		||||
"draft-mcgrew-tss-03". Several other implementations of this TSS format exist.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: RTSS_Share
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::vector<RTSS_Share> split(uint8_t M, uint8_t N, \
 | 
			
		||||
               const uint8_t secret[], uint16_t secret_len, \
 | 
			
		||||
               const std::vector<uint8_t>& identifier, \
 | 
			
		||||
               const std::string& hash_fn, \
 | 
			
		||||
               RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
     Split a secret. The identifier is an optional key identifier which may be
 | 
			
		||||
     up to 16 bytes long. Shorter identifiers are padded with zeros.
 | 
			
		||||
 | 
			
		||||
     The hash function must be either "SHA-1", "SHA-256", or "None" to disable
 | 
			
		||||
     the checksum.
 | 
			
		||||
 | 
			
		||||
     This will return a vector of length ``N``, any ``M`` of these shares is
 | 
			
		||||
     sufficient to reconstruct the data.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static secure_vector<uint8_t> reconstruct(const std::vector<RTSS_Share>& shares)
 | 
			
		||||
 | 
			
		||||
      Given a sufficient number of shares, reconstruct a secret.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: RTSS_Share(const uint8_t data[], size_t len)
 | 
			
		||||
 | 
			
		||||
      Read a TSS share as a sequence of bytes.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const secure_vector<uint8>& data() const
 | 
			
		||||
 | 
			
		||||
      Return the data of this share.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: uint8_t share_id() const
 | 
			
		||||
 | 
			
		||||
      Return the share ID which will be in the range 1...255
 | 
			
		||||
 | 
			
		||||
@@ -1,102 +0,0 @@
 | 
			
		||||
 | 
			
		||||
.. _versioning:
 | 
			
		||||
 | 
			
		||||
Versioning
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
All versions are of the tuple (major,minor,patch).
 | 
			
		||||
 | 
			
		||||
As of Botan 2.0.0, Botan uses semantic versioning. The minor number increases if
 | 
			
		||||
any feature addition is made. The patch version is used to indicate a release
 | 
			
		||||
where only bug fixes were applied. If an incompatible API change is required,
 | 
			
		||||
the major version will be increased.
 | 
			
		||||
 | 
			
		||||
The library has functions for checking compile-time and runtime versions.
 | 
			
		||||
 | 
			
		||||
The build-time version information is defined in `botan/build.h`
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_VERSION_MAJOR
 | 
			
		||||
 | 
			
		||||
   The major version of the release.
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_VERSION_MINOR
 | 
			
		||||
 | 
			
		||||
   The minor version of the release.
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_VERSION_PATCH
 | 
			
		||||
 | 
			
		||||
   The patch version of the release.
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_VERSION_DATESTAMP
 | 
			
		||||
 | 
			
		||||
   Expands to an integer of the form YYYYMMDD if this is an official
 | 
			
		||||
   release, or 0 otherwise. For instance, 1.10.1, which was released
 | 
			
		||||
   on July 11, 2011, has a `BOTAN_VERSION_DATESTAMP` of 20110711.
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_DISTRIBUTION_INFO
 | 
			
		||||
 | 
			
		||||
   .. versionadded:: 1.9.3
 | 
			
		||||
 | 
			
		||||
   A macro expanding to a string that is set at build time using the
 | 
			
		||||
   ``--distribution-info`` option. It allows a packager of the library
 | 
			
		||||
   to specify any distribution-specific patches. If no value is given
 | 
			
		||||
   at build time, the value is the string "unspecified".
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_VERSION_VC_REVISION
 | 
			
		||||
 | 
			
		||||
   .. versionadded:: 1.10.1
 | 
			
		||||
 | 
			
		||||
   A macro expanding to a string that is set to a revision identifier
 | 
			
		||||
   corresponding to the source, or "unknown" if this could not be
 | 
			
		||||
   determined. It is set for all official releases, and for builds that
 | 
			
		||||
   originated from within a git checkout.
 | 
			
		||||
 | 
			
		||||
The runtime version information, and some helpers for compile time
 | 
			
		||||
version checks, are included in `botan/version.h`
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string version_string()
 | 
			
		||||
 | 
			
		||||
   Returns a single-line string containing relevant information about
 | 
			
		||||
   this build and version of the library in an unspecified format.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: uint32_t version_major()
 | 
			
		||||
 | 
			
		||||
   Returns the major part of the version.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: uint32_t version_minor()
 | 
			
		||||
 | 
			
		||||
   Returns the minor part of the version.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: uint32_t version_patch()
 | 
			
		||||
 | 
			
		||||
   Returns the patch part of the version.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: uint32_t version_datestamp()
 | 
			
		||||
 | 
			
		||||
   Return the datestamp of the release (or 0 if the current version is
 | 
			
		||||
   not an official release).
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: std::string runtime_version_check(uint32_t major, uint32_t minor, uint32_t patch)
 | 
			
		||||
 | 
			
		||||
   Call this function with the compile-time version being built against, eg::
 | 
			
		||||
 | 
			
		||||
      Botan::runtime_version_check(BOTAN_VERSION_MAJOR, BOTAN_VERSION_MINOR, BOTAN_VERSION_PATCH)
 | 
			
		||||
 | 
			
		||||
   It will return an empty string if the versions match, or otherwise
 | 
			
		||||
   an error message indicating the discrepancy. This only is useful in
 | 
			
		||||
   dynamic libraries, where it is possible to compile and run against
 | 
			
		||||
   different versions.
 | 
			
		||||
 | 
			
		||||
.. c:macro:: BOTAN_VERSION_CODE_FOR(maj,min,patch)
 | 
			
		||||
 | 
			
		||||
   Return a value that can be used to compare versions. The current
 | 
			
		||||
   (compile-time) version is available as the macro
 | 
			
		||||
   `BOTAN_VERSION_CODE`. For instance, to choose one code path for
 | 
			
		||||
   version 2.1.0 and later, and another code path for older releases::
 | 
			
		||||
 | 
			
		||||
      #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,1,0)
 | 
			
		||||
         // 2.1+ code path
 | 
			
		||||
      #else
 | 
			
		||||
         // code path for older versions
 | 
			
		||||
      #endif
 | 
			
		||||
 | 
			
		||||
@@ -1,954 +0,0 @@
 | 
			
		||||
.. _x509_certificates:
 | 
			
		||||
 | 
			
		||||
X.509 Certificates and CRLs
 | 
			
		||||
=================================
 | 
			
		||||
 | 
			
		||||
A certificate is a binding between some identifying information
 | 
			
		||||
(called a *subject*) and a public key. This binding is asserted by a
 | 
			
		||||
signature on the certificate, which is placed there by some authority
 | 
			
		||||
(the *issuer*) that at least claims that it knows the subject named in
 | 
			
		||||
the certificate really "owns" the private key corresponding to the
 | 
			
		||||
public key in the certificate.
 | 
			
		||||
 | 
			
		||||
The major certificate format in use today is X.509v3, used for instance in the
 | 
			
		||||
:doc:`tls` protocol. A X.509 certificate is represented by the class
 | 
			
		||||
``X509_Certificate``. The data of an X.509 certificate is stored as a
 | 
			
		||||
``shared_ptr`` to a structure containing the decoded information. So copying
 | 
			
		||||
``X509_Certificate`` objects is quite cheap.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: X509_Certificate
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_Certificate(const std::string& filename)
 | 
			
		||||
 | 
			
		||||
     Load a certificate from a file. PEM or DER is accepted.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_Certificate(const std::vector<uint8_t>& in)
 | 
			
		||||
 | 
			
		||||
     Load a certificate from a byte string.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_Certificate(DataSource& source)
 | 
			
		||||
 | 
			
		||||
     Load a certificate from an abstract ``DataSource``.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_DN subject_dn() const
 | 
			
		||||
 | 
			
		||||
     Returns the distinguished name (DN) of the certificate's subject. This is
 | 
			
		||||
     the primary place where information about the subject of the certificate is
 | 
			
		||||
     stored. However "modern" information that doesn't fit in the X.500
 | 
			
		||||
     framework, such as DNS name, email, IP address, or XMPP address, appears
 | 
			
		||||
     instead in the subject alternative name.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_DN issuer_dn() const
 | 
			
		||||
 | 
			
		||||
     Returns the distinguished name (DN) of the certificate's issuer, ie the CA
 | 
			
		||||
     that issued this certificate.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const AlternativeName& subject_alt_name() const
 | 
			
		||||
 | 
			
		||||
      Return the subjects alternative name. This is used to store
 | 
			
		||||
      values like associated URIs, DNS addresses, and email addresses.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const AlternativeName& issuer_alt_name() const
 | 
			
		||||
 | 
			
		||||
      Return alternative names for the issuer.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::unique_ptr<Public_Key> load_subject_public_key() const
 | 
			
		||||
 | 
			
		||||
     Deserialize the stored public key and return a new object. This
 | 
			
		||||
     might throw, if it happens that the public key object stored in
 | 
			
		||||
     the certificate is malformed in some way, or in the case that the
 | 
			
		||||
     public key algorithm used is not supported by the library.
 | 
			
		||||
 | 
			
		||||
     See :ref:`serializing_public_keys` for more information about what to do
 | 
			
		||||
     with the returned object. It may be any type of key, in principle, though
 | 
			
		||||
     RSA and ECDSA are most common.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> subject_public_key_bits() const
 | 
			
		||||
 | 
			
		||||
     Return the binary encoding of the subject public key. This value (or a hash of
 | 
			
		||||
     it) is used in various protocols, eg for public key pinning.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: AlgorithmIdentifier subject_public_key_algo() const
 | 
			
		||||
 | 
			
		||||
     Return an algorithm identifier that identifies the algorithm used in the
 | 
			
		||||
     subject's public key.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> serial_number() const
 | 
			
		||||
 | 
			
		||||
     Return the certificates serial number. The tuple of issuer DN and
 | 
			
		||||
     serial number should be unique.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8> raw_subject_dn() const
 | 
			
		||||
 | 
			
		||||
     Return the binary encoding of the subject DN.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8> raw_issuer_dn() const
 | 
			
		||||
 | 
			
		||||
     Return the binary encoding of the issuer DN.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_Time not_before() const
 | 
			
		||||
 | 
			
		||||
     Returns the point in time the certificate becomes valid
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: X509_Time not_after() const
 | 
			
		||||
 | 
			
		||||
     Returns the point in time the certificate expires
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const Extensions& v3_extensions() const
 | 
			
		||||
 | 
			
		||||
     Returns all extensions of this certificate. You can use this
 | 
			
		||||
     to examine any extension data associated with the certificate,
 | 
			
		||||
     including custom extensions the library doesn't know about.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> authority_key_id() const
 | 
			
		||||
 | 
			
		||||
      Return the authority key id, if set. This is an arbitrary string; in the
 | 
			
		||||
      issuing certificate this will be the subject key id.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> subject_key_id() const
 | 
			
		||||
 | 
			
		||||
      Return the subject key id, if set.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool allowed_extended_usage(const OID& usage) const
 | 
			
		||||
 | 
			
		||||
      Return true if and only if the usage OID appears in the extended key usage
 | 
			
		||||
      extension. Also will return true if the extended key usage extension is
 | 
			
		||||
      not used in the current certificate.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<OID> extended_key_usage() const
 | 
			
		||||
 | 
			
		||||
      Return the list of extended key usages. May be empty.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string fingerprint(const std::string& hash_fn = "SHA-1") const
 | 
			
		||||
 | 
			
		||||
      Return a fingerprint for the certificate, which is basically just a hash
 | 
			
		||||
      of the binary contents. Normally SHA-1 or SHA-256 is used, but any hash
 | 
			
		||||
      function is allowed.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Key_Constraints constraints() const
 | 
			
		||||
 | 
			
		||||
      Returns a basic list of constraints which govern usage of the
 | 
			
		||||
      key embedded in this certificate.
 | 
			
		||||
 | 
			
		||||
      The Key_Constraints is a class that behaves somewhat like an
 | 
			
		||||
      ``enum``. The easiest way to use it is with its ``includes``
 | 
			
		||||
      method. For example::
 | 
			
		||||
 | 
			
		||||
        constraints().includes(Key_Constraints::DigitalSignature)
 | 
			
		||||
 | 
			
		||||
      checks if the certificate key is valid for generating digital
 | 
			
		||||
      signatures.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool matches_dns_name(const std::string& name) const
 | 
			
		||||
 | 
			
		||||
      Check if the certificate's subject alternative name DNS fields
 | 
			
		||||
      match ``name``. This function also handles wildcard certificates.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string to_string() const
 | 
			
		||||
 | 
			
		||||
      Returns a free-form human readable string describing the certificate.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string PEM_encode() const
 | 
			
		||||
 | 
			
		||||
      Returns the PEM encoding of the certificate
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> BER_encode() const
 | 
			
		||||
 | 
			
		||||
      Returns the DER/BER encoding of the certificate
 | 
			
		||||
 | 
			
		||||
X.509 Distinguished Names
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: X509_DN
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool has_field(const std::string& attr) const
 | 
			
		||||
 | 
			
		||||
      Returns true if ``get_attribute`` or ``get_first_attribute`` will return a value.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<std::string> get_attribute(const std::string& attr) const
 | 
			
		||||
 | 
			
		||||
      Return all attributes associated with a certain attribute type.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string get_first_attribute(const std::string& attr) const
 | 
			
		||||
 | 
			
		||||
      Like ``get_attribute`` but returns just the first attribute, or
 | 
			
		||||
      empty if the DN has no attribute of the specified type.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::multimap<OID, std::string> get_attributes() const
 | 
			
		||||
 | 
			
		||||
      Get all attributes of the DN. The OID maps to a DN component such as
 | 
			
		||||
      2.5.4.10 ("Organization"), and the strings are UTF-8 encoded.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::multimap<std::string, std::string> contents() const
 | 
			
		||||
 | 
			
		||||
      Similar to ``get_attributes``, but the OIDs are decoded to strings.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void add_attribute(const std::string& key, const std::string& val)
 | 
			
		||||
 | 
			
		||||
      Add an attribute to a DN.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void add_attribute(const OID& oid, const std::string& val)
 | 
			
		||||
 | 
			
		||||
      Add an attribute to a DN using an OID instead of string-valued attribute type.
 | 
			
		||||
 | 
			
		||||
The ``X509_DN`` type also supports iostream extraction and insertion operators,
 | 
			
		||||
for formatted input and output.
 | 
			
		||||
 | 
			
		||||
X.509v3 Extensions
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
X.509v3 specifies a large number of possible extensions. Botan supports some,
 | 
			
		||||
but by no means all of them. The following listing lists which X.509v3
 | 
			
		||||
extensions are supported and notes areas where there may be problems with the
 | 
			
		||||
handling.
 | 
			
		||||
 | 
			
		||||
 - Key Usage and Extended Key Usage: No problems known.
 | 
			
		||||
 | 
			
		||||
 - Basic Constraints: No problems known. A self-signed v1 certificate
 | 
			
		||||
   is assumed to be a CA, while a v3 certificate is marked as a CA if
 | 
			
		||||
   and only if the basic constraints extension is present and set for
 | 
			
		||||
   a CA cert.
 | 
			
		||||
 | 
			
		||||
 - Subject Alternative Names: Only the "rfc822Name", "dNSName", and
 | 
			
		||||
   "uniformResourceIdentifier" and raw IPv4 fields will be stored; all
 | 
			
		||||
   others are ignored.
 | 
			
		||||
 | 
			
		||||
 - Issuer Alternative Names: Same restrictions as the Subject
 | 
			
		||||
   Alternative Names extension. New certificates generated by Botan
 | 
			
		||||
   never include the issuer alternative name.
 | 
			
		||||
 | 
			
		||||
 - Authority Key Identifier: Only the version using KeyIdentifier is
 | 
			
		||||
   supported. If the GeneralNames version is used and the extension is
 | 
			
		||||
   critical, an exception is thrown. If both the KeyIdentifier and GeneralNames
 | 
			
		||||
   versions are present, then the KeyIdentifier will be used, and the
 | 
			
		||||
   GeneralNames ignored.
 | 
			
		||||
 | 
			
		||||
 - Subject Key Identifier: No problems known.
 | 
			
		||||
 | 
			
		||||
 - Name Constraints: No problems known (though encoding is not supported).
 | 
			
		||||
 | 
			
		||||
Any unknown critical extension in a certificate will lead to an
 | 
			
		||||
exception during path validation.
 | 
			
		||||
 | 
			
		||||
Extensions are handled by a special class taking care of encoding
 | 
			
		||||
and decoding. It also supports encoding and decoding of custom extensions.
 | 
			
		||||
To do this, it internally keeps two lists of extensions. Different lookup
 | 
			
		||||
functions are provided to search them.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
  Validation of custom extensions during path validation is currently not supported.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Extensions
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void add(Certificate_Extension* extn, bool critical = false)
 | 
			
		||||
 | 
			
		||||
     Adds a new extension to the extensions object. If an extension of the same
 | 
			
		||||
     type already exists, ``extn`` will replace it. If ``critical`` is true the
 | 
			
		||||
     extension will be marked as critical in the encoding.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: bool add_new(Certificate_Extension* extn, bool critical = false)
 | 
			
		||||
 | 
			
		||||
    Like ``add`` but an existing extension will not be replaced. Returns true if the
 | 
			
		||||
    extension was used, false if an extension of the same type was already in place.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void replace(Certificate_Extension* extn, bool critical = false)
 | 
			
		||||
 | 
			
		||||
     Adds an extension to the list or replaces it, if the same
 | 
			
		||||
     extension was already added
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::unique_ptr<Certificate_Extension> get(const OID& oid) const
 | 
			
		||||
 | 
			
		||||
     Searches for an extension by OID and returns the result
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: template<typename T> \
 | 
			
		||||
      std::unique_ptr<T> get_raw(const OID& oid)
 | 
			
		||||
 | 
			
		||||
     Searches for an extension by OID and returns the result.
 | 
			
		||||
     Only the unknown extensions, that is, extensions types that are not
 | 
			
		||||
     listed above, are searched for by this function.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> extensions() const
 | 
			
		||||
 | 
			
		||||
     Returns the list of extensions together with the corresponding
 | 
			
		||||
     criticality flag. Only contains the supported extension types
 | 
			
		||||
     listed above.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::map<OID, std::pair<std::vector<uint8_t>, bool>> extensions_raw() const
 | 
			
		||||
 | 
			
		||||
     Returns the list of extensions as raw, encoded bytes
 | 
			
		||||
     together with the corresponding criticality flag.
 | 
			
		||||
     Contains all extensions, known as well as unknown extensions.
 | 
			
		||||
 | 
			
		||||
Certificate Revocation Lists
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
It will occasionally happen that a certificate must be revoked before
 | 
			
		||||
its expiration date. Examples of this happening include the private
 | 
			
		||||
key being compromised, or the user to which it has been assigned
 | 
			
		||||
leaving an organization. Certificate revocation lists are an answer to
 | 
			
		||||
this problem (though online certificate validation techniques are
 | 
			
		||||
starting to become somewhat more popular). Every once in a while the
 | 
			
		||||
CA will release a new CRL, listing all certificates that have been
 | 
			
		||||
revoked. Also included is various pieces of information like what time
 | 
			
		||||
a particular certificate was revoked, and for what reason. In most
 | 
			
		||||
systems, it is wise to support some form of certificate revocation,
 | 
			
		||||
and CRLs handle this easily.
 | 
			
		||||
 | 
			
		||||
For most users, processing a CRL is quite easy. All you have to do is
 | 
			
		||||
call the constructor, which will take a filename (or a
 | 
			
		||||
``DataSource&``). The CRLs can either be in raw BER/DER, or in PEM
 | 
			
		||||
format; the constructor will figure out which format without any extra
 | 
			
		||||
information. For example::
 | 
			
		||||
 | 
			
		||||
   X509_CRL crl1("crl1.der");
 | 
			
		||||
 | 
			
		||||
   DataSource_Stream in("crl2.pem");
 | 
			
		||||
   X509_CRL crl2(in);
 | 
			
		||||
 | 
			
		||||
After that, pass the ``X509_CRL`` object to a ``Certificate_Store`` object
 | 
			
		||||
with
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: void Certificate_Store::add_crl(const X509_CRL& crl)
 | 
			
		||||
 | 
			
		||||
and all future verifications will take into account the provided CRL.
 | 
			
		||||
 | 
			
		||||
Certificate Stores
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
An object of type ``Certificate_Store`` is a generalized interface to
 | 
			
		||||
an external source for certificates (and CRLs). Examples of such a
 | 
			
		||||
store would be one that looked up the certificates in a SQL database,
 | 
			
		||||
or by contacting a CGI script running on a HTTP server. There are
 | 
			
		||||
currently three mechanisms for looking up a certificate, and one for
 | 
			
		||||
retrieving CRLs. By default, most of these mechanisms will return an
 | 
			
		||||
empty ``std::optional`` of ``X509_Certificate``. This storage mechanism
 | 
			
		||||
is *only* queried when doing certificate validation: it allows you to
 | 
			
		||||
distribute only the root key with an application, and let some online
 | 
			
		||||
method handle getting all the other certificates that are needed to
 | 
			
		||||
validate an end entity certificate. In particular, the search routines
 | 
			
		||||
will not attempt to access the external database.
 | 
			
		||||
 | 
			
		||||
The certificate lookup methods are ``find_cert`` (by Subject
 | 
			
		||||
Distinguished Name and optional Subject Key Identifier) and
 | 
			
		||||
``find_cert_by_pubkey_sha1`` (by SHA-1 hash of the certificate's
 | 
			
		||||
public key). The Subject Distinguished Name is given as a ``X509_DN``,
 | 
			
		||||
while the SKID parameter takes a ``std::vector<uint8_t>`` containing
 | 
			
		||||
the subject key identifier in raw binary. Both lookup methods are
 | 
			
		||||
mandatory to implement.
 | 
			
		||||
 | 
			
		||||
Finally, there is a method for finding a CRL, called ``find_crl_for``,
 | 
			
		||||
that takes an ``X509_Certificate`` object, and returns a
 | 
			
		||||
``std::optional`` of ``X509_CRL``. The ``std::optional`` return
 | 
			
		||||
type makes it easy to return no CRLs by returning ``nullopt``
 | 
			
		||||
(eg, if the certificate store doesn't support retrieving CRLs).
 | 
			
		||||
Implementing the function is optional, and by default will return
 | 
			
		||||
``nullopt``.
 | 
			
		||||
 | 
			
		||||
Certificate stores are used in the :doc:`tls` module to store a
 | 
			
		||||
list of trusted certificate authorities.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   In the 2.x library, the certificate store interface relied on
 | 
			
		||||
   ``shared_ptr<X509_Certificate>`` to avoid copies. However since
 | 
			
		||||
   2.4.0, the ``X509_Certificate`` was internally shared, and thus the
 | 
			
		||||
   outer ``shared_ptr`` was just a cause of needless runtime overhead
 | 
			
		||||
   and API complexity. Starting in version 3.0, the certificate store
 | 
			
		||||
   interface is defined in terms of plain ``X509_Certificate``.
 | 
			
		||||
 | 
			
		||||
In Memory Certificate Store
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The in memory certificate store keeps all objects in memory only.
 | 
			
		||||
Certificates can be loaded from disk initially, but also added
 | 
			
		||||
later.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Certificate_Store_In_Memory
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: Certificate_Store_In_Memory(const std::string& dir)
 | 
			
		||||
 | 
			
		||||
     Attempt to parse all files in ``dir`` (including subdirectories)
 | 
			
		||||
     as certificates. Ignores errors.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: Certificate_Store_In_Memory(const X509_Certificate& cert)
 | 
			
		||||
 | 
			
		||||
     Adds given certificate to the store
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: Certificate_Store_In_Memory()
 | 
			
		||||
 | 
			
		||||
     Create an empty store
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void add_certificate(const X509_Certificate& cert)
 | 
			
		||||
 | 
			
		||||
     Add a certificate to the store
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void add_crl(const X509_CRL& crl)
 | 
			
		||||
 | 
			
		||||
     Add a certificate revocation list (CRL) to the store.
 | 
			
		||||
 | 
			
		||||
System Certificate Stores
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
An interface to use the system provided certificate stores is available for
 | 
			
		||||
Unix, macOS and Windows systems, ``System_Certificate_Store``
 | 
			
		||||
 | 
			
		||||
Flatfile Certificate Stores
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
``Flatfile_Certificate_Store`` is an implementation of certificate store that
 | 
			
		||||
reads certificates as files from a directory. This is also used as the
 | 
			
		||||
implementation of the Unix/Linux system certificate store.
 | 
			
		||||
 | 
			
		||||
The constructor takes a path to the directory to read, along with an optional
 | 
			
		||||
boolean indicating if non-CA certificates should be ignored.
 | 
			
		||||
 | 
			
		||||
SQL-backed Certificate Stores
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The SQL-backed certificate stores store all objects in an SQL database. They
 | 
			
		||||
also additionally provide private key storage and revocation of individual
 | 
			
		||||
certificates.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Certificate_Store_In_SQL
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: Certificate_Store_In_SQL(const std::shared_ptr<SQL_Database> db, \
 | 
			
		||||
    const std::string& passwd, RandomNumberGenerator& rng, const std::string& table_prefix = "")
 | 
			
		||||
 | 
			
		||||
     Create or open an existing certificate store from an SQL database.
 | 
			
		||||
     The password in ``passwd`` will be used to encrypt private keys.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: bool insert_cert(const X509_Certificate& cert)
 | 
			
		||||
 | 
			
		||||
     Inserts ``cert`` into the store. Returns `false` if the certificate is
 | 
			
		||||
     already known and `true` if insertion was successful.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: remove_cert(const X509_Certificate& cert)
 | 
			
		||||
 | 
			
		||||
     Removes ``cert`` from the store. Returns `false` if the certificate could not
 | 
			
		||||
     be found and `true` if removal was successful.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::shared_ptr<const Private_Key> find_key(const X509_Certificate&) const
 | 
			
		||||
 | 
			
		||||
     Returns the private key for "cert" or an empty shared_ptr if none was found
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::vector<X509_Certificate> find_certs_for_key(const Private_Key& key) const
 | 
			
		||||
 | 
			
		||||
     Returns all certificates for private key ``key``
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: bool insert_key(const X509_Certificate& cert, const Private_Key& key)
 | 
			
		||||
 | 
			
		||||
     Inserts ``key`` for ``cert`` into the store, returns `false` if the key is
 | 
			
		||||
     already known and `true` if insertion was successful.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void remove_key(const Private_Key& key)
 | 
			
		||||
 | 
			
		||||
     Removes ``key`` from the store
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void revoke_cert(const X509_Certificate&, CRL_Code, \
 | 
			
		||||
    const X509_Time& time = X509_Time())
 | 
			
		||||
 | 
			
		||||
     Marks ``cert`` as revoked starting from ``time``
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: void affirm_cert(const X509_Certificate&)
 | 
			
		||||
 | 
			
		||||
     Reverses the revocation for ``cert``
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::vector<X509_CRL> generate_crls() const
 | 
			
		||||
 | 
			
		||||
     Generates CRLs for all certificates marked as revoked.
 | 
			
		||||
     A CRL is returned for each unique issuer DN.
 | 
			
		||||
 | 
			
		||||
The ``Certificate_Store_In_SQL`` class operates on an abstract ``SQL_Database``
 | 
			
		||||
object. If support for sqlite3 was enabled at build time, Botan includes an
 | 
			
		||||
implementation of this interface for sqlite3, and a subclass of
 | 
			
		||||
``Certificate_Store_In_SQL`` which creates or opens a sqlite3 database.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Certificate_Store_In_SQLite
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: Certificate_Store_In_SQLite(const std::string& db_path, \
 | 
			
		||||
    const std::string& passwd, RandomNumberGenerator& rng, const std::string& table_prefix = "")
 | 
			
		||||
 | 
			
		||||
     Create or open an existing certificate store from an sqlite database file.
 | 
			
		||||
     The password in ``passwd`` will be used to encrypt private keys. 
 | 
			
		||||
 | 
			
		||||
Path Validation
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
The process of validating a certificate chain up to a trusted root is
 | 
			
		||||
called `path validation`, and in botan that operation is handled by a
 | 
			
		||||
set of functions in ``x509path.h`` named ``x509_path_validate``:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: Path_Validation_Result \
 | 
			
		||||
   x509_path_validate(const X509_Certificate& end_cert, \
 | 
			
		||||
   const Path_Validation_Restrictions& restrictions, \
 | 
			
		||||
   const Certificate_Store& store, const std::string& hostname = "", \
 | 
			
		||||
   Usage_Type usage = Usage_Type::UNSPECIFIED, \
 | 
			
		||||
   std::chrono::system_clock::time_point validation_time = std::chrono::system_clock::now(), \
 | 
			
		||||
   std::chrono::milliseconds ocsp_timeout = std::chrono::milliseconds(0), \
 | 
			
		||||
   const std::vector<std::optional<OCSP::Response>>& ocsp_resp = std::vector<std::optional<OCSP::Response>>())
 | 
			
		||||
 | 
			
		||||
   The last five parameters are optional. ``hostname`` specifies a hostname which is
 | 
			
		||||
   matched against the subject DN in ``end_cert`` according to RFC 6125.
 | 
			
		||||
   An empty hostname disables hostname validation.
 | 
			
		||||
   ``usage`` specifies key usage restrictions that are compared
 | 
			
		||||
   to the key usage fields in `end_cert` according to RFC 5280, if not set to
 | 
			
		||||
   ``UNSPECIFIED``. ``validation_time`` allows setting the time point at which all certificates
 | 
			
		||||
   are validated. This is really only useful for testing. The default is the
 | 
			
		||||
   current system clock's current time. ``ocsp_timeout`` sets the timeout for
 | 
			
		||||
   OCSP requests. The default of 0 disables OCSP checks completely.
 | 
			
		||||
   ``ocsp_resp`` allows adding additional OCSP responses retrieved from outside
 | 
			
		||||
   of the path validation. Note that OCSP online checks are done only
 | 
			
		||||
   as long as the http_util module was compiled in. Availability of online
 | 
			
		||||
   OCSP checks can be checked using the macro BOTAN_HAS_ONLINE_REVOCATION_CHECKS.
 | 
			
		||||
 | 
			
		||||
   For the different flavors of ``x509_path_validate``, check ``x509path.h``.
 | 
			
		||||
 | 
			
		||||
The result of the validation is returned as a class:
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Path_Validation_Result
 | 
			
		||||
 | 
			
		||||
   Specifies the result of the validation
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool successful_validation() const
 | 
			
		||||
 | 
			
		||||
     Returns true if a certificate path from *end_cert* to a trusted
 | 
			
		||||
     root was found and all path validation checks passed.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string result_string() const
 | 
			
		||||
 | 
			
		||||
     Returns a descriptive string of the validation status (for
 | 
			
		||||
     instance "Verified", "Certificate is not yet valid", or
 | 
			
		||||
     "Signature error"). This is the string value of
 | 
			
		||||
     the `result` function below.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const X509_Certificate& trust_root() const
 | 
			
		||||
 | 
			
		||||
     If the validation was successful, returns the certificate which
 | 
			
		||||
     is acting as the trust root for *end_cert*.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const std::vector<X509_Certificate>& cert_path() const
 | 
			
		||||
 | 
			
		||||
     Returns the full certificate path starting with the end entity
 | 
			
		||||
     certificate and ending in the trust root.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Certificate_Status_Code result() const
 | 
			
		||||
 | 
			
		||||
     Returns the 'worst' error that occurred during validation. For
 | 
			
		||||
     instance, we do not want an expired certificate with an invalid
 | 
			
		||||
     signature to be reported to the user as being simply expired (a
 | 
			
		||||
     relatively innocuous and common error) when the signature isn't
 | 
			
		||||
     even valid.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const std::vector<std::set<Certificate_Status_Code>>& all_statuses() const
 | 
			
		||||
 | 
			
		||||
     For each certificate in the chain, returns a set of status which
 | 
			
		||||
     indicate all errors which occurred during validation. This is
 | 
			
		||||
     primarily useful for diagnostic purposes.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::set<std::string> trusted_hashes() const
 | 
			
		||||
 | 
			
		||||
     Returns the set of all cryptographic hash functions which are
 | 
			
		||||
     implicitly trusted for this validation to be correct.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
A ``Path_Validation_Restrictions`` is passed to the path
 | 
			
		||||
validator and specifies restrictions and options for the validation
 | 
			
		||||
step. The two constructors are:
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Path_Validation_Restrictions(bool require_rev, \
 | 
			
		||||
                                                 size_t minimum_key_strength, \
 | 
			
		||||
                                                 bool ocsp_all_intermediates, \
 | 
			
		||||
                                                 const std::set<std::string>& trusted_hashes)
 | 
			
		||||
 | 
			
		||||
    If `require_rev` is true, then any path without revocation
 | 
			
		||||
    information (CRL or OCSP check) is rejected with the code
 | 
			
		||||
    `NO_REVOCATION_DATA`. The `minimum_key_strength` parameter
 | 
			
		||||
    specifies the minimum strength of public key signature we will
 | 
			
		||||
    accept is. The set of hash names `trusted_hashes` indicates which
 | 
			
		||||
    hash functions we'll accept for cryptographic signatures.  Any
 | 
			
		||||
    untrusted hash will cause the error case `UNTRUSTED_HASH`.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Path_Validation_Restrictions(bool require_rev = false, \
 | 
			
		||||
                                                 size_t minimum_key_strength = 80, \
 | 
			
		||||
                                                 bool ocsp_all_intermediates = false)
 | 
			
		||||
 | 
			
		||||
    A variant of the above with some convenient defaults. The current
 | 
			
		||||
    default `minimum_key_strength` of 80 roughly corresponds to 1024
 | 
			
		||||
    bit RSA. The set of trusted hashes is set to all SHA-2 variants,
 | 
			
		||||
    and, if `minimum_key_strength` is less than or equal to 80, then
 | 
			
		||||
    SHA-1 signatures will also be accepted.
 | 
			
		||||
 | 
			
		||||
Creating New Certificates
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
A CA is represented by the type ``X509_CA``, which can be found in
 | 
			
		||||
``x509_ca.h``. A CA always needs its own certificate, which can either
 | 
			
		||||
be a self-signed certificate (see below on how to create one) or one
 | 
			
		||||
issued by another CA (see the section on PKCS #10 requests). Creating
 | 
			
		||||
a CA object is done by the following constructor:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: X509_CA::X509_CA(const X509_Certificate& cert, \
 | 
			
		||||
                                   const Private_Key& key, \
 | 
			
		||||
                                   const std::string& hash_fn, \
 | 
			
		||||
                                   RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
The private ``key`` is the private key corresponding to the public key in the
 | 
			
		||||
CA's certificate. ``hash_fn`` is the name of the hash function to use
 | 
			
		||||
for signing, e.g., `SHA-256`. ``rng`` is queried for random during signing.
 | 
			
		||||
 | 
			
		||||
There is an alternative constructor that lets you set additional options, namely
 | 
			
		||||
the padding scheme that will be used by the X509_CA object to sign certificates
 | 
			
		||||
and certificate revocation lists. If the padding is not set explicitly, the CA
 | 
			
		||||
will use some default. The only time you need this alternate interface is
 | 
			
		||||
for creating RSA-PSS certificates.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: X509_CA::X509_CA(const X509_Certificate& cert, \
 | 
			
		||||
                                   const Private_Key& key, \
 | 
			
		||||
                                   const std::string& hash_fn, \
 | 
			
		||||
                                   const std::string& padding_fn, \
 | 
			
		||||
                                   RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
Requests for new certificates are supplied to a CA in the form of PKCS
 | 
			
		||||
#10 certificate requests (called a ``PKCS10_Request`` object in
 | 
			
		||||
Botan). These are decoded in a similar manner to
 | 
			
		||||
certificates/CRLs/etc. A request is vetted by humans (who somehow
 | 
			
		||||
verify that the name in the request corresponds to the name of the
 | 
			
		||||
entity who requested it), and then signed by a CA key, generating a
 | 
			
		||||
new certificate:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: X509_Certificate \
 | 
			
		||||
   X509_CA::sign_request(const PKCS10_Request& req, \
 | 
			
		||||
                         RandomNumberGenerator& rng, \
 | 
			
		||||
                         const X509_Time& not_before, \
 | 
			
		||||
                         const X509_Time& not_after)
 | 
			
		||||
 | 
			
		||||
If you need more control over the signing process, you can use the methods
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: static X509_Certificate X509_CA::make_cert(PK_Signer& signer, \
 | 
			
		||||
                                        RandomNumberGenerator& rng, \
 | 
			
		||||
                                        const BigInt& serial_number, \
 | 
			
		||||
                                        const AlgorithmIdentifier& sig_algo, \
 | 
			
		||||
                                        const std::vector<uint8_t>& pub_key, \
 | 
			
		||||
                                        const X509_Time& not_before, \
 | 
			
		||||
                                        const X509_Time& not_after, \
 | 
			
		||||
                                        const X509_DN& issuer_dn, \
 | 
			
		||||
                                        const X509_DN& subject_dn, \
 | 
			
		||||
                                        const Extensions& extensions)
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: static Extensions X509_CA::choose_extensions(const PKCS10_Request& req, \
 | 
			
		||||
                                          const X509_Certificate& ca_certificate, \
 | 
			
		||||
                                          const std::string& hash_fn)
 | 
			
		||||
 | 
			
		||||
   Returns the extensions that would be created by sign_request if it was used.
 | 
			
		||||
   You can call this and then modify the extensions list before invoking
 | 
			
		||||
   :cpp:func:`X509_CA::make_cert`
 | 
			
		||||
 | 
			
		||||
Generating CRLs
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
As mentioned previously, the ability to process CRLs is highly
 | 
			
		||||
important in many PKI systems. In fact, according to strict X.509
 | 
			
		||||
rules, you must not validate any certificate if the appropriate CRLs
 | 
			
		||||
are not available (though hardly any systems are that strict). In any
 | 
			
		||||
case, a CA should have a valid CRL available at all times.
 | 
			
		||||
 | 
			
		||||
Of course, you might be wondering what to do if no certificates have
 | 
			
		||||
been revoked. Never fear; empty CRLs, which revoke nothing at all, can
 | 
			
		||||
be issued. To generate a new, empty CRL, just call
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: X509_CRL X509_CA::new_crl(RandomNumberGenerator& rng, \
 | 
			
		||||
                                            uint32_t next_update = 0)
 | 
			
		||||
 | 
			
		||||
  This function will return a new, empty CRL. The ``next_update`` parameter is
 | 
			
		||||
  the number of seconds before the CRL expires. If it is set to the (default)
 | 
			
		||||
  value of zero, then a reasonable default (currently 7 days) will be used.
 | 
			
		||||
 | 
			
		||||
On the other hand, you may have issued a CRL before. In that case, you will
 | 
			
		||||
want to issue a new CRL that contains all previously revoked
 | 
			
		||||
certificates, along with any new ones. This is done by calling
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: X509_CRL X509_CA::update_crl(const X509_CRL& last_crl, \
 | 
			
		||||
   std::vector<CRL_Entry> new_entries, RandomNumberGenerator& rng, \
 | 
			
		||||
   size_t next_update = 0)
 | 
			
		||||
 | 
			
		||||
  Where ``last_crl`` is the last CRL this CA issued, and
 | 
			
		||||
  ``new_entries`` is a list of any newly revoked certificates. The
 | 
			
		||||
  function returns a new ``X509_CRL`` to make available for
 | 
			
		||||
  clients.
 | 
			
		||||
 | 
			
		||||
The ``CRL_Entry`` type is a structure that contains, at a minimum, the serial
 | 
			
		||||
number of the revoked certificate. As serial numbers are never repeated, the
 | 
			
		||||
pairing of an issuer and a serial number (should) distinctly identify any
 | 
			
		||||
certificate. In this case, we represent the serial number as a
 | 
			
		||||
``secure_vector<uint8_t>`` called ``serial``. There are two additional (optional)
 | 
			
		||||
values, an enumeration called ``CRL_Code`` that specifies the reason for
 | 
			
		||||
revocation (``reason``), and an object that represents the time that the
 | 
			
		||||
certificate became invalid (if this information is known).
 | 
			
		||||
 | 
			
		||||
If you wish to remove an old entry from the CRL, insert a new entry for the
 | 
			
		||||
same cert, with a ``reason`` code of ``REMOVE_FROM_CRL``. For example, if a
 | 
			
		||||
revoked certificate has expired 'normally', there is no reason to continue to
 | 
			
		||||
explicitly revoke it, since clients will reject the cert as expired in any
 | 
			
		||||
case.
 | 
			
		||||
 | 
			
		||||
Self-Signed Certificates
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Generating a new self-signed certificate can often be useful, for
 | 
			
		||||
example when setting up a new root CA, or for use in specialized
 | 
			
		||||
protocols. The library provides a utility function for this:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: X509_Certificate create_self_signed_cert( \
 | 
			
		||||
   const X509_Cert_Options& opts, const Private_Key& key, \
 | 
			
		||||
   const std::string& hash_fn, RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
   Where ``key`` is the private key you wish to use (the public key,
 | 
			
		||||
   used in the certificate itself is extracted from the private key),
 | 
			
		||||
   and ``opts`` is an structure that has various bits of information
 | 
			
		||||
   that will be used in creating the certificate (this structure, and
 | 
			
		||||
   its use, is discussed below).
 | 
			
		||||
 | 
			
		||||
Creating PKCS #10 Requests
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Also in ``x509self.h``, there is a function for generating new PKCS #10
 | 
			
		||||
certificate requests:
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: PKCS10_Request create_cert_req( \
 | 
			
		||||
   const X509_Cert_Options& opts, const Private_Key& key, \
 | 
			
		||||
   const std::string& hash_fn, RandomNumberGenerator& rng)
 | 
			
		||||
 | 
			
		||||
This function acts quite similarly to
 | 
			
		||||
:cpp:func:`create_self_signed_cert`, except it instead returns a PKCS
 | 
			
		||||
#10 certificate request. After creating it, one would typically
 | 
			
		||||
transmit it to a CA, who signs it and returns a freshly minted X.509
 | 
			
		||||
certificate.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: PKCS10_Request PKCS10_Request::create(const Private_Key& key, \
 | 
			
		||||
                                   const X509_DN& subject_dn, \
 | 
			
		||||
                                   const Extensions& extensions, \
 | 
			
		||||
                                   const std::string& hash_fn, \
 | 
			
		||||
                                   RandomNumberGenerator& rng, \
 | 
			
		||||
                                   const std::string& padding_scheme = "", \
 | 
			
		||||
                                   const std::string& challenge = "")
 | 
			
		||||
 | 
			
		||||
  This function (added in 2.5) is similar to ``create_cert_req`` but allows
 | 
			
		||||
  specifying all the parameters directly. In fact ``create_cert_req`` just
 | 
			
		||||
  creates the DN and extensions from the options, then uses this call to
 | 
			
		||||
  actually create the ``PKCS10_Request`` object.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Certificate Options
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
What is this ``X509_Cert_Options`` thing we've been passing around?
 | 
			
		||||
It's a class representing a bunch of information that will end up
 | 
			
		||||
being stored into the certificate. This information comes in 3 major
 | 
			
		||||
flavors: information about the subject (CA or end-user), the validity
 | 
			
		||||
period of the certificate, and restrictions on the usage of the
 | 
			
		||||
certificate. For special cases, you can also add custom X.509v3
 | 
			
		||||
extensions.
 | 
			
		||||
 | 
			
		||||
First and foremost is a number of ``std::string`` members, which
 | 
			
		||||
contains various bits of information about the user: ``common_name``,
 | 
			
		||||
``serial_number``, ``country``, ``organization``, ``org_unit``,
 | 
			
		||||
``locality``, ``state``, ``email``, ``dns_name``, and ``uri``. As many
 | 
			
		||||
of these as possible should be filled it (especially an email
 | 
			
		||||
address), though the only required ones are ``common_name`` and
 | 
			
		||||
``country``.
 | 
			
		||||
 | 
			
		||||
Additionally there are a small selection of ``std::vector<std::string>``
 | 
			
		||||
members, which allow space for repeating elements:
 | 
			
		||||
``more_org_units`` and ``more_dns``.
 | 
			
		||||
 | 
			
		||||
There is another value that is only useful when creating a PKCS #10
 | 
			
		||||
request, which is called ``challenge``. This is a challenge password,
 | 
			
		||||
which you can later use to request certificate revocation (*if* the CA
 | 
			
		||||
supports doing revocations in this manner).
 | 
			
		||||
 | 
			
		||||
Then there is the validity period; these are set with ``not_before``
 | 
			
		||||
and ``not_after``. Both of these functions also take a
 | 
			
		||||
``std::string``, which specifies when the certificate should start
 | 
			
		||||
being valid, and when it should stop being valid. If you don't set the
 | 
			
		||||
starting validity period, it will automatically choose the current
 | 
			
		||||
time. If you don't set the ending time, it will choose the starting
 | 
			
		||||
time plus a default time period. The arguments to these functions
 | 
			
		||||
specify the time in the following format: "2002/11/27 1:50:14". The
 | 
			
		||||
time is in 24-hour format, and the date is encoded as
 | 
			
		||||
year/month/day. The date must be specified, but you can omit the time
 | 
			
		||||
or trailing parts of it, for example "2002/11/27 1:50" or
 | 
			
		||||
"2002/11/27".
 | 
			
		||||
 | 
			
		||||
Third, you can set constraints on a key. The one you're mostly likely
 | 
			
		||||
to want to use is to create (or request) a CA certificate, which can
 | 
			
		||||
be done by calling the member function ``CA_key``. This should only be
 | 
			
		||||
used when needed.
 | 
			
		||||
 | 
			
		||||
Moreover, you can specify the padding scheme to be used when digital signatures
 | 
			
		||||
are computed by calling function ``set_padding_scheme`` with a string
 | 
			
		||||
representing the padding scheme. This way, you can control the padding scheme
 | 
			
		||||
for self-signed certificates and PKCS #10 requests. The padding scheme used by
 | 
			
		||||
a CA when building a certificate or a certificate revocation list can be set in
 | 
			
		||||
the ``X509_CA`` constructor. The supported padding schemes can be found in
 | 
			
		||||
src/lib/pubkey/padding.cpp. Some alternative names for the padding schemes are
 | 
			
		||||
understood, as well.
 | 
			
		||||
 | 
			
		||||
Other constraints can be set by calling the member functions
 | 
			
		||||
``add_constraints`` and ``add_ex_constraints``. The first takes a
 | 
			
		||||
``Key_Constraints`` value, and replaces any previously set value. If
 | 
			
		||||
no value is set, then the certificate key is marked as being valid for
 | 
			
		||||
any usage.  You can set it to any of the following (for more than one
 | 
			
		||||
usage, OR them together): ``DigitalSignature``, ``NonRepudiation``,
 | 
			
		||||
``KeyEncipherment``, ``DataEncipherment``, ``KeyAgreement``,
 | 
			
		||||
``KeyCertSign``, ``CrlSign``, ``EncipherOnly``, or ``DecipherOnly``.
 | 
			
		||||
Many of these have quite special semantics, so you should either
 | 
			
		||||
consult the appropriate standards document (such as RFC 5280), or just
 | 
			
		||||
not call ``add_constraints``, in which case the appropriate values
 | 
			
		||||
will be chosen for you based on the key type.
 | 
			
		||||
 | 
			
		||||
The second function, ``add_ex_constraints``, allows you to specify an
 | 
			
		||||
OID that has some meaning with regards to restricting the key to
 | 
			
		||||
particular usages. You can, if you wish, specify any OID you like, but
 | 
			
		||||
there is a set of standard ones that other applications will be able
 | 
			
		||||
to understand. These are the ones specified by the PKIX standard, and
 | 
			
		||||
are named "PKIX.ServerAuth" (for TLS server authentication),
 | 
			
		||||
"PKIX.ClientAuth" (for TLS client authentication), "PKIX.CodeSigning",
 | 
			
		||||
"PKIX.EmailProtection" (most likely for use with S/MIME),
 | 
			
		||||
"PKIX.IPsecUser", "PKIX.IPsecTunnel", "PKIX.IPsecEndSystem", and
 | 
			
		||||
"PKIX.TimeStamping". You can call "add_ex_constraints" any number of
 | 
			
		||||
times - each new OID will be added to the list to include in the
 | 
			
		||||
certificate.
 | 
			
		||||
 | 
			
		||||
Lastly, you can add any X.509v3 extensions in the `extensions` member, which is
 | 
			
		||||
useful if you want to encode a custom extension, or encode an extension in a way
 | 
			
		||||
differently from how Botan defaults.
 | 
			
		||||
 | 
			
		||||
OCSP Requests
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
A client makes an OCSP request to what is termed an 'OCSP responder'. This
 | 
			
		||||
responder returns a signed response attesting that the certificate in question
 | 
			
		||||
has not been revoked. The most recent OCSP specification is as of this
 | 
			
		||||
writing :rfc:`6960`.
 | 
			
		||||
 | 
			
		||||
Normally OCSP validation happens automatically as part of X.509 certificate
 | 
			
		||||
validation, as long as OCSP is enabled (by setting a non-zero ``ocsp_timeout``
 | 
			
		||||
in the call to ``x509_path_validate``, or for TLS by implementing the related
 | 
			
		||||
``tls_verify_cert_chain_ocsp_timeout`` callback and returning a non-zero value
 | 
			
		||||
from that). So most applications should not need to directly manipulate OCSP
 | 
			
		||||
request and response objects.
 | 
			
		||||
 | 
			
		||||
For those that do, the primary ocsp interface is in ``ocsp.h``. First a request
 | 
			
		||||
must be formed, using information contained in the subject certificate and in
 | 
			
		||||
the subject's issuing certificate.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: OCSP::Request
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \
 | 
			
		||||
                                 const BigInt& subject_serial)
 | 
			
		||||
 | 
			
		||||
      Create a new OCSP request
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: OCSP::Request(const X509_Certificate& issuer_cert, \
 | 
			
		||||
                                 const X509_Certificate& subject_cert)
 | 
			
		||||
 | 
			
		||||
      Variant of the above, using serial number from ``subject_cert``.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::vector<uint8_t> BER_encode() const
 | 
			
		||||
 | 
			
		||||
      Encode the current OCSP request as a binary string.
 | 
			
		||||
 | 
			
		||||
 .. cpp:function:: std::string base64_encode() const
 | 
			
		||||
 | 
			
		||||
      Encode the current OCSP request as a base64 string.
 | 
			
		||||
 | 
			
		||||
Then the response is parsed and validated, and if valid, can be consulted
 | 
			
		||||
for certificate status information.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: OCSP::Response
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: OCSP::Response(const uint8_t response_bits[], size_t response_bits_len)
 | 
			
		||||
 | 
			
		||||
     Attempts to parse ``response_bits`` as an OCSP response. Throws an
 | 
			
		||||
     exception if parsing fails. Note that this does not verify that the OCSP
 | 
			
		||||
     response is valid (ie that the signature is correct), merely that the
 | 
			
		||||
     ASN.1 structure matches an OCSP response.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Certificate_Status_Code check_signature( \
 | 
			
		||||
                    const std::vector<Certificate_Store*>& trust_roots, \
 | 
			
		||||
                    const std::vector<X509_Certificate>& cert_path = const std::vector<X509_Certificate>()) const
 | 
			
		||||
 | 
			
		||||
     Find the issuing certificate of the OCSP response, and check the signature.
 | 
			
		||||
 | 
			
		||||
     If possible, pass the full certificate path being validated in
 | 
			
		||||
     the optional ``cert_path`` argument: this additional information
 | 
			
		||||
     helps locate the OCSP signer's certificate in some cases. If this
 | 
			
		||||
     does not return ``Certificate_Status_Code::OCSP_SIGNATURE_OK``,
 | 
			
		||||
     then the request must not be be used further.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Certificate_Status_Code verify_signature(const X509_Certificate& issuing_cert) const
 | 
			
		||||
 | 
			
		||||
     If the certificate that issued the OCSP response is already known (eg,
 | 
			
		||||
     because in some specific application all the OCSP responses will always
 | 
			
		||||
     be signed by a single trusted issuer whose cert is baked into the code)
 | 
			
		||||
     this provides an alternate version of `check_signature`.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Certificate_Status_Code status_for(const X509_Certificate& issuer, \
 | 
			
		||||
                        const X509_Certificate& subject, \
 | 
			
		||||
                        std::chrono::system_clock::time_point ref_time = std::chrono::system_clock::now()) const
 | 
			
		||||
 | 
			
		||||
     Assuming the signature is valid, returns the status for the subject certificate.
 | 
			
		||||
     Make sure to get the ordering of the issuer and subject certificates correct.
 | 
			
		||||
 | 
			
		||||
     The ``ref_time`` is normally just the system clock, but can be used if
 | 
			
		||||
     validation against some other reference time is desired (such as for
 | 
			
		||||
     testing, to verify an old previously valid OCSP response, or to use an
 | 
			
		||||
     alternate time source such as the Roughtime protocol instead of the local
 | 
			
		||||
     client system clock).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const X509_Time& produced_at() const
 | 
			
		||||
 | 
			
		||||
     Return the time this OCSP response was (claimed to be) produced at.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function::  const X509_DN& signer_name() const
 | 
			
		||||
 | 
			
		||||
     Return the distinguished name of the signer. This is used to help
 | 
			
		||||
     find the issuing certificate.
 | 
			
		||||
 | 
			
		||||
     This field is optional in OCSP responses, and may not be set.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const std::vector<uint8_t>& signer_key_hash() const
 | 
			
		||||
 | 
			
		||||
     Return the SHA-1 hash of the public key of the signer. This is used to
 | 
			
		||||
     help find the issuing certificate. The ``Certificate_Store`` API
 | 
			
		||||
     ``find_cert_by_pubkey_sha1`` can search on this value.
 | 
			
		||||
 | 
			
		||||
     This field is optional in OCSP responses, and may not be set.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: const std::vector<uint8_t>& raw_bits() const
 | 
			
		||||
 | 
			
		||||
     Return the entire raw ASN.1 blob (for debugging or specialized decoding needs)
 | 
			
		||||
 | 
			
		||||
One common way of making OCSP requests is via HTTP, see :rfc:`2560`
 | 
			
		||||
Appendix A for details. A basic implementation of this is the function
 | 
			
		||||
``online_check``, which is available as long as the ``http_util`` module
 | 
			
		||||
was compiled in; check by testing for the macro ``BOTAN_HAS_HTTP_UTIL``.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \
 | 
			
		||||
                                              const BigInt& subject_serial, \
 | 
			
		||||
                                              const std::string& ocsp_responder, \
 | 
			
		||||
                                              const Certificate_Store* trusted_roots)
 | 
			
		||||
 | 
			
		||||
   Assemble a OCSP request for serial number ``subject_serial`` and attempt to request
 | 
			
		||||
   it to responder at URI ``ocsp_responder`` over a new HTTP socket, parses and returns
 | 
			
		||||
   the response. If trusted_roots is not null, then the response is additionally
 | 
			
		||||
   validated using OCSP response API ``check_signature``. Otherwise, this call must be
 | 
			
		||||
   performed later by the application.
 | 
			
		||||
 | 
			
		||||
.. cpp:function:: OCSP::Response online_check(const X509_Certificate& issuer, \
 | 
			
		||||
                                              const X509_Certificate& subject, \
 | 
			
		||||
                                              const Certificate_Store* trusted_roots)
 | 
			
		||||
 | 
			
		||||
   Variant of the above but uses serial number and OCSP responder URI from ``subject``.
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
ZFEC Forward Error Correction
 | 
			
		||||
===============================
 | 
			
		||||
 | 
			
		||||
.. versionadded:: 3.0.0
 | 
			
		||||
 | 
			
		||||
The ``ZFEC`` class provides forward error correction compatible
 | 
			
		||||
with the `zfec <https://github.com/tahoe-lafs/zfec>`_ library.
 | 
			
		||||
 | 
			
		||||
Forward error correction takes an input and creates multiple "shares",
 | 
			
		||||
such that any ``K`` of ``N`` shares is sufficient to recover the
 | 
			
		||||
entire original input.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   Specific to the ZFEC format, the first ``K`` generated shares are
 | 
			
		||||
   identical to the original input data, followed by ``N-K`` shares of
 | 
			
		||||
   error correcting code. This is very different from threshold secret
 | 
			
		||||
   sharing, where having fewer than ``K`` shares gives no information
 | 
			
		||||
   about the original input.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
   If a corrupted share is provided to the decoding algorithm, the
 | 
			
		||||
   resulting decoding will be invalid. It is recommended to protect
 | 
			
		||||
   shares using a technique such as a MAC or public key signature, if
 | 
			
		||||
   corruption is likely in your application.
 | 
			
		||||
 | 
			
		||||
``ZFEC`` requires that the input length be exactly divisible by ``K``;
 | 
			
		||||
if needed define a padding scheme to pad your input to the necessary
 | 
			
		||||
size.
 | 
			
		||||
 | 
			
		||||
An example application that adds padding and a hash checksum is available
 | 
			
		||||
in ``src/cli/zfec.cpp`` and invokable using ``botan fec_encode`` and
 | 
			
		||||
``botan fec_decode``.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: ZFEC
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: ZFEC(size_t k, size_t n)
 | 
			
		||||
 | 
			
		||||
     Set up for encoding or decoding using parameters ``k`` and ``n``.
 | 
			
		||||
     Both must be less than 256, and ``k`` must be less than ``n``.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void encode_shares(const std::vector<const uint8_t*>& shares, \
 | 
			
		||||
         size_t share_size, \
 | 
			
		||||
         std::function<void (size_t, const uint8_t[], size_t)> output_cb) const
 | 
			
		||||
 | 
			
		||||
     Encode ``K`` shares in ``shares`` each of length ``share_size`` into ``N``
 | 
			
		||||
     shares, also each of length ``share_size``. The ``output_cb`` function will
 | 
			
		||||
     be called once for each output share (in some unspecified and possibly
 | 
			
		||||
     non-deterministic order).
 | 
			
		||||
 | 
			
		||||
     The parameters to ``output_cb`` are: the share being output, the share
 | 
			
		||||
     contents, and the length of the encoded share (which will always be
 | 
			
		||||
     equal to ``share_size``).
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: void decode_shares(const std::map<size_t, const uint8_t*>& shares, \
 | 
			
		||||
         size_t share_size, \
 | 
			
		||||
         std::function<void (size_t, const uint8_t[], size_t)> output_cb) const
 | 
			
		||||
 | 
			
		||||
     Decode some set of shares into the original input. Each share is
 | 
			
		||||
     of ``share_size`` bytes. The shares are identified by a small
 | 
			
		||||
     integer (between 0 and 255).
 | 
			
		||||
 | 
			
		||||
     The parameters to ``output_cb`` are similar to that of ``encode_shares``.
 | 
			
		||||
@@ -1,106 +0,0 @@
 | 
			
		||||
Alastair Houghton
 | 
			
		||||
Alexander Bluhm (genua GmbH)
 | 
			
		||||
Alex Gaynor
 | 
			
		||||
Alf-André Walla
 | 
			
		||||
Allan L. Bazinet
 | 
			
		||||
Alon Bar-Lev
 | 
			
		||||
Andrew Moon
 | 
			
		||||
Antonio Coratelli
 | 
			
		||||
Atanas Filyanov
 | 
			
		||||
Baruch Burstein
 | 
			
		||||
Bhaskar Biswas
 | 
			
		||||
Bi11
 | 
			
		||||
Bogdan Gusiev
 | 
			
		||||
Chris Desjardins
 | 
			
		||||
Christian Mainka (Hackmanit GmbH)
 | 
			
		||||
Christopher Bläsius
 | 
			
		||||
Christoph Ludwig
 | 
			
		||||
cryptosource GmbH
 | 
			
		||||
cynecx
 | 
			
		||||
Dan Brown
 | 
			
		||||
Daniel Neus (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
Daniel Seither (Kullo GmbH)
 | 
			
		||||
Daniel Wyatt
 | 
			
		||||
Elektrobit Automotive GmbH
 | 
			
		||||
Eric Cornelius
 | 
			
		||||
Erwan Chaussy
 | 
			
		||||
etcimon
 | 
			
		||||
Evgeny Pokhilko
 | 
			
		||||
Fabian Weissberg
 | 
			
		||||
Falko Strenzke (cryptosource GmbH)
 | 
			
		||||
Felix Yan
 | 
			
		||||
FlexSecure GmbH
 | 
			
		||||
Florent Le Coz
 | 
			
		||||
Francis Dupont
 | 
			
		||||
Frank Schoenmann
 | 
			
		||||
Google Inc
 | 
			
		||||
Gustavo Serra Scalet
 | 
			
		||||
guywithcrookedface
 | 
			
		||||
Hannes Rantzsch
 | 
			
		||||
Harry Reimann
 | 
			
		||||
Hegedüs Márton Csaba
 | 
			
		||||
Hubert Bugaj
 | 
			
		||||
ilovezfs
 | 
			
		||||
J08nY
 | 
			
		||||
Jack Lloyd
 | 
			
		||||
Jeffrey Walton
 | 
			
		||||
Joel Low
 | 
			
		||||
joerg
 | 
			
		||||
Jose Luis Pereira (Fyde Inc.)
 | 
			
		||||
Juraj Somorovsky (Hackmanit GmbH)
 | 
			
		||||
Justin Karneges
 | 
			
		||||
Kai Michaelis (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
Kirill A. Korinsky
 | 
			
		||||
Konstantinos Kolelis
 | 
			
		||||
Krzysztof Kwiatkowski
 | 
			
		||||
Lauri Nurmi
 | 
			
		||||
Luca Piccarreta
 | 
			
		||||
Manuel Glaser (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
Manuel Hartl
 | 
			
		||||
Marcus Brinkmann
 | 
			
		||||
Markus Wanner
 | 
			
		||||
Martin Doering
 | 
			
		||||
Matej Kenda (TopIT d.o.o.)
 | 
			
		||||
Mathieu Souchaud
 | 
			
		||||
Matthew Gregan
 | 
			
		||||
Matthias Gierlings (Hackmanit GmbH)
 | 
			
		||||
Matt Johnston
 | 
			
		||||
Michael Boric (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
Nathan Hourt
 | 
			
		||||
neXenio GmbH
 | 
			
		||||
Nicolas Sendrier
 | 
			
		||||
Nuno Goncalves
 | 
			
		||||
Ori Peleg
 | 
			
		||||
Patrick Sona
 | 
			
		||||
Patrick Wildt
 | 
			
		||||
Patrik Fiedler
 | 
			
		||||
Peter J Jones
 | 
			
		||||
Philippe Lieser (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
Philipp Weber (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
Projet SECRET, INRIA, Rocquencourt
 | 
			
		||||
René Korthaus (Rohde & Schwarz Cybersecurity)
 | 
			
		||||
René Meusel
 | 
			
		||||
Ribose Inc
 | 
			
		||||
Robert Dailey
 | 
			
		||||
Ryuhei Mori
 | 
			
		||||
schregger
 | 
			
		||||
Sergii Cherkavskyi
 | 
			
		||||
seu
 | 
			
		||||
Shlomi Fish
 | 
			
		||||
Simon Cogliani
 | 
			
		||||
Simon Warta (Kullo GmbH)
 | 
			
		||||
slaviber
 | 
			
		||||
souch
 | 
			
		||||
t0b3
 | 
			
		||||
tcely
 | 
			
		||||
Technische Universitat Darmstadt
 | 
			
		||||
Tim Oesterreich
 | 
			
		||||
Tobias @neverhub
 | 
			
		||||
Tomasz Frydrych
 | 
			
		||||
Uri Blumenthal
 | 
			
		||||
Vaclav Ovsik
 | 
			
		||||
Volker Aßmann
 | 
			
		||||
Yuri
 | 
			
		||||
Yves Jerschow
 | 
			
		||||
Zoltan Gyarmati
 | 
			
		||||
0xdefaced
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,441 +0,0 @@
 | 
			
		||||
Command Line Interface
 | 
			
		||||
========================================
 | 
			
		||||
.. highlight:: sh
 | 
			
		||||
 | 
			
		||||
Outline
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
The ``botan`` program is a command line tool for using a broad variety
 | 
			
		||||
of functions of the Botan library in the shell.
 | 
			
		||||
 | 
			
		||||
All commands follow the syntax ``botan <command> <command-options>``.
 | 
			
		||||
 | 
			
		||||
If ``botan`` is run with an unknown command, or without any command, or with the
 | 
			
		||||
``--help`` option, all available commands will be printed. If a particular
 | 
			
		||||
command is run with the ``--help`` option (like ``botan <command> --help``)
 | 
			
		||||
some information about the usage of the command is printed.
 | 
			
		||||
 | 
			
		||||
Starting in version 2.9, commands that take a passphrase (such as
 | 
			
		||||
``gen_bcrypt`` or ``pkcs8``) will also accept the literal ``-`` to mean
 | 
			
		||||
ask for the passphrase on the terminal. If supported by the operating
 | 
			
		||||
system, echo will be disabled while reading the passphrase.
 | 
			
		||||
 | 
			
		||||
Most arguments that take a path to a file will also accept the literal ``-``
 | 
			
		||||
to mean the file content should be read from STDIN instead.
 | 
			
		||||
 | 
			
		||||
All options for the command line are displayed in the summary line,
 | 
			
		||||
and in the help output. All options are, as the name suggests,
 | 
			
		||||
optional, and the default values are shown. For example ``hash file``
 | 
			
		||||
prints the SHA-256 of the file encoded as hex, while
 | 
			
		||||
``hash --format=base64 --algo=SHA-384 file`` prints the base64 encoded
 | 
			
		||||
SHA-384 hash of the same file.
 | 
			
		||||
 | 
			
		||||
Hash Function
 | 
			
		||||
----------------
 | 
			
		||||
``hash --algo=SHA-256 --buf-size=4096 --no-fsname --format=hex *files``
 | 
			
		||||
  Compute the *algo* digest over the data in any number of *files*. If
 | 
			
		||||
  no files are listed on the command line, the input source defaults
 | 
			
		||||
  to standard input. Unless the ``--no-fsname`` option is given, the
 | 
			
		||||
  filename is printed alongside the hash, in the style of tools such
 | 
			
		||||
  as ``sha256sum``.
 | 
			
		||||
 | 
			
		||||
Password Hash
 | 
			
		||||
----------------
 | 
			
		||||
``gen_argon2 --mem=65536 --p=1 --t=1 password``
 | 
			
		||||
  Calculate the Argon2 password digest of *password*. *mem* is the amount of
 | 
			
		||||
  memory to use in Kb, *p* the parallelization parameter and *t* the number of
 | 
			
		||||
  iterations to use.
 | 
			
		||||
 | 
			
		||||
``check_argon2 password hash``
 | 
			
		||||
  Checks if the Argon2 hash of the passed *password* equals the passed *hash* value.
 | 
			
		||||
 | 
			
		||||
``gen_bcrypt --work-factor=12 password``
 | 
			
		||||
  Calculate the bcrypt password digest of *password*. *work-factor* is an
 | 
			
		||||
  integer between 4 and 18.  A higher *work-factor* value results in a
 | 
			
		||||
  more expensive hash calculation.
 | 
			
		||||
 | 
			
		||||
``check_bcrypt password hash``
 | 
			
		||||
  Checks if the bcrypt hash of the passed *password* equals the passed *hash* value.
 | 
			
		||||
 | 
			
		||||
``pbkdf_tune --algo=Scrypt --max-mem=256 --output-len=32 --check *times``
 | 
			
		||||
  Tunes the PBKDF algorithm specified with ``--algo=`` for the given *times*.
 | 
			
		||||
 | 
			
		||||
HMAC
 | 
			
		||||
----------------
 | 
			
		||||
``hmac --hash=SHA-256 --buf-size=4096 --no-fsname key files``
 | 
			
		||||
  Compute the HMAC tag with the cryptographic hash function *hash*
 | 
			
		||||
  using the key in file *key* over the data in *files*. *files*
 | 
			
		||||
  defaults to STDIN. Unless the ``--no-fsname`` option is given, the
 | 
			
		||||
  filename is printed alongside the HMAC value.
 | 
			
		||||
 | 
			
		||||
Encryption
 | 
			
		||||
----------------
 | 
			
		||||
``cipher --buf-size=4096 --decrypt --cipher= --key= --nonce= --ad=``
 | 
			
		||||
 | 
			
		||||
  Encrypt a given file with the specified *cipher*, eg "AES-256/GCM".
 | 
			
		||||
  If ``--decrypt`` is provided the file is decrypted instead.
 | 
			
		||||
 | 
			
		||||
Public Key Cryptography
 | 
			
		||||
-------------------------------------
 | 
			
		||||
``keygen --algo=RSA --params= --passphrase= --cipher= --pbkdf= --pbkdf-ms=300 --provider= --der-out``
 | 
			
		||||
  Generate a PKCS #8 *algo* private key. If *der-out* is passed, the pair is BER
 | 
			
		||||
  encoded.  Otherwise, PEM encoding is used. To protect the PKCS #8 formatted
 | 
			
		||||
  key, it is recommended to encrypt it with a provided *passphrase*.
 | 
			
		||||
 | 
			
		||||
  If a passphrase is used, *cipher* specifies the name of the desired encryption
 | 
			
		||||
  algorithm (such as "AES-256/CBC", or leave empty to use a default), and
 | 
			
		||||
  *pbkdf* can be used to specify the password hashing mechanism (either a hash
 | 
			
		||||
  such as "SHA-256" to select PBKDF2, or "Scrypt").
 | 
			
		||||
 | 
			
		||||
  The cipher mode must have an object identifier defined, this allows use of
 | 
			
		||||
  ciphers such as AES, Twofish, Serpent, and SM4. Ciphers in CBC, GCM, and SIV
 | 
			
		||||
  modes are supported. However most other implementations support only AES or
 | 
			
		||||
  3DES in CBC mode.
 | 
			
		||||
 | 
			
		||||
  If encryption is used, the parameter *pbkdf-ms* controls how long the password
 | 
			
		||||
  hashing function will run to derive the encryption key from the passed
 | 
			
		||||
  *passphrase*.
 | 
			
		||||
 | 
			
		||||
  Algorithm specific parameters, as the desired bit length of an RSA key, can be
 | 
			
		||||
  passed with *params*.
 | 
			
		||||
 | 
			
		||||
    - For RSA *params* specifies the bit length of the RSA modulus. It defaults to 3072.
 | 
			
		||||
    - For DH *params* specifies the DH parameters. It defaults to modp/ietf/2048.
 | 
			
		||||
    - For DSA *params* specifies the DSA parameters. It defaults to dsa/botan/2048.
 | 
			
		||||
    - For EC algorithms *params* specifies the elliptic curve. It defaults to secp256r1.
 | 
			
		||||
 | 
			
		||||
``pkcs8 --pass-in= --pub-out --der-out --pass-out= --cipher= --pbkdf= --pbkdf-ms=300 key``
 | 
			
		||||
 | 
			
		||||
  Open a PKCS #8 formatted key at *key*. If *key* is encrypted, the passphrase
 | 
			
		||||
  must be passed as *pass-in*. It is possible to (re)encrypt the read key with
 | 
			
		||||
  the passphrase passed as *pass-out*. The parameters *cipher*, *pbkdf*, and
 | 
			
		||||
  *pbkdf-ms* work similarly to ``keygen``.
 | 
			
		||||
 | 
			
		||||
``sign --der-format --passphrase= --hash=SHA-256 --padding= --provider= key file``
 | 
			
		||||
 | 
			
		||||
  Sign the data in *file* using the PKCS #8 private key *key* and cryptographic
 | 
			
		||||
  hash *hash*. If *key* is encrypted, the used passphrase must be passed as
 | 
			
		||||
  *pass-in*.
 | 
			
		||||
 | 
			
		||||
  The *padding* option can be used to control padding for algorithms that have
 | 
			
		||||
  divergent methods; this mostly applies to RSA. For RSA, if the option is not
 | 
			
		||||
  specified PSS signatures are used. You can select generating a PKCS #1 v1.5
 | 
			
		||||
  formatted signature instead by providing ``--padding=PKCS1v15``.
 | 
			
		||||
 | 
			
		||||
  For ECDSA and DSA, the option ``--der-format`` outputs the signature as an
 | 
			
		||||
  ASN.1 encoded blob. Some other tools (including ``openssl``) default to this
 | 
			
		||||
  format. This option does not make sense for other algorithms such as RSA.
 | 
			
		||||
 | 
			
		||||
  The signature is formatted for your screen using base64.
 | 
			
		||||
 | 
			
		||||
``verify --der-format --hash=SHA-256 --padding= pubkey file signature``
 | 
			
		||||
  Verify the authenticity of the data in *file* with the provided signature
 | 
			
		||||
  *signature* and the public key *pubkey*. Similarly to the signing process,
 | 
			
		||||
  *padding* specifies the padding scheme and *hash* the cryptographic hash
 | 
			
		||||
  function to use.
 | 
			
		||||
 | 
			
		||||
``gen_dl_group --pbits=1024 --qbits=0 --seed= --type=subgroup``
 | 
			
		||||
  Generate ANSI X9.42 encoded Diffie-Hellman group parameters.
 | 
			
		||||
 | 
			
		||||
    - If *type=subgroup* is passed, the size of the prime subgroup q is sampled
 | 
			
		||||
      as a prime of *qbits* length and p is *pbits* long. If *qbits* is not
 | 
			
		||||
      passed, its length is estimated from *pbits* as described in RFC 3766.
 | 
			
		||||
    - If *type=strong* is passed, p is sampled as a safe prime with length
 | 
			
		||||
      *pbits* and the prime subgroup has size q with *pbits*-1 length.
 | 
			
		||||
    - If *type=dsa* is used, p and q are generated by the algorithm specified in
 | 
			
		||||
      FIPS 186-4. If the ``--seed`` parameter is used, it allows to select the
 | 
			
		||||
      seed value, instead of one being randomly generated. If the seed does not
 | 
			
		||||
      in fact generate a valid DSA group, the command will fail.
 | 
			
		||||
 | 
			
		||||
``dl_group_info --pem name``
 | 
			
		||||
  Print raw Diffie-Hellman parameters (p,g) of the standardized DH group
 | 
			
		||||
  *name*. If *pem* is set, the X9.42 encoded group is printed.
 | 
			
		||||
 | 
			
		||||
``ec_group_info --pem name``
 | 
			
		||||
  Print raw elliptic curve domain parameters of the standardized curve *name*. If
 | 
			
		||||
  *pem* is set, the encoded domain is printed.
 | 
			
		||||
 | 
			
		||||
``pk_encrypt --aead=AES-256/GCM rsa_pubkey datafile``
 | 
			
		||||
  Encrypts ``datafile`` using the specified AEAD algorithm, under a key protected
 | 
			
		||||
  by the specified RSA public key.
 | 
			
		||||
 | 
			
		||||
``pk_decrypt rsa_privkey datafile``
 | 
			
		||||
  Decrypts a file encrypted with ``pk_encrypt``. If the key is encrypted using a
 | 
			
		||||
  password, it will be prompted for on the terminal.
 | 
			
		||||
 | 
			
		||||
``fingerprint --no-fsname --algo=SHA-256 *keys``
 | 
			
		||||
  Calculate the public key fingerprint of the *keys*.
 | 
			
		||||
 | 
			
		||||
``pk_workfactor --type=rsa bits``
 | 
			
		||||
  Provide an estimate of the strength of a public key based on it's size.
 | 
			
		||||
  ``--type=`` can be "rsa", "dl" or "dl_exp".
 | 
			
		||||
 | 
			
		||||
X.509
 | 
			
		||||
----------------------------------------------
 | 
			
		||||
 | 
			
		||||
``gen_pkcs10 key CN --country= --organization= --ca --path-limit=1 --email= --dns= --ext-ku= --key-pass= --hash=SHA-256  --emsa=``
 | 
			
		||||
  Generate a PKCS #10 certificate signing request (CSR) using the passed PKCS #8
 | 
			
		||||
  private key *key*. If the private key is encrypted, the decryption passphrase
 | 
			
		||||
  *key-pass* has to be passed.*emsa* specifies the padding scheme to be used
 | 
			
		||||
  when calculating the signature.
 | 
			
		||||
 | 
			
		||||
    - For RSA keys EMSA4 (RSA-PSS) is the default scheme.
 | 
			
		||||
    - For ECDSA, DSA, ECGDSA, ECKCDSA and GOST-34.10 keys *emsa* defaults to EMSA1.
 | 
			
		||||
 | 
			
		||||
``gen_self_signed key CN --country= --dns= --organization= --email= --path-limit=1 --days=365 --key-pass= --ca --hash=SHA-256 --emsa= --der``
 | 
			
		||||
  Generate a self signed X.509 certificate using the PKCS #8 private key
 | 
			
		||||
  *key*. If the private key is encrypted, the decryption passphrase *key-pass*
 | 
			
		||||
  has to be passed. If *ca* is passed, the certificate is marked for certificate
 | 
			
		||||
  authority (CA) usage. *emsa* specifies the padding scheme to be used when
 | 
			
		||||
  calculating the signature.
 | 
			
		||||
 | 
			
		||||
    - For RSA keys EMSA4 (RSA-PSS) is the default scheme.
 | 
			
		||||
    - For ECDSA, DSA, ECGDSA, ECKCDSA and GOST-34.10 keys *emsa* defaults to EMSA1.
 | 
			
		||||
 | 
			
		||||
``sign_cert --ca-key-pass= --hash=SHA-256 --duration=365 --emsa= ca_cert ca_key pkcs10_req``
 | 
			
		||||
  Create a CA signed X.509 certificate from the information contained in the
 | 
			
		||||
  PKCS #10 CSR *pkcs10_req*. The CA certificate is passed as *ca_cert* and the
 | 
			
		||||
  respective PKCS #8 private key as *ca_key*. If the private key is encrypted,
 | 
			
		||||
  the decryption passphrase *ca-key-pass* has to be passed. The created
 | 
			
		||||
  certificate has a validity period of *duration* days. *emsa* specifies the
 | 
			
		||||
  padding scheme to be used when calculating the signature. *emsa* defaults to
 | 
			
		||||
  the padding scheme used in the CA certificate.
 | 
			
		||||
 | 
			
		||||
``ocsp_check --timeout=3000 subject issuer``
 | 
			
		||||
  Verify an X.509 certificate against the issuers OCSP responder. Pass the
 | 
			
		||||
  certificate to validate as *subject* and the CA certificate as *issuer*.
 | 
			
		||||
 | 
			
		||||
``cert_info --fingerprint file``
 | 
			
		||||
  Parse X.509 PEM certificate and display data fields. If ``--fingerprint`` is
 | 
			
		||||
  used, the certificate's fingerprint is also printed.
 | 
			
		||||
 | 
			
		||||
``cert_verify subject *ca_certs``
 | 
			
		||||
  Verify if the provided X.509 certificate *subject* can be successfully
 | 
			
		||||
  validated. The list of trusted CA certificates is passed with *ca_certs*,
 | 
			
		||||
  which is a list of one or more certificates.
 | 
			
		||||
 | 
			
		||||
``trust_roots --dn --dn-only --display``
 | 
			
		||||
  List the certificates in the system trust store.
 | 
			
		||||
 | 
			
		||||
TLS Server/Client
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
The ``--policy=`` argument of the TLS commands specifies the TLS policy to use.
 | 
			
		||||
The policy can be any of the strings "default", "suiteb_128", "suiteb_192",
 | 
			
		||||
"bsi", "strict", or "all" to denote built-in policies, or it can name a file
 | 
			
		||||
from which a policy description will be read.
 | 
			
		||||
 | 
			
		||||
``tls_ciphers --policy=default --version=tls1.2``
 | 
			
		||||
  Prints the list of ciphersuites that will be offered under a particular
 | 
			
		||||
  policy/version.
 | 
			
		||||
 | 
			
		||||
``tls_client host --port=443 --print-certs --policy=default --tls1.0 --tls1.1 --tls1.2 --skip-system-cert-store --trusted-cas= --session-db= --session-db-pass= --next-protocols= --type=tcp --client-cert= --client-cert-key=``
 | 
			
		||||
  Implements a testing TLS client, which connects to *host* via TCP or UDP on
 | 
			
		||||
  port *port*. The TLS version can be set with the flags *tls1.0*, *tls1.1* and
 | 
			
		||||
  *tls1.2* of which the lowest specified version is automatically chosen.  If
 | 
			
		||||
  none of the TLS version flags is set, the latest supported version is
 | 
			
		||||
  chosen. The client honors the TLS policy specified with *policy* and
 | 
			
		||||
  prints all certificates in the chain, if *print-certs* is passed.
 | 
			
		||||
  *next-protocols* is a comma separated list and specifies the protocols to
 | 
			
		||||
  advertise with Application-Layer Protocol Negotiation (ALPN).
 | 
			
		||||
  Pass a path to a client certificate PEM and unencrypted PKCS8 encoded private
 | 
			
		||||
  key if client authentication is required.
 | 
			
		||||
 | 
			
		||||
``tls_server cert key --port=443 --type=tcp --policy=default --dump-traces= --max-clients=0 --socket-id=0``
 | 
			
		||||
  Implements a testing TLS server, which allows TLS clients to connect and which
 | 
			
		||||
  echos any data that is sent to it. Binds to either TCP or UDP on port
 | 
			
		||||
  *port*. The server uses the certificate *cert* and the respective PKCS #8
 | 
			
		||||
  private key *key*. The server honors the TLS policy specified with *policy*.
 | 
			
		||||
  *socket-id* is only available on FreeBSD and sets the *so_user_cookie* value
 | 
			
		||||
  of the used socket.
 | 
			
		||||
 | 
			
		||||
``tls_http_server cert key --port=443 --policy=default --threads=0 --max-clients=0 --session-db --session-db-pass=``
 | 
			
		||||
  Only available if Boost.Asio support was enabled. Provides a simple HTTP server
 | 
			
		||||
  which replies to all requests with an informational text output. The server
 | 
			
		||||
  honors the TLS policy specified with *policy*.
 | 
			
		||||
 | 
			
		||||
``tls_proxy listen_port target_host target_port server_cert server_key--policy=default --threads=0 --max-clients=0 --session-db= --session-db-pass=``
 | 
			
		||||
  Only available if Boost.Asio support was enabled. Listens on a port and
 | 
			
		||||
  forwards all connects to a target server specified at
 | 
			
		||||
  ``target_host`` and ``target_port``.
 | 
			
		||||
 | 
			
		||||
``tls_client_hello --hex input``
 | 
			
		||||
  Parse and print a TLS client hello message.
 | 
			
		||||
 | 
			
		||||
Number Theory
 | 
			
		||||
-----------------------
 | 
			
		||||
``is_prime --prob=56 n``
 | 
			
		||||
  Test if the integer *n* is composite or prime with a Miller-Rabin primality test with *(prob+2)/2* iterations.
 | 
			
		||||
 | 
			
		||||
``factor n``
 | 
			
		||||
  Factor the integer *n* using a combination of trial division by small primes, and Pollard's Rho algorithm.
 | 
			
		||||
  It can in reasonable time factor integers up to 110 bits or so.
 | 
			
		||||
 | 
			
		||||
``gen_prime --count=1 bits``
 | 
			
		||||
  Samples *count* primes with a length of *bits* bits.
 | 
			
		||||
 | 
			
		||||
``mod_inverse n mod``
 | 
			
		||||
  Calculates a modular inverse.
 | 
			
		||||
 | 
			
		||||
PSK Database
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
The PSK database commands are only available if sqlite3 support was compiled in.
 | 
			
		||||
 | 
			
		||||
``psk_set db db_key name psk``
 | 
			
		||||
  Using the PSK database named db and encrypting under the (hex) key ``db_key``,
 | 
			
		||||
  save the provided psk (also hex) under ``name``::
 | 
			
		||||
 | 
			
		||||
    $ botan psk_set psk.db deadba55 bunny f00fee
 | 
			
		||||
 | 
			
		||||
``psk_get db db_key name``
 | 
			
		||||
  Get back a value saved with ``psk_set``::
 | 
			
		||||
 | 
			
		||||
    $ botan psk_get psk.db deadba55 bunny
 | 
			
		||||
    f00fee
 | 
			
		||||
 | 
			
		||||
``psk_list db db_key``
 | 
			
		||||
  List all values saved to the database under the given key::
 | 
			
		||||
 | 
			
		||||
    $ botan psk_list psk.db deadba55
 | 
			
		||||
    bunny
 | 
			
		||||
 | 
			
		||||
Secret Sharing
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
Split a file into several shares.
 | 
			
		||||
 | 
			
		||||
``tss_split M N data_file --id= --share-prefix=share --share-suffix=tss --hash=SHA-256``
 | 
			
		||||
  Split a file into ``N`` pieces any ``M`` of which suffices to
 | 
			
		||||
  recover the original input. The ID allows specifying a unique key ID
 | 
			
		||||
  which may be up to 16 bytes long, this ensures that shares can be
 | 
			
		||||
  uniquely matched.  If not specified a random 16 byte value is
 | 
			
		||||
  used. A checksum can be appended to the data to help verify correct
 | 
			
		||||
  recovery, this can be disabled using ``--hash=None``.
 | 
			
		||||
 | 
			
		||||
``tss_recover *shares``
 | 
			
		||||
  Recover some data split by ``tss_split``. If insufficient number of
 | 
			
		||||
  shares are provided an error is printed.
 | 
			
		||||
 | 
			
		||||
Data Encoding/Decoding
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
``base32_dec file``
 | 
			
		||||
  Decode *file* to Base32.
 | 
			
		||||
 | 
			
		||||
``base32_enc file``
 | 
			
		||||
  Encode Base32 encoded *file*.
 | 
			
		||||
 | 
			
		||||
``base58_enc --check file``
 | 
			
		||||
  Encode *file* to Base58. If ``--check`` is provided Base58Check is used.
 | 
			
		||||
 | 
			
		||||
``base58_dec --check file``
 | 
			
		||||
  Decode Base58 encoded *file*. If ``--check`` is provided Base58Check is used.
 | 
			
		||||
 | 
			
		||||
``base64_dec file``
 | 
			
		||||
  Decode *file* to Base64.
 | 
			
		||||
 | 
			
		||||
``base64_enc file``
 | 
			
		||||
  Encode Base64 encoded *file*.
 | 
			
		||||
 | 
			
		||||
``hex_dec file``
 | 
			
		||||
  Decode *file* to Hex.
 | 
			
		||||
 | 
			
		||||
``hex_enc file``
 | 
			
		||||
  Encode Hex encoded *file*.
 | 
			
		||||
 | 
			
		||||
Forward Error Correction
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
``fec_encode --suffix=fec --prefix= --output-dir= k n input``
 | 
			
		||||
  Split a given ``input`` file into ``n`` shares where ``k`` shares are required
 | 
			
		||||
  to recreate the original file. The output shares a written to files with the
 | 
			
		||||
  file extension specified in ``--suffix`` and either the original file name or
 | 
			
		||||
  the one specified in ``--prefix``. The output directory is either equal to the
 | 
			
		||||
  input file's directory or the one specified in ``--output-dir``.
 | 
			
		||||
 | 
			
		||||
``fec_decode *shares``
 | 
			
		||||
  If given enough shares, this will output the original input file's content to
 | 
			
		||||
  stdout. Otherwise an error is printed on stderr.
 | 
			
		||||
 | 
			
		||||
``fec_info share``
 | 
			
		||||
  Given a single share this will print information about the share.
 | 
			
		||||
  For instance: ``FEC share 4/4 with 3 needed for recovery``
 | 
			
		||||
 | 
			
		||||
Miscellaneous Commands
 | 
			
		||||
-------------------------------------
 | 
			
		||||
``version --full``
 | 
			
		||||
  Print the version number. If option ``--full`` is provided,
 | 
			
		||||
  additional details are printed.
 | 
			
		||||
 | 
			
		||||
``has_command cmd``
 | 
			
		||||
  Test if the command *cmd* is available.
 | 
			
		||||
 | 
			
		||||
``config info_type``
 | 
			
		||||
  Prints build information, useful for applications which want to
 | 
			
		||||
  build against the library.  The ``info_type`` argument can be any of
 | 
			
		||||
  ``prefix``, ``cflags``, ``ldflags``, or ``libs``. This is
 | 
			
		||||
  similar to information provided by the ``pkg-config`` tool.
 | 
			
		||||
 | 
			
		||||
``cpuid``
 | 
			
		||||
  List available processor flags (AES-NI, SIMD extensions, ...).
 | 
			
		||||
 | 
			
		||||
``cpu_clock --test-duration=500``
 | 
			
		||||
  Estimate the speed of the CPU cycle counter.
 | 
			
		||||
 | 
			
		||||
``asn1print --skip-context-specific --print-limit=4096 --bin-limit=2048 --max-depth=64 --pem file```
 | 
			
		||||
  Decode and print *file* with ASN.1 Basic Encoding Rules (BER). If flag ``--pem`` is
 | 
			
		||||
  used, or the filename ends in ``.pem``, then PEM encoding is assumed. Otherwise
 | 
			
		||||
  the input is assumed to be binary DER/BER.
 | 
			
		||||
 | 
			
		||||
``http_get --redirects=1 --timeout=3000 url``
 | 
			
		||||
  Retrieve resource from the passed http *url*.
 | 
			
		||||
 | 
			
		||||
``speed --msec=500 --format=default --ecc-groups= --provider= --buf-size=1024 --clear-cpuid= --cpu-clock-speed=0 --cpu-clock-ratio=1.0 *algos``
 | 
			
		||||
  Measures the speed of the passed *algos*. If no *algos* are passed all
 | 
			
		||||
  available speed tests are executed. *msec* (in milliseconds) sets the period
 | 
			
		||||
  of measurement for each algorithm. The *buf-size* option allows testing the
 | 
			
		||||
  same algorithm on one or more input sizes, for example
 | 
			
		||||
  ``speed --buf-size=136,1500 AES-128/GCM`` tests the performance of GCM for
 | 
			
		||||
  small and large packet sizes.
 | 
			
		||||
  *format* can be "default", "table" or "json".
 | 
			
		||||
 | 
			
		||||
``timing_test test_type --test-data-file= --test-data-dir=src/tests/data/timing --warmup-runs=1000 --measurement-runs=10000``
 | 
			
		||||
  Run various timing side channel tests.
 | 
			
		||||
 | 
			
		||||
``rng --format=hex --system --rdrand --auto --entropy --drbg --drbg-seed= *bytes``
 | 
			
		||||
  Sample *bytes* random bytes from the specified random number generator. If
 | 
			
		||||
  *system* is set, the system RNG is used. If *rdrand* is set, the hardware
 | 
			
		||||
  RDRAND instruction is used. If *auto* is set, AutoSeeded_RNG is used, seeded
 | 
			
		||||
  with the system RNG if available or the global entropy source otherwise. If
 | 
			
		||||
  *entropy* is set, AutoSeeded_RNG is used, seeded with the global entropy
 | 
			
		||||
  source. If *drbg* is set, HMAC_DRBG is used seeded with *drbg-seed*.
 | 
			
		||||
 | 
			
		||||
``entropy --truncate-at=128 source``
 | 
			
		||||
  Sample a raw entropy source.
 | 
			
		||||
 | 
			
		||||
``cc_encrypt CC passphrase --tweak=``
 | 
			
		||||
  Encrypt the passed valid credit card number *CC* using FPE encryption and the
 | 
			
		||||
  passphrase *passphrase*. The key is derived from the passphrase using PBKDF2
 | 
			
		||||
  with SHA256. Due to the nature of FPE, the ciphertext is also a credit card
 | 
			
		||||
  number with a valid checksum. *tweak* is public and parameterizes the
 | 
			
		||||
  encryption function.
 | 
			
		||||
 | 
			
		||||
``cc_decrypt CC passphrase --tweak=``
 | 
			
		||||
  Decrypt the passed valid ciphertext *CC* using FPE decryption with
 | 
			
		||||
  the passphrase *passphrase* and the tweak *tweak*.
 | 
			
		||||
 | 
			
		||||
``roughtime_check --raw-time chain-file``
 | 
			
		||||
  Parse and validate a Roughtime chain file.
 | 
			
		||||
 | 
			
		||||
``roughtime --raw-time --chain-file=roughtime-chain --max-chain-size=128 --check-local-clock=60 --host= --pubkey= --servers-file=``
 | 
			
		||||
  Retrieve time from a Roughtime server and store it in a chain file.
 | 
			
		||||
 | 
			
		||||
``uuid``
 | 
			
		||||
  Generate and print a random UUID.
 | 
			
		||||
 | 
			
		||||
``compress --type=gzip --level=6 --buf-size=8192 file``
 | 
			
		||||
  Compress a given file.
 | 
			
		||||
 | 
			
		||||
``decompress --buf-size=8192 file``
 | 
			
		||||
  Decompress a given compressed archive.
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Contents
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
 | 
			
		||||
   index
 | 
			
		||||
   goals
 | 
			
		||||
   support
 | 
			
		||||
   building
 | 
			
		||||
   sem_ver
 | 
			
		||||
   migration_guide
 | 
			
		||||
   api_ref/contents
 | 
			
		||||
   cli
 | 
			
		||||
   deprecated
 | 
			
		||||
   roadmap
 | 
			
		||||
   credits
 | 
			
		||||
   abi
 | 
			
		||||
   packaging
 | 
			
		||||
   security
 | 
			
		||||
   side_channels
 | 
			
		||||
   dev_ref/contents
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :hidden:
 | 
			
		||||
 | 
			
		||||
   old_news
 | 
			
		||||
@@ -1,179 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Credits
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
This is at least a partial credits-file of people that have contributed
 | 
			
		||||
to botan. It is sorted by name and formatted to allow easy grepping
 | 
			
		||||
and beautification by scripts. The fields are name (N), email (E),
 | 
			
		||||
web-address (W), PGP key ID and fingerprint (P), description (D),
 | 
			
		||||
snail-mail address (S), and Bitcoin address (B).
 | 
			
		||||
 | 
			
		||||
.. highlight:: none
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
  N: Alexander Bluhm
 | 
			
		||||
  W: https://www.genua.de/
 | 
			
		||||
  P: 1E3B BEA4 6C20 EA00 2FFC  DE4D C5F4 83AD DEE8 6380
 | 
			
		||||
  D: improve support for OpenBSD
 | 
			
		||||
  S: Kirchheim, Germany
 | 
			
		||||
 | 
			
		||||
  N: Charles Brockman
 | 
			
		||||
  W: http://www.securitygenetics.com/
 | 
			
		||||
  D: documentation editing
 | 
			
		||||
  S: Oregon, USA
 | 
			
		||||
 | 
			
		||||
  N: Simon Cogliani
 | 
			
		||||
  E: simon.cogliani@tanker.io
 | 
			
		||||
  W: https://www.tanker.io/
 | 
			
		||||
  P: EA73 D0AF 5A81 A61A 8931  C2CA C9AB F2E4 3820 4F25
 | 
			
		||||
  D: Getting keystream of ChaCha
 | 
			
		||||
  S: Paris, France
 | 
			
		||||
 | 
			
		||||
  N: Martin Doering
 | 
			
		||||
  E: doering@cdc.informatik.tu-darmstadt.de
 | 
			
		||||
  D: GF(p) arithmetic
 | 
			
		||||
 | 
			
		||||
  N: Olivier de Gaalon
 | 
			
		||||
  D: SQLite encryption codec (src/contrib/sqlite)
 | 
			
		||||
 | 
			
		||||
  N: Matthias Gierlings
 | 
			
		||||
  E: matthias.gierlings@hackmanit.de
 | 
			
		||||
  W: https://www.hackmanit.de/
 | 
			
		||||
  P: 39E0 D270 19A4 B356 05D0 29AE 1BD3 49CF 744A 02FF
 | 
			
		||||
  D: GMAC, Extended Hash-Based Signatures (XMSS)
 | 
			
		||||
  S: Bochum, Germany
 | 
			
		||||
 | 
			
		||||
  N: Matthew Gregan
 | 
			
		||||
  D: Binary file I/O support, allocator fixes
 | 
			
		||||
 | 
			
		||||
  N: Hany Greiss
 | 
			
		||||
  D: Windows porting
 | 
			
		||||
 | 
			
		||||
  N: Manuel Hartl
 | 
			
		||||
  E: hartl@flexsecure.de
 | 
			
		||||
  W: http://www.flexsecure.de/
 | 
			
		||||
  D: ECDSA, ECDH
 | 
			
		||||
 | 
			
		||||
  N: Yves Jerschow
 | 
			
		||||
  E: yves.jerschow@uni-duesseldorf.de
 | 
			
		||||
  D: Optimizations for memory load/store and HMAC
 | 
			
		||||
  D: Support for IPv4 addresses in X.509 alternative names
 | 
			
		||||
  S: Germany
 | 
			
		||||
 | 
			
		||||
  N: Matt Johnston
 | 
			
		||||
  D: Allocator fixes and optimizations, decompressor fixes
 | 
			
		||||
 | 
			
		||||
  N: Peter J. Jones
 | 
			
		||||
  E: pjones@pmade.org
 | 
			
		||||
  D: Bzip2 compression module
 | 
			
		||||
  S: Colorado, USA
 | 
			
		||||
 | 
			
		||||
  N: Justin Karneges
 | 
			
		||||
  D: Qt support modules (mutexes and types), X.509 API design
 | 
			
		||||
 | 
			
		||||
  N: Vojtech Kral
 | 
			
		||||
  E: vojtech@kral.hk
 | 
			
		||||
  D: LZMA compression module
 | 
			
		||||
  S: Czech Republic
 | 
			
		||||
 | 
			
		||||
  N: Matej Kenda
 | 
			
		||||
  E: matej.kenda@topit.si
 | 
			
		||||
  D: Locking in Algo_Registry for Windows OS
 | 
			
		||||
  S: Slovenia
 | 
			
		||||
 | 
			
		||||
  N: René Fischer (formerly Korthaus)
 | 
			
		||||
  E: rene.fischer@rohde-schwarz.com
 | 
			
		||||
  W: https://www.rohde-schwarz.com/cybersecurity
 | 
			
		||||
  P: C196 FF9D 3DDC A5E7 F98C E745 9AD0 F9FA 587E 74D6
 | 
			
		||||
  D: CI, ECGDSA, ECKCDSA
 | 
			
		||||
  S: Bochum, Germany
 | 
			
		||||
 | 
			
		||||
  N: Adam Langley
 | 
			
		||||
  E: agl@imperialviolet.org
 | 
			
		||||
  D: Curve25519
 | 
			
		||||
 | 
			
		||||
  N: Jack Lloyd
 | 
			
		||||
  E: jack@randombit.net
 | 
			
		||||
  W: https://www.randombit.net/
 | 
			
		||||
  P: 3F69 2E64 6D92 3BBE E7AE  9258 5C0F 96E8 4EC1 6D6B
 | 
			
		||||
  B: 1DwxWb2J4vuX4vjsbzaCXW696rZfeamahz
 | 
			
		||||
  D: Original designer/author, maintainer 2001-current
 | 
			
		||||
  S: Vermont, USA
 | 
			
		||||
 | 
			
		||||
  N: Joel Low
 | 
			
		||||
  D: DLL symbol visibility and Windows DLL support in general
 | 
			
		||||
  D: Threaded_Fork
 | 
			
		||||
 | 
			
		||||
  N: Christoph Ludwig
 | 
			
		||||
  E: ludwig@fh-worms.de
 | 
			
		||||
  D: GP(p) arithmetic
 | 
			
		||||
 | 
			
		||||
  N: Vaclav Ovsik
 | 
			
		||||
  E: vaclav.ovsik@i.cz
 | 
			
		||||
  D: Perl XS module (src/contrib/perl-xs)
 | 
			
		||||
 | 
			
		||||
  N: Luca Piccarreta
 | 
			
		||||
  E: luca.piccarreta@gmail.com
 | 
			
		||||
  D: x86/amd64 assembler, BigInt optimizations, Win32 mutex module
 | 
			
		||||
  S: Italy
 | 
			
		||||
 | 
			
		||||
  N: Daniel Seither
 | 
			
		||||
  E: post@tiwoc.de
 | 
			
		||||
  D: iOS support, improved Android support, improved MSVC support
 | 
			
		||||
 | 
			
		||||
  N: Falko Strenzke
 | 
			
		||||
  E: fstrenzke@cryptosource.de
 | 
			
		||||
  W: http://www.cryptosource.de
 | 
			
		||||
  D: McEliece, GF(p) arithmetic, CVC, Shanks-Tonelli algorithm
 | 
			
		||||
  S: Darmstadt, Germany
 | 
			
		||||
 | 
			
		||||
  N: Simon Warta
 | 
			
		||||
  E: simon@kullo.net
 | 
			
		||||
  W: https://www.kullo.net
 | 
			
		||||
  D: Build system
 | 
			
		||||
  S: Germany
 | 
			
		||||
 | 
			
		||||
  N: Philipp Weber
 | 
			
		||||
  E: philipp.weber@rohde-schwarz.com
 | 
			
		||||
  W: https://www.rohde-schwarz.com/cybersecurity
 | 
			
		||||
  D: KDF1-18033, ECIES
 | 
			
		||||
  S: Saarland, Germany
 | 
			
		||||
 | 
			
		||||
  N: Daniel Neus
 | 
			
		||||
  E: daniel.neus@rohde-schwarz.com
 | 
			
		||||
  W: https://www.rohde-schwarz.com/cybersecurity
 | 
			
		||||
  D: CI, PKCS#11, RdSeed, BSI module policy
 | 
			
		||||
  S: Bochum, Germany
 | 
			
		||||
 | 
			
		||||
  N: Erwan Chaussy
 | 
			
		||||
  D: Base32, Base64 matching Base32 implementation
 | 
			
		||||
  S: France
 | 
			
		||||
 | 
			
		||||
  N: Daniel Wyatt (on behalf of Ribose Inc)
 | 
			
		||||
  E: daniel.wyatt@ribose.com
 | 
			
		||||
  W: https://www.ribose.com/
 | 
			
		||||
  D: SM3, Streebog, various minor contributions
 | 
			
		||||
 | 
			
		||||
  N: Rostyslav Khudolii
 | 
			
		||||
  E: rhudoliy@gmail.com
 | 
			
		||||
  D: SRP6 FFI
 | 
			
		||||
  S: Ukraine/Denmark
 | 
			
		||||
 | 
			
		||||
  N: René Meusel
 | 
			
		||||
  E: rene.meusel@rohde-schwarz.com
 | 
			
		||||
  W: https://www.rohde-schwarz.com/cybersecurity
 | 
			
		||||
  D: CI, TLS 1.3, Kyber, Dilithium, SPHINCS+
 | 
			
		||||
  S: Berlin, Germany
 | 
			
		||||
 | 
			
		||||
  N: Philippe Lieser
 | 
			
		||||
  E: philippe.lieser@rohde-schwarz.com
 | 
			
		||||
  W: https://www.rohde-schwarz.com/cybersecurity
 | 
			
		||||
  D: CI, BSI module policy, various minor contributions
 | 
			
		||||
  S: Saarland, Germany
 | 
			
		||||
 | 
			
		||||
  N: Fabian Albert
 | 
			
		||||
  E: fabian.albert@rohde-schwarz.com
 | 
			
		||||
  W: https://www.rohde-schwarz.com/cybersecurity
 | 
			
		||||
  D: SPHINCS+
 | 
			
		||||
  S: Bochum, Germany
 | 
			
		||||
@@ -1,134 +0,0 @@
 | 
			
		||||
Deprecated Features
 | 
			
		||||
========================
 | 
			
		||||
 | 
			
		||||
Certain functionality is deprecated and is likely to be removed in
 | 
			
		||||
a future major release.
 | 
			
		||||
 | 
			
		||||
To help warn users, macros are used to annotate deprecated functions
 | 
			
		||||
and headers. These warnings are enabled by default, but can be
 | 
			
		||||
disabled by defining the macro ``BOTAN_NO_DEPRECATED_WARNINGS`` prior
 | 
			
		||||
to including any Botan headers.
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
    Not all of the functionality which is currently deprecated has an
 | 
			
		||||
    associated warning.
 | 
			
		||||
 | 
			
		||||
If you are using something which is currently deprecated and there
 | 
			
		||||
doesn't seem to be an obvious alternative, contact the developers to
 | 
			
		||||
explain your use case if you want to make sure your code continues to
 | 
			
		||||
work.
 | 
			
		||||
 | 
			
		||||
Platform Support Deprecations
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* Support for building for Windows systems prior to Windows 10 is deprecated.
 | 
			
		||||
 | 
			
		||||
TLS Protocol Deprecations
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The following TLS protocol features are deprecated and will be removed
 | 
			
		||||
in a future major release:
 | 
			
		||||
 | 
			
		||||
- Support for point compression in TLS. This is supported in v1.2 but
 | 
			
		||||
  removed in v1.3. For simplicity it will be removed in v1.2 also.
 | 
			
		||||
 | 
			
		||||
- All CBC mode ciphersuites. This includes all available 3DES ciphersuites.
 | 
			
		||||
  This implies also removing Encrypt-then-MAC extension.
 | 
			
		||||
 | 
			
		||||
- All DHE ciphersuites
 | 
			
		||||
 | 
			
		||||
- Support for renegotiation in TLS v1.2
 | 
			
		||||
 | 
			
		||||
- All ciphersuites using static RSA key exchange
 | 
			
		||||
 | 
			
		||||
- ``Credentials_Manager::psk()`` to provide various TLS-specific keys and
 | 
			
		||||
  secrets, most notably "session-ticket", "dtls-cookie-secret" and the actual
 | 
			
		||||
  TLS PSKs for given identities and hosts. Instead, use the dedicated methods in
 | 
			
		||||
  ``Credentials_Manager`` and do not override the ``psk()`` method any longer.
 | 
			
		||||
 | 
			
		||||
Deprecated Functionality
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
This section lists cryptographic functionality which will be removed
 | 
			
		||||
in a future major release.
 | 
			
		||||
 | 
			
		||||
- Kyber 90s mode is deprecated and will be removed.
 | 
			
		||||
 | 
			
		||||
- Currently it is possible to create an EC_Group with cofactor > 1.
 | 
			
		||||
  None of the builtin groups have composite order, and in the future
 | 
			
		||||
  it will be impossible to create composite order EC_Groups.
 | 
			
		||||
 | 
			
		||||
- Prior to 2.8.0, SM2 algorithms were implemented as two distinct key
 | 
			
		||||
  types, one used for encryption and the other for signatures. In 2.8,
 | 
			
		||||
  the two types were merged. However it is still possible to refer to
 | 
			
		||||
  SM2 using the split names of "SM2_Enc" or "SM2_Sig". In a future major
 | 
			
		||||
  release this will be removed, and only "SM2" will be recognized.
 | 
			
		||||
 | 
			
		||||
- DSA, ECDSA, ECGDSA, ECKCDSA, and GOST-34.10 previously (before Botan 3)
 | 
			
		||||
  required that the hash be named as "EMSA1(HASH_NAME)". This is no longer
 | 
			
		||||
  required. In a future major release, only "HASH_NAME" will be accepted.
 | 
			
		||||
 | 
			
		||||
- Block cipher GOST 28147, Noekeon, Lion
 | 
			
		||||
 | 
			
		||||
- Hash function GOST 34.11-94, Streebog, MD4
 | 
			
		||||
 | 
			
		||||
- GOST 34.10 signature scheme
 | 
			
		||||
 | 
			
		||||
- Stream cipher SHAKE (this does not affect SHAKE used as a HashFunction or XOF)
 | 
			
		||||
 | 
			
		||||
- The utility functions in cryptobox.h
 | 
			
		||||
 | 
			
		||||
- X9.42 KDF
 | 
			
		||||
 | 
			
		||||
- The current McEliece implementation (in ``pubkey/mce``) will be
 | 
			
		||||
  replaced by a more modern code-based KEM from the NIST
 | 
			
		||||
  competition. (Probably the "Classic McEliece" submission.)
 | 
			
		||||
 | 
			
		||||
- DLIES
 | 
			
		||||
 | 
			
		||||
- GCM support for 64-bit tags
 | 
			
		||||
 | 
			
		||||
- Weak or rarely used ECC builtin groups including "secp160k1", "secp160r1",
 | 
			
		||||
  "secp160r2", "secp192k1", "secp224k1",
 | 
			
		||||
  "brainpool160r1", "brainpool192r1", "brainpool224r1", "brainpool320r1",
 | 
			
		||||
  "x962_p192v2", "x962_p192v3", "x962_p239v1", "x962_p239v2", "x962_p239v3".
 | 
			
		||||
 | 
			
		||||
- All built in MODP groups < 2048 bits
 | 
			
		||||
 | 
			
		||||
- Support for explicit ECC curve parameters and ImplicitCA encoded parameters in
 | 
			
		||||
  EC_Group and all users (including X.509 certificates and PKCS#8 private keys).
 | 
			
		||||
 | 
			
		||||
- All pre-created DSA groups
 | 
			
		||||
 | 
			
		||||
- All support for loading, generating or using RSA keys with a public
 | 
			
		||||
  exponent larger than 2**64-1
 | 
			
		||||
 | 
			
		||||
Deprecated Headers
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
  PBKDF headers: ``bcrypt_pbkdf.h``, ``pbkdf2.h``, ``pgp_s2k.h``, ``scrypt.h``,
 | 
			
		||||
  and ``argon2.h``: Use the ``PasswordHash`` interface instead.
 | 
			
		||||
 | 
			
		||||
  Internal implementation headers - seemingly no reason for applications to use:
 | 
			
		||||
  ``curve_gfp.h``,
 | 
			
		||||
  ``reducer.h``,
 | 
			
		||||
  ``tls_algos.h``,
 | 
			
		||||
  ``tls_magic.h``
 | 
			
		||||
 | 
			
		||||
  Utility headers, nominally useful in applications but not a core part of
 | 
			
		||||
  the library API and most are just sufficient for what the library needs
 | 
			
		||||
  to implement other functionality.
 | 
			
		||||
  ``compiler.h``,
 | 
			
		||||
  ``uuid.h``,
 | 
			
		||||
 | 
			
		||||
Other API deprecations
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
- The ``PBKDF`` class is deprecated in favor of ``PasswordHash`` and
 | 
			
		||||
  ``PasswordHashFamily``.
 | 
			
		||||
 | 
			
		||||
- The ``Buffered_Computation`` base class. In a future release the
 | 
			
		||||
  class will be removed, and all of member functions instead declared
 | 
			
		||||
  directly on ``MessageAuthenticationCode`` and ``HashFunction``. So
 | 
			
		||||
  this only affects you if you are directly referencing
 | 
			
		||||
  ``Botan::Buffered_Computation`` in some way.
 | 
			
		||||
@@ -1,440 +0,0 @@
 | 
			
		||||
.. _configure_script:
 | 
			
		||||
 | 
			
		||||
Understanding configure.py
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
.. highlight:: none
 | 
			
		||||
 | 
			
		||||
Botan's build is handled with a custom Python script, ``configure.py``.
 | 
			
		||||
This document tries to explain how configure works.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   You only need to read this if you are modifying the library,
 | 
			
		||||
   or debugging some problem with your build. For how to use it,
 | 
			
		||||
   see :ref:`building`.
 | 
			
		||||
 | 
			
		||||
Build Structure
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
Modules are a group of related source and header files, which can be
 | 
			
		||||
individually enabled or disabled at build time. Modules can depend on
 | 
			
		||||
other modules; if a dependency is not available then the module itself
 | 
			
		||||
is also removed from the list.  Examples of modules in the existing
 | 
			
		||||
codebase are ``asn1`` and ``x509``, Since ``x509`` depends on (among
 | 
			
		||||
other things) ``asn1``, disabling ``asn1`` will also disable ``x509``.
 | 
			
		||||
 | 
			
		||||
Most modules define one or more macros, which application code can use
 | 
			
		||||
to detect the modules presence or absence. The value of each macro is
 | 
			
		||||
a datestamp, in the form YYYYMMDD which indicates the last time this
 | 
			
		||||
module changed in a way that would be visible to an application. For
 | 
			
		||||
example if a class gains a new function, the datestamp should be
 | 
			
		||||
incremented. That allows applications to detect if the new feature is
 | 
			
		||||
available.
 | 
			
		||||
 | 
			
		||||
What ``configure.py`` does
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
First, all command line options are parsed.
 | 
			
		||||
 | 
			
		||||
Then all of the files giving information about target CPUs, compilers,
 | 
			
		||||
etc are parsed and sanity checked.
 | 
			
		||||
 | 
			
		||||
In ``calculate_cc_min_version`` the compiler version is detected using
 | 
			
		||||
the preprocessor.
 | 
			
		||||
 | 
			
		||||
Then in ``check_compiler_arch`` the target architecture are detected, again
 | 
			
		||||
using the preprocessor.
 | 
			
		||||
 | 
			
		||||
Now that the target is identified and options have been parsed, the modules to
 | 
			
		||||
include into the artifact are picked, in ``ModulesChooser``.
 | 
			
		||||
 | 
			
		||||
In ``create_template_vars``, a dictionary of variables is created which describe
 | 
			
		||||
different aspects of the build. These are serialized to
 | 
			
		||||
``build/build_config.json``.
 | 
			
		||||
 | 
			
		||||
Up until this point no changes have been made on disk. This occurs in
 | 
			
		||||
``do_io_for_build``. Build output directories are created, and header files are
 | 
			
		||||
linked into ``build/include/botan``. Templates are processed to create the
 | 
			
		||||
Makefile, ``build.h`` and other artifacts.
 | 
			
		||||
 | 
			
		||||
When Modifying ``configure.py``
 | 
			
		||||
--------------------------------
 | 
			
		||||
 | 
			
		||||
Run ``./src/scripts/ci_build.py lint`` to run Pylint checks after any change.
 | 
			
		||||
 | 
			
		||||
Template Language
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
Various output files are generated by processing input files using a simple
 | 
			
		||||
template language. All input files are stored in ``src/build-data`` and use the
 | 
			
		||||
suffix ``.in``. Anything not recognized as a template command is passed through
 | 
			
		||||
to the output unmodified. The template elements are:
 | 
			
		||||
 | 
			
		||||
 * Variable substitution, ``%{variable_name}``. The configure script creates
 | 
			
		||||
   many variables for various purposes, this allows getting their value within
 | 
			
		||||
   the output. If a variable is not defined, an error occurs.
 | 
			
		||||
 | 
			
		||||
   If a variable reference ends with ``|upper``, the value is uppercased before
 | 
			
		||||
   being inserted into the template output.
 | 
			
		||||
 | 
			
		||||
 * Iteration, ``%{for variable} block %{endfor}``. This iterates over a list and
 | 
			
		||||
   repeats the block as many times as it is included. Variables within the block
 | 
			
		||||
   are expanded. The two template elements ``%{for ...}`` and ``%{endfor}`` must
 | 
			
		||||
   appear on lines with no text before or after.
 | 
			
		||||
 | 
			
		||||
 * Conditional inclusion, ``%{if variable} block %{endif}``. If the variable
 | 
			
		||||
   named is defined and true (in the Python sense of the word; if the variable
 | 
			
		||||
   is empty or zero it is considered false), then the block will be included and
 | 
			
		||||
   any variables expanded. As with the for loop syntax, both the start and end
 | 
			
		||||
   of the conditional must be on their own lines with no additional text.
 | 
			
		||||
 | 
			
		||||
Build.h
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
The ``build.h`` header file is generated and overwritten each time the
 | 
			
		||||
``configure.py`` script is executed. This header can be included in any header
 | 
			
		||||
or source file and provides plenty of compile-time information in the form of
 | 
			
		||||
preprocessor ``#define``\ s.
 | 
			
		||||
 | 
			
		||||
It is helpful to check which modules are included in the current build of the
 | 
			
		||||
library via macro defines of the form "BOTAN_HAS" followed by the module name.
 | 
			
		||||
Also, it contains :ref:`version information macros <versioning>` and compile-time
 | 
			
		||||
library configurations.
 | 
			
		||||
 | 
			
		||||
Adding a new module
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
Create a directory in the appropriate place and create a ``info.txt`` file.
 | 
			
		||||
 | 
			
		||||
Syntax of ``info.txt``
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
.. warning::
 | 
			
		||||
 | 
			
		||||
   The syntax described here is documented to make it easier to use
 | 
			
		||||
   and understand, but it is not considered part of the public API
 | 
			
		||||
   contract. That is, the developers are allowed to change the syntax
 | 
			
		||||
   at any time on the assumption that all users are contained within
 | 
			
		||||
   the library itself. If that happens this document will be updated.
 | 
			
		||||
 | 
			
		||||
Modules and files describing information about the system use the same
 | 
			
		||||
parser and have common syntactical elements.
 | 
			
		||||
 | 
			
		||||
Comments begin with '#' and continue to end of line.
 | 
			
		||||
 | 
			
		||||
There are three main types: maps, lists, and variables.
 | 
			
		||||
 | 
			
		||||
A map has a syntax like::
 | 
			
		||||
 | 
			
		||||
  <MAP_NAME>
 | 
			
		||||
  NAME1 -> VALUE1
 | 
			
		||||
  NAME2 -> VALUE2
 | 
			
		||||
  ...
 | 
			
		||||
  </MAP_NAME>
 | 
			
		||||
 | 
			
		||||
The interpretation of the names and values will depend on the map's name
 | 
			
		||||
and what type of file is being parsed.
 | 
			
		||||
 | 
			
		||||
A list has similar syntax, it just doesn't have values::
 | 
			
		||||
 | 
			
		||||
  <LIST_NAME>
 | 
			
		||||
  ELEM1
 | 
			
		||||
  ELEM2
 | 
			
		||||
  ...
 | 
			
		||||
  </LIST_NAME>
 | 
			
		||||
 | 
			
		||||
Lastly there are single value variables like::
 | 
			
		||||
 | 
			
		||||
  VAR1 SomeValue
 | 
			
		||||
  VAR2 "Quotes Can Be Used (And will be stripped out)"
 | 
			
		||||
  VAR3 42
 | 
			
		||||
 | 
			
		||||
Variables can have string, integer or boolean values. Boolean values
 | 
			
		||||
are specified with 'yes' or 'no'.
 | 
			
		||||
 | 
			
		||||
Module Syntax
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
The ``info.txt`` files have the following elements. Not all are required; a minimal
 | 
			
		||||
file for a module with no dependencies might just contain a macro define and module_info.
 | 
			
		||||
 | 
			
		||||
Lists:
 | 
			
		||||
 * ``comment`` and ``warning`` provides block-comments which
 | 
			
		||||
   are displayed to the user at build time.
 | 
			
		||||
 * ``requires`` is a list of module dependencies. An ``os_features`` can be
 | 
			
		||||
   specified as a condition for needing the dependency by writing it before
 | 
			
		||||
   the module name and separated by a ``?``, e.g. ``rtlgenrandom?dyn_load``.
 | 
			
		||||
 * ``header:internal`` is the list of headers (from the current module)
 | 
			
		||||
   which are internal-only.
 | 
			
		||||
 * ``header:public`` is a the list of headers (from the
 | 
			
		||||
   current module) which should be exported for public use. If neither
 | 
			
		||||
   ``header:internal`` nor ``header:public`` are used then all headers
 | 
			
		||||
   in the current directory are assumed internal.
 | 
			
		||||
 | 
			
		||||
   .. note:: If you omit a header from both internal and public lists, it will
 | 
			
		||||
      be ignored.
 | 
			
		||||
 | 
			
		||||
 * ``header:external`` is used when naming headers which are included
 | 
			
		||||
   in the source tree but might be replaced by an external version. This is used
 | 
			
		||||
   for the PKCS11 headers.
 | 
			
		||||
 * ``arch`` is a list of architectures this module may be used on.
 | 
			
		||||
 * ``isa`` lists ISA features which must be enabled to use this module.
 | 
			
		||||
   Can be proceeded by an ``arch`` name followed by a ``:`` if it is only needed
 | 
			
		||||
   on a specific architecture, e.g. ``x86_64:ssse3``.
 | 
			
		||||
 * ``cc`` is a list of compilers which can be used with this module. If the
 | 
			
		||||
   compiler name is suffixed with a version (like "gcc:5.0") then only compilers
 | 
			
		||||
   with that minimum version can use the module. If you need to exclude just
 | 
			
		||||
   one specific compiler (for example because that compiler miscompiles the code
 | 
			
		||||
   in the module), you can prefix a compiler name with ``!`` - like ``!msvc``.
 | 
			
		||||
 * ``os_features`` is a list of OS features which are required in order to use this
 | 
			
		||||
   module. Each line can specify one or more features combined with ','. Alternatives
 | 
			
		||||
   can be specified on additional lines.
 | 
			
		||||
 | 
			
		||||
Maps:
 | 
			
		||||
 * ``defines`` is a map from macros to datestamps. These macros will be defined in
 | 
			
		||||
   the generated ``build.h``.
 | 
			
		||||
 * ``module_info`` contains documentation-friendly information about the module.
 | 
			
		||||
   Available mappings:
 | 
			
		||||
 | 
			
		||||
   * ``name`` must contain a human-understandable name for the module
 | 
			
		||||
   * ``brief`` may provide a short description about the module's contents
 | 
			
		||||
   * ``type`` specifies the type of the module (defaults to ``Public``)
 | 
			
		||||
 | 
			
		||||
     * ``Public`` Library users can directly interact with this module. E.g.
 | 
			
		||||
       they may enable or disable the module at will during build.
 | 
			
		||||
     * ``Internal`` Library users must not directly interact with this module.
 | 
			
		||||
       It is enabled and used as required by other modules.
 | 
			
		||||
     * ``Virtual`` This module does not contain any implementation but acts as
 | 
			
		||||
       a container for other sub-modules. It cannot be interacted with by the
 | 
			
		||||
       library user and cannot be depended upon directly.
 | 
			
		||||
 | 
			
		||||
 * ``libs`` specifies additional libraries which should be linked if this module is
 | 
			
		||||
   included. It maps from the OS name to a list of libraries (comma seperated).
 | 
			
		||||
 * ``frameworks`` is a macOS/iOS specific feature which maps from an OS name to
 | 
			
		||||
   a framework.
 | 
			
		||||
 | 
			
		||||
Variables:
 | 
			
		||||
 * ``load_on`` Can take on values ``never``, ``always``, ``auto``, ``dep`` or ``vendor``.
 | 
			
		||||
   TODO describe the behavior of these
 | 
			
		||||
 * ``endian`` Required endian for the module (``any`` (default), ``little``, ``big``)
 | 
			
		||||
 | 
			
		||||
An example::
 | 
			
		||||
 | 
			
		||||
   # Disable this by default
 | 
			
		||||
   load_on never
 | 
			
		||||
 | 
			
		||||
   <isa>
 | 
			
		||||
   sse2
 | 
			
		||||
   </isa>
 | 
			
		||||
 | 
			
		||||
   <defines>
 | 
			
		||||
   DEFINE1 -> 20180104
 | 
			
		||||
   DEFINE2 -> 20190301
 | 
			
		||||
   </defines>
 | 
			
		||||
 | 
			
		||||
   <module_info>
 | 
			
		||||
   name -> "This Is Just To Say"
 | 
			
		||||
   brief -> "Contains a poem by William Carlos Williams"
 | 
			
		||||
   </module_info>
 | 
			
		||||
 | 
			
		||||
   <comment>
 | 
			
		||||
   I have eaten
 | 
			
		||||
   the plums
 | 
			
		||||
   that were in
 | 
			
		||||
   the icebox
 | 
			
		||||
   </comment>
 | 
			
		||||
 | 
			
		||||
   <warning>
 | 
			
		||||
   There are no more plums
 | 
			
		||||
   </warning>
 | 
			
		||||
 | 
			
		||||
   <header:public>
 | 
			
		||||
   header1.h
 | 
			
		||||
   </header:public>
 | 
			
		||||
 | 
			
		||||
   <header:internal>
 | 
			
		||||
   header_helper.h
 | 
			
		||||
   whatever.h
 | 
			
		||||
   </header:internal>
 | 
			
		||||
 | 
			
		||||
   <arch>
 | 
			
		||||
   x86_64
 | 
			
		||||
   </arch>
 | 
			
		||||
 | 
			
		||||
   <cc>
 | 
			
		||||
   gcc:4.9 # gcc 4.8 doesn't work for <reasons>
 | 
			
		||||
   clang
 | 
			
		||||
   </cc>
 | 
			
		||||
 | 
			
		||||
   # Can work with POSIX+getentropy or Win32
 | 
			
		||||
   <os_features>
 | 
			
		||||
   posix1,getentropy
 | 
			
		||||
   win32
 | 
			
		||||
   </os_features>
 | 
			
		||||
 | 
			
		||||
   <frameworks>
 | 
			
		||||
   macos -> FramyMcFramerson
 | 
			
		||||
   </frameworks>
 | 
			
		||||
 | 
			
		||||
   <libs>
 | 
			
		||||
   qnx -> foo,bar,baz
 | 
			
		||||
   solaris -> socket
 | 
			
		||||
   </libs>
 | 
			
		||||
 | 
			
		||||
Supporting a new CPU type
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
CPU information is stored in ``src/build-data/arch``.
 | 
			
		||||
 | 
			
		||||
There is also a file ``src/build-data/detect_arch.cpp`` which is used
 | 
			
		||||
for build-time architecture detection using the compiler preprocessor.
 | 
			
		||||
Supporting this is optional but recommended.
 | 
			
		||||
 | 
			
		||||
Lists:
 | 
			
		||||
  * ``aliases`` is a list of alternative names for the CPU architecture.
 | 
			
		||||
  * ``isa_extensions`` is a list of possible ISA extensions that can be used on
 | 
			
		||||
    this architecture. For example x86-64 has extensions "sse2", "ssse3",
 | 
			
		||||
    "avx2", "aesni", ...
 | 
			
		||||
 | 
			
		||||
Variables:
 | 
			
		||||
  * ``endian`` if defined should be "little" or "big". This can also be
 | 
			
		||||
    controlled or overridden at build time.
 | 
			
		||||
  * ``family`` can specify a family group for several related architecture.
 | 
			
		||||
    For example both x86_32 and x86_64 use ``family`` of "x86".
 | 
			
		||||
  * ``wordsize`` is the default wordsize, which controls the size of limbs
 | 
			
		||||
    in the multi precision integers. If not set, defaults to 32.
 | 
			
		||||
 | 
			
		||||
Supporting a new compiler
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
Compiler information is stored in ``src/build-data/cc``. Looking over
 | 
			
		||||
those files will probably help understanding, especially the ones for
 | 
			
		||||
GCC and Clang which are most complete.
 | 
			
		||||
 | 
			
		||||
In addition to the info file, for compilers there is a file
 | 
			
		||||
``src/build-data/detect_version.cpp``. The ``configure.py`` script runs the
 | 
			
		||||
preprocessor over this file to attempt to detect the compiler
 | 
			
		||||
version. Supporting this is not strictly necessary.
 | 
			
		||||
 | 
			
		||||
Maps:
 | 
			
		||||
 * ``binary_link_commands`` gives the command to use to run the linker,
 | 
			
		||||
   it maps from operating system name to the command to use. It uses
 | 
			
		||||
   the entry "default" for any OS not otherwise listed.
 | 
			
		||||
 * ``cpu_flags_no_debug`` unused, will be removed
 | 
			
		||||
 * ``cpu_flags`` used to emit CPU specific flags, for example LLVM
 | 
			
		||||
   bitcode target uses ``-emit-llvm`` flag. Rarely needed.
 | 
			
		||||
 * ``isa_flags`` maps from CPU extensions (like NEON or AES-NI) to
 | 
			
		||||
   compiler flags which enable that extension. These have the same name
 | 
			
		||||
   as the ISA flags listed in the architecture files.
 | 
			
		||||
 * ``lib_flags`` has a single possible entry "debug" which if set maps
 | 
			
		||||
   to additional flags to pass when building a debug library.
 | 
			
		||||
   Rarely needed.
 | 
			
		||||
 * ``mach_abi_linking`` specifies flags to enable when building and
 | 
			
		||||
   linking on a particular CPU. This is usually flags that modify
 | 
			
		||||
   ABI. There is a special syntax supported here
 | 
			
		||||
   "all!os1,arch1,os2,arch2" which allows setting ABI flags which are
 | 
			
		||||
   used for all but the named operating systems and/or architectures.
 | 
			
		||||
 * ``sanitizers`` is a map of sanitizers the compiler supports. It must
 | 
			
		||||
   include "default" which is a list of sanitizers to include by default
 | 
			
		||||
   when sanitizers are requested. The other keys should map to compiler
 | 
			
		||||
   flags.
 | 
			
		||||
 * ``so_link_commands`` maps from operating system to the command to
 | 
			
		||||
   use to build a shared object.
 | 
			
		||||
 | 
			
		||||
Variables:
 | 
			
		||||
  * ``binary_name`` the default name of the compiler binary.
 | 
			
		||||
  * ``linker_name`` the name of the linker to use with this compiler.
 | 
			
		||||
  * ``macro_name`` a macro of the for ``BOTAN_BUILD_COMPILER_IS_XXX``
 | 
			
		||||
    will be defined.
 | 
			
		||||
  * ``output_to_object`` (default "-o") gives the compiler option used to
 | 
			
		||||
    name the output object.
 | 
			
		||||
  * ``output_to_exe`` (default "-o") gives the compiler option used to
 | 
			
		||||
    name the output object.
 | 
			
		||||
  * ``add_include_dir_option`` (default "-I") gives the compiler option used
 | 
			
		||||
    to specify an additional include dir.
 | 
			
		||||
  * ``add_lib_dir_option`` (default "-L") gives the compiler option used
 | 
			
		||||
    to specify an additional library dir.
 | 
			
		||||
  * ``add_sysroot_option`` gives the compiler option used to specify the sysroot.
 | 
			
		||||
  * ``add_lib_option`` (default "-l%s") gives the compiler option to
 | 
			
		||||
    link in a library. ``%s`` will be replaced with the library name.
 | 
			
		||||
  * ``add_framework_option`` (default "-framework") gives the compiler option
 | 
			
		||||
    to add a macOS framework.
 | 
			
		||||
  * ``preproc_flags`` (default "-E") gives the compiler option used to run
 | 
			
		||||
    the preprocessor.
 | 
			
		||||
  * ``compile_flags`` (default "-c") gives the compiler option used to compile a file.
 | 
			
		||||
  * ``debug_info_flags`` (default "-g") gives the compiler option used to enable debug info.
 | 
			
		||||
  * ``optimization_flags`` gives the compiler optimization flags to use.
 | 
			
		||||
  * ``size_optimization_flags`` gives compiler optimization flags to use when
 | 
			
		||||
    compiling for size. If not set then ``--optimize-for-size`` will use
 | 
			
		||||
    the default optimization flags.
 | 
			
		||||
  * ``sanitizer_optimization_flags`` gives compiler optimization flags to use
 | 
			
		||||
    when building with sanitizers.
 | 
			
		||||
  * ``coverage_flags`` gives the compiler flags to use when generating coverage
 | 
			
		||||
    information.
 | 
			
		||||
  * ``stack_protector_flags`` gives compiler flags to enable stack overflow checking.
 | 
			
		||||
  * ``shared_flags`` gives compiler flags to use when generation shared libraries.
 | 
			
		||||
  * ``lang_flags`` gives compiler flags used to enable the required version of C++.
 | 
			
		||||
  * ``lang_binary_linker_flags`` gives flags to be passed to the linker when creating a binary
 | 
			
		||||
  * ``warning_flags`` gives warning flags to enable.
 | 
			
		||||
  * ``maintainer_warning_flags`` gives extra warning flags to enable during maintainer
 | 
			
		||||
    mode builds.
 | 
			
		||||
  * ``visibility_build_flags`` gives compiler flags to control symbol visibility
 | 
			
		||||
    when generation shared libraries.
 | 
			
		||||
  * ``visibility_attribute`` gives the attribute to use in the ``BOTAN_DLL`` macro
 | 
			
		||||
    to specify visibility when generation shared libraries.
 | 
			
		||||
  * ``ar_command`` gives the command to build static libraries
 | 
			
		||||
  * ``ar_options`` gives the options to pass to ``ar_command``, if not set here
 | 
			
		||||
    takes this from the OS specific information.
 | 
			
		||||
  * ``ar_output_to`` gives the flag to pass to ``ar_command`` to specify where to
 | 
			
		||||
    output the static library.
 | 
			
		||||
  * ``werror_flags`` gives the complier flags to treat warnings as errors.
 | 
			
		||||
 | 
			
		||||
Supporting a new OS
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
Operating system information is stored in ``src/build-data/os``.
 | 
			
		||||
 | 
			
		||||
Lists:
 | 
			
		||||
  * ``aliases`` is a list of alternative names which will be accepted
 | 
			
		||||
  * ``target_features`` is a list of target specific OS features. Some of these
 | 
			
		||||
    are supported by many OSes (for example "posix1") others are specific to
 | 
			
		||||
    just one or two OSes (such as "getauxval"). Adding a value here causes a new
 | 
			
		||||
    macro ``BOTAN_TARGET_OS_HAS_XXX`` to be defined at build time. Use
 | 
			
		||||
    ``configure.py --list-os-features`` to list the currently defined OS
 | 
			
		||||
    features.
 | 
			
		||||
  * ``feature_macros`` is a list of macros to define.
 | 
			
		||||
 | 
			
		||||
Variables:
 | 
			
		||||
  * ``ar_command`` gives the command to build static libraries
 | 
			
		||||
  * ``ar_options`` gives the options to pass to ``ar_command``
 | 
			
		||||
  * ``ar_output_to`` gives the flag to pass to ``ar_command`` to specify where to
 | 
			
		||||
    output the static library.
 | 
			
		||||
  * ``bin_dir`` (default "bin") specifies where binaries should be installed,
 | 
			
		||||
    relative to install_root.
 | 
			
		||||
  * ``cli_exe_name`` (default "botan") specifies the name of the command line utility.
 | 
			
		||||
  * ``default_compiler`` specifies the default compiler to use for this OS.
 | 
			
		||||
  * ``doc_dir`` (default "doc") specifies where documentation should be installed,
 | 
			
		||||
    relative to install_root
 | 
			
		||||
  * ``header_dir`` (default "include") specifies where include files
 | 
			
		||||
    should be installed, relative to install_root
 | 
			
		||||
  * ``install_root`` (default "/usr/local") specifies where to install
 | 
			
		||||
    by default.
 | 
			
		||||
  * ``lib_dir`` (default "lib") specifies where library should be installed,
 | 
			
		||||
    relative to install_root.
 | 
			
		||||
  * ``lib_prefix`` (default "lib") prefix to add to the library name
 | 
			
		||||
  * ``library_name``
 | 
			
		||||
  * ``man_dir`` specifies where man files should be installed, relative to install_root
 | 
			
		||||
  * ``obj_suffix`` (default "o") specifies the suffix used for object files
 | 
			
		||||
  * ``program_suffix`` (default "") specifies the suffix used for executables
 | 
			
		||||
  * ``shared_lib_symlinks`` (default "yes) specifies if symbolic names should be
 | 
			
		||||
    created from the base and patch soname to the library name.
 | 
			
		||||
  * ``soname_pattern_abi``
 | 
			
		||||
  * ``soname_pattern_base``
 | 
			
		||||
  * ``soname_pattern_patch``
 | 
			
		||||
  * ``soname_suffix`` file extension to use for shared library if ``soname_pattern_base``
 | 
			
		||||
    is not specified.
 | 
			
		||||
  * ``static_suffix`` (default "a") file extension to use for static library.
 | 
			
		||||
  * ``use_stack_protector`` (default "true") specify if by default stack smashing
 | 
			
		||||
    protections should be enabled.
 | 
			
		||||
  * ``uses_pkg_config`` (default "yes") specify if by default a pkg-config file
 | 
			
		||||
    should be created.
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
Developer Reference
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
This section contains information useful to people making
 | 
			
		||||
contributions to the library
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :maxdepth: 1
 | 
			
		||||
 | 
			
		||||
   contributing
 | 
			
		||||
   configure
 | 
			
		||||
   test_framework
 | 
			
		||||
   continuous_integration
 | 
			
		||||
   fuzzing
 | 
			
		||||
   release_process
 | 
			
		||||
   todo
 | 
			
		||||
   os
 | 
			
		||||
   oids
 | 
			
		||||
   reading_list
 | 
			
		||||
   mistakes
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
Continuous Integration and Automated Testing
 | 
			
		||||
===============================================
 | 
			
		||||
 | 
			
		||||
CI Build Script
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
The Github Actions builds are orchestrated using a script
 | 
			
		||||
``src/scripts/ci_build.py``. This allows one to easily reproduce the CI process
 | 
			
		||||
on a local machine.
 | 
			
		||||
 | 
			
		||||
Github Actions
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
https://github.com/randombit/botan/actions/workflows/ci.yml
 | 
			
		||||
 | 
			
		||||
Github Actions is the primary CI, and tests the Linux, Windows, macOS, and iOS
 | 
			
		||||
builds. Among other things it runs tests using valgrind, cross-compilation
 | 
			
		||||
for various architectures (currently including ARM and PPC64), MinGW build,
 | 
			
		||||
and a build that produces the coverage report.
 | 
			
		||||
 | 
			
		||||
The Github Actions configuration is in ``.github/workflows/ci.yml`` which
 | 
			
		||||
executes platform dependent setup scripts ``src/scripts/ci/setup_gh_actions.sh``
 | 
			
		||||
or ``src/scripts/ci/setup_gh_actions.ps1`` and ``.../setup_gh_actions_after_vcvars.ps1``
 | 
			
		||||
to install needed packages and detect certain platform specifics like compiler
 | 
			
		||||
cache locations.
 | 
			
		||||
 | 
			
		||||
Then ``src/scripts/ci_build.py`` is invoked to steer the actual build and test
 | 
			
		||||
runs.
 | 
			
		||||
 | 
			
		||||
Github Actions (nightly)
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
https://github.com/randombit/botan/actions/workflows/nightly.yml
 | 
			
		||||
 | 
			
		||||
Some checks are just too slow to include in the main CI builds. These
 | 
			
		||||
are instead delegated to a scheduled job that runs every night against
 | 
			
		||||
master.
 | 
			
		||||
 | 
			
		||||
Currently these checks include a full run of ``valgrind`` (the valgrind build in
 | 
			
		||||
CI only runs a subset of the tests), and a run of ``clang-tidy`` with all
 | 
			
		||||
warnings (that we are currently clean for) enabled. Each of these jobs takes
 | 
			
		||||
about an hour to run. In the main CI, we aim to have no job take more than
 | 
			
		||||
half an hour.
 | 
			
		||||
 | 
			
		||||
OSS-Fuzz
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
https://github.com/google/oss-fuzz/
 | 
			
		||||
 | 
			
		||||
OSS-Fuzz is a distributed fuzzer run by Google. Every night, the fuzzer harnesses
 | 
			
		||||
in ``src/fuzzer`` are built and run on many machines, with any findings reported
 | 
			
		||||
to the developers via email.
 | 
			
		||||
@@ -1,299 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Notes for New Contributors
 | 
			
		||||
===================================
 | 
			
		||||
 | 
			
		||||
Source Code Layout
 | 
			
		||||
-------------------------------------------------
 | 
			
		||||
 | 
			
		||||
Under ``src`` there are directories
 | 
			
		||||
 | 
			
		||||
* ``lib`` is the library itself, more on that below
 | 
			
		||||
* ``cli`` is the command line application ``botan``
 | 
			
		||||
* ``tests`` contain what you would expect. Input files go under ``tests/data``.
 | 
			
		||||
* ``python/botan3.py`` is the Python ctypes wrapper
 | 
			
		||||
* ``bogo_shim`` contains the shim binary and configuration for
 | 
			
		||||
  `BoringSSL's TLS test suite <https://github.com/google/boringssl/tree/master/ssl/test>`_
 | 
			
		||||
* ``fuzzer`` contains fuzz targets for various modules of the library
 | 
			
		||||
* ``build-data`` contains files read by the configure script. For
 | 
			
		||||
  example ``build-data/cc/gcc.txt`` describes various gcc options.
 | 
			
		||||
* ``examples`` contains usage examples used in the documentation.
 | 
			
		||||
* ``scripts`` contains misc scripts: install, distribution, various
 | 
			
		||||
  codegen things. Scripts controlling CI go under ``scripts/ci``.
 | 
			
		||||
* ``configs`` contains configuration files tools like pylint
 | 
			
		||||
* ``editors`` contains configuration files for editors like vscode and emacs
 | 
			
		||||
 | 
			
		||||
Under ``doc`` one finds the sources of this documentation
 | 
			
		||||
 | 
			
		||||
Library Layout
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Under ``src/lib`` are several directories
 | 
			
		||||
 | 
			
		||||
* ``asn1`` is the DER encoder/decoder
 | 
			
		||||
* ``base`` defines some high level types
 | 
			
		||||
* ``block`` contains the block cipher implementations
 | 
			
		||||
* ``codec`` has hex, base64, base32, base58
 | 
			
		||||
* ``compat`` a (partial) compatibility layer for the libsodium API
 | 
			
		||||
* ``compression`` has the compression wrappers (zlib, bzip2, lzma)
 | 
			
		||||
* ``entropy`` has various entropy sources used by some of the RNGs
 | 
			
		||||
* ``ffi`` is the C99 API
 | 
			
		||||
* ``filters`` is a filter/pipe API for data transforms
 | 
			
		||||
* ``hash`` contains the hash function implementations
 | 
			
		||||
* ``kdf`` contains the key derivation functions
 | 
			
		||||
* ``mac`` contains the message authentication codes
 | 
			
		||||
* ``math`` is the big integer math library. It is divided into three parts:
 | 
			
		||||
  ``mp`` which are the low level algorithms; ``bigint`` which is a C++ wrapper
 | 
			
		||||
  around ``mp``, and ``numbertheory`` which contains higher level algorithms like
 | 
			
		||||
  primality testing and exponentiation
 | 
			
		||||
* ``misc`` contains odds and ends: format preserving encryption, SRP, threshold
 | 
			
		||||
  secret sharing, all or nothing transform, and others
 | 
			
		||||
* ``modes`` contains block cipher modes (CBC, GCM, etc)
 | 
			
		||||
* ``passhash`` contains password hashing algorithms for authentication
 | 
			
		||||
* ``pbkdf`` contains password hashing algorithms for key derivation
 | 
			
		||||
* ``pk_pad`` contains padding schemes for public key algorithms
 | 
			
		||||
* ``prov`` contains bindings to external libraries such as PKCS #11
 | 
			
		||||
* ``psk_db`` contains a generic interface for a Pre-Shared-Key database
 | 
			
		||||
* ``pubkey`` contains the public key algorithms
 | 
			
		||||
* ``rng`` contains the random number generators
 | 
			
		||||
* ``stream`` contains the stream ciphers
 | 
			
		||||
* ``tls`` contains the TLS implementation
 | 
			
		||||
* ``utils`` contains various utility functions and types
 | 
			
		||||
* ``x509`` is X.509 certificates, PKCS #10 requests, OCSP
 | 
			
		||||
 | 
			
		||||
Each of these folders can contain subfolders which are treated as modules if they
 | 
			
		||||
contain an ``info.txt`` file. These submodules have an implicit dependency on their
 | 
			
		||||
parent module. The chapter :ref:`configure_script` contains more information on
 | 
			
		||||
Botan's module architecture.
 | 
			
		||||
 | 
			
		||||
Sending patches
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
All contributions should be submitted as pull requests via GitHub
 | 
			
		||||
(https://github.com/randombit/botan). If you are planning a large
 | 
			
		||||
change, open a discussion ticket on github before starting out to make
 | 
			
		||||
sure you are on the right path. And once you have something written,
 | 
			
		||||
even if it is not complete/ready to go, feel free to open a draft PR
 | 
			
		||||
for early review and comment.
 | 
			
		||||
 | 
			
		||||
If possible please sign your git commits using a PGP key.
 | 
			
		||||
See https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work for
 | 
			
		||||
instructions on how to set this up.
 | 
			
		||||
 | 
			
		||||
Depending on what your change is, your PR should probably also include an update
 | 
			
		||||
to ``news.rst`` with a note explaining the change. If your change is a
 | 
			
		||||
simple bug fix, a one sentence description is perhaps sufficient. If there is an
 | 
			
		||||
existing ticket on GitHub with discussion or other information, reference it in
 | 
			
		||||
your change note as 'GH #000'.
 | 
			
		||||
 | 
			
		||||
Update ``doc/credits.txt`` with your information so people know what you did!
 | 
			
		||||
 | 
			
		||||
If you are interested in contributing but don't know where to start check out
 | 
			
		||||
``doc/dev_ref/todo.rst`` for some ideas - these are changes we would almost
 | 
			
		||||
certainly accept once they've passed code review.
 | 
			
		||||
 | 
			
		||||
Also, try building and testing it on whatever hardware you have handy,
 | 
			
		||||
especially unusual platforms, or using C++ compilers other than the regularly
 | 
			
		||||
tested GCC, Clang, and Visual Studio.
 | 
			
		||||
 | 
			
		||||
FFI Additions
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
If adding a new function declaration to ``ffi.h``, the same PR must also add the
 | 
			
		||||
same declaration in the Python binding ``botan3.py``, in addition the new API
 | 
			
		||||
functionality must be exposed to Python and a test written in Python.
 | 
			
		||||
 | 
			
		||||
Git Usage
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Do *NOT* merge ``master`` into your topic branch, this creates needless commits
 | 
			
		||||
and noise in history. Instead, as needed, rebase your branch against master
 | 
			
		||||
(``git rebase -i master``) and force push the branch to update the PR. If the
 | 
			
		||||
GitHub PR page does not report any merge conflicts and nobody asks you to
 | 
			
		||||
rebase, you don't need to rebase.
 | 
			
		||||
 | 
			
		||||
Try to keep your history clean and use rebase to squash your commits as
 | 
			
		||||
needed. If your diff is less than roughly 100 lines, it should probably be a
 | 
			
		||||
single commit. Only split commits as needed to help with review/understanding of
 | 
			
		||||
the change.
 | 
			
		||||
 | 
			
		||||
Python
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Scripts should be in Python 3 whenever possible.
 | 
			
		||||
 | 
			
		||||
For configure.py (and helper scripts install.py, cleanup.py and build_docs.py)
 | 
			
		||||
the target is stock (no modules outside the standard library) CPython 3.x.
 | 
			
		||||
Support for PyPy, etc is great when viable (in the sense of not causing problems
 | 
			
		||||
for 3.x, and not requiring huge blocks of version dependent code). As running
 | 
			
		||||
this program successfully is required for a working build, making it as portable
 | 
			
		||||
as possible is considered key.
 | 
			
		||||
 | 
			
		||||
The python wrapper botan3.py targets CPython 3.x, and latest PyPy. Note that
 | 
			
		||||
a single file is used to avoid dealing with any of Python's various crazy module
 | 
			
		||||
distribution issues.
 | 
			
		||||
 | 
			
		||||
For random scripts not typically run by an end-user (codegen, visualization, and
 | 
			
		||||
so on) there isn't any need to worry about platform independence. Here it's fine
 | 
			
		||||
to depend on any useful modules such as graphviz or matplotlib, regardless if it
 | 
			
		||||
is available from a stock CPython install.
 | 
			
		||||
 | 
			
		||||
Build Tools and Hints
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
If you don't already use it for all your C/C++ development, install ``ccache``
 | 
			
		||||
(or on Windows, ``sccache``) right now, and configure a large cache on a fast
 | 
			
		||||
disk. It allows for very quick rebuilds by caching the compiler output.
 | 
			
		||||
 | 
			
		||||
Use ``--enable-sanitizers=`` flag to enable various sanitizer checks.  Supported
 | 
			
		||||
values including "address" and "undefined" for GCC and Clang. GCC also supports
 | 
			
		||||
"iterator" (checked iterators), and Clang supports "memory" (MSan) and
 | 
			
		||||
"coverage" (for fuzzing).
 | 
			
		||||
 | 
			
		||||
On Linux if you have the ``lcov`` and ``gcov`` tools installed, then running
 | 
			
		||||
``./src/scripts/ci_build.py coverage`` will produce a coverage enabled build,
 | 
			
		||||
run the tests, test the fuzzers against a corpus, and produce an HTML report
 | 
			
		||||
of total coverage. This coverage build requires the development headers for
 | 
			
		||||
zlib, bzip2, liblzma, TrouSerS (libtspi), and Sqlite3.
 | 
			
		||||
 | 
			
		||||
Copyright Notice
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
At the top of any new file add a comment with a copyright and a reference to the
 | 
			
		||||
license, for example::
 | 
			
		||||
 | 
			
		||||
  /*
 | 
			
		||||
  * (C) 202x <You>
 | 
			
		||||
  *
 | 
			
		||||
  * Botan is released under the Simplified BSD License (see license.txt)
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
If you are making a substantial or non-trivial change to an existing file, add
 | 
			
		||||
or update your own copyright statement at the top of each file.
 | 
			
		||||
 | 
			
		||||
Style Conventions
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
When writing your code remember the need for it to be easily understood by
 | 
			
		||||
reviewers and auditors, both at the time of the patch submission and in the
 | 
			
		||||
future.
 | 
			
		||||
 | 
			
		||||
Avoid complicated template metaprogramming where possible. It has its places but
 | 
			
		||||
should be used judiciously.
 | 
			
		||||
 | 
			
		||||
When designing a new API (for use either by library users or just internally)
 | 
			
		||||
try writing out the calling code first. That is, write out some code calling
 | 
			
		||||
your idealized API, then just implement that API.  This can often help avoid
 | 
			
		||||
cut-and-paste by creating the correct abstractions needed to solve the problem
 | 
			
		||||
at hand.
 | 
			
		||||
 | 
			
		||||
The C++11 ``auto`` keyword is very convenient but only use it when the type
 | 
			
		||||
truly is obvious (considering also the potential for unexpected integer
 | 
			
		||||
conversions and the like, such as an apparent uint8_t being promoted to an int).
 | 
			
		||||
 | 
			
		||||
Unless there is a specific reason otherwise (eg due to calling some C API which
 | 
			
		||||
requires exactly a ``long*`` be provided) integer types should be either
 | 
			
		||||
``(u)intXX_t`` or ``size_t``. If the variable is used for integer values of "no
 | 
			
		||||
particular size", as in the loop ``for(some_type i = 0; i != 100; ++i)`` then
 | 
			
		||||
the type should be ``size_t``. Use one of the specific size integer types only
 | 
			
		||||
when there is a algorithmic/protocol reason to use an integer of that size. For
 | 
			
		||||
example if a parsing a protocol that uses 16-bit integer fields to encode a
 | 
			
		||||
length, naturally one would use ``uint16_t`` there.
 | 
			
		||||
 | 
			
		||||
If a variable is defined and not modified, declare it ``const``.  Some exception
 | 
			
		||||
for very short-lived variables, but generally speaking being able to read the
 | 
			
		||||
declaration and know it will not be modified is useful.
 | 
			
		||||
 | 
			
		||||
Use ``override`` annotations whenever overriding a virtual function.  If
 | 
			
		||||
introducing a new type that is not intended for further derivation, mark it ``final``.
 | 
			
		||||
 | 
			
		||||
Avoid explicit ``new`` or (especially) explicit ``delete``: use RAII,
 | 
			
		||||
``make_unique``, etc.
 | 
			
		||||
 | 
			
		||||
Use ``m_`` prefix on all member variables.
 | 
			
		||||
 | 
			
		||||
``clang-format`` is used for all C++ formatting. The configuration is
 | 
			
		||||
in ``.clang-format`` in the root directory. You can rerun the
 | 
			
		||||
formatter using ``make fmt`` or by invoking the script
 | 
			
		||||
``src/scripts/dev_tools/run_clang_format.py``. If the output would be
 | 
			
		||||
truly horrible, it is allowed to disable formatting for a specific
 | 
			
		||||
area using ``// clang-format off`` annotations.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Since the output of clang-format varies from version to version, we
 | 
			
		||||
   currently require using exactly ``clang-format 15``.
 | 
			
		||||
 | 
			
		||||
Use braces on both sides of if/else blocks, even if only using a single
 | 
			
		||||
statement.
 | 
			
		||||
 | 
			
		||||
Avoid ``using namespace`` declarations, even inside of single functions.  One
 | 
			
		||||
allowed exception is ``using namespace std::placeholders`` in functions which
 | 
			
		||||
use ``std::bind``. (But, don't use ``std::bind`` - use a lambda instead).
 | 
			
		||||
 | 
			
		||||
Use ``::`` to explicitly refer to the global namespace (eg, when calling an OS
 | 
			
		||||
or external library function like ``::select`` or ``::sqlite3_open``).
 | 
			
		||||
 | 
			
		||||
Use of External Dependencies
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Compiler Dependencies
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
The library should always be as functional as possible when compiled with just
 | 
			
		||||
Standard C++20. However, feel free to use the full language.
 | 
			
		||||
 | 
			
		||||
Use of compiler extensions is fine whenever appropriate; this is typically
 | 
			
		||||
restricted to a single file or an internal header. Compiler extensions used
 | 
			
		||||
currently include native uint128_t, SIMD intrinsics, inline asm syntax and so
 | 
			
		||||
on, so there are some existing examples of appropriate use.
 | 
			
		||||
 | 
			
		||||
Generally intrinsics or inline asm is preferred over bare assembly to avoid
 | 
			
		||||
calling convention issues among different platforms; the improvement in
 | 
			
		||||
maintainability is seen as worth any potential performance tradeoff. One risk
 | 
			
		||||
with intrinsics is that the compiler might rewrite your clever const-time SIMD
 | 
			
		||||
into something with a conditional jump, but code intended to be const-time
 | 
			
		||||
should in any case be annotated (using ``CT::poison``) so it can be checked at
 | 
			
		||||
runtime with tools.
 | 
			
		||||
 | 
			
		||||
Operating System Dependencies
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
If you're adding a small OS dependency in some larger piece of code, try to
 | 
			
		||||
contain the actual non-portable operations to utils/os_utils.* and then call
 | 
			
		||||
them from there.
 | 
			
		||||
 | 
			
		||||
As a policy, operating systems which are not supported by their original vendor
 | 
			
		||||
are not supported by Botan either. Patches that complicate the code in order to
 | 
			
		||||
support obsolete operating systems will likely be rejected. In writing OS
 | 
			
		||||
specific code, feel free to assume roughly POSIX 2008, or for Windows, Windows 8
 | 
			
		||||
/Server 2012 (which are as of this writing the oldest versions still supported
 | 
			
		||||
by Microsoft).
 | 
			
		||||
 | 
			
		||||
Some operating systems, such as OpenBSD, only support the latest release. For
 | 
			
		||||
such cases, it's acceptable to add code that requires APIs added in the most
 | 
			
		||||
recent release of that OS as soon as the release is available.
 | 
			
		||||
 | 
			
		||||
Library Dependencies
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
Any external library dependency - even optional ones - is met with as one PR
 | 
			
		||||
submitter put it "great skepticism".
 | 
			
		||||
 | 
			
		||||
At every API boundary there is potential for confusion that does not exist when
 | 
			
		||||
the call stack is all contained within the boundary.  So the additional API
 | 
			
		||||
really needs to pull its weight. For example a simple text parser or such which
 | 
			
		||||
can be trivially implemented is not really for consideration. As a rough idea of
 | 
			
		||||
the bar, equate the viewed cost of an external dependency as at least 1000
 | 
			
		||||
additional lines of code in the library. That is, if the library really does
 | 
			
		||||
need this functionality, and it can be done in the library for less than that,
 | 
			
		||||
then it makes sense to just write the code. Yup.
 | 
			
		||||
 | 
			
		||||
Currently the (optional) external dependencies of the library are several
 | 
			
		||||
compression libraries (zlib, bzip2, lzma), sqlite3 database, Trousers (TPM
 | 
			
		||||
integration), plus various operating system utilities like basic filesystem
 | 
			
		||||
operations. These provide major pieces of functionality which seem worth the
 | 
			
		||||
trouble of maintaining an integration with.
 | 
			
		||||
 | 
			
		||||
At this point the most plausible examples of an appropriate new external
 | 
			
		||||
dependency are all deeper integrations with system level cryptographic
 | 
			
		||||
interfaces (CommonCrypto, CryptoAPI, /dev/crypto, iOS keychain, TPM 2.0, etc)
 | 
			
		||||
@@ -1,91 +0,0 @@
 | 
			
		||||
Fuzzing The Library
 | 
			
		||||
============================
 | 
			
		||||
 | 
			
		||||
Botan comes with a set of fuzzing endpoints which can be used to test
 | 
			
		||||
the library.
 | 
			
		||||
 | 
			
		||||
.. highlight:: shell
 | 
			
		||||
 | 
			
		||||
Fuzzing with libFuzzer
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
To fuzz with libFuzzer (https://llvm.org/docs/LibFuzzer.html), you'll first
 | 
			
		||||
need to compile libFuzzer::
 | 
			
		||||
 | 
			
		||||
  $ svn co https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer libFuzzer
 | 
			
		||||
  $ cd libFuzzer && clang -c -g -O2 -std=c++11 *.cpp
 | 
			
		||||
  $ ar cr libFuzzer.a libFuzzer/*.o
 | 
			
		||||
 | 
			
		||||
Then build the fuzzers::
 | 
			
		||||
 | 
			
		||||
  $ ./configure.py --cc=clang --build-fuzzer=libfuzzer --unsafe-fuzzer-mode \
 | 
			
		||||
        --with-debug-info --enable-sanitizers=coverage,address,undefined
 | 
			
		||||
  $ make fuzzers
 | 
			
		||||
 | 
			
		||||
Enabling 'coverage' sanitizer flags is required for libFuzzer to work.
 | 
			
		||||
Address sanitizer and undefined sanitizer are optional.
 | 
			
		||||
 | 
			
		||||
The fuzzer binaries will be in `build/fuzzer`. Simply pick one and run it, optionally
 | 
			
		||||
also passing a directory containing corpus inputs.
 | 
			
		||||
 | 
			
		||||
Using `libfuzzer` build mode implicitly assumes the fuzzers need to
 | 
			
		||||
link with `libFuzzer`; if another library is needed (for example in
 | 
			
		||||
OSS-Fuzz, which uses `libFuzzingEngine`), use the flag
 | 
			
		||||
`--with-fuzzer-lib` to specify the desired name.
 | 
			
		||||
 | 
			
		||||
Fuzzing with AFL
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
To fuzz with AFL (http://lcamtuf.coredump.cx/afl/)::
 | 
			
		||||
 | 
			
		||||
  $ ./configure.py --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-g++
 | 
			
		||||
  $ make fuzzers
 | 
			
		||||
 | 
			
		||||
For AFL sanitizers are optional. You can also use `afl-clang-fast++`
 | 
			
		||||
or `afl-clang++`, be sure to set `--cc=clang` also.
 | 
			
		||||
 | 
			
		||||
The fuzzer binaries will be in `build/fuzzer`. To run them you need to
 | 
			
		||||
run under `afl-fuzz`::
 | 
			
		||||
 | 
			
		||||
  $ afl-fuzz -i corpus_path -o output_path ./build/fuzzer/binary
 | 
			
		||||
 | 
			
		||||
Fuzzing with TLS-Attacker
 | 
			
		||||
--------------------------
 | 
			
		||||
 | 
			
		||||
TLS-Attacker (https://github.com/RUB-NDS/TLS-Attacker) includes a mode for fuzzing
 | 
			
		||||
TLS servers. A prebuilt copy of TLS-Attacker is available in a git repository::
 | 
			
		||||
 | 
			
		||||
  $ git clone --depth 1 https://github.com/randombit/botan-ci-tools.git
 | 
			
		||||
 | 
			
		||||
To run it against Botan's server::
 | 
			
		||||
 | 
			
		||||
  $ ./configure.py --with-sanitizers
 | 
			
		||||
  $ make botan
 | 
			
		||||
  $ ./src/scripts/run_tls_attacker.py ./botan ./botan-ci-tools
 | 
			
		||||
 | 
			
		||||
Output and logs from the fuzzer are placed into `/tmp`. See the
 | 
			
		||||
TLS-Attacker documentation for more information about how to use this
 | 
			
		||||
tool.
 | 
			
		||||
 | 
			
		||||
Input Corpus
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
AFL requires an input corpus, and libFuzzer can certainly make good
 | 
			
		||||
use of it.
 | 
			
		||||
 | 
			
		||||
Some crypto corpus repositories include
 | 
			
		||||
 | 
			
		||||
* https://github.com/randombit/crypto-corpus
 | 
			
		||||
* https://github.com/mozilla/nss-fuzzing-corpus
 | 
			
		||||
* https://github.com/google/boringssl/tree/master/fuzz
 | 
			
		||||
* https://github.com/openssl/openssl/tree/master/fuzz/corpora
 | 
			
		||||
 | 
			
		||||
Adding new fuzzers
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
New fuzzers are created by adding a source file to `src/fuzzers` which
 | 
			
		||||
have the signature:
 | 
			
		||||
 | 
			
		||||
``void fuzz(const uint8_t in[], size_t len)``
 | 
			
		||||
 | 
			
		||||
After adding your fuzzer, rerun ``./configure.py`` and build.
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
Mistakes Were Made
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
These are mistakes made early on in the project's history which are difficult to
 | 
			
		||||
fix now, but mentioned in the hope they may serve as an example for others.
 | 
			
		||||
 | 
			
		||||
C++ API
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
As an implementation language, I still think C++ is the best choice (or at least
 | 
			
		||||
the best choice available in early '00s) at offering good performance,
 | 
			
		||||
reasonable abstractions, and low overhead. But the user API should have been
 | 
			
		||||
pure C with opaque structs (rather like the FFI layer, which was added much
 | 
			
		||||
later). Then an expressive C++ API could be built on top of the C API. This
 | 
			
		||||
would have given us a stable ABI, allowed C applications to use the library, and
 | 
			
		||||
(these days) make it easier to progressively rewrite the library in Rust.
 | 
			
		||||
 | 
			
		||||
Public Algorithm Specific Classes
 | 
			
		||||
------------------------------------
 | 
			
		||||
 | 
			
		||||
Classes like AES_128 and SHA_256 should never have been exposed to applications.
 | 
			
		||||
Intead such operations should have been accessible only via the higher level
 | 
			
		||||
interfaces (here BlockCipher and HashFunction). This would substantially reduce
 | 
			
		||||
the overall API and ABI surface.
 | 
			
		||||
 | 
			
		||||
[These interfaces were made internal in 3.0]
 | 
			
		||||
 | 
			
		||||
Header Directories
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
It would have been better to install all headers as ``X/header.h``
 | 
			
		||||
where ``X`` is the base dir in the source, eg ``block/aes128.h``,
 | 
			
		||||
``hash/md5.h``, ...
 | 
			
		||||
 | 
			
		||||
Exceptions
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
Constant ABI headaches from this, and it impacts performance and makes APIs
 | 
			
		||||
harder to understand. Should have been handled with a result<> type instead.
 | 
			
		||||
 | 
			
		||||
Alternatively, and possibly more practically, there should have not been any
 | 
			
		||||
exception hierarchy (or at least not one visible to users) - instead only the
 | 
			
		||||
high level Exception type with contains an error type enum.
 | 
			
		||||
 | 
			
		||||
Virtual inheritance
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
This was used in the public key interfaces and the hierarchy is a tangle.
 | 
			
		||||
Public and private keys should be distinct classes, with a function on private
 | 
			
		||||
keys that creates a new object corresponding to the public key.
 | 
			
		||||
 | 
			
		||||
Cipher Interface
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
The cipher interface taking a secure_vector that it reads from and writes to was
 | 
			
		||||
an artifact of an earlier design which supported both compression and encryption
 | 
			
		||||
in a single API. But it leads to inefficient copies.
 | 
			
		||||
 | 
			
		||||
(I am hoping this issue can be somewhat fixed by introducing a new cipher API
 | 
			
		||||
and implementing the old API in terms of the new one.)
 | 
			
		||||
 | 
			
		||||
Pipe Interface
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
On the surface this API seems very convenient and easy to use. And it is.  But
 | 
			
		||||
the downside is it makes the application code totally opaque; some bytes go into
 | 
			
		||||
a Pipe object and then come out the end transformed in some way. What happens in
 | 
			
		||||
between? Unless the Pipe was built in the same function and you can see the
 | 
			
		||||
parameters to the constructor, there is no way to find out.
 | 
			
		||||
 | 
			
		||||
The problems with the Pipe API are documented, and it is no longer used within
 | 
			
		||||
the library itself. But since many people seem to like it and many applications
 | 
			
		||||
use it, we are stuck at least with maintaining it as it currently exists.
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
MIT is more widely used and doesn't have the ambiguity surrounding the
 | 
			
		||||
various flavors of BSD.
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
Private OID Assignments
 | 
			
		||||
==========================
 | 
			
		||||
 | 
			
		||||
The library uses some OIDs under a private arc assigned by IANA,
 | 
			
		||||
1.3.6.1.4.1.25258
 | 
			
		||||
 | 
			
		||||
Values currently assigned are::
 | 
			
		||||
 | 
			
		||||
  randombit   OBJECT IDENTIFIER ::= { 1 3 6 1 4 1 25258 }
 | 
			
		||||
 | 
			
		||||
  publicKey   OBJECT IDENTIFIER ::= { randombit 1 }
 | 
			
		||||
 | 
			
		||||
  mceliece    OBJECT IDENTIFIER ::= { publicKey 3 }
 | 
			
		||||
  -- { publicKey 4 } previously used as private X25519
 | 
			
		||||
  -- { publicKey 5 } previously used for XMSS draft 6
 | 
			
		||||
  gost-3410-with-sha256 OBJECT IDENTIFIER ::= { publicKey 6 1 }
 | 
			
		||||
 | 
			
		||||
  kyber       OBJECT IDENTIFIER ::= { publicKey 7 }
 | 
			
		||||
  kyber-90s   OBJECT IDENTIFIER ::= { publicKey 11 }
 | 
			
		||||
 | 
			
		||||
  kyber-512      OBJECT IDENTIFIER ::= { kyber 1 }
 | 
			
		||||
  kyber-768      OBJECT IDENTIFIER ::= { kyber 2 }
 | 
			
		||||
  kyber-1024     OBJECT IDENTIFIER ::= { kyber 3 }
 | 
			
		||||
  kyber-512-90s  OBJECT IDENTIFIER ::= { kyber-90s 1 }
 | 
			
		||||
  kyber-768-90s  OBJECT IDENTIFIER ::= { kyber-90s 2 }
 | 
			
		||||
  kyber-1024-90s OBJECT IDENTIFIER ::= { kyber-90s 3 }
 | 
			
		||||
 | 
			
		||||
  xmss        OBJECT IDENTIFIER ::= { publicKey 8 }
 | 
			
		||||
 | 
			
		||||
  -- The current dilithium implementation is compatible with the reference
 | 
			
		||||
  -- implementation commit 3e9b9f1412f6c7435dbeb4e10692ea58f181ee51
 | 
			
		||||
  dilithium     OBJECT IDENTIFIER ::= { publicKey 9 }
 | 
			
		||||
  dilithium-aes OBJECT IDENTIFIER ::= { publicKey 10 }
 | 
			
		||||
 | 
			
		||||
  dilithium-4x4     OBJECT IDENTIFIER ::= { dilithium 1 }
 | 
			
		||||
  dilithium-6x5     OBJECT IDENTIFIER ::= { dilithium 2 }
 | 
			
		||||
  dilithium-8x7     OBJECT IDENTIFIER ::= { dilithium 3 }
 | 
			
		||||
  dilithium-aes-4x4 OBJECT IDENTIFIER ::= { dilithium-aes 1 }
 | 
			
		||||
  dilithium-aes-6x5 OBJECT IDENTIFIER ::= { dilithium-aes 2 }
 | 
			
		||||
  dilithium-aes-8x7 OBJECT IDENTIFIER ::= { dilithium-aes 3 }
 | 
			
		||||
 | 
			
		||||
  SphincsPlus OBJECT IDENTIFIER ::= { publicKey 12 }
 | 
			
		||||
 | 
			
		||||
  SphincsPlus-shake  OBJECT IDENTIFIER ::= { SphincsPlus 1 }
 | 
			
		||||
  SphincsPlus-sha2   OBJECT IDENTIFIER ::= { SphincsPlus 2 }
 | 
			
		||||
  SphincsPlus-haraka OBJECT IDENTIFIER ::= { SphincsPlus 3 }
 | 
			
		||||
 | 
			
		||||
  SphincsPlus-shake-128s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-shake256 1 }
 | 
			
		||||
  SphincsPlus-shake-128f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-shake256 2 }
 | 
			
		||||
  SphincsPlus-shake-192s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-shake256 3 }
 | 
			
		||||
  SphincsPlus-shake-192f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-shake256 4 }
 | 
			
		||||
  SphincsPlus-shake-256s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-shake256 5 }
 | 
			
		||||
  SphincsPlus-shake-256f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-shake256 6 }
 | 
			
		||||
 | 
			
		||||
  SphincsPlus-sha2-128s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-sha256 1 }
 | 
			
		||||
  SphincsPlus-sha2-128f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-sha256 2 }
 | 
			
		||||
  SphincsPlus-sha2-192s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-sha256 3 }
 | 
			
		||||
  SphincsPlus-sha2-192f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-sha256 4 }
 | 
			
		||||
  SphincsPlus-sha2-256s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-sha256 5 }
 | 
			
		||||
  SphincsPlus-sha2-256f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-sha256 6 }
 | 
			
		||||
 | 
			
		||||
  SphincsPlus-haraka-128s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-haraka 1 }
 | 
			
		||||
  SphincsPlus-haraka-128f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-haraka 2 }
 | 
			
		||||
  SphincsPlus-haraka-192s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-haraka 3 }
 | 
			
		||||
  SphincsPlus-haraka-192f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-haraka 4 }
 | 
			
		||||
  SphincsPlus-haraka-256s-r3.1 OBJECT IDENTIFIER ::= { SphincsPlus-haraka 5 }
 | 
			
		||||
  SphincsPlus-haraka-256f-r3.1  OBJECT IDENTIFIER ::= { SphincsPlus-haraka 6 }
 | 
			
		||||
 | 
			
		||||
  symmetricKey OBJECT IDENTIFIER ::= { randombit 3 }
 | 
			
		||||
 | 
			
		||||
  ocbModes OBJECT IDENTIFIER ::= { symmetricKey 2 }
 | 
			
		||||
 | 
			
		||||
  aes-128-ocb      OBJECT IDENTIFIER ::= { ocbModes 1 }
 | 
			
		||||
  aes-192-ocb      OBJECT IDENTIFIER ::= { ocbModes 2 }
 | 
			
		||||
  aes-256-ocb      OBJECT IDENTIFIER ::= { ocbModes 3 }
 | 
			
		||||
  serpent-256-ocb  OBJECT IDENTIFIER ::= { ocbModes 4 }
 | 
			
		||||
  twofish-256-ocb  OBJECT IDENTIFIER ::= { ocbModes 5 }
 | 
			
		||||
  camellia-128-ocb OBJECT IDENTIFIER ::= { ocbModes 6 }
 | 
			
		||||
  camellia-192-ocb OBJECT IDENTIFIER ::= { ocbModes 7 }
 | 
			
		||||
  camellia-256-ocb OBJECT IDENTIFIER ::= { ocbModes 8 }
 | 
			
		||||
 | 
			
		||||
  sivModes OBJECT IDENTIFIER ::= { symmetricKey 4 }
 | 
			
		||||
 | 
			
		||||
  aes-128-siv      OBJECT IDENTIFIER ::= { sivModes 1 }
 | 
			
		||||
  aes-192-siv      OBJECT IDENTIFIER ::= { sivModes 2 }
 | 
			
		||||
  aes-256-siv      OBJECT IDENTIFIER ::= { sivModes 3 }
 | 
			
		||||
  serpent-256-siv  OBJECT IDENTIFIER ::= { sivModes 4 }
 | 
			
		||||
  twofish-256-siv  OBJECT IDENTIFIER ::= { sivModes 5 }
 | 
			
		||||
  camellia-128-siv OBJECT IDENTIFIER ::= { sivModes 6 }
 | 
			
		||||
  camellia-192-siv OBJECT IDENTIFIER ::= { sivModes 7 }
 | 
			
		||||
  camellia-256-siv OBJECT IDENTIFIER ::= { sivModes 8 }
 | 
			
		||||
  sm4-128-siv      OBJECT IDENTIFIER ::= { sivModes 9 }
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
OS Features
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
A summary of OS features as defined in ``src/build-data/os``.
 | 
			
		||||
 | 
			
		||||
::
 | 
			
		||||
 | 
			
		||||
  a: aix
 | 
			
		||||
  a: android
 | 
			
		||||
  c: cygwin
 | 
			
		||||
  d: dragonfly
 | 
			
		||||
  e: emscripten
 | 
			
		||||
  f: freebsd
 | 
			
		||||
  g: generic
 | 
			
		||||
  h: haiku
 | 
			
		||||
  h: hpux
 | 
			
		||||
  h: hurd
 | 
			
		||||
  i: ios
 | 
			
		||||
  l: linux
 | 
			
		||||
  l: llvm
 | 
			
		||||
  m: macos
 | 
			
		||||
  m: mingw
 | 
			
		||||
  n: netbsd
 | 
			
		||||
  n: none
 | 
			
		||||
  o: openbsd
 | 
			
		||||
  q: qnx
 | 
			
		||||
  s: solaris
 | 
			
		||||
  u: uwp
 | 
			
		||||
  w: windows
 | 
			
		||||
 | 
			
		||||
.. csv-table::
 | 
			
		||||
   :header: "Feature", "a", "a", "c", "d", "e", "f", "g", "h", "h", "h", "i", "l", "l", "m", "m", "n", "n", "o", "q", "s", "u", "w"
 | 
			
		||||
 | 
			
		||||
   "alloc_conceal", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " "
 | 
			
		||||
   "apple_keychain", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "arc4random", " ", "X", " ", "X", " ", "X", " ", " ", " ", " ", "X", " ", " ", "X", " ", "X", " ", "X", " ", " ", " ", " "
 | 
			
		||||
   "atomics", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X"
 | 
			
		||||
   "auxinfo", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "cap_enter", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "ccrandom", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "certificate_store", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", "X"
 | 
			
		||||
   "clock_gettime", "X", "X", " ", "X", " ", "X", " ", "X", "X", "X", " ", "X", " ", "X", " ", "X", " ", "X", "X", "X", " ", " "
 | 
			
		||||
   "commoncrypto", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "crypto_ng", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " "
 | 
			
		||||
   "dev_random", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", " ", "X", " ", "X", " ", "X", " ", "X", "X", "X", " ", " "
 | 
			
		||||
   "elf_aux_info", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "explicit_bzero", " ", " ", " ", "X", " ", "X", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X", " ", " ", " ", " "
 | 
			
		||||
   "explicit_memset", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "filesystem", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X"
 | 
			
		||||
   "getauxval", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "getentropy", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X", " ", "X", " ", " ", " ", "X", " ", "X", " ", " "
 | 
			
		||||
   "getrandom", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "pledge", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " "
 | 
			
		||||
   "posix1", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X", " ", "X", " ", "X", " ", "X", "X", "X", " ", " "
 | 
			
		||||
   "posix_mlock", "X", "X", " ", "X", " ", "X", " ", " ", "X", "X", "X", "X", " ", "X", " ", "X", " ", "X", "X", "X", " ", " "
 | 
			
		||||
   "prctl", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "proc_fs", "X", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", "X", " ", " "
 | 
			
		||||
   "rtlgenrandom", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", "X"
 | 
			
		||||
   "rtlsecurezeromemory", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", "X"
 | 
			
		||||
   "sandbox_proc", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", " ", " "
 | 
			
		||||
   "setppriv", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " "
 | 
			
		||||
   "sockets", "X", "X", "X", "X", " ", "X", " ", "X", "X", "X", "X", "X", " ", "X", " ", "X", " ", "X", "X", "X", " ", " "
 | 
			
		||||
   "thread_local", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", " ", "X", "X", "X", "X", "X"
 | 
			
		||||
   "threads", "X", "X", "X", "X", " ", "X", "X", "X", "X", "X", "X", "X", " ", "X", "X", "X", " ", "X", "X", "X", "X", "X"
 | 
			
		||||
   "virtual_lock", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", " ", "X"
 | 
			
		||||
   "win32", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", " ", " ", " ", " ", " ", "X", "X"
 | 
			
		||||
   "winsock2", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", "X", "X"
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   This file is auto generated by ``src/scripts/gen_os_features.py``. Dont modify it manually.
 | 
			
		||||
@@ -1,93 +0,0 @@
 | 
			
		||||
Reading List
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
These are papers, articles and books that are interesting or useful from the
 | 
			
		||||
perspective of crypto implementation.
 | 
			
		||||
 | 
			
		||||
Papers
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
Implementation Techniques
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
* "Randomizing the Montgomery Powering Ladder"
 | 
			
		||||
  Le, Tan, Tunstall https://eprint.iacr.org/2015/657
 | 
			
		||||
  A variant of Algorithm 7 is used for GF(p) point multplications when
 | 
			
		||||
  BOTAN_POINTGFP_BLINDED_MULTIPLY_USE_MONTGOMERY_LADDER is set
 | 
			
		||||
 | 
			
		||||
* "Accelerating AES with vector permute instructions"
 | 
			
		||||
  Mike Hamburg https://shiftleft.org/papers/vector_aes/
 | 
			
		||||
  His public doman assembly code was rewritten into SSS3 intrinsics
 | 
			
		||||
  for aes_ssse3.
 | 
			
		||||
 | 
			
		||||
* "Elliptic curves and their implementation" Langley
 | 
			
		||||
  http://www.imperialviolet.org/2010/12/04/ecc.html
 | 
			
		||||
  Describes sparse representations for ECC math
 | 
			
		||||
 | 
			
		||||
Random Number Generation
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
* "On Extract-then-Expand Key Derivation Functions and an HMAC-based KDF"
 | 
			
		||||
  Hugo Krawczyk http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.131.8254
 | 
			
		||||
  RNG design underlying HMAC_RNG
 | 
			
		||||
 | 
			
		||||
AES Side Channels
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
* "Software mitigations to hedge AES against cache-based software side
 | 
			
		||||
  channel vulnerabilities" https://eprint.iacr.org/2006/052.pdf
 | 
			
		||||
 | 
			
		||||
* "Cache Games - Bringing Access-Based Cache Attacks on AES to Practice"
 | 
			
		||||
  http://www.ieee-security.org/TC/SP2011/PAPERS/2011/paper031.pdf
 | 
			
		||||
 | 
			
		||||
* "Cache-Collision Timing Attacks Against AES" Bonneau, Mironov
 | 
			
		||||
  http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753
 | 
			
		||||
 | 
			
		||||
Public Key Side Channels
 | 
			
		||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
			
		||||
 | 
			
		||||
* "Fast Elliptic Curve Multiplications Resistant against Side Channel Attacks"
 | 
			
		||||
  http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.98.1028&rep=rep1&type=pdf
 | 
			
		||||
 | 
			
		||||
* "Resistance against Differential Power Analysis for Elliptic Curve Cryptosystems"
 | 
			
		||||
  Coron http://www.jscoron.fr/publications/dpaecc.pdf
 | 
			
		||||
 | 
			
		||||
* "Further Results and Considerations on Side Channel Attacks on RSA"
 | 
			
		||||
  Klima, Rosa https://eprint.iacr.org/2002/071
 | 
			
		||||
  Side channel attacks on RSA-KEM and MGF1-SHA1
 | 
			
		||||
 | 
			
		||||
* "Side-Channel Attacks on the McEliece and Niederreiter Public-Key Cryptosystems"
 | 
			
		||||
  Avanzi, Hoerder, Page, and Tunstall https://eprint.iacr.org/2010/479
 | 
			
		||||
 | 
			
		||||
* "Minimum Requirements for Evaluating Side-Channel Attack Resistance
 | 
			
		||||
  of Elliptic Curve Implementations" BSI
 | 
			
		||||
  https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Zertifizierung/Interpretationen/AIS_46_ECCGuide_e_pdf.pdf
 | 
			
		||||
 | 
			
		||||
Books
 | 
			
		||||
------
 | 
			
		||||
 | 
			
		||||
* "Handbook of Elliptic and Hyperelliptic Curve Cryptography"
 | 
			
		||||
  Cohen and Frey https://www.hyperelliptic.org/HEHCC/
 | 
			
		||||
  An excellent reference for ECC math, algorithms, and side channels
 | 
			
		||||
 | 
			
		||||
* "Post-Quantum Cryptography" Bernstein, Buchmann, Dahmen
 | 
			
		||||
  Covers code, lattice, and hash based cryptography
 | 
			
		||||
 | 
			
		||||
Standards
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
* IEEE 1363 http://grouper.ieee.org/groups/1363/
 | 
			
		||||
  Very influential early in the library lifetime, so a lot of terminology used
 | 
			
		||||
  in the public key (such as "EME" for message encoding) code comes from here.
 | 
			
		||||
 | 
			
		||||
* ISO/IEC 18033-2 http://www.shoup.net/iso/std4.pdf
 | 
			
		||||
  RSA-KEM, PSEC-KEM
 | 
			
		||||
 | 
			
		||||
* NIST SP 800-108
 | 
			
		||||
  http://csrc.nist.gov/publications/nistpubs/800-108/sp800-108.pdf
 | 
			
		||||
  KDF schemes
 | 
			
		||||
 | 
			
		||||
* NIST SP 800-90A
 | 
			
		||||
  http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf
 | 
			
		||||
  HMAC_DRBG, Hash_DRBG, CTR_DRBG, maybe one other thing?
 | 
			
		||||
 | 
			
		||||
@@ -1,103 +0,0 @@
 | 
			
		||||
Release Process and Checklist
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Releases are done quarterly, normally on the second non-holiday Monday
 | 
			
		||||
of January, April, July and October. A feature freeze goes into effect
 | 
			
		||||
starting 9 days before the release.
 | 
			
		||||
 | 
			
		||||
.. highlight:: shell
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   This information is only useful if you are a developer of botan who
 | 
			
		||||
   is creating a new release of the library.
 | 
			
		||||
 | 
			
		||||
Pre Release Testing
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Do maintainer-mode builds with Clang and GCC to catch any warnings
 | 
			
		||||
that should be corrected.
 | 
			
		||||
 | 
			
		||||
Other checks which are not in CI:
 | 
			
		||||
 | 
			
		||||
 - Native compile on FreeBSD x86-64
 | 
			
		||||
 - Native compile on at least one unusual platform (AIX, NetBSD, ...)
 | 
			
		||||
 - Build the website content to detect any Doxygen problems
 | 
			
		||||
 - Test many build configurations (using `src/scripts/test_all_configs.py`)
 | 
			
		||||
 - Build/test SoftHSM
 | 
			
		||||
 | 
			
		||||
Confirm that the release notes in ``news.rst`` are accurate and
 | 
			
		||||
complete and that the version number in ``version.txt`` is correct.
 | 
			
		||||
 | 
			
		||||
Tag the Release
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Update the release date in the release notes and change the entry for
 | 
			
		||||
the appropriate branch in ``readme.rst`` to point to the new release.
 | 
			
		||||
 | 
			
		||||
Now check in, and backport changes to the release branch::
 | 
			
		||||
 | 
			
		||||
  $ git commit readme.rst news.rst -m "Update for 3.8.2 release"
 | 
			
		||||
  $ git checkout release-3
 | 
			
		||||
  $ git merge master
 | 
			
		||||
  $ git tag 3.8.2
 | 
			
		||||
 | 
			
		||||
Build The Release Tarballs
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The release script is ``src/scripts/dist.py`` and must be run from a
 | 
			
		||||
git workspace.
 | 
			
		||||
 | 
			
		||||
  $ src/scripts/dist.py 3.8.2
 | 
			
		||||
 | 
			
		||||
One useful option is ``--output-dir``, which specifies where the
 | 
			
		||||
output will be placed.
 | 
			
		||||
 | 
			
		||||
Now do a final build/test of the released tarball.
 | 
			
		||||
 | 
			
		||||
The ``--pgp-key-id`` option is used to specify a PGP keyid. If set,
 | 
			
		||||
the script assumes that it can execute GnuPG and will attempt to
 | 
			
		||||
create signatures for the tarballs. The default value is ``EFBADFBC``,
 | 
			
		||||
which is the official signing key. You can use ``--pgp-key-id=none``
 | 
			
		||||
to avoid creating any signature, though official distributed releases
 | 
			
		||||
*should not* be released without signatures.
 | 
			
		||||
 | 
			
		||||
The releases served on the official site are taken from the contents
 | 
			
		||||
in a git repository::
 | 
			
		||||
 | 
			
		||||
  $ git checkout git@botan.randombit.net:/srv/git/botan-releases.git
 | 
			
		||||
  $ src/scripts/dist.py 3.8.2 --output-dir=botan-releases
 | 
			
		||||
  $ cd botan-releases
 | 
			
		||||
  $ sha256sum Botan-3.8.2.tgz >> sha256sums.txt
 | 
			
		||||
  $ git add .
 | 
			
		||||
  $ git commit -m "Release version 3.8.2"
 | 
			
		||||
  $ git push origin master
 | 
			
		||||
 | 
			
		||||
A cron job updates the live site every 10 minutes.
 | 
			
		||||
 | 
			
		||||
Push to GitHub
 | 
			
		||||
^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Don't forget to also push tags::
 | 
			
		||||
 | 
			
		||||
  $ git push origin --tags release-3 master
 | 
			
		||||
 | 
			
		||||
Update The Website
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The website content is created by ``src/scripts/website.py``.
 | 
			
		||||
 | 
			
		||||
The website is mirrored automatically from a git repository which must be updated::
 | 
			
		||||
 | 
			
		||||
  $ git checkout git@botan.randombit.net:/srv/git/botan-website.git
 | 
			
		||||
  $ ./src/scripts/website.py --output botan-website
 | 
			
		||||
  $ cd botan-website
 | 
			
		||||
  $ git add .
 | 
			
		||||
  $ git commit -m "Update for 3.8.2"
 | 
			
		||||
  $ git push origin master
 | 
			
		||||
 | 
			
		||||
Announce The Release
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Send an email to the botan-announce and botan-devel mailing lists
 | 
			
		||||
noting that a new release is available.
 | 
			
		||||
@@ -1,314 +0,0 @@
 | 
			
		||||
Test Framework
 | 
			
		||||
================
 | 
			
		||||
 | 
			
		||||
Botan uses a custom-built test framework. Some portions of it are
 | 
			
		||||
quite similar to assertion-based test frameworks such as Catch or
 | 
			
		||||
Gtest, but it also includes many features which are well suited for
 | 
			
		||||
testing cryptographic algorithms.
 | 
			
		||||
 | 
			
		||||
The intent is that the test framework and the test suite evolve
 | 
			
		||||
symbiotically; as a general rule of thumb if a new function would make
 | 
			
		||||
the implementation of just two distinct tests simpler, it is worth
 | 
			
		||||
adding to the framework on the assumption it will prove useful again.
 | 
			
		||||
Feel free to propose changes to the test system.
 | 
			
		||||
 | 
			
		||||
When writing a new test, there are three key classes that are used,
 | 
			
		||||
namely ``Test``, ``Test::Result``, and ``Text_Based_Test``. A ``Test``
 | 
			
		||||
(or ``Test_Based_Test``) runs and returns one or more ``Test::Result``.
 | 
			
		||||
 | 
			
		||||
Namespaces in Test
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
The test code lives in a distinct namespace (``Botan_Tests``) and all
 | 
			
		||||
code in the tests which calls into the library should use the
 | 
			
		||||
namespace prefix ``Botan::`` rather than a ``using namespace``
 | 
			
		||||
declaration. This makes it easier to see where the test is actually
 | 
			
		||||
invoking the library, and makes it easier to reuse test code for
 | 
			
		||||
applications.
 | 
			
		||||
 | 
			
		||||
Test Data
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
The test framework is heavily data driven. As of this writing, there
 | 
			
		||||
is about 1 Mib of test code and 17 MiB of test data. For most (though
 | 
			
		||||
certainly not all) tests, it is better to add a data file representing
 | 
			
		||||
the input and outputs, and run the tests over it. Data driven tests
 | 
			
		||||
make adding or editing tests easier, for example by writing scripts
 | 
			
		||||
which produce new test data and output it in the expected format.
 | 
			
		||||
 | 
			
		||||
Test
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Test
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: virtual std::vector<Test::Result> run() = 0
 | 
			
		||||
 | 
			
		||||
     This is the key function of a ``Test``: it executes and returns a
 | 
			
		||||
     list of results. Almost all other functions on ``Test`` are
 | 
			
		||||
     static functions which just serve as helper functions for ``run``.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::string read_data_file(const std::string& path)
 | 
			
		||||
 | 
			
		||||
     Return the contents of a data file and return it as a string.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::vector<uint8_t> read_binary_data_file(const std::string& path)
 | 
			
		||||
 | 
			
		||||
     Return the contents of a data file and return it as a vector of
 | 
			
		||||
     bytes.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static std::string data_file(const std::string& what)
 | 
			
		||||
 | 
			
		||||
     An alternative to ``read_data_file`` and ``read_binary_file``,
 | 
			
		||||
     use only as a last result, typically for library APIs which
 | 
			
		||||
     themselves accept a filename rather than a data blob.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static bool run_long_tests() const
 | 
			
		||||
 | 
			
		||||
     Returns true if the user gave option ``--run-long-tests``. Use
 | 
			
		||||
     this to gate particularly time-intensive tests.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: static Botan::RandomNumberGenerator& rng()
 | 
			
		||||
 | 
			
		||||
     Returns a reference to a fast, not cryptographically secure
 | 
			
		||||
     random number generator. It is deterministicly seeded with the
 | 
			
		||||
     seed logged by the test runner, so it is possible to reproduce
 | 
			
		||||
     results in "random" tests.
 | 
			
		||||
 | 
			
		||||
Tests are registered using the macro ``BOTAN_REGISTER_TEST`` which
 | 
			
		||||
takes 2 arguments: the name of the test and the name of the test class.
 | 
			
		||||
For example given a ``Test`` instance named ``MyTest``, use::
 | 
			
		||||
 | 
			
		||||
  BOTAN_REGISTER_TEST("mytest", MyTest);
 | 
			
		||||
 | 
			
		||||
All test names should contain only lowercase letters, numbers, and
 | 
			
		||||
underscore.
 | 
			
		||||
 | 
			
		||||
Test::Result
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Test::Result
 | 
			
		||||
 | 
			
		||||
    A ``Test::Result`` records one or more tests on a particular topic
 | 
			
		||||
    (say "AES-128/CBC" or "ASN.1 date parsing"). Most of the test functions
 | 
			
		||||
    return true or false if the test was successful or not; this allows
 | 
			
		||||
    performing conditional blocks as a result of earlier tests::
 | 
			
		||||
 | 
			
		||||
      if(result.test_eq("first value", produced, expected))
 | 
			
		||||
         {
 | 
			
		||||
         // further tests that rely on the initial test being correct
 | 
			
		||||
         }
 | 
			
		||||
 | 
			
		||||
    Only the most commonly used functions on ``Test::Result`` are documented here,
 | 
			
		||||
    see the header ``tests.h`` for more.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: Test::Result(const std::string& who)
 | 
			
		||||
 | 
			
		||||
       Create a test report on a particular topic. This will be displayed in the
 | 
			
		||||
       test results.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_success()
 | 
			
		||||
 | 
			
		||||
       Report a test that was successful.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_success(const std::string& note)
 | 
			
		||||
 | 
			
		||||
       Report a test that was successful, including some comment.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_failure(const std::string& err)
 | 
			
		||||
 | 
			
		||||
       Report a test failure of some kind. The error string will be logged.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_failure(const std::string& what, const std::string& error)
 | 
			
		||||
 | 
			
		||||
       Report a test failure of some kind, with a description of what failed and
 | 
			
		||||
       what the error was.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: void test_failure(const std::string& what, const uint8_t buf[], size_t buf_len)
 | 
			
		||||
 | 
			
		||||
       Report a test failure due to some particular input, which is provided as
 | 
			
		||||
       arguments. Normally this is only used if the test was using some
 | 
			
		||||
       randomized input which unexpectedly failed, since if the input is
 | 
			
		||||
       hardcoded or from a file it is easier to just reference the test number.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_eq(const std::string& what, const std::string& produced, const std::string& expected)
 | 
			
		||||
 | 
			
		||||
       Compare to strings for equality.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_ne(const std::string& what, const std::string& produced, const std::string& expected)
 | 
			
		||||
 | 
			
		||||
       Compare to strings for non-equality.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_eq(const char* producer, const std::string& what, \
 | 
			
		||||
                                   const uint8_t produced[], size_t produced_len, \
 | 
			
		||||
                                   const uint8_t expected[], size_t expected_len)
 | 
			
		||||
 | 
			
		||||
       Compare two arrays for equality.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_ne(const char* producer, const std::string& what, \
 | 
			
		||||
                                   const uint8_t produced[], size_t produced_len, \
 | 
			
		||||
                                   const uint8_t expected[], size_t expected_len)
 | 
			
		||||
 | 
			
		||||
       Compare two arrays for non-equality.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_eq(const std::string& producer, const std::string& what, \
 | 
			
		||||
                                   const std::vector<uint8_t>& produced, \
 | 
			
		||||
                                   const std::vector<uint8_t>& expected)
 | 
			
		||||
 | 
			
		||||
       Compare two vectors for equality.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_ne(const std::string& producer, const std::string& what, \
 | 
			
		||||
                                   const std::vector<uint8_t>& produced, \
 | 
			
		||||
                                   const std::vector<uint8_t>& expected)
 | 
			
		||||
 | 
			
		||||
       Compare two vectors for non-equality.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool confirm(const std::string& what, bool expr)
 | 
			
		||||
 | 
			
		||||
       Test that some expression evaluates to ``true``.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: template<typename T> bool test_not_null(const std::string& what, T* ptr)
 | 
			
		||||
 | 
			
		||||
       Verify that the pointer is not null.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_lt(const std::string& what, size_t produced, size_t expected)
 | 
			
		||||
 | 
			
		||||
       Test that ``produced`` < ``expected``.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_lte(const std::string& what, size_t produced, size_t expected)
 | 
			
		||||
 | 
			
		||||
       Test that ``produced`` <= ``expected``.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_gt(const std::string& what, size_t produced, size_t expected)
 | 
			
		||||
 | 
			
		||||
       Test that ``produced`` > ``expected``.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_gte(const std::string& what, size_t produced, size_t expected)
 | 
			
		||||
 | 
			
		||||
       Test that ``produced`` >= ``expected``.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_throws(const std::string& what, std::function<void ()> fn)
 | 
			
		||||
 | 
			
		||||
       Call a function and verify it throws an exception of some kind.
 | 
			
		||||
 | 
			
		||||
    .. cpp:function:: bool test_throws(const std::string& what, const std::string& expected, std::function<void ()> fn)
 | 
			
		||||
 | 
			
		||||
       Call a function and verify it throws an exception of some kind
 | 
			
		||||
       and that the exception message exactly equals ``expected``.
 | 
			
		||||
 | 
			
		||||
Text_Based_Test
 | 
			
		||||
-----------------
 | 
			
		||||
 | 
			
		||||
A ``Text_Based_Text`` runs tests that are produced from a text file
 | 
			
		||||
with a particular format which looks somewhat like an INI-file::
 | 
			
		||||
 | 
			
		||||
  # Comments begin with # and continue to end of line
 | 
			
		||||
  [Header]
 | 
			
		||||
  # Test 1
 | 
			
		||||
  Key1 = Value1
 | 
			
		||||
  Key2 = Value2
 | 
			
		||||
 | 
			
		||||
  # Test 2
 | 
			
		||||
  Key1 = Value1
 | 
			
		||||
  Key2 = Value2
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: VarMap
 | 
			
		||||
 | 
			
		||||
  An object of this type is passed to each invocation of the text-based test.
 | 
			
		||||
  It is used to access the test variables. All access takes a key, which is
 | 
			
		||||
  one of the strings which was passed to the constructor of ``Text_Based_Text``.
 | 
			
		||||
  Accesses are either required (``get_req_foo``), in which case an exception is
 | 
			
		||||
  throwing if the key is not set, or optional (``get_opt_foo``) in which case
 | 
			
		||||
  the test provides a default value which is returned if the key was not set
 | 
			
		||||
  for this particular instance of the test.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> get_req_bin(const std::string& key) const
 | 
			
		||||
 | 
			
		||||
     Return a required binary string. The input is assumed to be hex encoded.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<uint8_t> get_opt_bin(const std::string& key) const
 | 
			
		||||
 | 
			
		||||
     Return an optional binary string. The input is assumed to be hex encoded.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::vector<std::vector<uint8_t>> get_req_bin_list(const std::string& key) const
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Botan::BigInt get_req_bn(const std::string& key) const
 | 
			
		||||
 | 
			
		||||
     Return a required BigInt. The input can be decimal or (with "0x" prefix) hex encoded.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Botan::BigInt get_opt_bn(const std::string& key, const Botan::BigInt& def_value) const
 | 
			
		||||
 | 
			
		||||
     Return an optional BigInt. The input can be decimal or (with "0x" prefix) hex encoded.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string get_req_str(const std::string& key) const
 | 
			
		||||
 | 
			
		||||
     Return a required text string.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: std::string get_opt_str(const std::string& key, const std::string& def_value) const
 | 
			
		||||
 | 
			
		||||
     Return an optional text string.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t get_req_sz(const std::string& key) const
 | 
			
		||||
 | 
			
		||||
     Return a required integer. The input should be decimal.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: size_t get_opt_sz(const std::string& key, const size_t def_value) const
 | 
			
		||||
 | 
			
		||||
     Return an optional integer. The input should be decimal.
 | 
			
		||||
 | 
			
		||||
.. cpp:class:: Text_Based_Test : public Test
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Text_Based_Test(const std::string& input_file, \
 | 
			
		||||
                    const std::string& required_keys, \
 | 
			
		||||
                    const std::string& optional_keys = "")
 | 
			
		||||
 | 
			
		||||
     This constructor is
 | 
			
		||||
 | 
			
		||||
     .. note::
 | 
			
		||||
        The final element of required_keys is the "output key", that is
 | 
			
		||||
        the key which signifies the boundary between one test and the next.
 | 
			
		||||
        When this key is seen, ``run_one_test`` will be invoked. In the
 | 
			
		||||
        test input file, this key must always appear least for any particular
 | 
			
		||||
        test. All the other keys may appear in any order.
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: Test::Result run_one_test(const std::string& header, \
 | 
			
		||||
                    const VarMap& vars)
 | 
			
		||||
 | 
			
		||||
     Runs a single test and returns the result of it. The ``header``
 | 
			
		||||
     parameter gives the value (if any) set in a ``[Header]`` block.
 | 
			
		||||
     This can be useful to distinguish several types of tests within a
 | 
			
		||||
     single file, for example "[Valid]" and "[Invalid]".
 | 
			
		||||
 | 
			
		||||
  .. cpp:function:: bool clear_between_callbacks() const
 | 
			
		||||
 | 
			
		||||
     By default this function returns ``false``. If it returns
 | 
			
		||||
     ``true``, then when processing the data in the file, variables
 | 
			
		||||
     are not cleared between tests. This can be useful when several
 | 
			
		||||
     tests all use some common parameters.
 | 
			
		||||
 | 
			
		||||
Test Runner
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
If you are simply writing a new test there should be no need to modify
 | 
			
		||||
the runner, however it can be useful to be aware of its abilities.
 | 
			
		||||
 | 
			
		||||
The runner can run tests concurrently across many cores. By default single
 | 
			
		||||
threaded execution is used, but you can use ``--test-threads`` option to
 | 
			
		||||
specify the number of threads to use. If you use ``--test-threads=0`` then
 | 
			
		||||
the runner will probe the number of active CPUs and use that (but limited
 | 
			
		||||
to at most 16). If you want to run across many cores on a large machine,
 | 
			
		||||
explicitly specify a thread count. The speedup is close to linear.
 | 
			
		||||
 | 
			
		||||
The RNG used in the tests is deterministic, and the seed is logged for each
 | 
			
		||||
execution. You can cause the random sequence to repeat using ``--drbg-seed``
 | 
			
		||||
option.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
   Currently the RNG is seeded just once at the start of execution. So you
 | 
			
		||||
   must run the exact same sequence of tests as the original test run in
 | 
			
		||||
   order to get reproducible results.
 | 
			
		||||
 | 
			
		||||
If you are trying to track down a bug that happens only occasionally, two very
 | 
			
		||||
useful options are ``--test-runs`` and ``--abort-on-first-fail``. The first
 | 
			
		||||
takes an integer and runs the specified test cases that many times. The second
 | 
			
		||||
causes abort to be called on the very first failed test. This is sometimes
 | 
			
		||||
useful when tracing a memory corruption bug.
 | 
			
		||||
@@ -1,160 +0,0 @@
 | 
			
		||||
Todo List
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Feel free to take one of these on if it interests you. Before starting
 | 
			
		||||
out on something, send an email to the dev list or open a discussion
 | 
			
		||||
ticket on GitHub to make sure you're on the right track.
 | 
			
		||||
 | 
			
		||||
Request a new feature by opening a pull request to update this file.
 | 
			
		||||
 | 
			
		||||
New Ciphers/Hashes/MACs
 | 
			
		||||
----------------------------------------
 | 
			
		||||
* GCM-SIV (RFC 8452)
 | 
			
		||||
* EME* tweakable block cipher (https://eprint.iacr.org/2004/125)
 | 
			
		||||
* PMAC
 | 
			
		||||
* SIV-PMAC
 | 
			
		||||
* Threefish-1024
 | 
			
		||||
* Skein-MAC
 | 
			
		||||
* FFX format preserving encryption (NIST 800-38G)
 | 
			
		||||
* Adiantum (https://eprint.iacr.org/2018/720)
 | 
			
		||||
* HPKE (draft-irtf-cfrg-hpke)
 | 
			
		||||
* Blake3
 | 
			
		||||
 | 
			
		||||
Improved Ciphers Implementations
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Stiched AES/GCM mode for CPUs supporting both AES and CLMUL
 | 
			
		||||
* Combine AES-NI, ARMv8 and POWER AES implementations (as already done for CLMUL)
 | 
			
		||||
* Support for VAES (Zen4/Ice Lake)
 | 
			
		||||
* NEON/VMX support for the SIMD based GHASH
 | 
			
		||||
* Vector permute AES only supports little-endian systems; fix for big-endian
 | 
			
		||||
* SM4 using AES-NI (https://github.com/mjosaarinen/sm4ni) or vector permute
 | 
			
		||||
* Poly1305 using AVX2
 | 
			
		||||
* SHA-512 using BMI2+AVX2
 | 
			
		||||
* Constant time bitsliced DES
 | 
			
		||||
* SIMD evaluation of SHA-2 and SHA-3 compression functions
 | 
			
		||||
* Improved Salsa implementations (SIMD_4x32 and/or AVX2)
 | 
			
		||||
* Add CLMUL/PMULL implementations for CRC24/CRC32
 | 
			
		||||
 | 
			
		||||
Public Key Crypto, Math
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Short vector optimization for BigInt
 | 
			
		||||
* Abstract representation of ECC point elements to allow specific
 | 
			
		||||
  implementations of the field arithmetic depending upon the curve.
 | 
			
		||||
* Curves for pairings (BLS12-381)
 | 
			
		||||
* Identity based encryption
 | 
			
		||||
* Paillier homomorphic cryptosystem
 | 
			
		||||
* New PAKEs (pending CFRG bakeoff results)
 | 
			
		||||
* New post quantum schemes (pending NIST contest results)
 | 
			
		||||
* SPHINX password store (https://eprint.iacr.org/2018/695)
 | 
			
		||||
* X448 and Ed448
 | 
			
		||||
 | 
			
		||||
Utility Functions
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
* Make Memory_Pool more concurrent (currently uses a global lock)
 | 
			
		||||
* Guarded integer type to prevent overflow bugs
 | 
			
		||||
 | 
			
		||||
External Providers, Hardware Support
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Add support ARMv8.4-A SHA-512, SHA-3, SM3 and RNG
 | 
			
		||||
* Aarch64 inline asm for BigInt
 | 
			
		||||
* /dev/crypto provider (ciphers, hashes)
 | 
			
		||||
* Windows CryptoNG provider (ciphers, hashes)
 | 
			
		||||
* Extend Apple CommonCrypto provider (HMAC, CMAC, RSA, ECDSA, ECDH)
 | 
			
		||||
* Add support for iOS keychain access
 | 
			
		||||
* POWER8 SHA-2 extensions (GH #1486 + #1487)
 | 
			
		||||
* Add support VPSUM on big-endian PPC64 (GH #2252)
 | 
			
		||||
* Better TPM support: NVRAM, PCR measurements, sealing
 | 
			
		||||
* Add support for TPM 2.0 hardware
 | 
			
		||||
 | 
			
		||||
TLS
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Make DTLS support optional at build time
 | 
			
		||||
* Improve/optimize DTLS defragmentation and retransmission
 | 
			
		||||
* Make RSA optional at build time
 | 
			
		||||
* Make finite field DH optional at build time
 | 
			
		||||
* Certificate Transparency extensions
 | 
			
		||||
* TLS supplemental authorization data (RFC 4680, RFC 5878)
 | 
			
		||||
* DTLS-SCTP (RFC 6083)
 | 
			
		||||
 | 
			
		||||
PKIX
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Further tests of validation API (see GH #785)
 | 
			
		||||
* Test suite for validation of 'real world' cert chains (GH #611)
 | 
			
		||||
* X.509 policy constraints
 | 
			
		||||
* OCSP responder logic
 | 
			
		||||
 | 
			
		||||
New Protocols / Formats
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Noise protocol
 | 
			
		||||
* ACME protocol
 | 
			
		||||
* Cryptographic Message Syntax (RFC 5652)
 | 
			
		||||
* Fernet symmetric encryption (https://cryptography.io/en/latest/fernet/)
 | 
			
		||||
* RNCryptor format (https://github.com/RNCryptor/RNCryptor)
 | 
			
		||||
* Age format (https://age-encryption.org/v1)
 | 
			
		||||
* Useful OpenPGP subset 1: symmetrically encrypted files.
 | 
			
		||||
  Not aiming to process arbitrary OpenPGP, but rather produce
 | 
			
		||||
  something that happens to be readable by `gpg` and is relatively
 | 
			
		||||
  simple to process for decryption. Require AEAD mode (EAX/OCB).
 | 
			
		||||
* Useful OpenPGP subset 2: Process OpenPGP public keys
 | 
			
		||||
* Useful OpenPGP subset 3: Verification of OpenPGP signatures
 | 
			
		||||
 | 
			
		||||
Cleanups
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
* Unicode path support on Windows (GH #1615)
 | 
			
		||||
* The X.509 path validation tests have much duplicated logic
 | 
			
		||||
 | 
			
		||||
New C APIs
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* PKCS10 requests
 | 
			
		||||
* Certificate signing
 | 
			
		||||
* CRLs
 | 
			
		||||
* Expose TLS
 | 
			
		||||
* Expose NIST key wrap with padding
 | 
			
		||||
* Expose secret sharing
 | 
			
		||||
* Expose deterministic PRNG
 | 
			
		||||
* base32
 | 
			
		||||
* base58
 | 
			
		||||
* DL_Group
 | 
			
		||||
* EC_Group
 | 
			
		||||
 | 
			
		||||
Build/Test
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Support hardcoding all test vectors into the botan-test binary
 | 
			
		||||
  so it can run as a standalone item (copied to a device, etc)
 | 
			
		||||
* Run iOS binary under simulator in CI
 | 
			
		||||
* Run Android binary under simulator in CI
 | 
			
		||||
* Run the TPM tests against an emulator
 | 
			
		||||
  (https://github.com/PeterHuewe/tpm-emulator)
 | 
			
		||||
* Add support for vxWorks
 | 
			
		||||
 | 
			
		||||
CLI
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Add a ``--completion`` option to dump autocomplete info, write
 | 
			
		||||
  support for autocompletion in bash/zsh.
 | 
			
		||||
* Refactor ``speed``
 | 
			
		||||
* Change `tls_server` to be a tty<->socket app, like `tls_client` is,
 | 
			
		||||
  instead of a bogus echo server.
 | 
			
		||||
* `encrypt` / `decrypt` tools providing password based file encryption
 | 
			
		||||
* Add ECM factoring
 | 
			
		||||
* Clone of `minisign` signature utility
 | 
			
		||||
* Implementation of `tlsdate`
 | 
			
		||||
* Password store utility
 | 
			
		||||
* TOTP calculator
 | 
			
		||||
* Clone of magic wormhole
 | 
			
		||||
* ACVP client (https://github.com/usnistgov/ACVP)
 | 
			
		||||
 | 
			
		||||
Documentation
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Always needs help
 | 
			
		||||
@@ -1,131 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Project Goals
 | 
			
		||||
================================
 | 
			
		||||
 | 
			
		||||
Botan seeks to be a broadly applicable library that can be used to implement a
 | 
			
		||||
range of secure distributed systems.
 | 
			
		||||
 | 
			
		||||
The library has the following project goals guiding changes. It does not succeed
 | 
			
		||||
in all of these areas in every way just yet, but it describes the system that is
 | 
			
		||||
the desired end result. Over time further progress is made in each.
 | 
			
		||||
 | 
			
		||||
* Secure and reliable. The implementations must of course be correct and well
 | 
			
		||||
  tested, and attacks such as side channels and fault attacks should be
 | 
			
		||||
  accounted for where necessary. The library should never crash, or invoke
 | 
			
		||||
  undefined behavior, regardless of circumstances.
 | 
			
		||||
 | 
			
		||||
* Implement schemes important in practice. It should be practical to implement
 | 
			
		||||
  any real-world crypto protocol using just what the library provides. It is
 | 
			
		||||
  worth some (limited) additional complexity in the library, in order to expand
 | 
			
		||||
  the set of applications which can easily adopt Botan.
 | 
			
		||||
 | 
			
		||||
* Ease of use. It should be straightforward for an application programmer to do
 | 
			
		||||
  whatever it is they need to do. There should be one obvious way to perform any
 | 
			
		||||
  operation. The API should be predicable, and follow the "principle of least
 | 
			
		||||
  astonishment" in its design. This is not just a nicety; confusing APIs often
 | 
			
		||||
  result in errors that end up compromising security.
 | 
			
		||||
 | 
			
		||||
* Simplicity of design, clarity of code, ease of review. The code should be easy
 | 
			
		||||
  to read and understand by other library developers, users seeking to better
 | 
			
		||||
  understand the behavior of the code, and by professional reviewers looking for
 | 
			
		||||
  bugs. This is important because bugs in convoluted code can easily escape
 | 
			
		||||
  multiple expert reviews, and end up living on for years.
 | 
			
		||||
 | 
			
		||||
* Well tested. The code should be correct against the spec, with as close to
 | 
			
		||||
  100% test coverage as possible. All available static and dynamic analysis
 | 
			
		||||
  tools at our disposal should be used, including fuzzers, symbolic execution,
 | 
			
		||||
  and protocol specific tools. Within reason, all warnings from compilers and
 | 
			
		||||
  static analyzers should be addressed, even if they seem like false positives,
 | 
			
		||||
  because that maximizes the signal value of new warnings from the tool.
 | 
			
		||||
 | 
			
		||||
* Safe defaults. Policies should aim to be highly restrictive by default, and if
 | 
			
		||||
  they must be made less restrictive by certain applications, it should be
 | 
			
		||||
  obvious to the developer that they are doing something unsafe.
 | 
			
		||||
 | 
			
		||||
* Post quantum security. Possibly a practical quantum computer that can break
 | 
			
		||||
  RSA and ECC will never be built, but the future is notoriously hard to predict.
 | 
			
		||||
  It seems prudent to begin designing and deploying systems now which have at
 | 
			
		||||
  least the option of using a post-quantum scheme. Botan provides a conservative
 | 
			
		||||
  selection of algorithms thought to be post-quantum secure.
 | 
			
		||||
 | 
			
		||||
* Performance. Botan does not in every case strive to be faster than every other
 | 
			
		||||
  software implementation, but performance should be competitive and over time
 | 
			
		||||
  new optimizations are identified and applied.
 | 
			
		||||
 | 
			
		||||
* Support whatever I/O mechanism the application wants. Allow the application to
 | 
			
		||||
  control all aspects of how the network is contacted, and ensure the API makes
 | 
			
		||||
  asynchronous operations easy to handle. This both insulates Botan from
 | 
			
		||||
  system-specific details and allows the application to use whatever networking
 | 
			
		||||
  style they please.
 | 
			
		||||
 | 
			
		||||
* Portability to modern systems. Botan does not run everywhere, and we actually
 | 
			
		||||
  do not want it to (see non-goals below). But we do want it to run on anything
 | 
			
		||||
  that someone is deploying new applications on. That includes both major
 | 
			
		||||
  platforms like Windows, Linux, Android and iOS, and also promising new systems
 | 
			
		||||
  such as Fuchsia.
 | 
			
		||||
 | 
			
		||||
* Well documented. Ideally every public API would have some place in the manual
 | 
			
		||||
  describing its usage.
 | 
			
		||||
 | 
			
		||||
* Useful command line utility. The botan command line tool should be flexible
 | 
			
		||||
  and featured enough to replace similar tools such as ``openssl`` for everyday
 | 
			
		||||
  users.
 | 
			
		||||
 | 
			
		||||
Non-Goals
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
There are goals some crypto libraries have, but which Botan actively does not
 | 
			
		||||
seek to address.
 | 
			
		||||
 | 
			
		||||
* Deep embedded support. Botan requires a heap, C++ exceptions, and RTTI, and at
 | 
			
		||||
  least in terms of performance optimizations effectively assumes a 32 or 64 bit
 | 
			
		||||
  processor. It is not suitable for deploying on, say FreeRTOS running on a
 | 
			
		||||
  MSP430, or smartcard with an 8 bit CPU and 256 bytes RAM. A larger SoC, such
 | 
			
		||||
  as a Cortex-A7 running Linux, is entirely within scope.
 | 
			
		||||
 | 
			
		||||
* Implementing every crypto scheme in existence. The focus is on algorithms
 | 
			
		||||
  which are in practical use in systems deployed now, as well as promising
 | 
			
		||||
  algorithms for future deployment. Many algorithms which were of interest
 | 
			
		||||
  in the past but never saw widespread deployment and have no compelling
 | 
			
		||||
  benefit over other designs have been removed to simplify the codebase.
 | 
			
		||||
 | 
			
		||||
* Portable to obsolete systems. There is no reason for crypto software to
 | 
			
		||||
  support ancient OS platforms like SunOS or Windows 2000, since these unpatched
 | 
			
		||||
  systems are completely unsafe anyway. The additional complexity supporting
 | 
			
		||||
  such platforms just creates more room for bugs.
 | 
			
		||||
 | 
			
		||||
* Portable to every C++ compiler ever made. Over time Botan moves forward to
 | 
			
		||||
  both take advantage of new language/compiler features, and to shed workarounds
 | 
			
		||||
  for dealing with bugs in ancient compilers, allowing further simplifications
 | 
			
		||||
  in the codebase. The set of supported compilers is fixed for each new release
 | 
			
		||||
  branch, for example Botan 2.x will always support GCC 4.8. But a future 3.x
 | 
			
		||||
  release version will likely increase the required versions for all compilers.
 | 
			
		||||
 | 
			
		||||
* FIPS 140 validation. The primary developer was (long ago) a consultant with a
 | 
			
		||||
  NIST approved testing lab. He does not have a positive view of the process or
 | 
			
		||||
  results, particularly when it comes to Level 1 software validations. The only
 | 
			
		||||
  benefit of a Level 1 validation is to allow for government sales, and the cost
 | 
			
		||||
  of validation includes enormous amounts of time and money, adding 'checks'
 | 
			
		||||
  that are useless or actively harmful, then freezing the software so security
 | 
			
		||||
  updates cannot be applied in the future. It does force a certain minimum
 | 
			
		||||
  standard (ie, FIPS Level 1 does assure AES and RSA are probably implemented
 | 
			
		||||
  correctly) but this is an issue of interop not security since Level 1 does not
 | 
			
		||||
  seriously consider attacks of any kind. Any security budget would be far
 | 
			
		||||
  better spent on a review from a specialized crypto consultancy, who would look
 | 
			
		||||
  for actual flaws.
 | 
			
		||||
 | 
			
		||||
  That said it would be easy to add a "FIPS 140" build mode to Botan, which just
 | 
			
		||||
  disabled all the builtin crypto and wrapped whatever the most recent OpenSSL
 | 
			
		||||
  FIPS module exports.
 | 
			
		||||
 | 
			
		||||
* Educational purposes. The library code is intended to be easy to read and
 | 
			
		||||
  review, and so might be useful in an educational context. However it does not
 | 
			
		||||
  contain any toy ciphers (unless you count DES and RC4) nor any tools for
 | 
			
		||||
  simple cryptanalysis. Generally the manual and source comments assume previous
 | 
			
		||||
  knowledge on the basic concepts involved.
 | 
			
		||||
 | 
			
		||||
* User proof. Some libraries provide a very high level API in an attempt to save
 | 
			
		||||
  the user from themselves. Occasionally they succeed. It would be appropriate
 | 
			
		||||
  and useful to build such an API on top of Botan, but Botan itself wants to
 | 
			
		||||
  cover a broad set of uses cases and some of these involve having pointy things
 | 
			
		||||
  within reach.
 | 
			
		||||
@@ -1,55 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Getting Started
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
If you need to build the library first, start with :doc:`building`.
 | 
			
		||||
Some Linux distributions include packages for Botan, so building from
 | 
			
		||||
source may not be required on your system.
 | 
			
		||||
 | 
			
		||||
.. only:: html
 | 
			
		||||
 | 
			
		||||
   The :ref:`genindex` and :ref:`search` may be useful to get started.
 | 
			
		||||
 | 
			
		||||
.. only:: html and website
 | 
			
		||||
 | 
			
		||||
   You can also download this manual as a `PDF <https://botan.randombit.net/handbook/botan.pdf>`_.
 | 
			
		||||
 | 
			
		||||
Examples
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
Some examples of usage are included in this documentation. However a better
 | 
			
		||||
source for example code is in the implementation of the
 | 
			
		||||
`command line interface <https://github.com/randombit/botan/tree/master/src/cli>`_,
 | 
			
		||||
which was intentionally written to act as practical examples of usage.
 | 
			
		||||
 | 
			
		||||
Books and other references
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
You should have some knowledge of cryptography *before* trying to use
 | 
			
		||||
the library. This is an area where it is very easy to make mistakes,
 | 
			
		||||
and where things are often subtle and/or counterintuitive. Obviously
 | 
			
		||||
the library tries to provide things at a high level precisely to
 | 
			
		||||
minimize the number of ways things can go wrong, but naive use will
 | 
			
		||||
almost certainly not result in a secure system.
 | 
			
		||||
 | 
			
		||||
Especially recommended are:
 | 
			
		||||
 | 
			
		||||
- *Cryptography Engineering*
 | 
			
		||||
  by Niels Ferguson, Bruce Schneier, and Tadayoshi Kohno
 | 
			
		||||
 | 
			
		||||
- `Security Engineering -- A Guide to Building Dependable Distributed Systems
 | 
			
		||||
  <https://www.cl.cam.ac.uk/~rja14/book.html>`_ by Ross Anderson
 | 
			
		||||
 | 
			
		||||
- `Handbook of Applied Cryptography <http://www.cacr.math.uwaterloo.ca/hac/>`_
 | 
			
		||||
  by Alfred J. Menezes, Paul C. Van Oorschot, and Scott A. Vanstone
 | 
			
		||||
 | 
			
		||||
If you're doing something non-trivial or unique, you might want to at
 | 
			
		||||
the very least ask for review/input at a place such as the
 | 
			
		||||
`cryptography stack exchange <https://crypto.stackexchange.com/>`_.
 | 
			
		||||
And (if possible) pay a professional cryptographer or security company
 | 
			
		||||
to review your design and code.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. toctree::
 | 
			
		||||
   :maxdepth: 1
 | 
			
		||||
   :numbered:
 | 
			
		||||
@@ -1,449 +0,0 @@
 | 
			
		||||
Botan 2.x to 3.x Migration
 | 
			
		||||
==============================
 | 
			
		||||
 | 
			
		||||
This is a guide on migrating applications from Botan 2.x to 3.0.
 | 
			
		||||
 | 
			
		||||
This guide attempts to be, but is not, complete. If you run into a problem while
 | 
			
		||||
converting code that does not seem to be described here, please open an issue on
 | 
			
		||||
Github.
 | 
			
		||||
 | 
			
		||||
Headers
 | 
			
		||||
--------
 | 
			
		||||
 | 
			
		||||
Many headers have been removed from the public API.
 | 
			
		||||
 | 
			
		||||
In some cases, such as ``datastor.h`` or ``tls_blocking.h``, the functionality
 | 
			
		||||
presented was entirely deprecated, in which case it has been removed.
 | 
			
		||||
 | 
			
		||||
In other cases (such as ``loadstor.h`` or ``rotate.h``) the header was really an
 | 
			
		||||
implementation header of the library and not intended to be consumed as a public
 | 
			
		||||
API. In these cases the header is still used internally, but not installed for
 | 
			
		||||
application use.
 | 
			
		||||
 | 
			
		||||
However in most cases there is a better way of performing the same operations,
 | 
			
		||||
which usually works in both 2.x and 3.x. For example, in 3.0 all of the
 | 
			
		||||
algorithm headers (such as ``aes.h``) have been removed. Instead you should
 | 
			
		||||
create objects via the factory methods (in the case of AES,
 | 
			
		||||
``BlockCipher::create``) which works in both 2.x and 3.0
 | 
			
		||||
 | 
			
		||||
Build Artifacts
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
For consistency with other platforms the DLL is now suffixed with the library's
 | 
			
		||||
major version on Windows as well.
 | 
			
		||||
 | 
			
		||||
TLS
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
Starting with Botan 3.0 TLS 1.3 is supported.
 | 
			
		||||
This development required a number of backward-incompatible changes to
 | 
			
		||||
accomodate the protocol differences to TLS 1.2, which is still supported.
 | 
			
		||||
 | 
			
		||||
Build modules
 | 
			
		||||
^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The build module ``tls`` is now internal and contains common TLS helpers. Users
 | 
			
		||||
have to explicitly enable ``tls12`` and/or ``tls13``. Note that for Botan 3.0 it
 | 
			
		||||
is not (yet) possible to exclusively enable TLS 1.3 at build time.
 | 
			
		||||
 | 
			
		||||
Removed Functionality
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Functionality removed from the TLS implementation includes
 | 
			
		||||
 | 
			
		||||
* TLS 1.0, 1.1 and DTLS 1.0
 | 
			
		||||
* DSA ciphersuites
 | 
			
		||||
* anonymous ciphersuites
 | 
			
		||||
* SRP ciphersuites
 | 
			
		||||
* SEED ciphersuites
 | 
			
		||||
* Camellia CBC ciphersuites
 | 
			
		||||
* AES-128 OCB ciphersuites
 | 
			
		||||
* DHE_PSK ciphersuites
 | 
			
		||||
* CECPQ1 ciphersuites
 | 
			
		||||
 | 
			
		||||
enum classes
 | 
			
		||||
^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The publicly available C++ enums in the TLS namespace are now `enum class` and
 | 
			
		||||
their member naming scheme was converted from `SHOUTING_SNAKE_CASE` to
 | 
			
		||||
`CamelCase`.
 | 
			
		||||
 | 
			
		||||
Callbacks
 | 
			
		||||
^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
A number of new callbacks were added with TLS 1.3. None of those new callbacks
 | 
			
		||||
is mandatory to implement by applications, though. Additionally there are a few
 | 
			
		||||
backward incompatible changes in callbacks that might require attention by some
 | 
			
		||||
applications:
 | 
			
		||||
 | 
			
		||||
tls_record_received() / tls_emit_data()
 | 
			
		||||
"""""""""""""""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
Those callbacks now take `std::span<const uint8_t>` instead of `const uint8_t*`
 | 
			
		||||
with a `size_t` buffer length.
 | 
			
		||||
 | 
			
		||||
tls_session_established()
 | 
			
		||||
"""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
This callback provides a summary of the just-negotiated connection. It used to
 | 
			
		||||
have a bool return value letting an application decide to store or discard the
 | 
			
		||||
connection's resumption information. This use case is now provided via:
 | 
			
		||||
`tls_should_persist_resumption_information()` which might be called more than
 | 
			
		||||
once for a single TLS 1.3 connection.
 | 
			
		||||
 | 
			
		||||
`tls_session_established` is not a mandatory callback anymore but still allows
 | 
			
		||||
applications to abort a connection given a summary of the negotiated
 | 
			
		||||
characteristics. Note that this summary is not a persistable `Session` anymore.
 | 
			
		||||
 | 
			
		||||
tls_verify_cert_chain()
 | 
			
		||||
"""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
The parameter `ocsp_responses`, which was previously
 | 
			
		||||
`std::shared_ptr<OCSP::Response>`, is now `std::optional<OCSP::Response>`.
 | 
			
		||||
 | 
			
		||||
tls_modify_extensions() / tls_examine_extensions()
 | 
			
		||||
""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
These callbacks now have an additional parameter of type `Handshake_Type` that
 | 
			
		||||
identify the TLS handshake message the extensions in question are residing in.
 | 
			
		||||
TLS 1.3 makes much heavier use of such extensions in a wider range of messages
 | 
			
		||||
to implement core protocol functionality.
 | 
			
		||||
 | 
			
		||||
tls_dh_agree() / tls_ecdh_agree() / tls_decode_group_param()
 | 
			
		||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
These callbacks were used as customization points for the TLS 1.2 key exchange
 | 
			
		||||
in the TLS client. To allow similar (and more) customizations with the
 | 
			
		||||
introduction of TLS 1.3, these callbacks were replaced with a more generic
 | 
			
		||||
approach.
 | 
			
		||||
 | 
			
		||||
Key agreement is split into two callbacks, namely `tls_generate_ephemeral_key()`
 | 
			
		||||
and `tls_ephemeral_key_agreement()`. Those are used in both clients and servers
 | 
			
		||||
and in all protocol versions. `tls_decode_group_param()` is removed as it became
 | 
			
		||||
obsolete by the replacement of the other two callbacks.
 | 
			
		||||
 | 
			
		||||
Policy
 | 
			
		||||
^^^^^^
 | 
			
		||||
 | 
			
		||||
choose_key_exchange_group()
 | 
			
		||||
"""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
The new parameter `offered_by_peer` identifies the key exchange groups a peer
 | 
			
		||||
has sent public exchange offerings for (in TLS 1.3 handshakes only).
 | 
			
		||||
Choosing a key exchange group that is not listed is legal but will result in an
 | 
			
		||||
additional network round trip (cf. "Hello Retry Request").
 | 
			
		||||
In TLS 1.2, this vector is always empty and can be ignored.
 | 
			
		||||
 | 
			
		||||
session_ticket_lifetime()
 | 
			
		||||
"""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
Now returns `std::chrono::seconds` rather than a bare `uint32_t`.
 | 
			
		||||
 | 
			
		||||
Credentials Manager
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
find_cert_chain(), cert_chain() and cert_chain_single_type()
 | 
			
		||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
These methods now have a `cert_signature_schemes` parameter that identifies
 | 
			
		||||
a list of signature schemes the peer is willing to accept for signatures
 | 
			
		||||
in certificates.
 | 
			
		||||
Notably, this *does not necessarily* mean that the leaf certificate must feature
 | 
			
		||||
a public key type able to generate one of those schemes.
 | 
			
		||||
 | 
			
		||||
private_key_for()
 | 
			
		||||
"""""""""""""""""
 | 
			
		||||
 | 
			
		||||
Applications must now provide a `std::shared_ptr<>` to the requested private key
 | 
			
		||||
object instead of a raw pointer to better communicate the implementation's
 | 
			
		||||
life-time expectations of this private key object.
 | 
			
		||||
 | 
			
		||||
.. _tls_session_manager_migration:
 | 
			
		||||
 | 
			
		||||
Session and Ticket Handling
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Old (pre-Botan 3.0) sessions won't load in Botan 3.0 anymore and should be
 | 
			
		||||
discarded.
 | 
			
		||||
For applications using `Session_Manager_SQL` or `Session_Manager_SQLite`
 | 
			
		||||
discarding happens automatically on first access after the update.
 | 
			
		||||
 | 
			
		||||
With Botan 3.0 the session manager now is responsible for stateful session
 | 
			
		||||
handling (backed by a database) and creation and management of stateless session
 | 
			
		||||
tickets.
 | 
			
		||||
The latter was previously handled transparently by the TLS implementation itself.
 | 
			
		||||
 | 
			
		||||
Therefore, TLS server applications that relied on Botan's default session
 | 
			
		||||
management implementations (most notably `Session_Manager_SQLite` or
 | 
			
		||||
`Session_Manager_In_Memory`) are advised to re-evaluate their choice.
 | 
			
		||||
Have a look at `Session_Manager_Hybrid` to retain support for both stateful and
 | 
			
		||||
stateless TLS sessions.
 | 
			
		||||
TLS client applications may safely keep relying on the above-mentioned default
 | 
			
		||||
implementations.
 | 
			
		||||
 | 
			
		||||
Applications implementing their own `Session_Manager` will need to adapt to the
 | 
			
		||||
new base class API.
 | 
			
		||||
 | 
			
		||||
New API of Session Manager
 | 
			
		||||
""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
TLS 1.3 removed the legacy resumption procedures based on session IDs or session
 | 
			
		||||
tickets and combined them under the protocol's Pre-Shared Key mechanism.
 | 
			
		||||
This new approach allows TLS servers to handle sessions both stateless (as
 | 
			
		||||
self-contained encrypted and authenticated tickets) and stateful (identified
 | 
			
		||||
with unique database handles).
 | 
			
		||||
 | 
			
		||||
To accomodates this flexibility the `Session_Manager` base class API has changed
 | 
			
		||||
drastically and is now responsible for creation, storage and management of both
 | 
			
		||||
stateful sessions and stateless session tickets.
 | 
			
		||||
Sub-classes therefore gain full control over the session ticket's structure and
 | 
			
		||||
content.
 | 
			
		||||
 | 
			
		||||
API details are documented in the class' doxygen comments.
 | 
			
		||||
 | 
			
		||||
The Session Object and its Handle
 | 
			
		||||
"""""""""""""""""""""""""""""""""
 | 
			
		||||
 | 
			
		||||
Objects of class `Session` are not aware of their "session ID" or their "session
 | 
			
		||||
ticket" anymore.
 | 
			
		||||
Instead, the new class `Session_Handle` encapsulates the session's identifier or
 | 
			
		||||
ticket and accompanies the `Session` object where necessary.
 | 
			
		||||
 | 
			
		||||
Algorithms Removed
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
The algorithms CAST-256, MISTY1, Kasumi, DESX, XTEA, PBKDF1, MCEIES, CBC-MAC,
 | 
			
		||||
Tiger, CECPQ1, and NewHope have been removed.
 | 
			
		||||
 | 
			
		||||
Certificate API shared_ptr
 | 
			
		||||
----------------------------
 | 
			
		||||
 | 
			
		||||
Previously the certificate store used ``shared_ptr<X509_Certificate>`` in
 | 
			
		||||
various APIs. However starting in 2.4.0, ``X509_Certificate`` itself is a pimpl
 | 
			
		||||
to a ``shared_ptr``, making the outer shared pointer pointless. In 3.0 the
 | 
			
		||||
certificate interfaces have changed to just consume and return ``X509_Certificate``.
 | 
			
		||||
 | 
			
		||||
All Or Nothing Package Transform
 | 
			
		||||
----------------------------------
 | 
			
		||||
 | 
			
		||||
This code was deprecated and has been removed.
 | 
			
		||||
 | 
			
		||||
Exception Changes
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
Several exceptions, mostly ones not used by the library, were removed.
 | 
			
		||||
 | 
			
		||||
A few others that were very specific (such as Illegal_Point) were replaced
 | 
			
		||||
by throws of their immediate base class exception type.
 | 
			
		||||
 | 
			
		||||
The base class of Encoding_Error and Decoding_Error changed from
 | 
			
		||||
Invalid_Argument to Exception. If you are explicitly catching Invalid_Argument,
 | 
			
		||||
verify that you do not need to now also explicitly catch Encoding_Error and/or
 | 
			
		||||
Decoding_Error.
 | 
			
		||||
 | 
			
		||||
X.509 Certificate Info Access
 | 
			
		||||
-------------------------------
 | 
			
		||||
 | 
			
		||||
Previously ``X509_Certificate::subject_info`` and ``issuer_info`` could be used
 | 
			
		||||
to query information about extensions. This is not longer the case; instead you
 | 
			
		||||
should either call a specific function on ``X509_Certificate`` which returns the
 | 
			
		||||
same information, or lacking that, iterate over the result of
 | 
			
		||||
``X509_Certificate::v3_extensions``.
 | 
			
		||||
 | 
			
		||||
OCSP Response Validation
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
After mitigating CVE-2022-43705 the OCSP response signature validation was refactored.
 | 
			
		||||
This led to the removal of the `OCSP::Response::check_signature()` method. If you
 | 
			
		||||
must validate OCSP responses directly in your application please use the new method
 | 
			
		||||
`OCSP::Response::find_signing_certificate()` and `OCSP::Response::verify_signature()`.
 | 
			
		||||
 | 
			
		||||
Use of ``enum class``
 | 
			
		||||
--------------------------------
 | 
			
		||||
 | 
			
		||||
Several enumerations where modified to become ``enum class``, including
 | 
			
		||||
``DL_Group::Format``, ``CRL_Code``, ``EC_Group_Encoding``, ``Signature_Format``,
 | 
			
		||||
``Cipher_Dir``, ``TLS::Extension_Code``, ``TLS::Connection_Side``,
 | 
			
		||||
``TLS::Record_Type``, and ``TLS::Handshake_Type``
 | 
			
		||||
 | 
			
		||||
In many cases the enumeration values were renamed from ``SHOUTING_CASE`` to
 | 
			
		||||
``CamelCase``. In some cases where the enumeration was commonly used by
 | 
			
		||||
applications (for example ``Signature_Format`` and ``Cipher_Dir``) the old
 | 
			
		||||
enumeration names are retained as deprecated variants.
 | 
			
		||||
 | 
			
		||||
ASN.1 enums
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
The enum ``ASN1_Tag`` has been split into ``ASN1_Type`` and ``ASN1_Class``.
 | 
			
		||||
Unlike ``ASN1_Tag``, these new enums are ``enum class``. The members of the
 | 
			
		||||
enums have changed from ``SHOUTING_CASE`` to ``CamelCase``, eg ``CONSTRUCTED``
 | 
			
		||||
is now ``Constructed``.
 | 
			
		||||
 | 
			
		||||
Also an important change related to ``ASN1_Tag::PRIVATE``. This enum value was
 | 
			
		||||
incorrect, and actually was used for explicitly tagged context specific values.
 | 
			
		||||
Now, ``ASN1_Class::Private`` refers to the correct class, but would lead to a
 | 
			
		||||
different encoding vs 2.x's ``ASN1_Tag::PRIVATE``. The correct value to use in
 | 
			
		||||
3.0 to match ``ASN1_Tag::PRIVATE`` is ``ASN1_Class::ExplicitContextSpecific``.
 | 
			
		||||
 | 
			
		||||
Cipher Mode Granularity
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
Previously Cipher_Mode::update_granularity specified the minimum buffer size
 | 
			
		||||
that must be provided during processing. However the value returned was often
 | 
			
		||||
much larger than what was strictly required. In particular some modes can easily
 | 
			
		||||
accept inputs as small as 1 byte, but their update_granularity was much larger
 | 
			
		||||
to encourage best performance.
 | 
			
		||||
 | 
			
		||||
Now update_granularity returns the true minimum value, and the new
 | 
			
		||||
Cipher_Mode::ideal_granularity returns a value which is a multiple of
 | 
			
		||||
update_granularity sized for good performance.
 | 
			
		||||
 | 
			
		||||
If you are sizing buffers on the basis of update_granularity consider
 | 
			
		||||
using ideal_granularity instead. Otherwise you may encounter performance
 | 
			
		||||
regressions due to creating and processing very small buffers.
 | 
			
		||||
 | 
			
		||||
"SHA-160" and "SHA1"
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
Previously the library accepted "SHA-160" and "SHA1" alternative names
 | 
			
		||||
for "SHA-1". This is no longer the case, you must use "SHA-1". Botan
 | 
			
		||||
2.x also recognizes "SHA-1".
 | 
			
		||||
 | 
			
		||||
PointGFp
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
This type is now named ``EC_Point``
 | 
			
		||||
 | 
			
		||||
X509::load_key
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
Previously these functions returned a raw pointer. They now return
 | 
			
		||||
a std::unique_ptr
 | 
			
		||||
 | 
			
		||||
PKCS11_Request::subject_public_key and X509_Certificate::subject_public_key
 | 
			
		||||
-----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
These functions now return a unique_ptr
 | 
			
		||||
 | 
			
		||||
choose_sig_format removed
 | 
			
		||||
---------------------------
 | 
			
		||||
 | 
			
		||||
The freestanding functions choose_sig_format have been removed.
 | 
			
		||||
Use X509_Object::choose_sig_format
 | 
			
		||||
 | 
			
		||||
DLIES Constructors
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
Previously the constructors to the DLIES classes took raw pointers,
 | 
			
		||||
and retained ownership of them. They now consume std::unique_ptrs
 | 
			
		||||
 | 
			
		||||
Credentials_Manager::private_key_for
 | 
			
		||||
-------------------------------------
 | 
			
		||||
 | 
			
		||||
Previously this function returned a raw pointer, which the Credentials_Manager
 | 
			
		||||
implementation had to keep alive "forever", since there was no way for it to
 | 
			
		||||
know when or if the TLS layer had completed using the returned key.
 | 
			
		||||
 | 
			
		||||
Now this function returns std::shared_ptr<Private_Key>
 | 
			
		||||
 | 
			
		||||
OID operator+
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
OID operator+ allowed concatenating new fields onto an object identifier. This
 | 
			
		||||
was not used at all within the library or the tests, and seems of marginal
 | 
			
		||||
value, so it was removed.
 | 
			
		||||
 | 
			
		||||
If necessary in your application, this can be done by retrieving the
 | 
			
		||||
vector of components from your source OID, push the new element onto the vector
 | 
			
		||||
and create an OID from the result.
 | 
			
		||||
 | 
			
		||||
RSA with "EMSA1" padding
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
EMSA1 indicates that effectively the plain hash is signed, with no other
 | 
			
		||||
padding. It is typically used for algorithms like ECSDA, but was allowed for
 | 
			
		||||
RSA. This is now no longer implemented.
 | 
			
		||||
 | 
			
		||||
If you must generate such signatures for some horrible reason, you can pre-hash
 | 
			
		||||
the message using a hash function as usual, and then sign using a "Raw" padding,
 | 
			
		||||
which will allow you to sign any arbitrary bits with no preprocessing.
 | 
			
		||||
 | 
			
		||||
ECDSA/DSA with "EMSA1" padding
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
Previous versions of Botan required using a hash specifier like "EMSA1(SHA-256)"
 | 
			
		||||
when generating or verifying ECDSA/DSA signatures, with the specified hash. The
 | 
			
		||||
"EMSA1" was a reference to a now obsolete IEEE standard.
 | 
			
		||||
 | 
			
		||||
In Botan 3 the "EMSA1" notation is still accepted, but now also it is possible
 | 
			
		||||
to simply use the name of the hash, eg "EMSA1(SHA-256)" becomes "SHA-256".
 | 
			
		||||
 | 
			
		||||
Signature Algorithm OIDs
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
In line with the previous entries, previously Botan used a string like
 | 
			
		||||
"ECDSA/EMSA1(SHA-256)" to identify the OID 1.2.840.10045.4.3.2. Now it
 | 
			
		||||
uses the string "ECDSA/SHA-256" instead, and does not recognize the
 | 
			
		||||
EMSA1 variant at all (for example in ``OID::from_string``).
 | 
			
		||||
 | 
			
		||||
Public Key Signature Padding
 | 
			
		||||
-----------------------------
 | 
			
		||||
 | 
			
		||||
In previous versions Botan was somewhat lenient about allowing the application
 | 
			
		||||
to specify using a hash which was in fact incompatible with the algorithm. For
 | 
			
		||||
example, Ed25519 signatures are *always* generated using SHA-512; there is no
 | 
			
		||||
choice in the matter. In the past, requesting using some other hash, say
 | 
			
		||||
SHA-256, would be silently ignored. Now an exception is thrown, indicating the
 | 
			
		||||
desired hash is not compatible with the algorithm.
 | 
			
		||||
 | 
			
		||||
In previous versions, various APIs required that the application specify the
 | 
			
		||||
hash function to be used. In most cases this can now be omitted (passing an
 | 
			
		||||
empty string) and a suitable default will be chosen.
 | 
			
		||||
 | 
			
		||||
Discrete Logarithm Key Changes
 | 
			
		||||
--------------------------------
 | 
			
		||||
 | 
			
		||||
Keys based on the discrete logarithm problem no longer derive from the
 | 
			
		||||
DL_Scheme_PrivateKey and DL_Scheme_PublicKey classes; these classes
 | 
			
		||||
have been removed.
 | 
			
		||||
 | 
			
		||||
Functions to access DL algorithm internal fields (such as the integer value of
 | 
			
		||||
the private key using ``get_x``) have been removed. If you need access to this
 | 
			
		||||
information you can use the new ``get_int_field`` function.
 | 
			
		||||
 | 
			
		||||
The constructors of the DL scheme private keys have changed. Previously, loading
 | 
			
		||||
and creating a key used the same constructor, namely one taking arguments
 | 
			
		||||
``(DL_Group, RandomNumberGenerator&, BigInt x = 0)`` and then the behavior of
 | 
			
		||||
the constructor depend on if ``x`` was zero (in which case a new key was
 | 
			
		||||
created) or otherwise if ``x`` was non-zero then it was taken as the private
 | 
			
		||||
key. Now there are two constructors, one taking a random number generator and a
 | 
			
		||||
group, which generates a new key, and a second taking a group and an integer,
 | 
			
		||||
which loads an existing key.
 | 
			
		||||
 | 
			
		||||
XMSS Signature Changes
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
The logic to derive WOTS+ private keys from the seed contained in the XMSS
 | 
			
		||||
private key has been updated according to the recommendations in
 | 
			
		||||
NIST SP 800-208. While signatures created with old private keys are still valid using
 | 
			
		||||
the old public key, new valid signatures cannot be created. To still support legacy
 | 
			
		||||
private XMSS keys, they can be used by passing ``WOTS_Derivation_Method::Botan2x`` to
 | 
			
		||||
the constructor of the ``XMSS_PrivateKey``.
 | 
			
		||||
 | 
			
		||||
Private XMSS keys created this way use the old derivation logic and can therefore
 | 
			
		||||
generate new valid signatures. It is recommended to use
 | 
			
		||||
``WOTS_Derivation_Method::NIST_SP800_208`` (default) when creating new XMSS keys.
 | 
			
		||||
 | 
			
		||||
Random Number Generator
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
Fetching a large number of bytes via `randomize_with_input()` from a stateful
 | 
			
		||||
RNG will now incorporate the provided "input" data in the first request to the
 | 
			
		||||
underlying DRBG only. This applies to such DRBGs that pose a limit on the number
 | 
			
		||||
of bytes per request (most notable ``HMAC_DRBG`` with a 64kB default). Botan 2.x
 | 
			
		||||
(erroneously) applied the input to *all* underlying DRBG requests in such cases.
 | 
			
		||||
 | 
			
		||||
Applications that rely on a static seed for deterministic RNG output might
 | 
			
		||||
observe a different byte stream in such cases. As a workaround, users are
 | 
			
		||||
advised to "mimick" the legacy behaviour by manually pulling from the RNG in
 | 
			
		||||
"byte limit"-sized chunks and provide the "input" with each invocation.
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,54 +0,0 @@
 | 
			
		||||
Notes for Distributors
 | 
			
		||||
========================
 | 
			
		||||
 | 
			
		||||
This document has information for anyone who is packaging copies of Botan for
 | 
			
		||||
use by downstream developers, such as through a Linux distribution or other
 | 
			
		||||
package management system.
 | 
			
		||||
 | 
			
		||||
Recommended Options
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
In most environments, zlib, bzip2, and sqlite are already installed, so there is
 | 
			
		||||
no reason to not include support for them in Botan as well. Build with options
 | 
			
		||||
``--with-zlib --with-bzip2 --with-sqlite3`` to enable these features.
 | 
			
		||||
 | 
			
		||||
Set Path to the System CA bundle
 | 
			
		||||
---------------------------------
 | 
			
		||||
 | 
			
		||||
Most Unix/Linux systems maintain a list of trusted CA certificates at some well
 | 
			
		||||
known path like ``/etc/ssl/certs/ca-certificates.crt`` or
 | 
			
		||||
``/etc/ssl/cert.pem``. Unfortunately the exact path varies between systems. Use
 | 
			
		||||
``--system-cert-bundle=PATH`` to set this path. If the option is not used,
 | 
			
		||||
``configure.py`` tries a list of known locations.
 | 
			
		||||
 | 
			
		||||
Set Distribution Info
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
If your distribution of Botan involves creating library binaries, use the
 | 
			
		||||
configure.py flag ``--distribution-info=`` to set the version of your
 | 
			
		||||
packaging. For example Foonix OS might distribute its 4th revision of the
 | 
			
		||||
package for Botan 2.1.3 using ``--distribution-info='Foonix 2.1.3-4'``. The
 | 
			
		||||
string is completely free-form, since it depends on how the distribution numbers
 | 
			
		||||
releases and packages.
 | 
			
		||||
 | 
			
		||||
Any value set with ``--distribution-info`` flag will be included in the version
 | 
			
		||||
string, and can read through the ``BOTAN_DISTRIBUTION_INFO`` macro.
 | 
			
		||||
 | 
			
		||||
Minimize Distribution Patches
 | 
			
		||||
------------------------------
 | 
			
		||||
 | 
			
		||||
We (Botan upstream) *strongly* prefer that downstream distributions maintain no
 | 
			
		||||
long-term patches against Botan. Even if it is a build problem which probably
 | 
			
		||||
only affects your environment, please open an issue on github and include the
 | 
			
		||||
patch you are using. Perhaps the issue does affect other users, and even if not
 | 
			
		||||
it would be better for everyone if the library were improved so it were not
 | 
			
		||||
necessary for the patch to be created in the first place. For example, having to
 | 
			
		||||
modify or remove a build data file, or edit the makefile after generation,
 | 
			
		||||
suggests an area where the build system is insufficiently flexible.
 | 
			
		||||
 | 
			
		||||
Obviously nothing in the BSD-2 license prevents you from distributing patches or
 | 
			
		||||
modified versions of Botan however you please. But long term patches by
 | 
			
		||||
downstream distributors have a tendency to bitrot and sometimes even result in
 | 
			
		||||
security problems (such as in the Debian OpenSSL RNG fiasco) because the patches
 | 
			
		||||
are never reviewed by the library developers. So we try to discourage them, and
 | 
			
		||||
work to ensure they are never necessary.
 | 
			
		||||
@@ -1,169 +0,0 @@
 | 
			
		||||
The following PGP key is used to sign all releases:
 | 
			
		||||
 | 
			
		||||
pub   2048R/EFBADFBC 2004-10-30
 | 
			
		||||
      Key fingerprint = 621D AF64 11E1 851C 4CF9  A2E1 6211 EBF1 EFBA DFBC
 | 
			
		||||
uid                  Botan Distribution Key
 | 
			
		||||
 | 
			
		||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
 | 
			
		||||
Version: GnuPG v2.0.17 (GNU/Linux)
 | 
			
		||||
 | 
			
		||||
mQELBEGD1j0BCADHxPJkPcjJE+4Dlisx2hVc0Dj6JI1MSLrkM8R+2bOhVUSferxP
 | 
			
		||||
T1EMPhfrAdOHTAloyvRThJztnZsNKqfLL49GGcBLdEGAVNks1pG37Teze5Lx1XIu
 | 
			
		||||
zJFrozL2sqBy5C6nHpFgd1tcD68Rah2wp0u2cR9owXf1IqKdEfuo661+MTv7wTB1
 | 
			
		||||
4hKV75nB7ZO6676SEZRILYM+7RJwKAKEmEPJc6hEf94VXn9ecNzaTlHgYkjhz9db
 | 
			
		||||
LOd3od9XvuUw+LMR1dwBqMxbvR90MiXjbedDEkbArcZB9YOAIvEX/lC3qaW4XJt4
 | 
			
		||||
iwHWl/YVZEfALcvQywe2CDrH5hO794wd9MpBAAYptBZCb3RhbiBEaXN0cmlidXRp
 | 
			
		||||
b24gS2V5iQEqBBMBAgAUAhsDAh4BAheABQJKfFpnBBUKCQgACgkQYhHr8e+637xk
 | 
			
		||||
PQf/aOi78XenwwvFrwXOVIVTdZIf8rK1zJksf26h09UD8uVV6z5iiTcpn86+eN9p
 | 
			
		||||
6Ar8IH3tD+JuFnPSwZ/r9MNC2XZwenYo4Gb14jqM6/9hBe328vmeM4Y1G7bD4HrL
 | 
			
		||||
kgV5WEyokqm3zbp3FBLr3Vh68TAC5JB9aHevra+cCA2u3vBNI3YUM5z4TdO150P3
 | 
			
		||||
J00whkqImQEUni8bgxvllBLFM+uhucsX3HZWkoDEpotbg8yd0bqMkiPEyMr1OnJq
 | 
			
		||||
eDVDMrB5wnyLgLFfRAAw3mopM0C1PNOAHr/BIYiaDHX2OwnOfep8rMDoRVf2Ge0D
 | 
			
		||||
DBgsJJ6LduQHLeg403SHWL2F6YkCHAQTAQIABgUCQYPWUgAKCRBcD5boTsFta+r9
 | 
			
		||||
EACWVis7YcaGkKKgRB/5ox8rM36XVhMXdh/hnnGHt5rapbbRRkRHRcWU8WIcFO1A
 | 
			
		||||
59+TfwNNd8gN1MEt/5aX5KHWVKHBDexJgIxm6Dm1pisYHf/dnYQPM18hmqqwNlKY
 | 
			
		||||
97hFkPpHd7enrtc/SvGbQhhLXYlpwBrdMl76e9xJLnnrRQksxegGPo8cr+C9HTs1
 | 
			
		||||
Lwa8zzBxyBwYBYX+0moDkDShEhuXx6mEOXrGvQanJuIvpoIwGH+62E65MbJGlwWp
 | 
			
		||||
w/MAtm2jFhBIhGV0bqJCFp9zIgdNgfskBaPr0oilbuJQZqP0Iqe/6CCt4XkS51yW
 | 
			
		||||
ZqxjLAFpEpvDec4PGw3witKf/koGon9X8C035+nEjLBrWy18Q91vw2USyLI+mm9d
 | 
			
		||||
iMAS8pY2gomfxBO2VwYHJryZykjCYQkccRA1tHteRj4gqTObo0Ak47y5MnplTWwi
 | 
			
		||||
40oP7K2cfhCRBmMioxmYES4xsHEupfRBo3xr1Jq9q0t688WTT1NXHPMPoueF9mKZ
 | 
			
		||||
Cf2pa9aHsqBmWTm3sCaNQKGubCDBEUmJUyndmSatJyYM7NVYoUp6EfqMACFuTNdB
 | 
			
		||||
sjKMh7aWVikQpbJDfA1BIU3lZeqgjgrghVAWkEOBfhG0IVZj+RVCJpsqoTJ8asY2
 | 
			
		||||
VreArSCyr/VnLEnfuH/QpgvCiCbepo3E34DJt4SaAOO2ZohGBBARAgAGBQJMGVc1
 | 
			
		||||
AAoJEKY/LL36AvvMgsoAn2G7kXd09BF7ffk1Sfh174SVrvM9AKC7+R7x0+yV3SCd
 | 
			
		||||
JkkUOo3xR5cOxw==
 | 
			
		||||
=1QuR
 | 
			
		||||
-----END PGP PUBLIC KEY BLOCK-----
 | 
			
		||||
 | 
			
		||||
This key can be used to contact the primary maintainer:
 | 
			
		||||
 | 
			
		||||
pub   rsa3072/57123B60 2015-03-23
 | 
			
		||||
      Key fingerprint = 4E60 C735 51AF 2188 DF0A  5A62 78E9 8043 5712 3B60
 | 
			
		||||
      uid            Jack Lloyd <jack@randombit.net>
 | 
			
		||||
 | 
			
		||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
 | 
			
		||||
 | 
			
		||||
mQGNBFUQXRMBDACZJvcSkr+GNDtIdP9fQWRXByriiIKvuKbqU8KGdhTcPeKwl3y3
 | 
			
		||||
l1W9XsWA2DJ8QDKo4ZcV0lycszIvwBLZllJJWSVNFKxJK2IW33xcIo9dhNqj+hcz
 | 
			
		||||
LxKtBlBU3QKXdQ9+VKSY4EpO6gt/ar21PV+EQcFA9UtT1mRKVqY0pGGxqfQjrOss
 | 
			
		||||
rJKoJyA+1trH4ir7+0/524HNzsBj3B1GmrYfstspqetXyVQ1DoFiThUnj/zJGes5
 | 
			
		||||
uW9laI9VBgrtMTBbYrylBytXiF0Flzx+bd21krgL37NH2uU0EHPjSx571q/XGG2U
 | 
			
		||||
4iOEPvPu7vtV8Rpqd0xQyaHcpoHNklcfND1c/6uZG1Sx9atDScRYHinUZvtTRtN+
 | 
			
		||||
OY5vW+H7LJqT6CeMjh6Ev53V+0JCDZFQLaBdP/NanSQBUhPkyfyQSiqWOSuaMD6n
 | 
			
		||||
Eu+BigmzwDlsauuReTJ65gdIGI9Egt7Ax/ooKpBvPkWeT+GORKTs+qGy6sbKXrTe
 | 
			
		||||
crFFN/HZPWAJ+c8AEQEAAbQfSmFjayBMbG95ZCA8amFja0ByYW5kb21iaXQubmV0
 | 
			
		||||
PokB0QQTAQoAOwIbAwULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgBYhBE5gxzVRryGI
 | 
			
		||||
3wpaYnjpgENXEjtgBQJlIUveAhkBAAoJEHjpgENXEjtg9d0L/iMxl7bVhwrRNUDo
 | 
			
		||||
fdxZoCVPqPBnA29uiwN4Ff8VIr5yiA39DYAD14PoQN8+mVc9+0P5ersLanszSg7b
 | 
			
		||||
ZMLd1s39Ryydy2YfXqk9jHlDOFpsimknAd+NEYYPrRTQ+dybk9qoL/qeNxZl7Oig
 | 
			
		||||
/GyMS96I9PDHLx43gBe4OsIe+QB2ulgVTMIDwnMyeuaIDRmL+w4+caTxKBj4fwtV
 | 
			
		||||
3SN1VSugEV1Uli0Ofk1yp+NsEIVyOJCi7mV/KLmffdAMqSoBnHZvNqz65i4Tt2mV
 | 
			
		||||
PvEb5Xvh5E4HBGLCFNj5XEFZmWvjOhkx7XyaJBqHS2I3j/JWGhpLDXwITlpQLBMi
 | 
			
		||||
ssstlL4ju+STOCfGWDQjOxFGelgbjD54Pu2N/TlidT5FORLguR0Eqtb0A6gYybNh
 | 
			
		||||
UY/dJqbSPegd9xFWszrnO5o7sV3O1x5oWIOkEi/IYhy9SschPPi3m5RI7qJt6PRI
 | 
			
		||||
TfF5IBx9GQQtDnrQnbCHB3+BkVuixbEOORmYxm1sR79NE8UTerQgSmFjayBMbG95
 | 
			
		||||
ZCA8bGxveWRAcmFuZG9tYml0Lm5ldD6JARwEEAEIAAYFAlYaUEwACgkQYhHr8e+6
 | 
			
		||||
37zLeQf+OdP/xE2YyFUJL1+xEKHpvAeN+98Vn1C2sTmotNIaPwVBY9FLeA484IWd
 | 
			
		||||
FwnJfXx1gQyybxlytz4BZuC7Jzu60OEmk5IFRIqQoVywEXWCOUg/UEBWZm+ZcRzI
 | 
			
		||||
Fciqj9PcOfpt6s/aSZd5+Rcm5HUGALYCqek2s9nGO8a1Wnk4m9d1u/RAGlxFM2th
 | 
			
		||||
e1v5p597ItGhcOP3tjWVPPOuTe0E+/FI3ZxpotKGdfS6F/GB2bP7kma2iVO621Cs
 | 
			
		||||
9wsYmrZEamKpax7X7p9myaAG0YRdCTslFd/EOTLOllPhy58DTr7qyswBPEI0x8WE
 | 
			
		||||
DTE0G0IdQYNmLq4kuzeOaIlcUMULzYkBuQQTAQIAIwUCVRBdEwIbAwcLCQgHAwIB
 | 
			
		||||
BhUIAgkKCwQWAgMBAh4BAheAAAoJEHjpgENXEjtgjxoL/0ZjgM16mq2imrViVjVe
 | 
			
		||||
u3IuDe0bMq8lUdfDTuQZmK68U5hclwPO4qEVoa4grEn7s++t45fJwP/39YVfILC+
 | 
			
		||||
FzMyBtF/eUWqSNB2a+fCYgZR9kvemqiskN1KMqJpeTz80kEQEeVM3X31sUQJPMGv
 | 
			
		||||
jyR4YevNQ9RiHZTfCjwI1blmwcceaJuN6g6l90uAr52dQ3A6Tf+cRm1ZR31xPAKd
 | 
			
		||||
3m/LG3sjWnWe1vcksAR3jPnB3Zp8kduNBne6JNAFcNR3U8Ufojp8jsv5R5T60Y09
 | 
			
		||||
7d97ob7M2HGYk8oE8TDNMD+vqK4utDA0Edg9ibon98oENTXXsefC7Phb1FJVWu2L
 | 
			
		||||
MJYhtroSm0V6dyKCu4Ido7gJZsWXvUK7yfqJsQg0d0qkT2pDNIPmQd/CwnoVWeX1
 | 
			
		||||
CTzImqH1Ts0X8LyEctukX0nmfhZ83epnIWlQxuwRWnpGG/85ufHBqo1hYKoLKIJr
 | 
			
		||||
Cw2T/+Szhev4eZ48ndcD2XO+BUKgwStr6fVFscIQYialSYkB0AQTAQoAOgIbAwcL
 | 
			
		||||
CQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAFiEETmDHNVGvIYjfClpieOmAQ1cSO2AF
 | 
			
		||||
AmUhSvkACgkQeOmAQ1cSO2A22QwAk8/mcCQOeBn8mHgeoYiaSTW1JoIC0fIagMPh
 | 
			
		||||
hp2eAbPofk/I3L443t31Ye4YSMjqF7YiyNo063qBBQoyok4kT3hftnIrml8CwIO0
 | 
			
		||||
33pREPKg3dgU/t+4cOIFlBYiCYn5T3SLjGAL5vlxzTmSKX1Xu79uo+EKa7G2u5hM
 | 
			
		||||
Gpz5rDXkPgSyZ19/uDu+01CG+JlwHgwOh8bZQSu0/Jg8Qu0ecc87ENpR+eFXqlSL
 | 
			
		||||
hzdYJ6XPTC6RN/LQFLxTcR8TQ15ThRK6LEocZadg1kJDeadcdM8aRYPI2S7aLCha
 | 
			
		||||
MnqUzckYdDSW40Bsg0PdxNKTDSBoa7vPbDMR/XkAd03bRGzdezxbr7m7SHOzjnmY
 | 
			
		||||
SXhAlnkVH6ouSM0GFarWqIeMe6isDiKX8LKdWNySEiMuSuTz2KX15ZedOcYPksdb
 | 
			
		||||
DfC0tuQUL6O3plsIGJWy9fVOrLnW6D+P77AlHQsRe7OxlFo3Jhsf4FdsD4cLXVN4
 | 
			
		||||
r/fngFYkokBOv3rGp+aXcEF5uYKAtCFKYWNrIExsb3lkIDxqYWNrLmxsb3lkQGdt
 | 
			
		||||
YWlsLmNvbT6JAc4EEwEKADgCGwMFCwkIBwIGFQgJCgsCBBYCAwECHgECF4AWIQRO
 | 
			
		||||
YMc1Ua8hiN8KWmJ46YBDVxI7YAUCZSFK4QAKCRB46YBDVxI7YGvdC/4jdtd4Qfo2
 | 
			
		||||
i4VUmOrjJ1sFiSehutOCsTAweDDyqUjxmXaMLOlPAeVp9Nq/kUtO4qtLac5sRBxX
 | 
			
		||||
KigxjrBYJpBq0cK9nYnMEHdX86uXhfvclFQIxzvwkC3pYQgZcD9XfduUTiJeNGrh
 | 
			
		||||
mQbyopcfbKzv3Q5j4v1H4s61L3LySIDxvZYvzgQEcCrG89+gxlsG2eWMuPySBICE
 | 
			
		||||
skEAe/2rLuGKcSSFTJXpVAkB9r8o9cOHSw63BydvL5o1T1KeDs4cZD1KUlJ2VaBf
 | 
			
		||||
W1IoaXynUIHcti1h8iHWNifirgtSRSezz5/G3JeQ8cUSyC4bkMXmQulrHUUCuhZ6
 | 
			
		||||
GxqtxAEQ8rUrNV8G9xZrU0VP1un3c0RGS4kz2IKa1uk1FEnxDa6YQaExwrHbWzR0
 | 
			
		||||
8YX1zl7/lekdE1tjRrqIdpzu84MiLHraEvX5agrbdv3F59cJB5lYTXsYaX/8rgus
 | 
			
		||||
AFdFAQA87MfUKVo38fBZF4BKFu8goGUP7UeGIuZGExavIAjzQkDrUwO5AY0EVRBd
 | 
			
		||||
EwEMAN6NE/fR/Ours4jc6SaVocKSZ+/pGXVrxQ/ZFoba7kJq09DLQZ21vHYkq7wM
 | 
			
		||||
rAta9D6gH5bLZ90xI6ScyR9fYTWYDXdDHx8Sg7Mj3ZKhxjr1tQicRPT6BP4WLqBI
 | 
			
		||||
CdlUWV//OCRFk13G8feDO+ZT8YP/dVUrj3n9/mwfOHm7Npb7PHX/LFuDyo/1EXZZ
 | 
			
		||||
yqw3/LlI+z+1uBKFYD2WqzLw8Sm/U+ajzP6y04wUkf45VjLkFI2bPk6CVYNt2TvO
 | 
			
		||||
EzIO3zBAN6DSLSFOTYn9UwR2vrpvoJsDjjSRjcjbZ/8uFCWfLhgTwMeQcH0jxHr4
 | 
			
		||||
7Qs2coApHBAIB57eS6Z/y4Vja3Y0ANpb51Fu7MDPXQXW4g89GMTIEKu2/KUN/onG
 | 
			
		||||
IYh6Js9RYNf8SJ+waQ0NULXAMk1AAfknl2Apl9gKRDH6EvevQXPVI6ElOTZw4gqG
 | 
			
		||||
z9xGqC+gbmh2UmS5n8B/nK2d0AMN+1elZAapTFFdOMhMdDeBk+1GRQ/t/zsLTUPS
 | 
			
		||||
SRVLFwARAQABiQGfBBgBAgAJBQJVEF0TAhsMAAoJEHjpgENXEjtg3rgMAIDJgnuE
 | 
			
		||||
Y7neuJMIzHyO59a8X+9ip9XfeDNwjaqJk0rIoqSdkIqjG8I6C4lbeL0pnGzliudv
 | 
			
		||||
EmQij4hnSNfOUk58oGyRdyUeK9eC2KeZ+Hs3sqMuAhlYIh+RR6ifo5kqxR/geo6i
 | 
			
		||||
XKS8VqDQRiqoSSrLqhIU7kQiFcQWc3wYaSOUXNpZzvlTlMYM4qP9Yrzu8dG1tKST
 | 
			
		||||
3fmWi8l9/TmHIPtskgB0dzTdkKe2kZpJFFquYtorWtCQwF+wmtA02NMHwrQzwh/R
 | 
			
		||||
qNz9wUEwhQVBa/A8p0wdEskLFQZXt3PnY8GHQVz59tArolw3kes0/VrtgCUFS7tv
 | 
			
		||||
mn9xI6lJxveQiN6Ec2z5gbwKBShkSvopi0g83YLeSNPrCIBmLSCOm1AjsXF3sQaz
 | 
			
		||||
EYqAGhB6qibCsuebxnprq8Qa/j0wsq7n8ZO7a6cdcnhu4fF3YdWcaWlCUKzzWb8W
 | 
			
		||||
XXoeCaOKxmD5IgsGiAxnPKvsBge1rMhlCoJJhJEmUlwxoP67Nt2mHbYh/Q==
 | 
			
		||||
=4XG/
 | 
			
		||||
-----END PGP PUBLIC KEY BLOCK-----
 | 
			
		||||
 | 
			
		||||
This key is used for signing git commits:
 | 
			
		||||
 | 
			
		||||
pub   rsa2048 2016-03-03 [SC] [expires: 2028-03-01]
 | 
			
		||||
      117510149DF418ABD19CB06D9FFD596FAB50F90D
 | 
			
		||||
uid           Jack Lloyd (Git Signing Key) <jack@randombit.net>
 | 
			
		||||
 | 
			
		||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
 | 
			
		||||
 | 
			
		||||
mQENBFbYWi4BCACjgz3gYgWMybPLiovNLnLonG0ex2y9kJgsR+Pm08L2fwCVCaHx
 | 
			
		||||
wjlK5Oq04x3bvujZk7P0TThqS1WonYtEiVxz3Hcvt7rlU5fSCj/1uYmZV+mbPBdY
 | 
			
		||||
f/yXMx3UD1UkZrdzbM21L78dfOoLZ2ybyuk4QOEad/AkouDCUA2pY3DJdNyX8Aee
 | 
			
		||||
dBdQ+sQqF6DyDz4SDY+KAq3nFmmT04bdkiL9sZb2HUokxIdeA6HIR+CxxFaZzrYW
 | 
			
		||||
Ky4iNPS1Zxv5D1KmpZzUOfN9RTgkbdRltgWxjpB+DFNUkpu3hYm/Y9lTPqGBt2C8
 | 
			
		||||
JfIS5OaHxUVz0A+DtIGy+lk8/O5ek4suQBZ3ABEBAAG0MUphY2sgTGxveWQgKEdp
 | 
			
		||||
dCBTaWduaW5nIEtleSkgPGphY2tAcmFuZG9tYml0Lm5ldD6JAVcEEwEIAEECGwMF
 | 
			
		||||
CwkIBwIGFQgJCgsCBBYCAwECHgECF4ACGQEWIQQRdRAUnfQYq9GcsG2f/Vlvq1D5
 | 
			
		||||
DQUCZAH4lgUJFo+f6AAKCRCf/Vlvq1D5DfCYB/0TXJ9WuuL5cgXJLK6IyvrlJJvp
 | 
			
		||||
mncY2PDzfscgO8jWLGfnhOO/Fiy6JvSXmllgNiSufNbaaq3c9wx+qXY7qqUbwiM8
 | 
			
		||||
w0bokFyVCbIc+Y7d7q359mdFFx0U8NWuQStkeGQ7GcckMLZ2rftY4fyBgeL0MiuH
 | 
			
		||||
YpzWpFgvmllB+vVniHAh79VMQqnR42Y7r6W5XWYmz6AmpBlI7IOLY272k6nyu7Qr
 | 
			
		||||
SGlKVU3XctvKS8RAEqvD6CSbls9tXcEZ9XEcOxvUPAgb+NRN7aXbHed3eE8s4NBY
 | 
			
		||||
Z2vPDgPBCQ423PRnB+McFVHA+N7fdMGOcxkkDi0F1DcgSAcyMuiJFns88BKgiQE9
 | 
			
		||||
BBMBCAAnBQJYD2ybAhsDBQkHhM4ABQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJ
 | 
			
		||||
EJ/9WW+rUPkNXfIIAIOgepYeZN2HL2T3A8pk+5JR2cfBoRufYgnG6mVHPejgZDW+
 | 
			
		||||
9PH1tPDgidnePw3/jfD1oskt1VwOCkqaSBAcG2QeOBEklcsrQuvOfW7B7XFydYGw
 | 
			
		||||
T9Fm8/sxekiGjDQQWQEEH4j3Vt1GlI2sJrpqMe/WMXISsEnLfw0kDspUSlFOn8oy
 | 
			
		||||
rBU9Pd8KaSi38lp05a9Mcun5enJ3JpQHQ5RlNXDNh/Sn9NZ+MKWggytZqIy82jnv
 | 
			
		||||
6zo0raZDup4hLKopjen/SINR5XcwRK2lUtYVwwQH8FHG9IkeVJNWJkVCdZLB08sq
 | 
			
		||||
4WHRbtVjy6mpvEHTmolAtHjLSiV5W50LDKLwX260MkphY2sgTGxveWQgKEdpdCBT
 | 
			
		||||
aWduaW5nIEtleSkgPGxsb3lkQHJhbmRvbWJpdC5uZXQ+iQFUBBMBCAA+AhsDBQsJ
 | 
			
		||||
CAcCBhUICQoLAgQWAgMBAh4BAheAFiEEEXUQFJ30GKvRnLBtn/1Zb6tQ+Q0FAmQB
 | 
			
		||||
+J0FCRaPn+gACgkQn/1Zb6tQ+Q1DIAgAlR0igunTJjz38Zs9M8rWr5OzeG9Hbkse
 | 
			
		||||
mClFcH2TPGxLIjI5eMLLjVbxyQkeP2rjaZb/bnuzrohQ5X6Le0LZQA77khFkWpRZ
 | 
			
		||||
HQ0wDHGSLlLeSD9BiPmhf4drDf8/M+QXA5kTxEHMyKxPsLaOhXYgHPyYQcS3R+H4
 | 
			
		||||
6jIVmCB5PyYynsSKhFoUiFcBbURApAagaUTf/TGzcaXDGzKkdA6X5g1xlLt+3GTK
 | 
			
		||||
3aKwOLN7RhMYLz1V6FwblLUYSgpwuAmDfGayNVcBkhK/Qg4yPT0M25H5tLrELh2L
 | 
			
		||||
fvkeuV29sD3005sI3t+4T4yTCNOCcahaRCaFfUKpyZk7OyUYXRAPaokBnAQQAQgA
 | 
			
		||||
BgUCVthcNwAKCRB46YBDVxI7YLwrC/95sk2uEyiScbl1I9UmknEvS1r+bgpgGNf3
 | 
			
		||||
hWwHo5/P3pSac2UJ70TFuLTZ5wvKBB8H1RS/ueys5EY5KggQhX9FJiA3Z5hQzbUM
 | 
			
		||||
d12WBUbcNNGsb/+JXqvMB2CRl1GTEGGfN4UlG/hMyadFBczbH6COiCcNYumOB2+R
 | 
			
		||||
EVy/mXp9MfbgiV1x3Kae+aoGawu+qgoWPXcK2wOOeCnmAaCn+J4hbqw+aBBfWkkJ
 | 
			
		||||
YcUN7/SpyO+7LR8oyrQ7J3T/x1cKc1rA9v/3GVBj6UKkcgt+8WxW3Ll2OoeoM0oQ
 | 
			
		||||
G5jHI+McgI8ZG6RIr7MJLQQTyfP+jGivg4ivmy9rB8g7lnDr1RKjTWML4rU5JElC
 | 
			
		||||
2EV+3kapPCR8eeJglJWHsrWs8j8ffm1/5dksHCVp9azu9Bvxdl8A/OGrD1uVzlFL
 | 
			
		||||
jvyurM1DQXU8chONtpIKQwKBo1rZp5qgjD25COnq4HZPjEYB6qx3ok+uvmDVVkU+
 | 
			
		||||
q2Fd2IO7omY3hpWSwb9ILHYLC/aqK5I=
 | 
			
		||||
=fsUW
 | 
			
		||||
-----END PGP PUBLIC KEY BLOCK-----
 | 
			
		||||
@@ -1,43 +0,0 @@
 | 
			
		||||
 | 
			
		||||
Development Roadmap
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Near Term Plans
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
Here is an outline for the development plans over the next 12-24 months,
 | 
			
		||||
as of February 2023.
 | 
			
		||||
 | 
			
		||||
Botan 2
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
Botan 2 is still supported, but no further feature work is planned.
 | 
			
		||||
Only security issues and serious bugs will be addressed.
 | 
			
		||||
 | 
			
		||||
Botan 3
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
The following future work is currently planned for Botan 3:
 | 
			
		||||
 | 
			
		||||
* BSI Project 481 [https://github.com/randombit/botan/issues/3108]
 | 
			
		||||
  will add several new post-quantum algorithms including SPHINCS+
 | 
			
		||||
  signatures, LMS signatures, FrodoKEM, and Classic McEliece.
 | 
			
		||||
 | 
			
		||||
* New ECC based password authenticated key exchanges, to replace SRP.
 | 
			
		||||
  The most likely candidate algorithms are CPace, OPAQUE, or SPAKE2+.
 | 
			
		||||
 | 
			
		||||
* Adding an implementation of BLS12-381 elliptic curve pairing.
 | 
			
		||||
 | 
			
		||||
* Low level integer math and elliptic curve arithmetic optimizations.
 | 
			
		||||
 | 
			
		||||
Botan 4
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
At this time there is no immediate plan for a new major version. When it occurs,
 | 
			
		||||
it will remove functionality currently marked as deprecated, and adopt a new C++
 | 
			
		||||
version. This is unlikely to occur before 2026, at the earliest.
 | 
			
		||||
 | 
			
		||||
One major change already planned for Botan 4 is that in this release, Public_Key
 | 
			
		||||
will no longer derive from Private_Key. And similarly, specific private keys
 | 
			
		||||
(for example RSA_PrivateKey) will no longer derive from their cooresponding
 | 
			
		||||
public key type.
 | 
			
		||||
@@ -1,390 +0,0 @@
 | 
			
		||||
 | 
			
		||||
.. highlight:: none
 | 
			
		||||
 | 
			
		||||
Security Advisories
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
If you think you have found a security bug in Botan please contact
 | 
			
		||||
Jack Lloyd (jack@randombit.net). If you would like to encrypt your
 | 
			
		||||
mail please use::
 | 
			
		||||
 | 
			
		||||
  pub   rsa3072/57123B60 2015-03-23
 | 
			
		||||
        Key fingerprint = 4E60 C735 51AF 2188 DF0A  5A62 78E9 8043 5712 3B60
 | 
			
		||||
        uid         Jack Lloyd <jack@randombit.net>
 | 
			
		||||
 | 
			
		||||
This key can be found in the file ``doc/pgpkey.txt`` or online at
 | 
			
		||||
https://keybase.io/jacklloyd and on most PGP keyservers.
 | 
			
		||||
 | 
			
		||||
2022
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2022-11-16: Failure to correctly check OCSP responder embedded certificate
 | 
			
		||||
 | 
			
		||||
  OCSP responses for some end entity are either signed by the issuing CA certificate of
 | 
			
		||||
  the PKI, or an OCSP responder certificate that the PKI authorized to sign responses in
 | 
			
		||||
  their name. In the latter case, the responder certificate (and its validation path
 | 
			
		||||
  certificate) may be embedded into the OCSP response and clients must verify that such
 | 
			
		||||
  certificates are indeed authorized by the CA when validating OCSP responses.
 | 
			
		||||
 | 
			
		||||
  The OCSP implementation failed to verify that an authorized responder certificate
 | 
			
		||||
  embedded in an OCSP response is authorized by the issuing CA. As a result, any valid
 | 
			
		||||
  signature by an embedded certificate passed the check and was allowed to make claims
 | 
			
		||||
  about the revocation status of certificates of any CA.
 | 
			
		||||
 | 
			
		||||
  Attackers that are in a position to spoof OCSP responses for a client could therefore
 | 
			
		||||
  render legitimate certificates of a 3rd party CA as revoked or even use a compromised
 | 
			
		||||
  (and actually revoked) certificate by spoofing an OCSP-"OK" response. E.g. an attacker
 | 
			
		||||
  could exploit this to impersonate a legitimate TLS server using a compromised
 | 
			
		||||
  certificate of that host and get around the revocation check using OCSP stapling.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.34, fixed in 2.19.3
 | 
			
		||||
 | 
			
		||||
2020
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2020-12-21 (CVE-2021-24115): Codec encoding/decoding was not constant time
 | 
			
		||||
 | 
			
		||||
  The base64, base32, base58 and hex encoding/decoding routines used lookup
 | 
			
		||||
  tables which could leak information via a cache-based side channel attack.
 | 
			
		||||
  The encoding tables were small and unlikely to be exploitable, but the
 | 
			
		||||
  decoding tables were large enough to cause non-negligible information
 | 
			
		||||
  leakage. In particular parsing an unencrypted PEM-encoded private key within
 | 
			
		||||
  an SGX enclave could be easily attacked to leak key material.
 | 
			
		||||
 | 
			
		||||
  Identified and reported by Jan Wichelmann, Thomas Eisenbarth,
 | 
			
		||||
  Sebastian Berndt, and Florian Sieck.
 | 
			
		||||
 | 
			
		||||
  Fixed in 2.17.3
 | 
			
		||||
 | 
			
		||||
* 2020-07-05: Failure to enforce name constraints on alternative names
 | 
			
		||||
 | 
			
		||||
  The path validation algorithm enforced name constraints on the primary DN
 | 
			
		||||
  included in the certificate but failed to do so against alternative DNs which
 | 
			
		||||
  may be included in the subject alternative name. This would allow a corrupted
 | 
			
		||||
  sub-CA which was constrained by a name constraints extension in its own
 | 
			
		||||
  certificate to issue a certificate containing a prohibited DN. Until 2.15.0,
 | 
			
		||||
  there was no API to access these alternative name DNs so it is unlikely that
 | 
			
		||||
  any application would make incorrect access control decisions on the basis of
 | 
			
		||||
  the incorrect DN. Reported by Mario Korth of Ruhr-Universität Bochum.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.29, fixed in 2.15.0
 | 
			
		||||
 | 
			
		||||
* 2020-03-24: Side channel during CBC padding
 | 
			
		||||
 | 
			
		||||
  The CBC padding operations were not constant time and as a result would leak
 | 
			
		||||
  the length of the plaintext values which were being padded to an attacker
 | 
			
		||||
  running a side channel attack via shared resources such as cache or branch
 | 
			
		||||
  predictor. No information about the contents was leaked, but the length alone
 | 
			
		||||
  might be used to make inferences about the contents. This issue affects TLS
 | 
			
		||||
  CBC ciphersuites as well as CBC encryption using PKCS7 or other similar padding
 | 
			
		||||
  mechanisms. In all cases, the unpadding operations were already constant time
 | 
			
		||||
  and are not affected. Reported by Maximilian Blochberger of Universität
 | 
			
		||||
  Hamburg.
 | 
			
		||||
 | 
			
		||||
  Fixed in 2.14.0, all prior versions affected.
 | 
			
		||||
 | 
			
		||||
2018
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2018-12-17 (CVE-2018-20187): Side channel during ECC key generation
 | 
			
		||||
 | 
			
		||||
  A timing side channel during ECC key generation could leak information about
 | 
			
		||||
  the high bits of the secret scalar. Such information allows an attacker to
 | 
			
		||||
  perform a brute force attack on the key somewhat more efficiently than they
 | 
			
		||||
  would otherwise. Found by Ján Jančár using ECTester.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.20, fixed in 2.8.0.
 | 
			
		||||
 | 
			
		||||
* 2018-06-13 (CVE-2018-12435): ECDSA side channel
 | 
			
		||||
 | 
			
		||||
  A side channel in the ECDSA signature operation could allow a local attacker
 | 
			
		||||
  to recover the secret key. Found by Keegan Ryan of NCC Group.
 | 
			
		||||
 | 
			
		||||
  Bug introduced in 2.5.0, fixed in 2.7.0. The 1.10 branch is not affected.
 | 
			
		||||
 | 
			
		||||
* 2018-04-10 (CVE-2018-9860): Memory overread in TLS CBC decryption
 | 
			
		||||
 | 
			
		||||
  An off by one error in TLS CBC decryption meant that for a particular
 | 
			
		||||
  malformed ciphertext, the receiver would miscompute a length field and HMAC
 | 
			
		||||
  exactly 64K bytes of data following the record buffer as if it was part of the
 | 
			
		||||
  message. This cannot be used to leak information since the MAC comparison will
 | 
			
		||||
  subsequently fail and the connection will be closed. However it might be used
 | 
			
		||||
  for denial of service. Found by OSS-Fuzz.
 | 
			
		||||
 | 
			
		||||
  Bug introduced in 1.11.32, fixed in 2.6.0
 | 
			
		||||
 | 
			
		||||
* 2018-03-29 (CVE-2018-9127): Invalid wildcard match
 | 
			
		||||
 | 
			
		||||
  RFC 6125 wildcard matching was incorrectly implemented, so that a wildcard
 | 
			
		||||
  certificate such as ``b*.domain.com`` would match any hosts ``*b*.domain.com``
 | 
			
		||||
  instead of just server names beginning with ``b``. The host and certificate
 | 
			
		||||
  would still have to be in the same domain name. Reported by Fabian Weißberg of
 | 
			
		||||
  Rohde and Schwarz Cybersecurity.
 | 
			
		||||
 | 
			
		||||
  Bug introduced in 2.2.0, fixed in 2.5.0
 | 
			
		||||
 | 
			
		||||
2017
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2017-10-02 (CVE-2017-14737): Potential side channel using cache information
 | 
			
		||||
 | 
			
		||||
  In the Montgomery exponentiation code, a table of precomputed values
 | 
			
		||||
  is used. An attacker able to analyze which cache lines were accessed
 | 
			
		||||
  (perhaps via an active attack such as Prime+Probe) could recover
 | 
			
		||||
  information about the exponent. Identified in "CacheD: Identifying
 | 
			
		||||
  Cache-Based Timing Channels in Production Software" by Wang, Wang,
 | 
			
		||||
  Liu, Zhang, and Wu (Usenix Security 2017).
 | 
			
		||||
 | 
			
		||||
  Fixed in 1.10.17 and 2.3.0, all prior versions affected.
 | 
			
		||||
 | 
			
		||||
* 2017-07-16: Failure to fully zeroize memory before free
 | 
			
		||||
 | 
			
		||||
  The secure_allocator type attempts to zeroize memory before freeing it. Due to
 | 
			
		||||
  a error sometimes only a portion of the memory would be zeroed, because of a
 | 
			
		||||
  confusion between the number of elements vs the number of bytes that those
 | 
			
		||||
  elements use. So byte vectors would always be fully zeroed (since the two
 | 
			
		||||
  notions result in the same value), but for example with an array of 32-bit
 | 
			
		||||
  integers, only the first 1/4 of the elements would be zeroed before being
 | 
			
		||||
  deallocated. This may result in information leakage, if an attacker can access
 | 
			
		||||
  memory on the heap. Reported by Roman Pozlevich.
 | 
			
		||||
 | 
			
		||||
  Bug introduced in 1.11.10, fixed in 2.2.0
 | 
			
		||||
 | 
			
		||||
* 2017-04-04 (CVE-2017-2801): Incorrect comparison in X.509 DN strings
 | 
			
		||||
 | 
			
		||||
  Botan's implementation of X.509 name comparisons had a flaw which
 | 
			
		||||
  could result in an out of bound memory read while processing a
 | 
			
		||||
  specially formed DN. This could potentially be exploited for
 | 
			
		||||
  information disclosure or denial of service, or result in incorrect
 | 
			
		||||
  validation results. Found independently by Aleksandar Nikolic of
 | 
			
		||||
  Cisco Talos, and OSS-Fuzz automated fuzzing infrastructure.
 | 
			
		||||
 | 
			
		||||
  Bug introduced in 1.6.0 or earlier, fixed in 2.1.0 and 1.10.16
 | 
			
		||||
 | 
			
		||||
* 2017-03-23 (CVE-2017-7252): Incorrect bcrypt computation
 | 
			
		||||
 | 
			
		||||
  Botan's implementation of bcrypt password hashing scheme truncated long
 | 
			
		||||
  passwords at 56 characters, instead of at bcrypt's standard 72 characters
 | 
			
		||||
  limit. Passwords with lengths between these two bounds could be cracked more
 | 
			
		||||
  easily than should be the case due to the final password bytes being ignored.
 | 
			
		||||
  Found and reported by Solar Designer.
 | 
			
		||||
 | 
			
		||||
  Bug introduced in 1.11.0, fixed in 2.1.0.
 | 
			
		||||
 | 
			
		||||
2016
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2016-11-27 (CVE-2016-9132) Integer overflow in BER decoder
 | 
			
		||||
 | 
			
		||||
  While decoding BER length fields, an integer overflow could occur. This could
 | 
			
		||||
  occur while parsing untrusted inputs such as X.509 certificates. The overflow
 | 
			
		||||
  does not seem to lead to any obviously exploitable condition, but exploitation
 | 
			
		||||
  cannot be positively ruled out. Only 32-bit platforms are likely affected; to
 | 
			
		||||
  cause an overflow on 64-bit the parsed data would have to be many gigabytes.
 | 
			
		||||
  Bug found by Falko Strenzke, cryptosource GmbH.
 | 
			
		||||
 | 
			
		||||
  Fixed in 1.10.14 and 1.11.34, all prior versions affected.
 | 
			
		||||
 | 
			
		||||
* 2016-10-26 (CVE-2016-8871) OAEP side channel
 | 
			
		||||
 | 
			
		||||
  A side channel in OAEP decoding could be used to distinguish RSA ciphertexts
 | 
			
		||||
  that did or did not have a leading 0 byte. For an attacker capable of
 | 
			
		||||
  precisely measuring the time taken for OAEP decoding, this could be used as an
 | 
			
		||||
  oracle allowing decryption of arbitrary RSA ciphertexts. Remote exploitation
 | 
			
		||||
  seems difficult as OAEP decoding is always paired with RSA decryption, which
 | 
			
		||||
  takes substantially more (and variable) time, and so will tend to mask the
 | 
			
		||||
  timing channel. This attack does seems well within reach of a local attacker
 | 
			
		||||
  capable of a cache or branch predictor based side channel attack. Finding,
 | 
			
		||||
  analysis, and patch by Juraj Somorovsky.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.29, fixed in 1.11.33
 | 
			
		||||
 | 
			
		||||
* 2016-08-30 (CVE-2016-6878) Undefined behavior in Curve25519
 | 
			
		||||
 | 
			
		||||
  On systems without a native 128-bit integer type, the Curve25519 code invoked
 | 
			
		||||
  undefined behavior. This was known to produce incorrect results on 32-bit ARM
 | 
			
		||||
  when compiled by Clang.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.12, fixed in 1.11.31
 | 
			
		||||
 | 
			
		||||
* 2016-08-30 (CVE-2016-6879) Bad result from X509_Certificate::allowed_usage
 | 
			
		||||
 | 
			
		||||
  If allowed_usage was called with more than one Key_Usage set in the enum
 | 
			
		||||
  value, the function would return true if *any* of the allowed usages were set,
 | 
			
		||||
  instead of if *all* of the allowed usages are set.  This could be used to
 | 
			
		||||
  bypass an application key usage check. Credit to Daniel Neus of Rohde &
 | 
			
		||||
  Schwarz Cybersecurity for finding this issue.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.0, fixed in 1.11.31
 | 
			
		||||
 | 
			
		||||
* 2016-03-17 (CVE-2016-2849): ECDSA side channel
 | 
			
		||||
 | 
			
		||||
  ECDSA (and DSA) signature algorithms perform a modular inverse on the
 | 
			
		||||
  signature nonce `k`.  The modular inverse algorithm used had input dependent
 | 
			
		||||
  loops, and it is possible a side channel attack could recover sufficient
 | 
			
		||||
  information about the nonce to eventually recover the ECDSA secret key. Found
 | 
			
		||||
  by Sean Devlin.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.7.15, fixed in 1.10.13 and 1.11.29
 | 
			
		||||
 | 
			
		||||
* 2016-03-17 (CVE-2016-2850): Failure to enforce TLS policy
 | 
			
		||||
 | 
			
		||||
  TLS v1.2 allows negotiating which signature algorithms and hash functions each
 | 
			
		||||
  side is willing to accept. However received signatures were not actually
 | 
			
		||||
  checked against the specified policy.  This had the effect of allowing a
 | 
			
		||||
  server to use an MD5 or SHA-1 signature, even though the default policy
 | 
			
		||||
  prohibits it. The same issue affected client cert authentication.
 | 
			
		||||
 | 
			
		||||
  The TLS client also failed to verify that the ECC curve the server chose to
 | 
			
		||||
  use was one which was acceptable by the client policy.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.0, fixed in 1.11.29
 | 
			
		||||
 | 
			
		||||
* 2016-02-01 (CVE-2016-2196): Overwrite in P-521 reduction
 | 
			
		||||
 | 
			
		||||
  The P-521 reduction function would overwrite zero to one word
 | 
			
		||||
  following the allocated block. This could potentially result
 | 
			
		||||
  in remote code execution or a crash. Found with AFL
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.10, fixed in 1.11.27
 | 
			
		||||
 | 
			
		||||
* 2016-02-01 (CVE-2016-2195): Heap overflow on invalid ECC point
 | 
			
		||||
 | 
			
		||||
  The PointGFp constructor did not check that the affine coordinate
 | 
			
		||||
  arguments were less than the prime, but then in curve multiplication
 | 
			
		||||
  assumed that both arguments if multiplied would fit into an integer
 | 
			
		||||
  twice the size of the prime.
 | 
			
		||||
 | 
			
		||||
  The bigint_mul and bigint_sqr functions received the size of the
 | 
			
		||||
  output buffer, but only used it to dispatch to a faster algorithm in
 | 
			
		||||
  cases where there was sufficient output space to call an unrolled
 | 
			
		||||
  multiplication function.
 | 
			
		||||
 | 
			
		||||
  The result is a heap overflow accessible via ECC point decoding,
 | 
			
		||||
  which accepted untrusted inputs. This is likely exploitable for
 | 
			
		||||
  remote code execution.
 | 
			
		||||
 | 
			
		||||
  On systems which use the mlock pool allocator, it would allow an
 | 
			
		||||
  attacker to overwrite memory held in secure_vector objects. After
 | 
			
		||||
  this point the write will hit the guard page at the end of the
 | 
			
		||||
  mmap'ed region so it probably could not be used for code execution
 | 
			
		||||
  directly, but would allow overwriting adjacent key material.
 | 
			
		||||
 | 
			
		||||
  Found by Alex Gaynor fuzzing with AFL
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.9.18, fixed in 1.11.27 and 1.10.11
 | 
			
		||||
 | 
			
		||||
* 2016-02-01 (CVE-2016-2194): Infinite loop in modular square root algorithm
 | 
			
		||||
 | 
			
		||||
  The ressol function implements the Tonelli-Shanks algorithm for
 | 
			
		||||
  finding square roots could be sent into a nearly infinite loop due
 | 
			
		||||
  to a misplaced conditional check. This could occur if a composite
 | 
			
		||||
  modulus is provided, as this algorithm is only defined for primes.
 | 
			
		||||
  This function is exposed to attacker controlled input via the OS2ECP
 | 
			
		||||
  function during ECC point decompression. Found by AFL
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.7.15, fixed in 1.11.27 and 1.10.11
 | 
			
		||||
 | 
			
		||||
2015
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2015-11-04: TLS certificate authentication bypass
 | 
			
		||||
 | 
			
		||||
  When the bugs affecting X.509 path validation were fixed in 1.11.22, a check
 | 
			
		||||
  in Credentials_Manager::verify_certificate_chain was accidentally removed
 | 
			
		||||
  which caused path validation failures not to be signaled to the TLS layer.  So
 | 
			
		||||
  for affected versions, certificate authentication in TLS is bypassed. As a
 | 
			
		||||
  workaround, applications can override the call and implement the correct
 | 
			
		||||
  check. Reported by Florent Le Coz in GH #324
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.22, fixed in 1.11.24
 | 
			
		||||
 | 
			
		||||
* 2015-10-26 (CVE-2015-7824): Padding oracle attack on TLS
 | 
			
		||||
 | 
			
		||||
  A padding oracle attack was possible against TLS CBC ciphersuites because if a
 | 
			
		||||
  certain length check on the packet fields failed, a different alert type than
 | 
			
		||||
  one used for message authentication failure would be returned to the sender.
 | 
			
		||||
  This check triggering would leak information about the value of the padding
 | 
			
		||||
  bytes and could be used to perform iterative decryption.
 | 
			
		||||
 | 
			
		||||
  As with most such oracle attacks, the danger depends on the underlying
 | 
			
		||||
  protocol - HTTP servers are particularly vulnerable. The current analysis
 | 
			
		||||
  suggests that to exploit it an attacker would first have to guess several
 | 
			
		||||
  bytes of plaintext, but again this is quite possible in many situations
 | 
			
		||||
  including HTTP.
 | 
			
		||||
 | 
			
		||||
  Found in a review by Sirrix AG and 3curity GmbH.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.0, fixed in 1.11.22
 | 
			
		||||
 | 
			
		||||
* 2015-10-26 (CVE-2015-7825): Infinite loop during certificate path validation
 | 
			
		||||
 | 
			
		||||
  When evaluating a certificate path, if a loop in the certificate chain
 | 
			
		||||
  was encountered (for instance where C1 certifies C2, which certifies C1)
 | 
			
		||||
  an infinite loop would occur eventually resulting in memory exhaustion.
 | 
			
		||||
  Found in a review by Sirrix AG and 3curity GmbH.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.6, fixed in 1.11.22
 | 
			
		||||
 | 
			
		||||
* 2015-10-26 (CVE-2015-7826): Acceptance of invalid certificate names
 | 
			
		||||
 | 
			
		||||
  RFC 6125 specifies how to match a X.509v3 certificate against a DNS name
 | 
			
		||||
  for application usage.
 | 
			
		||||
 | 
			
		||||
  Otherwise valid certificates using wildcards would be accepted as matching
 | 
			
		||||
  certain hostnames that should they should not according to RFC 6125. For
 | 
			
		||||
  example a certificate issued for ``*.example.com`` should match
 | 
			
		||||
  ``foo.example.com`` but not ``example.com`` or ``bar.foo.example.com``. Previously
 | 
			
		||||
  Botan would accept such a certificate as also valid for ``bar.foo.example.com``.
 | 
			
		||||
 | 
			
		||||
  RFC 6125 also requires that when matching a X.509 certificate against a DNS
 | 
			
		||||
  name, the CN entry is only compared if no subjectAlternativeName entry is
 | 
			
		||||
  available. Previously X509_Certificate::matches_dns_name would always check
 | 
			
		||||
  both names.
 | 
			
		||||
 | 
			
		||||
  Found in a review by Sirrix AG and 3curity GmbH.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.11.0, fixed in 1.11.22
 | 
			
		||||
 | 
			
		||||
* 2015-10-26 (CVE-2015-7827): PKCS #1 v1.5 decoding was not constant time
 | 
			
		||||
 | 
			
		||||
  During RSA decryption, how long decoding of PKCS #1 v1.5 padding took was
 | 
			
		||||
  input dependent. If these differences could be measured by an attacker, it
 | 
			
		||||
  could be used to mount a Bleichenbacher million-message attack. PKCS #1 v1.5
 | 
			
		||||
  decoding has been rewritten to use a sequence of operations which do not
 | 
			
		||||
  contain any input-dependent indexes or jumps. Notations for checking constant
 | 
			
		||||
  time blocks with ctgrind (https://github.com/agl/ctgrind) were added to PKCS
 | 
			
		||||
  #1 decoding among other areas. Found in a review by Sirrix AG and 3curity GmbH.
 | 
			
		||||
 | 
			
		||||
  Fixed in 1.11.22 and 1.10.13. Affected all previous versions.
 | 
			
		||||
 | 
			
		||||
* 2015-08-03 (CVE-2015-5726): Crash in BER decoder
 | 
			
		||||
 | 
			
		||||
  The BER decoder would crash due to reading from offset 0 of an empty vector if
 | 
			
		||||
  it encountered a BIT STRING which did not contain any data at all. This can be
 | 
			
		||||
  used to easily crash applications reading untrusted ASN.1 data, but does not
 | 
			
		||||
  seem exploitable for code execution. Found with afl.
 | 
			
		||||
 | 
			
		||||
  Fixed in 1.11.19 and 1.10.10, affected all previous versions of 1.10 and 1.11
 | 
			
		||||
 | 
			
		||||
* 2015-08-03 (CVE-2015-5727): Excess memory allocation in BER decoder
 | 
			
		||||
 | 
			
		||||
  The BER decoder would allocate a fairly arbitrary amount of memory in a length
 | 
			
		||||
  field, even if there was no chance the read request would succeed.  This might
 | 
			
		||||
  cause the process to run out of memory or invoke the OOM killer. Found with afl.
 | 
			
		||||
 | 
			
		||||
  Fixed in 1.11.19 and 1.10.10, affected all previous versions of 1.10 and 1.11
 | 
			
		||||
 | 
			
		||||
2014
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
* 2014-04-10 (CVE-2014-9742): Insufficient randomness in Miller-Rabin primality check
 | 
			
		||||
 | 
			
		||||
  A bug in the Miller-Rabin primality test resulted in only a single random base
 | 
			
		||||
  being used instead of a sequence of such bases. This increased the probability
 | 
			
		||||
  that a non-prime would be accepted by is_prime or that a randomly generated
 | 
			
		||||
  prime might actually be composite.  The probability of a random 1024 bit
 | 
			
		||||
  number being incorrectly classed as prime with a single base is around 2^-40.
 | 
			
		||||
  Reported by Jeff Marrison.
 | 
			
		||||
 | 
			
		||||
  Introduced in 1.8.3, fixed in 1.10.8 and 1.11.9
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
Semantic Versioning
 | 
			
		||||
=====================
 | 
			
		||||
 | 
			
		||||
Starting with 2.0.0, Botan adopted semantic versioning. This means we endevour
 | 
			
		||||
to make no change which will either break compilation of existing code, or cause
 | 
			
		||||
different behavior in a way that will cause compatability issues. Such changes
 | 
			
		||||
are reserved for new major versions.
 | 
			
		||||
 | 
			
		||||
If on upgrading to a new minor version, you encounter a problem where your
 | 
			
		||||
existing code either fails to compile, or the code behaves differently in some
 | 
			
		||||
way that causes trouble, it is probably a bug; please report it on Github.
 | 
			
		||||
 | 
			
		||||
Exception
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
There is an important exception to the SemVer guarantees that you should be
 | 
			
		||||
aware of. If you in your application derive a new class from a class in the
 | 
			
		||||
library, we do not guarantee a future minor release will not break your
 | 
			
		||||
code. For example, we may in a minor release introduce a new pure virtual
 | 
			
		||||
function to a base class like ``BlockCipher``, and implement it for all
 | 
			
		||||
subclasses within the library. In this case your code would fail to compile
 | 
			
		||||
until you implemented the new virtual function. Or we might rename or remove a
 | 
			
		||||
protected function, or a protected member variable.
 | 
			
		||||
 | 
			
		||||
There is also an exception to this exception! The following classes are intended
 | 
			
		||||
for derivation by applications, and are fully covered by SemVer:
 | 
			
		||||
 | 
			
		||||
* ``Credentials_Manager``
 | 
			
		||||
* ``Entropy_Source``
 | 
			
		||||
* ``TLS::Callbacks``
 | 
			
		||||
* ``TLS::Policy`` (and subclasses thereof)
 | 
			
		||||
* ``TLS::Stream<T>``
 | 
			
		||||
@@ -1,469 +0,0 @@
 | 
			
		||||
Side Channels
 | 
			
		||||
=========================
 | 
			
		||||
 | 
			
		||||
Many cryptographic systems can be easily broken by side channels. This document
 | 
			
		||||
notes side channel protections which are currently implemented, as well as areas
 | 
			
		||||
of the code which are known to be vulnerable to side channels. The latter are
 | 
			
		||||
obviously all open for future improvement.
 | 
			
		||||
 | 
			
		||||
The following text assumes the reader is already familiar with cryptographic
 | 
			
		||||
implementations, side channel attacks, and common countermeasures.
 | 
			
		||||
 | 
			
		||||
Modular Exponentiation
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
Modular exponentiation uses a fixed window algorithm with Montgomery
 | 
			
		||||
representation. A side channel silent table lookup is used to access the
 | 
			
		||||
precomputed powers. The caller provides the maximum possible bit length of the
 | 
			
		||||
exponent, and the exponent is zero-padded as required. For example, in a DSA
 | 
			
		||||
signature with 256-bit q, the caller will specify a maximum length of exponent
 | 
			
		||||
of 256 bits, even if the k that was generated was 250 bits. This avoids leaking
 | 
			
		||||
the length of the exponent through the number of loop iterations.
 | 
			
		||||
See monty_exp.cpp and monty.cpp
 | 
			
		||||
 | 
			
		||||
Karatsuba multiplication algorithm avoids any conditional branches; in
 | 
			
		||||
cases where different operations must be performed it instead uses masked
 | 
			
		||||
operations. See mp_karat.cpp for details.
 | 
			
		||||
 | 
			
		||||
The Montgomery reduction is written to run in constant time.
 | 
			
		||||
The final reduction is handled with a masked subtraction. See mp_monty.cpp.
 | 
			
		||||
 | 
			
		||||
Barrett Reduction
 | 
			
		||||
--------------------
 | 
			
		||||
 | 
			
		||||
The Barrett reduction code is written to avoid input dependent branches. The
 | 
			
		||||
Barrett algorithm only works for inputs up to a certain size, and larger values
 | 
			
		||||
fall back on a different (slower) division algorithm. This secondary algorithm
 | 
			
		||||
is also const time, but the branch allows detecting when a value larger than
 | 
			
		||||
2^{2k} was reduced, where k is the word length of the modulus. This leaks only
 | 
			
		||||
the size of the two values, and not anything else about their value.
 | 
			
		||||
 | 
			
		||||
RSA
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
Blinding is always used to protect private key operations (there is no way to
 | 
			
		||||
turn it off). Both base blinding and exponent blinding are used.
 | 
			
		||||
 | 
			
		||||
For base blinding, as an optimization, instead of choosing a new random mask and
 | 
			
		||||
inverse with each decryption, both the mask and its inverse are simply squared
 | 
			
		||||
to choose the next blinding factor. This is much faster than computing a fresh
 | 
			
		||||
value each time, and the additional relation is thought to provide only minimal
 | 
			
		||||
useful information for an attacker. Every BOTAN_BLINDING_REINIT_INTERVAL
 | 
			
		||||
(default 64) operations, a new starting point is chosen.
 | 
			
		||||
 | 
			
		||||
Exponent blinding uses new values for each signature, with 64 bit masks.
 | 
			
		||||
 | 
			
		||||
RSA signing uses the CRT optimization, which is much faster but vulnerable to
 | 
			
		||||
trivial fault attacks [RsaFault] which can result in the key being entirely
 | 
			
		||||
compromised. To protect against this (or any other computational error which
 | 
			
		||||
would have the same effect as a fault attack in this case), after every private
 | 
			
		||||
key operation the result is checked for consistency with the public key. This
 | 
			
		||||
introduces only slight additional overhead and blocks most fault attacks; it is
 | 
			
		||||
possible to use a second fault attack to bypass this verification, but such a
 | 
			
		||||
double fault attack requires significantly more control on the part of an
 | 
			
		||||
attacker than a BellCore style attack, which is possible if any error at all
 | 
			
		||||
occurs during either modular exponentiation involved in the RSA signature
 | 
			
		||||
operation.
 | 
			
		||||
 | 
			
		||||
RSA key generation is also prone to side channel vulnerabilities due to the need
 | 
			
		||||
to calculate the CRT parameters. The GCD computation, LCM computations, modulo,
 | 
			
		||||
and inversion of ``q`` modulo ``p`` are all done via constant time algorithms.
 | 
			
		||||
An additional inversion, of ``e`` modulo ``phi(n)``, is also required. This one
 | 
			
		||||
is somewhat more complicated because ``phi(n)`` is even and the primary constant
 | 
			
		||||
time algorithm for inversions only works for odd moduli. This is worked around
 | 
			
		||||
by a technique based on the CRT - ``phi(n)`` is factored to ``2**e * z`` for
 | 
			
		||||
some ``e`` > 1 and some odd ``z``. Then ``e`` is inverted modulo ``2**e`` and
 | 
			
		||||
also modulo ``z``. The inversion modulo ``2**e`` is done via a specialized
 | 
			
		||||
constant-time algoirthm which only works for powers of 2. Then the two
 | 
			
		||||
inversions are combined using the CRT. This process does leak the value of
 | 
			
		||||
``e``; to avoid problems ``p`` and ``q`` are chosen so that ``e`` is always 1.
 | 
			
		||||
 | 
			
		||||
See blinding.cpp and rsa.cpp.
 | 
			
		||||
 | 
			
		||||
Decryption of PKCS #1 v1.5 Ciphertexts
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
This padding scheme is used with RSA, and is very vulnerable to errors. In a
 | 
			
		||||
scenario where an attacker can repeatedly present RSA ciphertexts, and a
 | 
			
		||||
legitimate key holder will attempt to decrypt each ciphertext and simply
 | 
			
		||||
indicates to the attacker if the PKCS padding was valid or not (without
 | 
			
		||||
revealing any additional information), the attacker can use this behavior as an
 | 
			
		||||
oracle to perform iterative decryption of arbitrary RSA ciphertexts encrypted
 | 
			
		||||
under that key. This is the famous million message attack [MillionMsg].  A side
 | 
			
		||||
channel such as a difference in time taken to handle valid and invalid RSA
 | 
			
		||||
ciphertexts is enough to mount the attack [MillionMsgTiming].
 | 
			
		||||
 | 
			
		||||
As a first step, the PKCS v1.5 decoding operation runs without any
 | 
			
		||||
conditional jumps or indexes, with the only variance in runtime being
 | 
			
		||||
based on the length of the public modulus, which is public information.
 | 
			
		||||
 | 
			
		||||
Preventing the attack in full requires some application level changes. In
 | 
			
		||||
protocols which know the expected length of the encrypted key, PK_Decryptor
 | 
			
		||||
provides the function `decrypt_or_random` which first generates a random fake
 | 
			
		||||
key, then decrypts the presented ciphertext, then in constant time either copies
 | 
			
		||||
out the random key or the decrypted plaintext depending on if the ciphertext was
 | 
			
		||||
valid or not (valid padding and expected plaintext length). Then in the case of
 | 
			
		||||
an attack, the protocol will carry on with a randomly chosen key, which will
 | 
			
		||||
presumably cause total failure in a way that does not allow an attacker to
 | 
			
		||||
distinguish (via any timing or other side channel, nor any error messages
 | 
			
		||||
specific to the one situation vs the other) if the RSA padding was valid or
 | 
			
		||||
invalid.
 | 
			
		||||
 | 
			
		||||
One very important user of PKCS #1 v1.5 encryption is the TLS protocol. In TLS,
 | 
			
		||||
some extra versioning information is embedded in the plaintext message, along
 | 
			
		||||
with the key. It turns out that this version information must be treated in an
 | 
			
		||||
identical (constant-time) way with the PKCS padding, or again the system is
 | 
			
		||||
broken. [VersionOracle]. This is supported by a special version of
 | 
			
		||||
PK_Decryptor::decrypt_or_random that additionally allows verifying one or more
 | 
			
		||||
content bytes, in addition to the PKCS padding.
 | 
			
		||||
 | 
			
		||||
See eme_pkcs.cpp and pubkey.cpp.
 | 
			
		||||
 | 
			
		||||
Verification of PKCS #1 v1.5 Signatures
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
One way of verifying PKCS #1 v1.5 signature padding is to decode it with an
 | 
			
		||||
ASN.1 BER parser. However such a design commonly leads to accepting signatures
 | 
			
		||||
besides the (single) valid RSA PKCS #1 v1.5 signature for any given message,
 | 
			
		||||
because often the BER parser accepts variations of the encoding which are
 | 
			
		||||
actually invalid. It also needlessly exposes the BER parser to untrusted inputs.
 | 
			
		||||
 | 
			
		||||
It is safer and simpler to instead re-encode the hash value we are expecting
 | 
			
		||||
using the PKCS #1 v1.5 encoding rules, and const time compare our expected
 | 
			
		||||
encoding with the output of the RSA operation. So that is what Botan does.
 | 
			
		||||
 | 
			
		||||
See emsa_pkcs.cpp.
 | 
			
		||||
 | 
			
		||||
OAEP
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
RSA OAEP is (PKCS#1 v2) is the recommended version of RSA encoding standard,
 | 
			
		||||
because it is not directly vulnerable to Bleichenbacher attack. However, if
 | 
			
		||||
implemented incorrectly, a side channel can be presented to an attacker and
 | 
			
		||||
create an oracle for decrypting RSA ciphertexts [OaepTiming].
 | 
			
		||||
 | 
			
		||||
This attack is avoided in Botan by making the OAEP decoding operation run
 | 
			
		||||
without any conditional jumps or indexes, with the only variance in runtime
 | 
			
		||||
coming from the length of the RSA key (which is public information).
 | 
			
		||||
 | 
			
		||||
See eme_oaep.cpp.
 | 
			
		||||
 | 
			
		||||
ECC point decoding
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The API function OS2ECP, which is used to convert byte strings to ECC points,
 | 
			
		||||
verifies that all points satisfy the ECC curve equation. Points that do not
 | 
			
		||||
satisfy the equation are invalid, and can sometimes be used to break
 | 
			
		||||
protocols ([InvalidCurve] [InvalidCurveTLS]). See ec_point.cpp.
 | 
			
		||||
 | 
			
		||||
ECC scalar multiply
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
There are several different implementations of ECC scalar multiplications which
 | 
			
		||||
depend on the API invoked. This include ``EC_Point::operator*``,
 | 
			
		||||
``EC_Group::blinded_base_point_multiply`` and
 | 
			
		||||
``EC_Group::blinded_var_point_multiply``.
 | 
			
		||||
 | 
			
		||||
The ``EC_Point::operator*`` implementation uses the Montgomery ladder, which is
 | 
			
		||||
fairly resistant to side channels. However it leaks the size of the scalar,
 | 
			
		||||
because the loop iterations are bounded by the scalar size. It should not be
 | 
			
		||||
used in cases when the scalar is a secret.
 | 
			
		||||
 | 
			
		||||
Both ``blinded_base_point_multiply`` and ``blinded_var_point_multiply`` apply
 | 
			
		||||
side channel countermeasures. The scalar is masked by a multiple of the group
 | 
			
		||||
order (this is commonly called Coron's first countermeasure [CoronDpa]),
 | 
			
		||||
currently the mask is scaled to be half the bit length of the order of the group.
 | 
			
		||||
 | 
			
		||||
Botan stores all ECC points in Jacobian representation. This form allows faster
 | 
			
		||||
computation by representing points (x,y) as (X,Y,Z) where x=X/Z^2 and
 | 
			
		||||
y=Y/Z^3. As the representation is redundant, for any randomly chosen non-zero r,
 | 
			
		||||
(X*r^2,Y*r^3,Z*r) is an equivalent point. Changing the point values prevents an
 | 
			
		||||
attacker from mounting attacks based on the input point remaining unchanged over
 | 
			
		||||
multiple executions. This is commonly called Coron's third countermeasure, see
 | 
			
		||||
again [CoronDpa].
 | 
			
		||||
 | 
			
		||||
The base point multiplication algorithm is a comb-like technique which
 | 
			
		||||
precomputes ``P^i,(2*P)^i,(3*P)^i`` for all ``i`` in the range of valid scalars.
 | 
			
		||||
This means the scalar multiplication involves only point additions and no
 | 
			
		||||
doublings, which may help against attacks which rely on distinguishing between
 | 
			
		||||
point doublings and point additions. The elements of the table are accessed by
 | 
			
		||||
masked lookups, so as not to leak information about bits of the scalar via a
 | 
			
		||||
cache side channel. However, whenever 3 sequential bits of the (masked) scalar
 | 
			
		||||
are all 0, no operation is performed in that iteration of the loop. This exposes
 | 
			
		||||
the scalar multiply to a cache-based side channel attack; scalar blinding is
 | 
			
		||||
necessary to prevent this attack from leaking information about the scalar.
 | 
			
		||||
 | 
			
		||||
The variable point multiplication algorithm uses a fixed-window algorithm. Since
 | 
			
		||||
this is normally invoked using untrusted points (eg during ECDH key exchange) it
 | 
			
		||||
randomizes all inputs to prevent attacks which are based on chosen input
 | 
			
		||||
points. The table of precomputed multiples is accessed using a masked lookup
 | 
			
		||||
which should not leak information about the secret scalar to an attacker who can
 | 
			
		||||
mount a cache-based side channel attack.
 | 
			
		||||
 | 
			
		||||
See ec_point.cpp and point_mul.cpp in src/lib/pubkey/ec_group
 | 
			
		||||
 | 
			
		||||
ECDH
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
ECDH verifies (through its use of OS2ECP) that all input points received from
 | 
			
		||||
the other party satisfy the curve equation. This prevents twist attacks. The
 | 
			
		||||
same check is performed on the output point, which helps prevent fault attacks.
 | 
			
		||||
 | 
			
		||||
ECDSA
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
Inversion of the ECDSA nonce k must be done in constant time, as any leak of
 | 
			
		||||
even a single bit of the nonce can be sufficient to allow recovering the private
 | 
			
		||||
key. In Botan all inverses modulo an odd number are performed using a constant
 | 
			
		||||
time algorithm due to Niels Möller.
 | 
			
		||||
 | 
			
		||||
x25519
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The x25519 code is independent of the main Weierstrass form ECC code, instead
 | 
			
		||||
based on curve25519-donna-c64.c by Adam Langley. The code seems immune to cache
 | 
			
		||||
based side channels. It does make use of integer multiplications; on some old
 | 
			
		||||
CPUs these multiplications take variable time and might allow a side channel
 | 
			
		||||
attack. This is not considered a problem on modern processors.
 | 
			
		||||
 | 
			
		||||
TLS CBC ciphersuites
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The original TLS v1.0 CBC Mac-then-Encrypt mode is vulnerable to an oracle
 | 
			
		||||
attack. If an attacker can distinguish padding errors through different error
 | 
			
		||||
messages [TlsCbcOracle] or via a side channel attack like [Lucky13], they can
 | 
			
		||||
abuse the server as a decryption oracle.
 | 
			
		||||
 | 
			
		||||
The side channel protection for Lucky13 follows the approach proposed in the
 | 
			
		||||
Lucky13 paper. It is not perfectly constant time, but does hide the padding
 | 
			
		||||
oracle in practice. Tools to test TLS CBC decoding are included in the timing
 | 
			
		||||
tests. See https://github.com/randombit/botan/pull/675 for more information.
 | 
			
		||||
 | 
			
		||||
The Encrypt-then-MAC extension, which completely avoids the side channel, is
 | 
			
		||||
implemented and used by default for CBC ciphersuites.
 | 
			
		||||
 | 
			
		||||
CBC mode padding
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
In theory, any good protocol protects CBC ciphertexts with a MAC. But in
 | 
			
		||||
practice, some protocols are not good and cannot be fixed immediately. To avoid
 | 
			
		||||
making a bad problem worse, the code to handle decoding CBC ciphertext padding
 | 
			
		||||
bytes runs in constant time, depending only on the block size of the cipher.
 | 
			
		||||
 | 
			
		||||
base64 decoding
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
Base64 (and related encodings base32, base58 and hex) are sometimes used to
 | 
			
		||||
encode or decode secret data. To avoid possible side channels which might leak
 | 
			
		||||
key material during the encoding or decoding process, these functions avoid any
 | 
			
		||||
input-dependent table lookups.
 | 
			
		||||
 | 
			
		||||
AES
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
Some x86, ARMv8 and POWER processors support AES instructions which
 | 
			
		||||
are fast and are thought to be side channel silent. These instructions
 | 
			
		||||
are used when available.
 | 
			
		||||
 | 
			
		||||
On CPUs which do not have hardware AES instructions but do support SIMD vectors
 | 
			
		||||
with a byte shuffle (including x86's SSSE3, ARM's NEON and PowerPC AltiVec), a
 | 
			
		||||
version of AES is implemented which is side channel silent. This implementation
 | 
			
		||||
is based on code by Mike Hamburg [VectorAes], see aes_vperm.cpp.
 | 
			
		||||
 | 
			
		||||
On all other processors, a constant time bitsliced implementation is used. This
 | 
			
		||||
is typically slower than the vector permute implementation, and additionally for
 | 
			
		||||
best performance multiple blocks must be processed in parellel.  So modes such
 | 
			
		||||
as CTR, GCM or XTS are relatively fast, but others such as CBC encryption
 | 
			
		||||
suffer.
 | 
			
		||||
 | 
			
		||||
GCM
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
On platforms that support a carryless multiply instruction (ARMv8 and recent x86),
 | 
			
		||||
GCM is fast and constant time.
 | 
			
		||||
 | 
			
		||||
On all other platforms, GCM uses an algorithm based on precomputing all powers
 | 
			
		||||
of H from 1 to 128. Then for every bit of the input a mask is formed which
 | 
			
		||||
allows conditionally adding that power without leaking information via a cache
 | 
			
		||||
side channel. There is also an SSSE3 variant of this algorithm which is somewhat
 | 
			
		||||
faster on processors which have SSSE3 but no AES-NI instructions.
 | 
			
		||||
 | 
			
		||||
OCB
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
It is straightforward to implement OCB mode in a efficient way that does not
 | 
			
		||||
depend on any secret branches or lookups. See ocb.cpp for the implementation.
 | 
			
		||||
 | 
			
		||||
Poly1305
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The Poly1305 implementation does not have any secret lookups or conditionals.
 | 
			
		||||
The code is based on the public domain version by Andrew Moon.
 | 
			
		||||
 | 
			
		||||
DES/3DES
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The DES implementation relies on table lookups but they are limited to
 | 
			
		||||
tables which are exactly 64 bytes in size. On systems with 64 byte (or
 | 
			
		||||
larger) cache lines, these should not leak information. It may still
 | 
			
		||||
be vulnerable to side channels on processors which leak cache line
 | 
			
		||||
access offsets via cache bank conflicts; vulnerable hardware includes
 | 
			
		||||
Sandy Bridge processors, but not later Intel or AMD CPUs.
 | 
			
		||||
 | 
			
		||||
Twofish
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
This algorithm uses table lookups with secret sboxes. No cache-based side
 | 
			
		||||
channel attack on Twofish has ever been published, but it is possible nobody
 | 
			
		||||
sufficiently skilled has ever tried.
 | 
			
		||||
 | 
			
		||||
ChaCha20, Serpent, Threefish, ...
 | 
			
		||||
-----------------------------------
 | 
			
		||||
 | 
			
		||||
Some algorithms including ChaCha, Salsa, Serpent and Threefish are 'naturally'
 | 
			
		||||
silent to cache and timing side channels on all recent processors.
 | 
			
		||||
 | 
			
		||||
IDEA
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
IDEA encryption, decryption, and key schedule are implemented to take constant
 | 
			
		||||
time regardless of their inputs.
 | 
			
		||||
 | 
			
		||||
Hash Functions
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
Most hash functions included in Botan such as MD5, SHA-1, SHA-2, SHA-3, Skein,
 | 
			
		||||
and BLAKE2 do not require any input-dependent memory lookups, and so seem to not be
 | 
			
		||||
affected by common CPU side channels. However the implementations of Whirlpool
 | 
			
		||||
and Streebog use table lookups and probably can be attacked by side channels.
 | 
			
		||||
 | 
			
		||||
Memory comparisons
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
The function same_mem in header mem_ops.h provides a constant-time comparison
 | 
			
		||||
function. It is used when comparing MACs or other secret values. It is also
 | 
			
		||||
exposed for application use.
 | 
			
		||||
 | 
			
		||||
Memory zeroizing
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
There is no way in portable C/C++ to zero out an array before freeing it, in
 | 
			
		||||
such a way that it is guaranteed that the compiler will not elide the
 | 
			
		||||
'additional' (seemingly unnecessary) writes to zero out the memory.
 | 
			
		||||
 | 
			
		||||
The function secure_scrub_memory (in mem_ops.cpp) uses some system specific
 | 
			
		||||
trick to zero out an array. If possible an OS provided routine (such as
 | 
			
		||||
``RtlSecureZeroMemory`` or ``explicit_bzero``) is used.
 | 
			
		||||
 | 
			
		||||
On other platforms, by default the trick of referencing memset through a
 | 
			
		||||
volatile function pointer is used. This approach is not guaranteed to work on
 | 
			
		||||
all platforms, and currently there is no systematic check of the resulting
 | 
			
		||||
binary function that it is compiled as expected. But, it is the best approach
 | 
			
		||||
currently known and has been verified to work as expected on common platforms.
 | 
			
		||||
 | 
			
		||||
If BOTAN_USE_VOLATILE_MEMSET_FOR_ZERO is set to 0 in build.h (not the default) a
 | 
			
		||||
byte at a time loop through a volatile pointer is used to overwrite the array.
 | 
			
		||||
 | 
			
		||||
Memory allocation
 | 
			
		||||
----------------------
 | 
			
		||||
 | 
			
		||||
Botan's secure_vector type is a std::vector with a custom allocator. The
 | 
			
		||||
allocator calls secure_scrub_memory before freeing memory.
 | 
			
		||||
 | 
			
		||||
Some operating systems support an API call to lock a range of pages
 | 
			
		||||
into memory, such that they will never be swapped out (``mlock`` on POSIX,
 | 
			
		||||
``VirtualLock`` on Windows). On many POSIX systems ``mlock`` is only usable by
 | 
			
		||||
root, but on Linux, FreeBSD and possibly other systems a small amount
 | 
			
		||||
of memory can be locked by processes without extra credentials.
 | 
			
		||||
 | 
			
		||||
If available, Botan uses such a region for storing key material. A page-aligned
 | 
			
		||||
block of memory is allocated and locked, then the memory is scrubbed before
 | 
			
		||||
freeing. This memory pool is used by secure_vector when available. It can be
 | 
			
		||||
disabled at runtime setting the environment variable BOTAN_MLOCK_POOL_SIZE to 0.
 | 
			
		||||
 | 
			
		||||
Automated Analysis
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
Currently the main tool used by the Botan developers for testing for side
 | 
			
		||||
channels at runtime is valgrind; valgrind's runtime API is used to taint memory
 | 
			
		||||
values, and any jumps or indexes using data derived from these values will cause
 | 
			
		||||
a valgrind warning. This technique was first used by Adam Langley in ctgrind.
 | 
			
		||||
See header ct_utils.h.
 | 
			
		||||
 | 
			
		||||
To check, install valgrind, configure the build with --with-valgrind, and run
 | 
			
		||||
the tests.
 | 
			
		||||
 | 
			
		||||
.. highlight:: shell
 | 
			
		||||
 | 
			
		||||
There is also a test utility built into the command line util, `timing_test`,
 | 
			
		||||
which runs an operation on several different inputs many times in order to
 | 
			
		||||
detect simple timing differences. The output can be processed using the
 | 
			
		||||
Mona timing report library (https://github.com/seecurity/mona-timing-report).
 | 
			
		||||
To run a timing report (here for example pow_mod)::
 | 
			
		||||
 | 
			
		||||
  $ ./botan timing_test pow_mod > pow_mod.raw
 | 
			
		||||
 | 
			
		||||
This must be run from a checkout of the source, or otherwise ``--test-data-dir=``
 | 
			
		||||
must be used to point to the expected input files.
 | 
			
		||||
 | 
			
		||||
Build and run the Mona report as::
 | 
			
		||||
 | 
			
		||||
  $ git clone https://github.com/seecurity/mona-timing-report.git
 | 
			
		||||
  $ cd mona-timing-report
 | 
			
		||||
  $ ant
 | 
			
		||||
  $ java -jar ReportingTool.jar --lowerBound=0.4 --upperBound=0.5 --inputFile=pow_mod.raw --name=PowMod
 | 
			
		||||
 | 
			
		||||
This will produce plots and an HTML file in subdirectory starting with
 | 
			
		||||
``reports_`` followed by a representation of the current date and time.
 | 
			
		||||
 | 
			
		||||
References
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
[Aes256Sc] Neve, Tiri "On the complexity of side-channel attacks on AES-256"
 | 
			
		||||
(https://eprint.iacr.org/2007/318.pdf)
 | 
			
		||||
 | 
			
		||||
[AesCacheColl] Bonneau, Mironov "Cache-Collision Timing Attacks Against AES"
 | 
			
		||||
(http://www.jbonneau.com/doc/BM06-CHES-aes_cache_timing.pdf)
 | 
			
		||||
 | 
			
		||||
[CoronDpa] Coron,
 | 
			
		||||
"Resistance against Differential Power Analysis for Elliptic Curve Cryptosystems"
 | 
			
		||||
(https://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.1.5695)
 | 
			
		||||
 | 
			
		||||
[InvalidCurve] Biehl, Meyer, Müller: Differential fault attacks on
 | 
			
		||||
elliptic curve cryptosystems
 | 
			
		||||
(https://www.iacr.org/archive/crypto2000/18800131/18800131.pdf)
 | 
			
		||||
 | 
			
		||||
[InvalidCurveTLS] Jager, Schwenk, Somorovsky: Practical Invalid Curve
 | 
			
		||||
Attacks on TLS-ECDH
 | 
			
		||||
(https://www.nds.rub.de/research/publications/ESORICS15/)
 | 
			
		||||
 | 
			
		||||
[SafeCurves] Bernstein, Lange: SafeCurves: choosing safe curves for
 | 
			
		||||
elliptic-curve cryptography. (https://safecurves.cr.yp.to)
 | 
			
		||||
 | 
			
		||||
[Lucky13] AlFardan, Paterson "Lucky Thirteen: Breaking the TLS and DTLS Record Protocols"
 | 
			
		||||
(http://www.isg.rhul.ac.uk/tls/TLStiming.pdf)
 | 
			
		||||
 | 
			
		||||
[MillionMsg] Bleichenbacher "Chosen Ciphertext Attacks Against Protocols Based
 | 
			
		||||
on the RSA Encryption Standard PKCS1"
 | 
			
		||||
(https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.19.8543)
 | 
			
		||||
 | 
			
		||||
[MillionMsgTiming] Meyer, Somorovsky, Weiss, Schwenk, Schinzel, Tews: Revisiting
 | 
			
		||||
SSL/TLS Implementations: New Bleichenbacher Side Channels and Attacks
 | 
			
		||||
(https://www.nds.rub.de/research/publications/mswsst2014-bleichenbacher-usenix14/)
 | 
			
		||||
 | 
			
		||||
[OaepTiming] Manger, "A Chosen Ciphertext Attack on RSA Optimal Asymmetric
 | 
			
		||||
Encryption Padding (OAEP) as Standardized in PKCS #1 v2.0"
 | 
			
		||||
(http://archiv.infsec.ethz.ch/education/fs08/secsem/Manger01.pdf)
 | 
			
		||||
 | 
			
		||||
[RsaFault] Boneh, Demillo, Lipton
 | 
			
		||||
"On the importance of checking cryptographic protocols for faults"
 | 
			
		||||
(https://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.9764)
 | 
			
		||||
 | 
			
		||||
[RandomMonty] Le, Tan, Tunstall "Randomizing the Montgomery Powering Ladder"
 | 
			
		||||
(https://eprint.iacr.org/2015/657)
 | 
			
		||||
 | 
			
		||||
[VectorAes] Hamburg, "Accelerating AES with Vector Permute Instructions"
 | 
			
		||||
https://shiftleft.org/papers/vector_aes/vector_aes.pdf
 | 
			
		||||
 | 
			
		||||
[VersionOracle] Klíma, Pokorný, Rosa "Attacking RSA-based Sessions in SSL/TLS"
 | 
			
		||||
(https://eprint.iacr.org/2003/052)
 | 
			
		||||
@@ -1,89 +0,0 @@
 | 
			
		||||
Support Information
 | 
			
		||||
=======================
 | 
			
		||||
 | 
			
		||||
Supported Platforms
 | 
			
		||||
------------------------
 | 
			
		||||
 | 
			
		||||
For Botan 3, the tier-1 supported platforms are
 | 
			
		||||
 | 
			
		||||
* Linux x86-64, GCC 11.2 or later
 | 
			
		||||
* Linux x86-64, Clang 14 or later
 | 
			
		||||
* Linux aarch64, GCC 11.2 or later
 | 
			
		||||
* Linux ppc64le, GCC 11.2 or later
 | 
			
		||||
* Windows x86-64, Visual C++ 2022 or later
 | 
			
		||||
 | 
			
		||||
These platforms are all tested by continuous integration, and the developers
 | 
			
		||||
have access to hardware in order to test patches. Problems affecting these
 | 
			
		||||
platforms are considered release blockers.
 | 
			
		||||
 | 
			
		||||
For Botan 3, the tier-2 supported platforms are
 | 
			
		||||
 | 
			
		||||
* macOS x86-64, latest XCode Clang
 | 
			
		||||
* iOS aarch64, latest XCode Clang
 | 
			
		||||
* Windows x86-64, latest MinGW GCC
 | 
			
		||||
* Android aarch64, latest NDK Clang
 | 
			
		||||
* Linux arm32, GCC 11.2 or later
 | 
			
		||||
* Linux x86-32, GCC 11.2 or later
 | 
			
		||||
* FreeBSD x86-64, Clang 14 or later
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   Notice that the minimum version requirements for XCode and NDK is different
 | 
			
		||||
   from other compilers. With GCC or Clang, we fix the minimum required compiler
 | 
			
		||||
   version and aim to maintain that support for the entire lifecycle of
 | 
			
		||||
   Botan 3. In contrast, for XCode and NDK the minimum version is floating;
 | 
			
		||||
   namely, we will only support the very latest version. It's possible earlier
 | 
			
		||||
   versions will work, but this is not guaranteed.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   As of June 2023, it is known that at least XCode 13.3 is required, since
 | 
			
		||||
   earlier versions did not support certain C++20 language features that the
 | 
			
		||||
   library uses. XCode 15.0 or higher is recommended.
 | 
			
		||||
 | 
			
		||||
.. note::
 | 
			
		||||
 | 
			
		||||
   For Android, NDK 26 is required
 | 
			
		||||
 | 
			
		||||
Some (but not all) of the tier-2 platforms are tested by CI. Everything should
 | 
			
		||||
work, and if problems are encountered, the developers will probably be able to
 | 
			
		||||
help. But they are not as carefully tested as tier-1.
 | 
			
		||||
 | 
			
		||||
Of course most other modern OSes such as QNX, AIX, OpenBSD, NetBSD, and Solaris
 | 
			
		||||
also work just fine. Some are tested occasionally, usually just before a new
 | 
			
		||||
release. But very little code specific to these platforms is written by the
 | 
			
		||||
primary developers. For example, any functionality in the library which
 | 
			
		||||
utilizes OpenBSD specific APIs was likely contributed by someone interested in
 | 
			
		||||
that platform.
 | 
			
		||||
 | 
			
		||||
In theory any working C++20 compiler is fine but in practice, we only regularly
 | 
			
		||||
test with GCC, Clang, and Visual C++. Several other compilers (such as IBM XLC,
 | 
			
		||||
Intel C++, and Sun Studio) are supported by the build system but are not tested
 | 
			
		||||
by the developers and may have build or codegen problems. Patches to improve
 | 
			
		||||
support for these compilers is welcome.
 | 
			
		||||
 | 
			
		||||
Branch Support Status
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
Following table provides the support status for Botan branches, as of
 | 
			
		||||
July 2023.
 | 
			
		||||
 | 
			
		||||
"Active development" refers to adding new features and optimizations. At the
 | 
			
		||||
conclusion of the active development phase, only bugfixes are applied.
 | 
			
		||||
 | 
			
		||||
End of life dates may be extended as circumstances warrant.
 | 
			
		||||
 | 
			
		||||
============== ============== ========================== ============
 | 
			
		||||
Branch         First Release  End of Active Development  End of Life
 | 
			
		||||
============== ============== ========================== ============
 | 
			
		||||
Botan 1.8      2008-12-08     2010-08-31                 2016-02-13
 | 
			
		||||
Botan 1.10     2011-06-20     2012-07-10                 2018-12-31
 | 
			
		||||
Botan 2        2017-01-06     2020-11-05                 2024-12-31 or later
 | 
			
		||||
Botan 3        2023-04-11     ?                          2026-12-31 or later
 | 
			
		||||
============== ============== ========================== ============
 | 
			
		||||
 | 
			
		||||
Getting Help
 | 
			
		||||
------------------
 | 
			
		||||
 | 
			
		||||
To get help with Botan, open an issue on
 | 
			
		||||
`GitHub <https://github.com/randombit/botan/issues>`_
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
Copyright (C) 1999-2023 The Botan Authors
 | 
			
		||||
All rights reserved.
 | 
			
		||||
 | 
			
		||||
Redistribution and use in source and binary forms, with or without
 | 
			
		||||
modification, are permitted provided that the following conditions are met:
 | 
			
		||||
 | 
			
		||||
1. Redistributions of source code must retain the above copyright notice,
 | 
			
		||||
   this list of conditions, and the following disclaimer.
 | 
			
		||||
 | 
			
		||||
2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
   notice, this list of conditions, and the following disclaimer in the
 | 
			
		||||
   documentation and/or other materials provided with the distribution.
 | 
			
		||||
 | 
			
		||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 | 
			
		||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | 
			
		||||
POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,136 +0,0 @@
 | 
			
		||||
Botan: Crypto and TLS for Modern C++
 | 
			
		||||
========================================
 | 
			
		||||
 | 
			
		||||
Botan (Japanese for peony flower) is a C++ cryptography library released under the
 | 
			
		||||
permissive `Simplified BSD <https://botan.randombit.net/license.txt>`_ license.
 | 
			
		||||
 | 
			
		||||
Botan's goal is to be the best option for cryptography in C++ by offering the
 | 
			
		||||
tools necessary to implement a range of practical systems, such as TLS protocol,
 | 
			
		||||
X.509 certificates, modern AEAD ciphers, PKCS#11 and TPM hardware support,
 | 
			
		||||
password hashing, and post quantum crypto schemes. A Python binding is included,
 | 
			
		||||
and several other `language bindings
 | 
			
		||||
<https://github.com/randombit/botan/wiki/Language-Bindings>`_ are available.
 | 
			
		||||
The library is accompanied by a featureful
 | 
			
		||||
`command line interface <https://botan.randombit.net/handbook/cli.html>`_.
 | 
			
		||||
 | 
			
		||||
See the `documentation <https://botan.randombit.net/handbook>`_ for more
 | 
			
		||||
information about included features.
 | 
			
		||||
 | 
			
		||||
Development is coordinated on `GitHub <https://github.com/randombit/botan>`_
 | 
			
		||||
and contributions are welcome. If you need help, please open an issue on
 | 
			
		||||
`GitHub <https://github.com/randombit/botan/issues>`_.
 | 
			
		||||
 | 
			
		||||
If you think you have found a security issue, see the `security page
 | 
			
		||||
<https://botan.randombit.net/security.html>`_ for contact information.
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/randombit/botan/actions/workflows/ci.yml/badge.svg?branch=master
 | 
			
		||||
    :target: https://github.com/randombit/botan/actions/workflows/ci.yml
 | 
			
		||||
    :alt: CI status
 | 
			
		||||
 | 
			
		||||
.. image:: https://github.com/randombit/botan/actions/workflows/nightly.yml/badge.svg?branch=master
 | 
			
		||||
    :target: https://github.com/randombit/botan/actions/workflows/nightly.yml
 | 
			
		||||
    :alt: nightly CI status
 | 
			
		||||
 | 
			
		||||
.. image:: https://img.shields.io/coverallsCoverage/github/randombit/botan?branch=master
 | 
			
		||||
    :target: https://coveralls.io/github/randombit/botan
 | 
			
		||||
    :alt: Coverage report
 | 
			
		||||
 | 
			
		||||
.. image:: https://oss-fuzz-build-logs.storage.googleapis.com/badges/botan.svg
 | 
			
		||||
    :target: https://oss-fuzz.com/coverage-report/job/libfuzzer_asan_botan/latest
 | 
			
		||||
    :alt: OSS-Fuzz status
 | 
			
		||||
 | 
			
		||||
.. image:: https://repology.org/badge/tiny-repos/botan.svg
 | 
			
		||||
    :target: https://repology.org/project/botan/versions
 | 
			
		||||
    :alt: Packaging status
 | 
			
		||||
 | 
			
		||||
.. image:: https://api.securityscorecards.dev/projects/github.com/randombit/botan/badge
 | 
			
		||||
    :target: https://securityscorecards.dev/viewer/?uri=github.com/randombit/botan
 | 
			
		||||
    :alt: CII Best Practices statement
 | 
			
		||||
 | 
			
		||||
.. image:: https://bestpractices.coreinfrastructure.org/projects/531/badge
 | 
			
		||||
    :target: https://bestpractices.coreinfrastructure.org/projects/531
 | 
			
		||||
    :alt: CII Best Practices statement
 | 
			
		||||
 | 
			
		||||
Releases
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
The latest release from the Botan2 release series is
 | 
			
		||||
`2.19.3 <https://botan.randombit.net/releases/Botan-2.19.3.tar.xz>`_
 | 
			
		||||
`(sig) <https://botan.randombit.net/releases/Botan-2.19.3.tar.xz.asc>`_,
 | 
			
		||||
released on 2022-11-16.
 | 
			
		||||
 | 
			
		||||
The latest release from the Botan3 release series is
 | 
			
		||||
`3.2.0 <https://botan.randombit.net/releases/Botan-3.2.0.tar.xz>`_
 | 
			
		||||
`(sig) <https://botan.randombit.net/releases/Botan-3.2.0.tar.xz.asc>`_,
 | 
			
		||||
released on 2023-10-09.
 | 
			
		||||
 | 
			
		||||
All releases are signed with a `PGP key <https://botan.randombit.net/pgpkey.txt>`_.
 | 
			
		||||
See the `release notes <https://botan.randombit.net/news.html>`_ for
 | 
			
		||||
what is new. Botan is also available through most
 | 
			
		||||
`distributions <https://github.com/randombit/botan/wiki/Distros>`_
 | 
			
		||||
such as Fedora, Debian, Arch and Homebrew.
 | 
			
		||||
 | 
			
		||||
Find Enclosed
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Transport Layer Security (TLS) Protocol
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* TLS v1.2/v1.3, and DTLS v1.2
 | 
			
		||||
* Supported extensions include session tickets, SNI, ALPN, OCSP stapling,
 | 
			
		||||
  encrypt-then-mac CBC, and extended master secret.
 | 
			
		||||
* Supports authentication using certificates or preshared keys (PSK)
 | 
			
		||||
* Supports record encryption with ChaCha20Poly1305, AES/OCB, AES/GCM, AES/CCM,
 | 
			
		||||
  Camellia/GCM as well as legacy CBC ciphersuites.
 | 
			
		||||
* Key exchange using ECDH, FFDHE, or RSA
 | 
			
		||||
 | 
			
		||||
Public Key Infrastructure
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* X.509v3 certificates and CRL creation and handling
 | 
			
		||||
* PKIX certificate path validation, including name constraints.
 | 
			
		||||
* OCSP request creation and response handling
 | 
			
		||||
* PKCS #10 certificate request generation and processing
 | 
			
		||||
* Access to Windows, macOS and Unix system certificate stores
 | 
			
		||||
* SQL database backed certificate store
 | 
			
		||||
 | 
			
		||||
Public Key Cryptography
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* RSA signatures and encryption
 | 
			
		||||
* DH and ECDH key agreement
 | 
			
		||||
* Signature schemes ECDSA, DSA, Ed25519, ECGDSA, ECKCDSA, SM2, GOST 34.10
 | 
			
		||||
* Post-quantum signature schemes Dilithium, SPHINCS+, and XMSS
 | 
			
		||||
* Post-quantum key agreement schemes McEliece and Kyber
 | 
			
		||||
* ElGamal encryption
 | 
			
		||||
* Padding schemes OAEP, PSS, PKCS #1 v1.5, X9.31
 | 
			
		||||
 | 
			
		||||
Ciphers, hashes, MACs, and checksums
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Authenticated cipher modes EAX, OCB, GCM, SIV, CCM, (X)ChaCha20Poly1305
 | 
			
		||||
* Cipher modes CTR, CBC, XTS, CFB, OFB
 | 
			
		||||
* Block ciphers AES, ARIA, Blowfish, Camellia, CAST-128, DES/3DES, IDEA,
 | 
			
		||||
  Lion, SEED, Serpent, SHACAL2, SM4, Threefish-512, Twofish
 | 
			
		||||
* Stream ciphers (X)ChaCha20, (X)Salsa20, SHAKE-128, RC4
 | 
			
		||||
* Hash functions SHA-1, SHA-2, SHA-3, MD5, RIPEMD-160, BLAKE2b,
 | 
			
		||||
  Skein-512, SM3, Streebog, Whirlpool
 | 
			
		||||
* Password hashing schemes PBKDF2, Argon2, Scrypt, bcrypt
 | 
			
		||||
* Authentication codes HMAC, CMAC, Poly1305, SipHash, GMAC, X9.19 DES-MAC
 | 
			
		||||
* Non-cryptographic checksums Adler32, CRC24, CRC32
 | 
			
		||||
 | 
			
		||||
Other Useful Things
 | 
			
		||||
----------------------------------------
 | 
			
		||||
 | 
			
		||||
* Full C++ PKCS #11 API wrapper
 | 
			
		||||
* Interfaces for TPM v1.2 device access
 | 
			
		||||
* Simple compression API wrapping zlib, bzip2, and lzma libraries
 | 
			
		||||
* RNG wrappers for system RNG and hardware RNGs
 | 
			
		||||
* HMAC_DRBG and entropy collection system for userspace RNGs
 | 
			
		||||
* SRP-6a password authenticated key exchange
 | 
			
		||||
* Key derivation functions including HKDF, KDF2, SP 800-108, SP 800-56A, SP 800-56C
 | 
			
		||||
* HOTP and TOTP algorithms
 | 
			
		||||
* Format preserving encryption scheme FE1
 | 
			
		||||
* Threshold secret sharing
 | 
			
		||||
* NIST key wrapping
 | 
			
		||||
* Boost.Asio compatible TLS client stream
 | 
			
		||||
@@ -1,82 +0,0 @@
 | 
			
		||||
---
 | 
			
		||||
# This file was automatically generated by src/scripts/dev_tools/run_clang_tidy.py --regenerate-inline-config-file
 | 
			
		||||
#
 | 
			
		||||
# All manual edits to this file will be lost. Edit the script
 | 
			
		||||
# then regenerate this configuration file.
 | 
			
		||||
 | 
			
		||||
Checks: >
 | 
			
		||||
    bugprone-*,
 | 
			
		||||
    cert-*,
 | 
			
		||||
    clang-analyzer-*,
 | 
			
		||||
    cppcoreguidelines-*,
 | 
			
		||||
    hicpp-*,
 | 
			
		||||
    misc-*,
 | 
			
		||||
    modernize-*,
 | 
			
		||||
    performance-*,
 | 
			
		||||
    portability-*,
 | 
			
		||||
    readability-*,
 | 
			
		||||
    -*-named-parameter,
 | 
			
		||||
    -*-member-init,
 | 
			
		||||
    -bugprone-lambda-function-name,
 | 
			
		||||
    -bugprone-unchecked-optional-access,
 | 
			
		||||
    -cert-err58-cpp,
 | 
			
		||||
    -cppcoreguidelines-avoid-const-or-ref-data-members,
 | 
			
		||||
    -cppcoreguidelines-init-variables,
 | 
			
		||||
    -cppcoreguidelines-owning-memory,
 | 
			
		||||
    -cppcoreguidelines-prefer-member-initializer,
 | 
			
		||||
    -cppcoreguidelines-slicing,
 | 
			
		||||
    -hicpp-explicit-conversions,
 | 
			
		||||
    -misc-const-correctness,
 | 
			
		||||
    -misc-redundant-expression,
 | 
			
		||||
    -misc-misplaced-const,
 | 
			
		||||
    -misc-confusable-identifiers,
 | 
			
		||||
    -modernize-avoid-bind,
 | 
			
		||||
    -modernize-pass-by-value,
 | 
			
		||||
    -readability-convert-member-functions-to-static,
 | 
			
		||||
    -readability-implicit-bool-conversion,
 | 
			
		||||
    -readability-inconsistent-declaration-parameter-name,
 | 
			
		||||
    -readability-qualified-auto,
 | 
			
		||||
    -readability-simplify-boolean-expr,
 | 
			
		||||
    -readability-static-accessed-through-instance,
 | 
			
		||||
    -*-array-to-pointer-decay,
 | 
			
		||||
    -*-avoid-c-arrays,
 | 
			
		||||
    -*-else-after-return,
 | 
			
		||||
    -*-function-size,
 | 
			
		||||
    -*-magic-numbers,
 | 
			
		||||
    -*-narrowing-conversions,
 | 
			
		||||
    -*-no-array-decay,
 | 
			
		||||
    -*-use-auto,
 | 
			
		||||
    -*-use-emplace,
 | 
			
		||||
    -*-deprecated-headers,
 | 
			
		||||
    -bugprone-argument-comment,
 | 
			
		||||
    -bugprone-branch-clone,
 | 
			
		||||
    -bugprone-easily-swappable-parameters,
 | 
			
		||||
    -bugprone-implicit-widening-of-multiplication-result,
 | 
			
		||||
    -cppcoreguidelines-avoid-do-while,
 | 
			
		||||
    -cppcoreguidelines-non-private-member-variables-in-classes,
 | 
			
		||||
    -cppcoreguidelines-pro-bounds-pointer-arithmetic,
 | 
			
		||||
    -cppcoreguidelines-pro-bounds-constant-array-index,
 | 
			
		||||
    -cppcoreguidelines-pro-type-const-cast,
 | 
			
		||||
    -cppcoreguidelines-pro-type-reinterpret-cast,
 | 
			
		||||
    -cppcoreguidelines-pro-type-vararg,
 | 
			
		||||
    -hicpp-no-assembler,
 | 
			
		||||
    -hicpp-vararg,
 | 
			
		||||
    -hicpp-signed-bitwise,
 | 
			
		||||
    -misc-no-recursion,
 | 
			
		||||
    -modernize-loop-convert,
 | 
			
		||||
    -modernize-raw-string-literal,
 | 
			
		||||
    -modernize-use-trailing-return-type,
 | 
			
		||||
    -modernize-return-braced-init-list,
 | 
			
		||||
    -modernize-use-default-member-init,
 | 
			
		||||
    -modernize-use-nodiscard,
 | 
			
		||||
    -modernize-use-using,
 | 
			
		||||
    -portability-simd-intrinsics,
 | 
			
		||||
    -readability-container-data-pointer,
 | 
			
		||||
    -readability-function-cognitive-complexity,
 | 
			
		||||
    -readability-identifier-length,
 | 
			
		||||
    -readability-isolate-declaration,
 | 
			
		||||
    -readability-non-const-parameter,
 | 
			
		||||
    -readability-redundant-access-specifiers,
 | 
			
		||||
    -readability-suspicious-call-argument,
 | 
			
		||||
    -readability-use-anyofallof,
 | 
			
		||||
---
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,221 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
    "LooseErrorTests": {
 | 
			
		||||
        "AppDataBeforeHandshake": "BoGo expects different error before vs after CCS",
 | 
			
		||||
        "AppDataBeforeHandshake-Empty": "Invalid record message",
 | 
			
		||||
        "ServerHelloBogusCipher": "Unexpected error",
 | 
			
		||||
        "Garbage": "Decoding error",
 | 
			
		||||
        "Resume-Client-CipherMismatch": "Unexpected error",
 | 
			
		||||
        "InvalidECDHPoint-Server": "Unexpected error",
 | 
			
		||||
        "NoSharedCipher": "Unexpected error",
 | 
			
		||||
        "NoSharedCipher-TLS13": "Unexpected error",
 | 
			
		||||
 | 
			
		||||
        "PartialFinishedWithServerHelloDone": "Unexpected record vs excess handshake data",
 | 
			
		||||
        "HelloRetryRequest-DuplicateCurve-TLS13": "expects 'illegal parameter' but we want to stick with 'decode error'",
 | 
			
		||||
        "HelloRetryRequest-DuplicateCookie-TLS13": "expects 'illegal parameter' but we want to stick with 'decode error'",
 | 
			
		||||
        "EncryptedExtensionsWithKeyShare-TLS13": "expects 'unsupported extension' but RFC requires 'illegal parameter'",
 | 
			
		||||
        "ClientSkipCertificateVerify-TLS13": "would require ambiguous error mapping",
 | 
			
		||||
        "Resume-Client-Mismatch-TLS13-TLS12-TLS": "server requests a downgrade to TLS 1.2, echoing the random session ID during a TLS 1.3 resumption. => error mapping conflict",
 | 
			
		||||
        "ServerAuth-NoFallback-TLS13": "would require ambiguous error mapping"
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    "DisabledTests": {
 | 
			
		||||
        "*TLS1": "No TLS 1.0",
 | 
			
		||||
        "*-TLS1-*": "No TLS 1.0",
 | 
			
		||||
        "*-TLS10-*": "No TLS 1.0",
 | 
			
		||||
        "TLS1-*": "No TLS 1.0",
 | 
			
		||||
        "VersionNegotiation*-TLS": "No TLS 1.0",
 | 
			
		||||
        "VersionNegotiation*-DTLS": "No DTLS 1.0",
 | 
			
		||||
 | 
			
		||||
        "*TLS11": "No TLS 1.1",
 | 
			
		||||
        "*-TLS11-*": "No TLS 1.1",
 | 
			
		||||
        "TLS11-*": "No TLS 1.1",
 | 
			
		||||
 | 
			
		||||
        "*RSA_PKCS1_MD5_SHA1": "We do not implement MD5/SHA1 concatenation anyway",
 | 
			
		||||
        "Compliance-fips202205-*": "We do not have explicit support for a FIPS TLS policy",
 | 
			
		||||
        "Compliance-fips-202205-*": "We do not have explicit support for a FIPS TLS policy",
 | 
			
		||||
        "Compliance-wpa-202304-*": "We do not have explicit support for the WPA Enterprise mode",
 | 
			
		||||
 | 
			
		||||
        "CBCRecordSplitting*": "No need to split CBC records in TLS 1.2",
 | 
			
		||||
        "DelegatedCredentials*": "No support of -delegated-cerdential",
 | 
			
		||||
 | 
			
		||||
        "*SCSV*": "SCSV is meaningless without TLS 1.0/1.1 support",
 | 
			
		||||
 | 
			
		||||
        "AllExtensions-*": "Not all extensions are implemented",
 | 
			
		||||
 | 
			
		||||
        "VersionTolerance-TLS13": "We are not tolerating 0x0400 as Client Hello legacy_version",
 | 
			
		||||
 | 
			
		||||
        "Server-JDK11-*": "We don't implement JDK-specific workarounds",
 | 
			
		||||
        "Client-RejectJDK11DowngradeRandom": "We don't implement this workaround",
 | 
			
		||||
        "ExportTrafficSecrets-*": "Exporting traffic secrets is not implemented",
 | 
			
		||||
        "TooManyChangeCipherSpec-Client-TLS13": "Limits on the number of CCS are not implemented",
 | 
			
		||||
        "TooManyChangeCipherSpec-Server-TLS13": "Limits on the number of CCS are not implemented",
 | 
			
		||||
        "TooManyKeyUpdates": "Limits on the number of KeyUpdates are not implemented",
 | 
			
		||||
 | 
			
		||||
        "TLS12SessionID-TLS13": "We don't offer TLS 1.3 when a TLS 1.2 session was found",
 | 
			
		||||
        "Ticket-Forbidden-TLS13": "We don't offer TLS 1.3 when a TLS 1.2 session was found",
 | 
			
		||||
        "Resume-Client-NoResume-TLS12-TLS13-TLS": "We don't offer TLS 1.3 when a TLS 1.2 session was found",
 | 
			
		||||
        "Resume-Client-Mismatch-TLS12-TLS13-TLS": "We don't offer TLS 1.3 when a TLS 1.2 session was found",
 | 
			
		||||
        "Resume-Server-UnofferedCipher-TLS13": "BoringSSL will not allow switching ciphers during TLS 1.3 resumption, we do, though.",
 | 
			
		||||
 | 
			
		||||
        "HttpGET": "TLS 1.3 server does not detect HTTP",
 | 
			
		||||
        "HttpPOST": "TLS 1.3 server does not detect HTTP",
 | 
			
		||||
        "HttpPUT": "TLS 1.3 server does not detect HTTP",
 | 
			
		||||
        "HttpHEAD": "TLS 1.3 server does not detect HTTP",
 | 
			
		||||
        "HttpCONNECT": "TLS 1.3 server does not detect HTTP",
 | 
			
		||||
 | 
			
		||||
        "*EarlyData*": "No TLS 1.3 Early Data, yet",
 | 
			
		||||
        "TLS13-TicketAgeSkew-*": "No TLS 1.3 Early Data, yet",
 | 
			
		||||
        "ExportKeyingMaterial-Server-HalfRTT-TLS13": "No TLS 1.3 Early Data, yet",
 | 
			
		||||
        "EarlyDataEnabled*": "No TLS 1.3 Early Data, yet",
 | 
			
		||||
        "EarlyData-Reject0RTT*": "No TLS 1.3 Early Data, yet",
 | 
			
		||||
        "PartialEndOfEarlyDataWithClientHello": "No TLS 1.3 Early Data, yet",
 | 
			
		||||
 | 
			
		||||
        "SendNoClientCertificateExtensions-TLS13": "-signed-cert-timestamps currently not supported in the shim",
 | 
			
		||||
        "KeyUpdate-RequestACK-UnfinishedWrite": "-read-with-unfinished-write currently not supported in the shim",
 | 
			
		||||
 | 
			
		||||
        "TLS-ECH*": "No ECH support",
 | 
			
		||||
        "ECH*": "No ECH support",
 | 
			
		||||
 | 
			
		||||
        "DuplicateCertCompressionExt*": "No support for 1.3 cert compression extension",
 | 
			
		||||
        "CertCompression*-TLS13": "No support for 1.3 cert compression extension",
 | 
			
		||||
 | 
			
		||||
        "SupportedVersionSelection-TLS12": "We just ignore the version extension in this case",
 | 
			
		||||
 | 
			
		||||
        "Downgrade-*-Client-Ignore": "Not possible to ignore downgrade indicator",
 | 
			
		||||
 | 
			
		||||
        "Agree-Digest-SHA1": "No SHA-1 in TLS 1.2",
 | 
			
		||||
        "ServerAuth-SHA1-Fallback-*": "No SHA-1 in TLS 1.2",
 | 
			
		||||
        "*-InvalidSignature-*_SHA1-TLS12": "No SHA-1 in TLS 1.2",
 | 
			
		||||
        "*-Sign-*_SHA1-TLS12": "No SHA-1 in TLS 1.2",
 | 
			
		||||
        "*-Sign-Negotiate-*_SHA1-TLS12": "No SHA-1 in TLS 1.2",
 | 
			
		||||
        "*-VerifyDefault-*_SHA1-TLS12": "No SHA-1 in TLS 1.2",
 | 
			
		||||
        "*-Verify-*_SHA1-TLS12": "No SHA-1 in TLS 1.2",
 | 
			
		||||
 | 
			
		||||
        "*QUIC*": "No QUIC",
 | 
			
		||||
        "ALPS*": "No ALPS",
 | 
			
		||||
        "ExtraClientEncryptedExtension-TLS-TLS13": "No ALPS",
 | 
			
		||||
 | 
			
		||||
        "*NPN*": "No support for NPN",
 | 
			
		||||
        "ALPNServer-Preferred-*": "No support for NPN",
 | 
			
		||||
        "*-NextProtocol*": "No support for NPN",
 | 
			
		||||
 | 
			
		||||
        "*SignedCertificateTimestamp*": "No support for SCT",
 | 
			
		||||
        "*SCT*": "No support for SCT",
 | 
			
		||||
        "Renegotiation-ChangeAuthProperties": "No support for SCT",
 | 
			
		||||
        "UnsolicitedCertificateExtensions-*": "No support for SCT",
 | 
			
		||||
        "IgnoreExtensionsOnIntermediates-TLS13": "No support for SCT",
 | 
			
		||||
        "SendNoExtensionsOnIntermediate-TLS13": "No support for SCT",
 | 
			
		||||
 | 
			
		||||
        "CertificateVerificationSoftFail*":  "Fail, but don't fail... wtf?",
 | 
			
		||||
 | 
			
		||||
        "*NULL-SHA*": "No support for NULL ciphers",
 | 
			
		||||
        "*WITH_NULL*": "No support for NULL ciphers",
 | 
			
		||||
        "*GREASE*": "No support for GREASE",
 | 
			
		||||
        "*ChannelID*": "No support for ChannelID",
 | 
			
		||||
        "*TokenBinding*": "No support for Token Binding",
 | 
			
		||||
        "ClientHelloPadding": "No support for client hello padding extension",
 | 
			
		||||
        "TLSUnique*": "Not supported",
 | 
			
		||||
        "*CECPQ2*": "Not implemented",
 | 
			
		||||
        "PQExperimentSignal*": "Not implemented",
 | 
			
		||||
        "*P-224*": "P-224 not supported in TLS",
 | 
			
		||||
        "*V2ClientHello*": "No support for SSLv2 client hellos",
 | 
			
		||||
        "*Ed25519*": "Ed25519 not implemented in TLS",
 | 
			
		||||
        "*FalseStart*": "Botan doesn't do false start",
 | 
			
		||||
        "MaxSendFragment*": "Maximum fragment extension not supported",
 | 
			
		||||
        "ExportKeyingMaterial-EmptyContext*": "No support for empty context",
 | 
			
		||||
 | 
			
		||||
        "Peek-*": "No peek API",
 | 
			
		||||
        "*OldCallback*": "BoringSSL specific API test",
 | 
			
		||||
        "*Renegotiate-Client-Explicit*":  "BoringSSL specific API test",
 | 
			
		||||
        "CBCRecordSplittingPartialWrite*": "BoringSSL specific API test",
 | 
			
		||||
        "TicketCallback*": "BoringSSL specific API test",
 | 
			
		||||
        "Server-DDoS*": "BoringSSL specific API test",
 | 
			
		||||
        "RetainOnlySHA256-*": "BoringSSL specific API test",
 | 
			
		||||
        "Renegotiate-Client-UnfinishedWrite": "BoringSSL specific API test",
 | 
			
		||||
        "FailEarlyCallback": "BoringSSL specific API test",
 | 
			
		||||
 | 
			
		||||
        "NotJustKyberKeyShare": "BoringSSL specific policy test (we may offer solo PQ/T groups)",
 | 
			
		||||
        "KyberKeyShareIncludedSecond": "BoringSSL specific policy test (we may offer solo PQ/T groups)",
 | 
			
		||||
        "KyberKeyShareIncludedThird": "BoringSSL specific policy test (we may offer solo PQ/T groups)",
 | 
			
		||||
 | 
			
		||||
        "ShimTicketRewritable": "Botan has a different ticket format",
 | 
			
		||||
        "Resume-Server-DeclineCrossVersion*": "Botan has a different ticket format",
 | 
			
		||||
        "Resume-Server-DeclineBadCipher*": "Botan has a different ticket format",
 | 
			
		||||
        "Resume-Server-CipherNotPreferred*": "Botan has a different ticket format",
 | 
			
		||||
 | 
			
		||||
        "TLS*-NoTicket-NoAccept": "BoGo expects that if ticket is issued stateful resumption is impossible",
 | 
			
		||||
 | 
			
		||||
        "CheckLeafCurve": "Botan doesn't care what curve an ECDSA cert uses",
 | 
			
		||||
 | 
			
		||||
        "CertificateVerificationDoesNotFailOnResume*": "Botan doesn't support reverify on resume",
 | 
			
		||||
        "CertificateVerificationFailsOnResume*": "Botan doesn't support reverify on resume",
 | 
			
		||||
        "CertificateVerificationPassesOnResume*": "Botan doesn't support reverify on resume",
 | 
			
		||||
 | 
			
		||||
        "CipherNegotiation-2": "No support for cipher equivalence classes",
 | 
			
		||||
        "CipherNegotiation-3": "No support for cipher equivalence classes",
 | 
			
		||||
        "CipherNegotiation-4": "No support for cipher equivalence classes",
 | 
			
		||||
        "CipherNegotiation-5": "No support for cipher equivalence classes",
 | 
			
		||||
        "CipherNegotiation-8": "No support for cipher equivalence classes",
 | 
			
		||||
 | 
			
		||||
        "ALPNServer-SelectEmpty-*": "Botan treats empty ALPN from callback as a decline",
 | 
			
		||||
 | 
			
		||||
        "AppDataAfterChangeCipherSpec-DTLS*": "BoringSSL DTLS drops out of order AppData, we reject",
 | 
			
		||||
 | 
			
		||||
        "Resume-Client-NoResume-TLS1-TLS11-TLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
        "Resume-Client-NoResume-TLS1-TLS12-TLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
        "Resume-Client-NoResume-TLS11-TLS12-TLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
        "Resume-Client-NoResume-TLS1-TLS12-DTLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
 | 
			
		||||
        "Resume-Client-Mismatch-TLS1-TLS11-TLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
        "Resume-Client-Mismatch-TLS1-TLS12-TLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
        "Resume-Client-Mismatch-TLS11-TLS12-TLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
        "Resume-Client-Mismatch-TLS1-TLS12-DTLS": "BoGo expects resumption attempt sends latest version",
 | 
			
		||||
 | 
			
		||||
        "LooseInitialRecordVersion-TLS12": "Botan is somewhat strict about the record version number",
 | 
			
		||||
 | 
			
		||||
        "CurveTest-*-Compressed*": "Point compression is supported, which BoGo doesn't expect",
 | 
			
		||||
        "PointFormat-*-MissingUncompressed": "Point compression is supported, which BoGo doesn't expect",
 | 
			
		||||
 | 
			
		||||
        "RSAPSSSupport-ConfigPSS-NoCerts-TLS12-*": "Needs investigation",
 | 
			
		||||
        "RSAPSSSupport-Default-NoCerts-TLS12-*": "Needs investigation",
 | 
			
		||||
 | 
			
		||||
        "DTLS-Retransmit*": "Shim needs timeout support",
 | 
			
		||||
 | 
			
		||||
        "DTLS-StrayRetransmitFinished-ClientFull": "Needs investigation",
 | 
			
		||||
        "DTLS-StrayRetransmitFinished-ServerResume": "Needs investigation",
 | 
			
		||||
 | 
			
		||||
        "SRTP-Server-IgnoreMKI-*": "Non-empty MKI is rejected (bug)",
 | 
			
		||||
 | 
			
		||||
        "Renegotiate-Client-Packed": "Packing HelloRequest with Finished loses the HelloRequest (bug)",
 | 
			
		||||
        "SendHalfHelloRequest*PackHandshake": "Packing HelloRequest with Finished loses the HelloRequest (bug)",
 | 
			
		||||
 | 
			
		||||
        "PartialClientFinishedWithClientHello": "Need to check for buffered messages when CCS (bug)",
 | 
			
		||||
        "SendUnencryptedFinished-DTLS": "Need to check for buffered messages when CCS (bug)",
 | 
			
		||||
 | 
			
		||||
        "RSAKeyUsage-*-TLS12": "We always enforce key usage",
 | 
			
		||||
        "RSAKeyUsage-Client-WantSignature-GotEncipherment-AlwaysEnforced-TLS13": "We always enforce key usage",
 | 
			
		||||
 | 
			
		||||
        "AllExtensions-Client-Permute-TLS-TLS12" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "AllExtensions-Client-Permute-DTLS-TLS12" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "EarlyData-WriteAfterEncryptedExtensions" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "EarlyData-WriteAfterServerHello" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-CipherMismatch1" : "Requires new shim flags that are NYI (as of March 2023)",
 | 
			
		||||
        "TLS-HintMismatch-CipherMismatch2" : "Requires new shim flags that are NYI (as of March 2023)",
 | 
			
		||||
        "TLS-HintMismatch-ECDHE-Group" : "Requires new shim flags that are NYI (as of March 2023)",
 | 
			
		||||
        "TLS-HintMismatch-SignatureInput" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-KeyShare" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-HandshakerHelloRetryRequest" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-ShimHelloRetryRequest" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-SignatureAlgorithm-TLS*" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-NoTickets1-TLS*" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-NoTickets2-TLS*" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-Version2" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-CertificateRequest" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-CertificateCompression-HandshakerOnly" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-CertificateCompression-ShimOnly" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-CertificateCompression-AlgorithmMismatch" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-CertificateCompression-InputMismatch" : "Requires new shim flags that are NYI (as of March 2022)",
 | 
			
		||||
        "TLS-HintMismatch-Version1" : "Requires new shim flags that are NYI (as of March 2022)"
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
endian little
 | 
			
		||||
wordsize 64
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
axp
 | 
			
		||||
alphaaxp
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1,21 +0,0 @@
 | 
			
		||||
endian little
 | 
			
		||||
family arm
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
arm
 | 
			
		||||
armeb
 | 
			
		||||
armel # For Debian
 | 
			
		||||
armhf # For Debian
 | 
			
		||||
evbarm # For NetBSD
 | 
			
		||||
 | 
			
		||||
armv7
 | 
			
		||||
armv7l
 | 
			
		||||
armv7a
 | 
			
		||||
armv7-a
 | 
			
		||||
 | 
			
		||||
armv8l # For AlpineLinux
 | 
			
		||||
</aliases>
 | 
			
		||||
 | 
			
		||||
<isa_extensions>
 | 
			
		||||
neon
 | 
			
		||||
</isa_extensions>
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
endian little
 | 
			
		||||
wordsize 64
 | 
			
		||||
 | 
			
		||||
family arm
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
aarch64
 | 
			
		||||
aarch64_be
 | 
			
		||||
armv8
 | 
			
		||||
armv8-a
 | 
			
		||||
</aliases>
 | 
			
		||||
 | 
			
		||||
<isa_extensions>
 | 
			
		||||
neon
 | 
			
		||||
armv8crypto
 | 
			
		||||
armv8sm3
 | 
			
		||||
armv8sm4
 | 
			
		||||
armv8sha3
 | 
			
		||||
armv8sha512
 | 
			
		||||
</isa_extensions>
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
 | 
			
		||||
# This target can be used when building an amalgamation which must
 | 
			
		||||
# be built on multiple architectures, or when targetting a CPU
 | 
			
		||||
# which the build system doesn't know about.
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
<aliases>
 | 
			
		||||
hp-pa
 | 
			
		||||
parisc
 | 
			
		||||
parisc64
 | 
			
		||||
pa-risc
 | 
			
		||||
hp-parisc
 | 
			
		||||
hp-pa-risc
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
wordsize 64
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
itanium
 | 
			
		||||
itanic
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
wordsize 64
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
family loongarch
 | 
			
		||||
endian little
 | 
			
		||||
wordsize 64
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
680x0
 | 
			
		||||
68k
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
<aliases>
 | 
			
		||||
mips
 | 
			
		||||
mipsbe # RedHat
 | 
			
		||||
mipsle # RedHat
 | 
			
		||||
mipsel # Debian
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
wordsize 64
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
mips64el
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
 | 
			
		||||
family ppc
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
 | 
			
		||||
family ppc
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
powerpc
 | 
			
		||||
ppc
 | 
			
		||||
</aliases>
 | 
			
		||||
 | 
			
		||||
<isa_extensions>
 | 
			
		||||
altivec
 | 
			
		||||
</isa_extensions>
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
 | 
			
		||||
family ppc
 | 
			
		||||
wordsize 64
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
powerpc64
 | 
			
		||||
powerpc64le
 | 
			
		||||
ppc64le
 | 
			
		||||
ppc64el
 | 
			
		||||
</aliases>
 | 
			
		||||
 | 
			
		||||
<isa_extensions>
 | 
			
		||||
altivec
 | 
			
		||||
vsx
 | 
			
		||||
powercrypto
 | 
			
		||||
power9
 | 
			
		||||
</isa_extensions>
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
family riscv
 | 
			
		||||
endian little
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
family riscv
 | 
			
		||||
endian little
 | 
			
		||||
wordsize 64
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
@@ -1,2 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
wordsize 64
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
endian big
 | 
			
		||||
 | 
			
		||||
family sparc
 | 
			
		||||
 | 
			
		||||
<aliases>
 | 
			
		||||
sparc
 | 
			
		||||
</aliases>
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
family sparc
 | 
			
		||||
wordsize 64
 | 
			
		||||
endian big
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user