Tongsuo Documentation

repository·master·Indexed 23 days ago

https://github.com/tongsuo-project/tongsuo

An open-source fundamental cryptography library, formerly Alibaba's OpenSSL fork. It provides secure communication protocols and modern cryptographic algorithms, including Post-Quantum Cryptography and Chinese commercial standards, for networking, key management, and privacy computing.

Tokens
25K
Snippets
57
Records
128
Agent score
80%

What's inside Tongsuo

  1. Overview of Tongsuo features

    master

    Tongsuo is an open-source fundamental cryptography library providing modern cryptographic algorithms and secure communication protocols. It supports:

    • Compliance: Meets GM/T 0028 (Software Cryptographic Module Security Level 1) and GM/T 0005-2021 (Randomness Testing).
    • Chinese Commercial Cryptography: SM2, SM3, SM4, ZUC.
    • International Algorithms: ECDSA, RSA, AES, SHA.
    • Homomorphic Encryption: EC-ElGamal, Paillier.
    • Post-Quantum Cryptography (PQC): ML-KEM (Kyber), ML-DSA (Dilithium), SLH-DSA (SPHINCS+).
    • Zero-Knowledge Proofs (ZKP): Bulletproofs range, Bulletproofs R1CS.
    • Secure Protocols: TLCP (GB/T 38636-2020), TLS 1.3 + National Cryptography Single Certificate (RFC 8998), QUIC API, Delegated Credentials, and TLS Certificate Compression.
  2. Use a Standalone NDK Toolchain for Android

    master

    Instead of using a full NDK, you can use a 'standalone toolchain' tailored for a specific platform and API level. When using a standalone toolchain:

    1. Set ANDROID_NDK_ROOT to the location of the standalone toolchain.
    2. Pass the matching target name to ./Configure.
    3. Do not use the -D__ANDROID_API__=N flag.
    4. You can simplify your PATH adjustment to $ANDROID_NDK_ROOT/bin:$PATH.
  3. How ENGINE_TABLE manages algorithm implementations

    master

    The ENGINE_TABLE (implemented in files like tb_cipher.c, tb_digest.c, tb_rsa.c, etc.) manages the mapping between algorithm identifiers (nid) and ENGINE implementations.

    • EVP_CIPHER/EVP_MD: Uses a hash table keyed by nid. Each entry points to an ENGINE_PILE (a list of ENGINEs implementing that nid).
    • RSA/DSA/DH/RAND: These use a degenerate form of the table where they all share an implicit nid of 1, as they represent interoperable implementations of a single type rather than different algorithm/mode pairs.

    Caching and Initialization: To avoid expensive init() calls (like loading DSOs) for every request, the ENGINE_TABLE caches the result of the first successful lookup for a nid. Subsequent requests return the cached ENGINE pointer immediately.

    Configuration: Use ENGINE_set_table_flags() with the ENGINE_TABLE_FLAG_NOINIT flag to prevent the table from attempting to initialize ENGINEs from the pile. In this mode, only already-initialized ENGINEs will be used.

  4. Manage linking and atexit() on NonStop

    master

    Due to the NonStop Common Runtime Environment (CRE), programs cannot concurrently statically link OpenSSL libraries and dynamically load OpenSSL shared libraries. Doing so may cause a SIGSEGV during atexit() processing when a library is unloaded or the program terminates.

    To mitigate this, as of version 3.3.x, you can control atexit() calls in libcrypto builds using the following flags:

    • disable-atexit: Disables atexit() calls (disabled by default for NonStop builds).
    • enable-atexit: Enables atexit() to automatically register OPENSSL_cleanup().

    Best Practice: Instead of relying on atexit(), explicitly call OPENSSL_cleanup() from your application.

  5. Understand the Sparse Array implementation

    master

    The sparse array implementation in sparse_array.c uses a tree structure to store pointers to user-supplied leaf values. It is designed to be both space and time efficient for sparse data sets.

    Key Characteristics

    • Storage: Only nodes along the path from the root to an added leaf are allocated. Nodes are allocated on an as-needed basis.
    • Complexity:
      • Access Time: $O(\log n)$, where $n$ is the largest index. The base of the logarithm is SA_BLOCK_MAX. For small indices, this can achieve near constant-time access.
      • Space Usage: $O(\min(m, n \log n))$, where $m$ is the number of elements stored.
    • Data Type: Sparse arrays only store pointers. To store types like char, you must use a pointer-based approach (e.g., SPARSE_ARRAY_OF(char) to store a string).
    • Removal: Values are removed by setting their index position to NULL. Note that the data structure does not reclaim nodes or reduce tree height upon removal.
  6. How ENGINE hooks into EVP_CIPHER and EVP_MD

    master

    The ENGINE mechanism allows hardware or third-party implementations to intercept EVP_CIPHER and EVP_MD requests.

    When an EVP_CIPHER_CTX is initialized with an EVP_CIPHER method, the system checks if any ENGINE has registered an implementation for that specific algorithm/mode (identified by its nid).

    • If no ENGINE is registered: The EVP_CIPHER_CTX stores a NULL engine pointer and uses the original EVP_CIPHER structure as the implementation (standard software fallback).
    • If an ENGINE is registered: The EVP_CIPHER_CTX receives a functional reference to that ENGINE. The original EVP_CIPHER provided by the application is replaced by a 'private' EVP_CIPHER implementation owned by the ENGINE. This ensures the implementation is safe to use because the context holds a functional reference to the owning ENGINE.
  7. Configure ENGINE control commands

    master

    ENGINE implementations can define their own configuration mechanisms using "control commands". These allow applications to pass name-value pairs to the engine to configure specific hardware or parameters.

    Applications should use the ENGINE_ctrl_cmd_string API (or equivalent) to pass these settings. This allows the application to remain agnostic of the specific hardware while still providing a way for users/admins to configure it.

    Note: While work is planned to support these commands via standard OpenSSL configuration files (CONF/NCONF), currently applications must use the ENGINE API directly to provide these settings.

  8. Configure OpenSSL installation directories

    master

    When installing OpenSSL, the install process creates several directories under OPENSSLDIR (the directory specified by --openssldir or the default). These directories are used for organizing files:

    • certs: The default location for certificate files.
    • private: The default location for private key files.
    • misc: Contains various scripts.

    Security Note: Ensure the installation directory is protected so unprivileged users cannot modify OpenSSL binaries, files, or install engines. If your OS already has an OpenSSL version, it is recommended to install Tongsuo/OpenSSL to a separate location rather than overwriting the system version.

  9. Understand the Tongsuo state machine architecture

    master

    The Tongsuo state machine is designed to manage TLS/DTLS handshakes by separating message flow logic from handshake logic. This separation helps manage complexity and prevents common errors where the state machine expects a specific message type that does not arrive.

    Key Abstractions

    • Handshake State: Tracks which specific handshake message is currently being processed.
    • Message Flow State: Manages the operational lifecycle of messages, including:
      • When to flush buffers.
      • Handling restarts during Non-Blocking I/O (NBIO) events.
      • The common sequence of steps for reading and writing messages.

    The message flow state machine is further subdivided into a reading sub-state machine and a writing sub-state machine.

    Component Hierarchy

    The architecture is organized into a core component with specialized implementations for clients, servers, and transport protocols:

    1. Core State Machine (statem.c): Contains the central logic and transitions.
    2. Protocol-Specific Implementations:
      • statem_clnt.c: TLS/DTLS client-specific code.
      • statem_srvr.c: TLS/DTLS server-specific code.
    3. Common Library Functions:
      • statem_lib.c: Functions common to both servers and clients.
      • statem_dtls.c: Functions common to both DTLS servers and clients.
  10. Understand the ENGINE API and its deprecation

    master

    The ENGINE API is a low-level interface used for adding alternative implementations of cryptographic primitives, primarily for integrating hardware crypto devices.

    Important: The ENGINE interface is deprecated in OpenSSL 3.0 and has been superseded by the PROVIDER API. For new hardware support or new algorithms, you should use providers. Existing ENGINE implementations should be converted to providers as soon as possible.

  11. How target configuration inheritance works

    master

    Configuration targets can use the inherit_from key to inherit values from other targets. This allows for modular configuration building.

    • Recursive Resolution: Inherited values are resolved recursively.
    • Concatenation: If multiple targets are listed in inherit_from, the values for the same attribute are concatenated with space separation.
    • Code Blocks: Instead of a scalar or array, a value can be a Perl code block sub { ... }. This block is called with the list of inherited values as arguments. This is useful for custom string manipulation during inheritance.

    Example of inheritance logic:

    "foo" => {
            template => 1,
            haha => "ha ha",
            hoho => "ho",
            ignored => "This should not appear in the end result",
    },
    "bar" => {
            template => 1,
            haha => "ah",
            hoho => "haho",
            hehe => "hehe"
    },
    "laughter" => {
            inherit_from => [ "foo", "bar" ],
            hehe => sub { join(" ",(@_,"!!!")) },
            ignored => "",
    }
    
    # Resulting 'laughter' entry:
    "laughter" => {
            haha => "ha ha ah",
            hoho => "ho haho",
            hehe => "hehe !!!",
            ignored => ""
    }
    "laughter" => {
            inherit_from => [ "foo", "bar" ],
            hehe => sub { join(" ",(@_,"!!!")) },
            ignored => "",
    }