openssl/openssl
libcrypto
Active contributors: Pauli, Tomas Mraz, Neil Horman, Bob Beck, Matt Caswell, Richard Levitte, slontis
Purpose
libcrypto is OpenSSL's general-purpose cryptographic library. It provides the high-level EVP_* API that applications and libssl use, plus dozens of domain-specific APIs for ASN.1, X.509, BIGNUM, BIO, CMS, PKCS#7/12, OCSP, CMP, RAND, error reporting, threading, and configuration. Since 3.0 it does not contain algorithm implementations directly — they live in providers.
Directory layout
crypto/
├── context.c, init.c, info.c, cversion.c, defaults.c, indicator_core.c, …
├── core_namemap.c, core_algorithm.c, core_fetch.c -- algorithm lookup
├── provider*.c, provider_core.c, provider_conf.c, provider_child.c
├── property/ -- property string parser and matcher
├── evp/ -- the EVP API (algorithm-agnostic)
├── asn1/ -- ASN.1 parser/serializer + templates
├── bio/ -- the BIO abstraction
├── bn/ -- BIGNUM
├── conf/ -- openssl.cnf parser
├── err/ -- error stack machinery
├── encode_decode/ -- OSSL_ENCODER/OSSL_DECODER scaffolding
├── http/ -- HTTP client
├── store/ -- OSSL_STORE (load by URI)
├── thread/, threads_*.c -- threading primitives
├── trace.c -- OSSL_TRACE_*
├── mem.c, mem_sec.c -- general and secure heaps
├── rand/ -- DRBG and entropy
├── x509/, ocsp/, cms/, pkcs7/, pkcs12/, ts/, cmp/, crmf/, ess/, ct/
├── aes/, des/, sha/, md5/, … -- per-algorithm code (some still here for legacy reasons; the canonical impls are in providers/)
├── ml_kem/, ml_dsa/, slh_dsa/, lms/ -- post-quantum
├── hpke/ -- RFC 9180 HPKE
├── perlasm/ -- the perlasm framework used by *.pl asm generators
└── *cpuid.pl, *cap.c -- CPU feature detectionKey abstractions
| Type | Purpose | File |
|---|---|---|
OSSL_LIB_CTX |
Library context (providers, namemap, RNG, properties) | crypto/context.c |
OSSL_PROVIDER |
Loaded provider handle | crypto/provider_core.c |
OSSL_NAMEMAP |
Name↔ID map | crypto/core_namemap.c |
OSSL_PROPERTY_LIST |
Property query | crypto/property/*.c |
EVP_* |
The algorithm-agnostic API surface | crypto/evp/*.c |
BIO |
I/O abstraction | crypto/bio/*.c |
BIGNUM |
Arbitrary-precision integer | crypto/bn/*.c |
ASN1_TYPE, ASN1_ITEM |
ASN.1 representation | crypto/asn1/*.c |
X509, X509_STORE, X509_STORE_CTX |
Certificate, trust store, verification context | crypto/x509/*.c |
RAND_* |
Legacy RNG façade over the EVP_RAND DRBG hierarchy | crypto/rand/*.c |
ERR_* |
Error stack | crypto/err/*.c |
OSSL_PARAM, OSSL_PARAM_BLD |
Universal arg-pack | crypto/params*.c, crypto/param_build.c |
OSSL_STORE_* |
Open a key/cert by URI | crypto/store/*.c |
OSSL_HTTP_* |
Minimal HTTP client used by OCSP/CMP/TS | crypto/http/*.c |
Header tree
The public headers live in include/openssl/. Many are templates (*.h.in) processed at configure time so they can reference OPENSSL_NO_* flags. The most important are:
include/openssl/crypto.h.in—OSSL_LIB_CTX,OPENSSL_init_*,CRYPTO_THREAD_*, threading.include/openssl/evp.h— the EVP API. ~78 KB, large enough that you'll want to grep it.include/openssl/core.h,core_dispatch.h,core_names.h.in,core_object.h— the provider ABI.include/openssl/params.h,param_build.h—OSSL_PARAM.include/openssl/types.h— every opaque-typedef the rest of the API uses.include/openssl/x509*.h.in,x509_acert.h.in,x509_vfy.h.in,x509v3.h.in— X.509.include/openssl/ssl.h.in— TLS API (provided by libssl, but typedefs flow through here).include/openssl/quic.h— small public surface for the QUIC API.
The internal-only headers live in include/internal/ (cross-cutting helpers) and include/crypto/ (libcrypto-internal interfaces between subsystems).
How it works
graph TD
APP[Application] -->|EVP_MD_fetch, EVP_PKEY_*, X509_*, …| API[Public API in include/openssl/*.h]
API --> EVP[EVP_* implementations<br/>crypto/evp/]
API --> DOM[Domain libs<br/>x509, cms, pkcs12, ocsp, cmp, ts, crl, …]
EVP --> CORE[Core: namemap + property + fetch<br/>crypto/core_*.c, crypto/property/]
DOM --> EVP
CORE -->|OSSL_DISPATCH| Prov[Loaded providers<br/>default / fips / legacy / base / null + 3rd party]
Prov --> Impl[providers/implementations/]When an application calls e.g. EVP_DigestInit_ex(ctx, NULL, NULL), OpenSSL implicitly fetches the default digest for the active library context and binds it to ctx. New code is encouraged to call EVP_MD_fetch(libctx, "SHA2-256", "fips=yes") explicitly so the choice of implementation is visible.
For the deeper picture of fetch + property + namemap, see subsystems/core-and-libctx.
Initialization
You almost never need to call OPENSSL_init_crypto(). The library auto-initializes on first use. If you need fine control, the API is in include/openssl/crypto.h.in and the implementation is in crypto/init.c and crypto/initthread.c.
OPENSSL_cleanup() exists; it is normally redundant because all per-thread state is cleaned up by pthread_atfork-style hooks.
Configuration
libcrypto reads openssl.cnf (a sample is shipped at apps/openssl.cnf). The parser is in crypto/conf/; the bindings that interpret [providers], [engines], [ssl_sect] etc. live in the relevant subsystems (e.g. crypto/provider_conf.c, crypto/evp/evp_cnf.c, ssl/ssl_mcnf.c). See reference/configuration.
Integration points
libssluseslibcrypto's EVP API for all crypto (digests, ciphers, MACs, KDFs, signature verification, RNG, X.509 verification).apps/openssluseslibcryptofor all subcommand functionality.- External consumers:
libcurl, OpenSSH, NGINX, Apache httpd, BIND, Postfix, and many more link against the publiclibcrypto.so.4ABI. - Providers are dynamically loaded into a libctx via
OSSL_PROVIDER_load. They publish algorithms viaOSSL_DISPATCHtables; libcrypto looks them up byEVP_*_fetch.
Entry points for modification
- Adding a new algorithm: write a provider implementation in
providers/implementations/<area>/, register it in the relevantdefltprov.c/fipsprov.ctable, regenerate err codes withmake update, add tests undertest/. See providers. - Adding a new public function: declare in a header under
include/openssl/, implement in the relevantcrypto/<area>/, runmake updateto add it toutil/libcrypto.num. Add a POD page underdoc/man3/. - Adding a new error code: edit
crypto/err/openssl.txt(or the per-subsystem*err.h) and runmake update. Seecrypto/err/README.md. - Adding a new domain (e.g. a new RFC parser): create
crypto/<area>/, add a public headerinclude/openssl/<area>.h.in, wire up the ASN.1 templates, write tests.
Where to read about specific subsystems
| Subsystem | Wiki page |
|---|---|
| Core, libctx, namemap, property, fetch | subsystems/core-and-libctx |
| EVP layer | subsystems/evp |
| ASN.1, BIO, error, threading, memory, RAND | subsystems/asn1, subsystems/bio, subsystems/error-handling, subsystems/threading, subsystems/memory, subsystems/random |
| X.509 / PKI | features/x509-pki |
| CMS, CMP, encoders/decoders, post-quantum | features |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.