Microsoft SymCrypt

repository·main·Indexed 21 days ago

https://github.com/microsoft/symcrypt

A core cryptographic function library used by Windows, providing symmetric and asymmetric cryptographic algorithms. Designed for high performance, security, and compatibility across Windows-supported CPU architectures, it supports Windows (kernel and user mode), Linux, and macOS. The library follows Semantic Versioning 2.0.0 and provides both generic C and optimized assembly implementations.

Tokens
4.8K
Snippets
12
Records
21
Agent score
74%

What's inside SymCrypt

  1. Avoid direct use of internal type definitions in symcrypt_internal.h

    main

    SymCrypt is removing several struct definitions from symcrypt_internal.h to allow for future changes to structure sizes and alignments without breaking caller code.

    Best Practices:

    • Do not use specific struct definitions (e.g., SYMCRYPT_ECPOINT) directly in your code.
    • Do handle these structures via pointers provided by the API rather than attempting to instantiate or manipulate the structs directly.

    Note: The concept of SYMCRYPT_ASYM_ALIGN may also be removed.

  2. Understand SymCrypt versioning and compatibility

    main

    SymCrypt follows the Semantic Versioning 2.0.0 specification. Understanding the version numbers helps determine the impact of updates:

    • Major version changes: Introduce breaking changes to the API or ABI, including changes in behavior.
    • Minor version changes: Introduce backwards-compatible functionality, improvements, or bug fixes.
    • Patch version changes: Introduce backwards-compatible bug fixes.

    It is highly recommended to regularly update to the latest version of SymCrypt to receive security fixes and performance improvements.

  3. Supported Platforms and Architectures

    main

    SymCrypt provides both generic C implementations and optimized assembly (ASM) implementations. Not all combinations support ASM optimizations.

    Operating EnvironmentArchitectureSupported CompilersASM Enabled
    Windows kernel modeAMD64, ARM64MSVC
    Windows user modeAMD64, ARM64, x86MSVC
    Linux user modeAMD64, ARM64GCC, Clang
    Linux user modex86GCC, Clang
    macOSARM64Apple Clang
    macOSAMD64Apple Clang

    Important Notes:

    • Windows Kernel Mode: Use MSBuild for official Windows builds, as CMake does not currently support building kernel mode components.
    • AMD64: This refers to x86-64.
    • macOS AMD64: Support is expected to be deprecated soon.
  4. Consume SymCrypt in .NET on Linux

    main

    SymCrypt can be consumed by .NET projects on Linux using PackageReference. The .NET SDK automatically extracts the native binary libsymcrypt.so from the runtimes/<rid>/native/ directory in the package and places it next to your published output. You can then access the functions via [DllImport("symcrypt")].

    Requirements:

    • The project must use PackageReference.
    • You must specify a RuntimeIdentifier (e.g., linux-x64 or linux-arm64).
    • Use dotnet publish -r <RID> to build the application.

    Caveats:

    • The package does not include a libsymcrypt.so.<MAJOR> SONAME symlink. If your runtime loader requires lookup by SONAME, you must manually create the symlink during your publish step.
    • Non-.NET Linux C/C++ builds are not supported via NuGet. For those, use the Azure Linux .tar.gz binary distribution directly.
    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net8.0</TargetFramework>
        <RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Microsoft.SymCrypt" Version="<SymCrypt Package Version>" />
      </ItemGroup>
    </Project>
    using System.Runtime.InteropServices;
    
    internal static class SymCrypt
    {
        [DllImport("symcrypt")]
        public static extern void SymCryptSha256(byte[] data, nuint cbData, byte[] result);
    }
  5. Run SymCrypt unit tests

    main

    After a successful build, you can execute the extensive functional test suite using the scripts/test.py helper script. On Windows, the tests may also perform comparisons against Windows APIs (CNG and CAPI) and provide performance metrics if the necessary dependencies are present.

    python scripts/test.py
  6. Clone the SymCrypt repository with submodules

    main

    To ensure all necessary components are present, especially when building Linux modules that require FIPS-certifiable entropy, you must initialize the submodules after cloning the repository. Specifically, the jitterentropy-library submodule is required for these modules.

    Note: The unittest/SymCryptDependencies submodule is only available to Microsoft employees. External users can ignore this submodule as it is only used for unit test benchmarks and does not affect the core SymCrypt product code.

    git submodule update --init
  7. Build SymCrypt using Python helper scripts

    main

    The easiest way to build, test, and package SymCrypt is using the provided Python scripts. This ensures a consistent build solution across platforms.

    Build

    • Windows or Linux (CMake): scripts/build.py cmake <build_dir>
    • Windows (MSBuild): scripts\build.py msbuild (Outputs to build\bin)

    Test

    Run unit tests after a build: scripts/test.py <build_dir>

    Package

    Create an archive of the built binaries: scripts/package.py <build_dir> <arch> <configuration> <module_name> <release_dir>

    Arguments for packaging:

    • arch: Architecture (e.g., AMD64, ARM64).
    • configuration: Build configuration (Debug, Release, Sanitize).
    • module_name: Relevant for Linux builds.
    # Example: Build for Linux using CMake into a directory named 'out'
    python3 scripts/build.py cmake out
    
    # Example: Run tests
    python3 scripts/test.py out
  8. Prepare for removal of asymmetric Create and Wipe functions

    main

    To comply with FIPS certification requirements and support dynamic linking, SymCrypt is moving away from exposing internal structure sizes and creation functions for asymmetric algorithms.

    Impacted Actions:

    • Avoid using functions that allow callers to calculate the size of structures used by asymmetric functions.
    • Avoid using functions that create asymmetric structures from existing buffers (e.g., SymCryptRsakeyCreate).

    Reasoning: This change ensures that internal structure sizes can change without breaking callers and allows SymCrypt to be distributed as a dynamically linked, FIPS-certifiable module that can be updated independently of the host application.

  9. Build the SymCrypt NuGet Package

    main

    Manual building of the NuGet package is generally not recommended; use the Azure DevOps pipeline if possible. If you must build manually, follow these steps:

    1. Build for target platforms:
      • Windows AMD64 and ARM64: Use scripts/build.py msbuild for each architecture.
      • Azure Linux AMD64 and ARM64: Use the Clang Release preset.
    2. Package flavors: Use scripts/package.py to package each build flavor.
    3. Organize contents: Copy package contents to the locations defined in symcrypt.nuspec:
      • Windows AMD64: ../pkg/win-x64/
      • Windows ARM64: ../pkg/win-arm64/
      • Linux AMD64: ../pkg/linux-x64/ (includes inc/symcrypt_no_sal.h and lib/libsymcrypt.so)
      • Linux ARM64: ../pkg/linux-arm64/ (includes lib/libsymcrypt.so)
    4. Pack: Use the NuGet CLI to create the .nupkg file.

    Note: For Linux, the pipeline copies the SONAME-versioned binary (e.g., libsymcrypt.so.1.2.3) into the unversioned libsymcrypt.so slot before packing to ensure compatibility with zip-based .nupkg files.

    nuget pack symcrypt.nuspec -Version <SymCrypt Package Version>
  10. Prerequisites for building SymCrypt

    main

    Before building SymCrypt, ensure your environment meets the following requirements:

    Windows

    • Visual Studio: 2019 or newer (with Windows 10 SDK version 18362).
    • CMake: version 3.13.0 or newer.
    • Python 3: Required for SymCryptAsm translation and integrity checks.
    • Note: You can use the CMake included with Visual Studio by adding its bin directory to your $env:PATH.

    Linux

    • Compilers: gcc >= 9.4.0 or clang >= 10.0.0.
    • CMake: version 3.13.0 or newer.
    • Python 3: Required for SymCryptAsm translation and integrity checks.
    • Python Dependencies: For integrity checks, install requirements via: pip3 install -r ./scripts/requirements.txt.

    macOS

    • Xcode: Required for developer tools, headers, and frameworks.
    • CMake: Required.
    • Python 3: Required for build scripts.
  11. Migrate from extern variables to getter functions

    main

    SymCrypt is replacing extern variables defined in SymCrypt headers with equivalent getter functions. This change is intended to simplify cross-platform dynamic module exports.

    Action Required: Identify any code accessing SymCrypt variables directly via headers and update them to use the new getter function equivalents.

  12. Consume SymCrypt in MSVC C++ on Windows

    main

    To use the SymCrypt NuGet package in a Windows MSVC C++ project, you must restore the packages and build using MSBuild.

    1. Open test/cpp/packages.config and replace %NUGET_VERSION% with the specific version of the SymCrypt package you wish to use.
    2. Restore the NuGet packages to a local directory.
    3. Build the project using msbuild, passing the NuGet_Version property to ensure the build system resolves the correct package version.
    cd test/cpp
    nuget restore packages.config -PackagesDirectory .\packages
    msbuild /p:NuGet_Version=<SymCrypt Package Version>