Open-Source Wikis

/

OpenSSL

/

OpenSSL

/

Architecture

openssl/openssl

Architecture

OpenSSL has two major libraries, a CLI front-end, and a pluggable provider model that decouples algorithm implementations from the public API.

Top-level layout

graph TD
    subgraph Application
        APP[Your application or apps/openssl]
    end

    subgraph libssl[libssl - TLS, DTLS, QUIC]
        SSL[ssl/ssl_lib.c, statem, record, quic, ech]
    end

    subgraph libcrypto[libcrypto - everything else]
        EVP[EVP API<br/>crypto/evp]
        CORE[Core: libctx, namemap, fetch<br/>crypto/context.c, core_namemap.c]
        BIO[BIO, BIGNUM, ASN.1, X.509,<br/>CMS, PKCS, OCSP, CMP, TS, …]
    end

    subgraph providers[Providers - algorithm impls]
        DEF[default<br/>providers/defltprov.c]
        FIPS[fips<br/>providers/fips/]
        LEG[legacy<br/>providers/legacyprov.c]
        BASE[base<br/>providers/baseprov.c]
        NULL[null<br/>providers/nullprov.c]
        IMPL[providers/implementations/<br/>ciphers digests kdfs kem signature …]
    end

    APP -->|TLS API: SSL_*, SSL_CTX_*| SSL
    APP -->|crypto API: EVP_*, X509_*, BIO_*, …| EVP
    SSL -->|EVP_CIPHER, EVP_MD, EVP_PKEY| EVP
    EVP -->|fetch / dispatch table| CORE
    CORE -->|OSSL_DISPATCH| DEF
    CORE --> FIPS
    CORE --> LEG
    CORE --> BASE
    CORE --> NULL
    DEF --> IMPL
    FIPS --> IMPL
    LEG --> IMPL
    BIO -.shared by.-> SSL

The arrows tell you the only sanctioned data flows:

  • Applications call into libssl (for TLS/DTLS/QUIC) or directly into libcrypto (for everything else).
  • libssl uses libcrypto's EVP API for all crypto. There is no secret-handling code that lives only in libssl — it must go through EVP and end up in a provider. The TLS state machine itself does, of course, live in ssl/statem/.
  • The EVP layer in libcrypto does not implement algorithms. It looks them up by name and properties from one of the loaded providers and calls through an OSSL_DISPATCH function table.
  • Providers are the only place where actual algorithm code (AES, SHA-3, RSA, ML-KEM, …) lives. The default and FIPS providers share most of providers/implementations/; they differ in which algorithms they expose and in extra security checks.

libcrypto

libcrypto is the foundation. It is divided into roughly three layers:

  1. Core (crypto/context.c, crypto/core_*.c, crypto/provider*.c, crypto/property/). Owns the OSSL_LIB_CTX (per-process or per-context state), the namemap (algorithm names → integers), the property store (e.g. fips=yes,provider=default), the provider loader, and the algorithm cache.
  2. EVP (crypto/evp/). The public, algorithm-agnostic API: EVP_CIPHER, EVP_MD, EVP_PKEY, EVP_KDF, EVP_MAC, EVP_RAND, EVP_KEM, EVP_SIGNATURE, EVP_KEYEXCH, EVP_KEYMGMT, EVP_ENCODER, EVP_DECODER, EVP_SKEYMGMT. Plus the legacy controller-style EVP_PKEY_CTX_ctrl() translator (crypto/evp/ctrl_params_translate.c).
  3. Domain libraries. ASN.1 (crypto/asn1/), BIGNUM (crypto/bn/), X.509 (crypto/x509/), CMS (crypto/cms/), PKCS#7 (crypto/pkcs7/), PKCS#12 (crypto/pkcs12/), OCSP (crypto/ocsp/), CMP (crypto/cmp/, crypto/crmf/), TS (crypto/ts/), HTTP client (crypto/http/), STORE (crypto/store/), encoders/decoders (crypto/encode_decode/), error machinery (crypto/err/), threading (crypto/thread*.c), memory (crypto/mem*.c), tracing (crypto/trace.c), and many more. Each domain owns its part of the public API but routes the cryptographic primitives through EVP.

Per-domain pages: see subsystems/ for the most-used pieces (EVP, ASN.1, BIO, error, threading, memory, RAND, core/libctx).

libssl

