# BoringSSL API Conventions

This document describes conventions for BoringSSL APIs. The [style
guide](./STYLE.md) also includes guidelines, but this document is targeted at
both API consumers and developers. API documentation in BoringSSL may assume
these conventions by default, rather than repeating them for every function.


## Documentation

All supported public APIs are documented in the public header files, found in
`include/openssl`. The API documentation is also available
[online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).

Experimental public APIs are found in `include/openssl/experimental`. Use of
these will likely be incompatible with changes in the near future as they are
finalized.

## Forward declarations

Do not write `typedef struct foo_st FOO` or try otherwise to define BoringSSL's
types. Including `openssl/base.h` (or `openssl/ossl_typ.h` for consumers who
wish to be OpenSSL-compatible) will forward-declare each type without importing
the rest of the library or invasive macros.


## Error-handling

Most functions in BoringSSL may fail, either due to allocation failures or input
errors. Functions which return an `int` typically return one on success and zero
on failure. Functions which return a pointer typically return `NULL` on failure.
However, due to legacy constraints, some functions are more complex. Consult the
API documentation before using a function.

On error, most functions also push errors on the error queue, an `errno`-like
mechanism. See the documentation for
[err.h](https://commondatastorage.googleapis.com/chromium-boringssl-docs/err.h.html)
for more details.

As with `errno`, callers must test the function's return value, not the error
queue to determine whether an operation failed. Some codepaths may not interact
with the error queue, and the error queue may have state from a previous failed
operation. After checking for failure, the caller can then inspect the error
queue in the failure case for details.

As a notable exception, some functions in the SSL/TLS library use a multi-step
process to indicate failure: First, the return value indicates whether the
operation failed. Then, `SSL_get_error` indicates whether the failure was due to
an error (`SSL_ERROR_SSL`) or some recoverable condition (e.g.
`SSL_ERROR_WANT_READ`). In the former case, the caller can use the error queue
for more information.

When ignoring a failed operation, it is recommended to call `ERR_clear_error` to
avoid the state interacting with future operations. Failing to do so should not
affect the actual behavior of any functions, but may result in errors from both
operations being mixed in error logging. We hope to
[improve](https://bugs.chromium.org/p/boringssl/issues/detail?id=38) this
situation in the future.

Where possible, avoid conditioning on specific reason codes and limit usage to
logging. The reason codes are very fine-grained and tend to leak details of the
library's internal structure. Changes in the library often have a side effect of
changing the exact reason code returned.


## Memory allocation

BoringSSL allocates memory via `OPENSSL_malloc`, found in `mem.h`. Use
`OPENSSL_free`, found in the same header file, to release it. BoringSSL
functions will fail gracefully on allocation error, but it is recommended to use
a `malloc` implementation that `abort`s on failure.


## Pointers and slices

Unless otherwise specified, pointer parameters that refer to a single object,
either as an input or output parameter, may not be `NULL`. In this case,
BoringSSL often will not check for `NULL` before dereferencing, so passing
`NULL` may crash or exhibit other undefined behavior. (Sometimes the function
will check for `NULL` anyway, for OpenSSL compatibility, but we still consider
passing `NULL` to be a caller error.)

Pointer parameters may also refer to a contiguous sequence of objects, sometimes
referred to as a *slice*. These will typically be a pair of pointer and length
parameters named like `plaintext` and `plaintext_len`, or `objs` and `num_objs`.
We prefer the former for byte buffers and the latter for sequences of other
types. The documentation will usually refer to both parameters together, e.g.
"`EVP_DigestUpdate` hashes `len` bytes from `data`."

Parameters in C and C++ that use array syntax, such as
`uint8_t out[SHA256_DIGEST_LENGTH]`, are really pointers. In BoringSSL's uses of
this syntax, the pointer must point to the specified number of values.

In other cases, the documentation will describe how the function parameters
determine the slice's length. For example, a slice's length may be measured in
units other than element count, multiple slice parameters may share a length, or
a slice's length may be implicitly determined by other means like RSA key size.

By default, BoringSSL follows C++'s
[slice conventions](https://davidben.net/2024/01/15/empty-slices.html)
for pointers. That is, unless otherwise specified, pointers for non-empty
(non-zero length) slices must be represented by a valid pointer to that many
objects in memory. Pointers for empty (zero length) slices must either be `NULL`
or point within some sequence of objects of a compatible type.

WARNING: The dangling, non-null pointer used by Rust empty slices may *not* be
passed into BoringSSL. Rust FFIs must adjust such pointers to before passing to
BoringSSL. For example, see the `FfiSlice` abstraction in `bssl-crypto`. (We may
relax this if pointer arithmetic rules in C/C++ are adjusted to permit Rust's
pointers. Until then, it is impractical for a C/C++ library to act on such a
slice representation. See
[this document](https://davidben.net/2024/01/15/empty-slices.html) for more
discussion.)

In some cases, OpenSSL compatibility requires that a function will treat `NULL`
slice pointers differently from non-`NULL` pointers. Such behavior will be
described in documentation. For examples, see `EVP_EncryptUpdate`,
`EVP_DigestSignFinal`, and `HMAC_Init_ex`. Callers passing potentially empty
slices into such functions should take care that the `NULL` case is either
unreachable or still has the desired behavior.

If a `const char *` parameter is described as a "NUL-terminated string" or a
"C string", it must point to a sequence of `char` values containing a NUL (zero)
value, which determines the length. Unless otherwise specified, the pointer may
not be `NULL`, matching the C standard library.

For purposes of C and C++'s
[strict aliasing](https://en.cppreference.com/w/c/language/object#Strict_aliasing)
requirements, objects passed by pointers must be accessible as the specified
type. `uint8_t` may be assumed to be the same type as `unsigned char` and thus
may be the pointer type for all object types. BoringSSL does not support
platforms where `uint8_t` is a non-character type. However, there is no
strict aliasing sanitizer, very few C and C++ codebases are valid by strict
aliasing, and BoringSSL itself has some
[known strict aliasing bugs](https://crbug.com/boringssl/444), thus we strongly
recommend consumers build with `-fno-strict-aliasing`.

Pointer parameters additionally have ownership and lifetime requirements,
discussed in the section below.


## Object initialization and cleanup

BoringSSL defines a number of structs for use in its APIs. It is a C library,
so the caller is responsible for ensuring these structs are properly
initialized and released. Consult the documentation for a module for the
proper use of its types. Some general conventions are listed below.


### Heap-allocated types

Some types, such as `RSA`, are heap-allocated. All instances will be allocated
and returned from BoringSSL's APIs. It is an error to instantiate a heap-
allocated type on the stack or embedded within another object.

Heap-allocated types may have functions named like `RSA_new` which allocates a
fresh blank `RSA`. Other functions may also return newly-allocated instances.
For example, `RSA_parse_public_key` is documented to return a newly-allocated
`RSA` object.

Heap-allocated objects must be released by the corresponding free function,
named like `RSA_free`. Like C's `free` and C++'s `delete`, all free functions
internally check for `NULL`. It is redundant to check for `NULL` before calling.

A heap-allocated type may be reference-counted. In this case, a function named
like `RSA_up_ref` will be available to take an additional reference count. The
free function must be called to decrement the reference count. It will only
release resources when the final reference is released. For OpenSSL
compatibility, these functions return `int`, but callers may assume they always
successfully return one because reference counts use saturating arithmetic.

C++ consumers are recommended to use `bssl::UniquePtr` to manage heap-allocated
objects. `bssl::UniquePtr<T>`, like other types, is forward-declared in
`openssl/base.h`. Code that needs access to the free functions, such as code
which destroys a `bssl::UniquePtr`, must include the corresponding module's
header. (This matches `std::unique_ptr`'s relationship with forward
declarations.) Note, despite the name, `bssl::UniquePtr` is also used with
reference-counted types. It owns a single reference to the object. To take an
additional reference, use the `bssl::UpRef` function, which will return a
separate `bssl::UniquePtr`.


### Stack-allocated types

Other types in BoringSSL are stack-allocated, such as `EVP_MD_CTX`. These
types may be allocated on the stack or embedded within another object.
However, they must still be initialized before use.

Every stack-allocated object in BoringSSL has a *zero state*, analogous to
initializing a pointer to `NULL`. In this state, the object may not be
completely initialized, but it is safe to call cleanup functions. Entering the
zero state cannot fail. (It is usually `memset(0)`.)

The function to enter the zero state is named like `EVP_MD_CTX_init` or
`CBB_zero` and will always return `void`. To release resources associated with
the type, call the cleanup function, named like `EVP_MD_CTX_cleanup`. The
cleanup function must be called on all codepaths, regardless of success or
failure. For example:

    uint8_t md[EVP_MAX_MD_SIZE];
    unsigned md_len;
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);  /* Enter the zero state. */
    int ok = EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) &&
             EVP_DigestUpdate(&ctx, "hello ", 6) &&
             EVP_DigestUpdate(&ctx, "world", 5) &&
             EVP_DigestFinal_ex(&ctx, md, &md_len);
    EVP_MD_CTX_cleanup(&ctx);  /* Release `ctx`. */

Note that `EVP_MD_CTX_cleanup` is called whether or not the `EVP_Digest*`
operations succeeded. More complex C functions may use the `goto err` pattern:

      int ret = 0;
      EVP_MD_CTX ctx;
      EVP_MD_CTX_init(&ctx);

      if (!some_other_operation()) {
        goto err;
      }

      uint8_t md[EVP_MAX_MD_SIZE];
      unsigned md_len;
      if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) ||
          !EVP_DigestUpdate(&ctx, "hello ", 6) ||
          !EVP_DigestUpdate(&ctx, "world", 5) ||
          !EVP_DigestFinal_ex(&ctx, md, &md_len) {
        goto err;
      }

      ret = 1;

    err:
      EVP_MD_CTX_cleanup(&ctx);
      return ret;

Note that, because `ctx` is set to the zero state before any failures,
`EVP_MD_CTX_cleanup` is safe to call even if the first operation fails before
`EVP_DigestInit_ex`. However, it would be illegal to move the `EVP_MD_CTX_init`
below the `some_other_operation` call.

As a rule of thumb, enter the zero state of stack-allocated structs in the
same place they are declared.

C++ consumers are recommended to use the wrappers named like
`bssl::ScopedEVP_MD_CTX`, defined in the corresponding module's header. These
wrappers are automatically initialized to the zero state and are automatically
cleaned up.


### Data-only types

A few types, such as `SHA_CTX`, are data-only types and do not require cleanup.
These are usually for low-level cryptographic operations. These types may be
used freely without special cleanup conventions.


### Ownership and lifetime

When working with allocated objects, it is important to think about *ownership*
of each object, or what code is responsible for releasing it. This matches the
corresponding notion in higher-level languages like C++ and Rust.

Ownership applies to both uniquely-owned types and reference-counted types. For
the latter, ownership means the code is responsible for releasing one
reference. Note a *reference* in BoringSSL refers to an increment (and eventual
decrement) of an object's reference count, not `T&` in C++. Thus, to "take a
reference" means to increment the reference count and take ownership of
decrementing it.

As BoringSSL's APIs are primarily in C, ownership and lifetime obligations are
not rigorously annotated in the type signatures or checked at compile-time.
Instead, they are described in
[API documentation](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
This section describes some conventions.

Unless otherwise documented, functions do not take ownership of pointer
arguments. The pointer typically must remain valid for the duration of the
function call. The function may internally copy information from the argument or
take a reference, but the caller is free to release its copy or reference at any
point after the call completes.

A function may instead be documented to *take* or *transfer* ownership of a
pointer. The caller must own the object before the function call and, after
transfer, no longer owns it. As a corollary, the caller may no longer reference
the object without a separate guarantee on the lifetime. The function may even
release the object before returning. Callers that wish to independently retain a
transferred object must therefore take a reference or make a copy before
transferring. Callers should also take note of whether the function is
documented to transfer pointers unconditionally or only on success. Unlike C++
and Rust, functions in BoringSSL typically only transfer on success.

Likewise, output pointers may be owning or non-owning. Unless otherwise
documented, functions output non-owning pointers. The caller is not responsible
for releasing the output pointer, but it must not use the pointer beyond its
lifetime. The pointer may be released when the parent object is released or even
sooner on state change in the parent object.

If documented to output a *newly-allocated* object or a *reference* or *copy* of
one, the caller is responsible for releasing the object when it is done.

By convention, functions named `get0` return non-owning pointers. Functions
named `new` or `get1` return owning pointers. Functions named `set0` or `add0`
take ownership of arguments. Functions named `set1` or `add1` do not. They
typically take a reference or make a copy internally. These names originally
referred to the effect on a reference count, but the convention applies equally
to non-reference-counted types.

API documentation may also describe more complex obligations. For instance, an
object may borrow a pointer for longer than the duration of a single function
call, in which case the caller must ensure the lifetime extends accordingly.

Memory errors are one of the most common and dangerous bugs in C and C++, so
callers are encouraged to make use of tools such as
[AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) and
higher-level languages.


## Thread safety

BoringSSL is internally aware of the platform threading library and calls into
it as needed. Consult the API documentation for the threading guarantees of
particular objects. In general, stateless reference-counted objects like `RSA`
or `EVP_PKEY` which represent keys may typically be used from multiple threads
simultaneously, provided no thread mutates the key.


## Callbacks and Closures

Several BoringSSL APIs, particularly in libssl, allow applications to configure
callbacks to customize behavior. Often, an application may wish to pass in some
[closure](https://en.wikipedia.org/wiki/Closure_(computer_programming)), where
the callback is bound to some additional state. For example, a callback for TLS
private key offload may need a handle to the application-specific private key.

BoringSSL's APIs are C-based and use C function pointers, which do not support
bound variables. Instead, C callback APIs split the closure into a function
pointer and some `void *` data parameter. This is sometimes called "arg",
"callback data", "context", "data", or "user data".

For example, the `SSL_CTX_set_cert_cb` function takes an `arg` parameter, which
is passed back into the user-supplied callback, `cb`. The user would pass a
function that casts `arg` back to the expected type and looks up bound data as
needed:

```
OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx,
                                        int (*cb)(SSL *ssl, void *arg),
                                        void *arg);
```

An application might use it with a C++ `std::function` as follows:

```
int RunCertCallback(SSL *ssl, void *arg) {
  auto *f = static_cast<std::function<int(SSL*)>*>(arg);
  return (*f)(ssl);
}

std::function<int(SSL*)> cert_cb = ...;
SSL_CTX_set_cert_cb(ctx, RunCertCallback, &cert_cb);
```

Note that such an application would additionally need to ensure that `cert_cb`
outlives `ctx`, e.g. by storing it in the `SSL_CTX`'s owning object.

BoringSSL APIs, however, commonly take callbacks without an explicit data
parameter. For example, the `SSL_set_custom_verify` takes an undecorated
`callback` parameter:

```
OPENSSL_EXPORT void SSL_set_custom_verify(
    SSL *ssl, int mode,
    enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert));
```

In such APIs, the callback is expected to look up data through the owning
object, here the `ssl`. Many types in BoringSSL, including `SSL`, support
`ex_data`. `ex_data` lets applications associate extra data with the object. See
the [API documentation](https://commondatastorage.googleapis.com/chromium-boringssl-docs/ex_data.h.html)
for more details. `ex_data` also supports registering a `free_func` callback,
which can give the application more options to ensure callback data outlives the
object.

Often, for a callback-heavy object like `SSL`, the application will already have
some owning object that wraps the `SSL`. The application can then register a
single `ex_data` index, pointering back to the owning object, and store all the
callback state there.

For example, this code snippet connects `SSL` callbacks to methods on some
wrapper `MySSLConnection` class.

```
class MySSLConnection {
 private:
  void Init() {
    ssl_.reset(SSL_new(...));
    // Save a pointer in `ssl_` back to `this`. `this` owns and thus outlives
    // `ssl_`. (To have `ssl_` own its ex_data, use `SSL_get_ex_new_index`'s
    // `free_func` parameter.)
    CHECK(SSL_set_ex_data(ssl_.get(), ExDataIndex(), this));
    // Register callbacks.
    SSL_set_custom_verify(ssl_.get(), SSL_VERIFY_PEER,
                          &MySSLConnection::DoVerifyCallback);
    SSL_set_info_callback(ssl_.get(), &MySSLConnection::DoInfoCallback);
    ...
  }

  static int ExDataIndex() {
    static const int kIndex = [] {
      int idx = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr);
      CHECK(idx >= 0);
      return idx;
    }();
    return kIndex;
  }

  static MySSLConnection *FromSSL(const SSL *ssl) {
    return static_cast<MySSLConnection*>(
        SSL_get_ex_data(ssl_.get(), ExDataIndex()));
  }

  // Callback functions passed to BoringSSL:
  static ssl_verify_result_t DoVerifyCallback(SSL *ssl, uint8_t *out_alert)) {
    return FromSSL(ssl)->Verify(out_alert);
  }
  static void DoInfoCallback(const SSL *ssl, int type, int value) {
    return FromSSL(ssl)->InfoCallback(type, value);
  }

  // The underlying methods that the callback functions forward to:
  ssl_verify_result_t VerifyCallback(uint8_t *out_alert)) { ... }
  void InfoCallback(int type, int value) { ... }

  bssl::UniquePtr<SSL> ssl_;
};
```

In other cases, the callback may live on a different object than is passed into
the callback. The application can then use ex_data on either the passed-in
object, or follow accessors to parent objects. For example, an `SSL_get_SSL_CTX`
returns the `SSL_CTX` of an `SSL` and
[`SSL_CTX_set_cert_verify_callback`'s documentation](https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_CTX_set_cert_verify_callback)
mentions that `SSL_get_ex_data_X509_STORE_CTX_idx` may be used to find the `SSL`
corresponding to the `X509_STORE_CTX`.

```
OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
    SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session));

OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(
    SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg),
    void *arg);
```


## Contexts

Many types in BoringSSL are named like `FOO_CTX`, where `CTX` is an abbrevation
for "context". `FOO_CTX` is some object that is related to `FOO`. Due to the
history of API names in OpenSSL, the relationship between the two can depend on
context.

Sometimes, `FOO` is a long-lived object and `FOO_CTX` is an individual operation
on that object. For example:

* An `EVP_MD` is a hash algorithm ("Message Digest"). An `EVP_MD_CTX` for some
  `EVP_MD` is single streaming hash operation that can accept data.

* An `EVP_AEAD` is an AEAD algorithm. An `EVP_AEAD_CTX` for some `EVP_AEAD` is
  an AEAD key that can be used to encrypt or decrypt.

* An `EVP_PKEY` is a public or private key. An `EVP_PKEY_CTX` for some
  `EVP_PKEY` is single signing, verifying, etc., operation on that key.

* An `X509_STORE` carries trusted root certificates, etc., for verifying X.509
  certificates. An `X509_STORE_CTX` is a single verification operation.

In this case, the operation object may be a separate object, rather than a
single-shot function, to allow the caller to configure extra parameters (similar
to [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern)) or perform
a multi-step, streaming operation.

In other cases, the context object is the broader-scoped one:

* An `SSL_CTX` is shared configuration and state between TLS/DTLS connections.
  An `SSL` is a single TLS/DTLS connection.

* A `BIGNUM` is a big integer. A `BN_CTX` is a pool for reusing `BIGNUM`
  allocations.

* An `X509V3_CTX` contains additional parameters for the legacy string-based
  X.509 extension API. (Do not use this API.)

Consult the documentation if unsure which case a given pair of types falls into.
