# 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.

To re-iterate the POSIX standard, `OPENSSL_malloc` will satisfy the following
post-conditions.

- The allocated memory is suitably aligned for any type that fits into the
  requested size or less.
- The bytes delimited from the beginning of the allocation pointed at by the
  pointer until `size` bytes after the pointer, exclusive, are valid for write.
- `size` must have been no more than `PTRDIFF_MAX` bytes.


## 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.