libssl implements all current TLS, DTLS, and QUIC variants. Its directories:

  • ssl/ssl_lib.c (226 KB), ssl/s3_lib.c (149 KB), ssl/t1_lib.c (~173 KB) — the main connection objects (SSL, SSL_CTX), cipher suite logic, and TLS 1.0–1.3 protocol code.
  • ssl/statem/ — the handshake state machine. Separate files for client (statem_clnt.c), server (statem_srvr.c), DTLS (statem_dtls.c), and shared dispatch (statem.c, statem_lib.c). Extension handling lives in ssl/statem/extensions*.c.
  • ssl/record/ — the record layer. Pluggable record method objects in ssl/record/methods/ and the record-layer code for TLS (rec_layer_s3.c) and DTLS (rec_layer_d1.c).
  • ssl/quic/ — the QUIC implementation: channel, port, transport parameters, packetization, retransmission, ACK manager, congestion control, demux, and a tserver test harness. See features/quic.
  • ssl/ech/ — ECH (Encrypted Client Hello), an experimental TLS extension. See features/tls.
  • ssl/rio/ — the RIO event-driven I/O abstraction used by QUIC.

For the handshake walk-through, see features/tls.

The openssl CLI

apps/openssl.c is the front door. Each subcommand is a .c file in apps/: req.c, x509.c, s_client.c, s_server.c, cms.c, cmp.c, speed.c, genpkey.c, pkeyutl.c, enc.c, dgst.c, verify.c, ts.c, … Subcommands share helpers in apps/lib/. The list of subcommands is generated from apps/progs.pl. See libraries/openssl-cli.

The provider model (key concept)

Since OpenSSL 3.0, every cryptographic algorithm in libcrypto is reached through a provider. A provider is a module (built-in or dynamically loadable shared object) that publishes a set of algorithms via dispatch tables.

sequenceDiagram
    participant App
    participant EVP as EVP_* in libcrypto
    participant Core as core / libctx
    participant Prov as provider (default/fips/...)
    App->>EVP: EVP_CIPHER_fetch(libctx, "AES-256-GCM", "fips=yes")
    EVP->>Core: OSSL_method_construct(...)
    Core->>Core: lookup by namemap + property query
    Core->>Prov: query operation table
    Prov-->>Core: OSSL_ALGORITHM[] for OSSL_OP_CIPHER
    Core->>Prov: provider's algorithm "newctx" function
    Prov-->>Core: provctx
    Core-->>EVP: EVP_CIPHER bound to dispatch table
    EVP-->>App: EVP_CIPHER *
    App->>EVP: EVP_EncryptInit_ex2 / Update / Final
    EVP->>Prov: dispatch via OSSL_FUNC_cipher_*

Key files:

  • include/openssl/core.h — the small set of types (OSSL_DISPATCH, OSSL_PARAM, OSSL_ALGORITHM, OSSL_CALLBACK) that flow between core and providers.
  • include/openssl/core_dispatch.h — every dispatch ID and function signature (OSSL_FUNC_*).
  • include/openssl/core_names.h.in — every well-known parameter and provider name string constant.
  • crypto/provider_core.c — the core's view of a provider (load, init, query).
  • crypto/core_fetch.c, crypto/core_namemap.c — algorithm lookup.
  • crypto/property/ — property string parser and matcher.
  • providers/defltprov.c, providers/fips/fipsprov.c, providers/legacyprov.c, providers/baseprov.c, providers/nullprov.c — the five built-in providers' entry points.
  • providers/implementations/** — the algorithm implementations themselves.

For the full discussion, see providers/ and subsystems/core-and-libctx.

Library context (OSSL_LIB_CTX)

Almost every public API in 3.x and later takes (or has a _ex variant that takes) an OSSL_LIB_CTX *libctx. A library context owns:

  • Loaded providers
  • The algorithm namemap and fetch cache
  • Default property query
  • Per-context RNG state
  • Configuration

NULL means "the default library context". This is what makes it possible to have, in the same process, one context that uses the FIPS provider and another that uses the default provider. See subsystems/core-and-libctx.

Trust boundaries

graph LR
    Net[Untrusted network bytes] -->|record layer parses| Record[ssl/record/, ssl/quic/quic_record_*.c]
    Record -->|after AEAD decrypt| Statem[ssl/statem/]
    User[Application bytes / files] -->|BIO_*| BIO[crypto/bio]
    BIO -->|d2i_, PEM_read_| ASN1[crypto/asn1, x509]
    ASN1 -->|verified| EVP[EVP_*]
    EVP -->|via OSSL_DISPATCH| Prov[provider]
    Conf[openssl.cnf] -->|crypto/conf/| Init[OPENSSL_init_*]
    Init --> EVP

Anything that comes from the network or the filesystem is parsed in crypto/asn1/, crypto/x509/, crypto/pem/, crypto/cms/, or the ssl/ record layer before it reaches the algorithm code in providers/. See pitfalls for security-sensitive integration gotchas.

Where to go next

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – OpenSSL wiki | Factory