1# BoringSSL API Conventions 2 3This document describes conventions for BoringSSL APIs. The [style 4guide](./STYLE.md) also includes guidelines, but this document is targeted at 5both API consumers and developers. API documentation in BoringSSL may assume 6these conventions by default, rather than repeating them for every function. 7 8 9## Documentation 10 11All supported public APIs are documented in the public header files, found in 12`include/openssl`. The API documentation is also available 13[online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html). 14 15Experimental public APIs are found in `include/openssl/experimental`. Use of 16these will likely be incompatible with changes in the near future as they are 17finalized. 18 19## Forward declarations 20 21Do not write `typedef struct foo_st FOO` or try otherwise to define BoringSSL's 22types. Including `openssl/base.h` (or `openssl/ossl_typ.h` for consumers who 23wish to be OpenSSL-compatible) will forward-declare each type without importing 24the rest of the library or invasive macros. 25 26 27## Error-handling 28 29Most functions in BoringSSL may fail, either due to allocation failures or input 30errors. Functions which return an `int` typically return one on success and zero 31on failure. Functions which return a pointer typically return `NULL` on failure. 32However, due to legacy constraints, some functions are more complex. Consult the 33API documentation before using a function. 34 35On error, most functions also push errors on the error queue, an `errno`-like 36mechanism. See the documentation for 37[err.h](https://commondatastorage.googleapis.com/chromium-boringssl-docs/err.h.html) 38for more details. 39 40As with `errno`, callers must test the function's return value, not the error 41queue to determine whether an operation failed. Some codepaths may not interact 42with the error queue, and the error queue may have state from a previous failed 43operation. 44 45When ignoring a failed operation, it is recommended to call `ERR_clear_error` to 46avoid the state interacting with future operations. Failing to do so should not 47affect the actual behavior of any functions, but may result in errors from both 48operations being mixed in error logging. We hope to 49[improve](https://bugs.chromium.org/p/boringssl/issues/detail?id=38) this 50situation in the future. 51 52Where possible, avoid conditioning on specific reason codes and limit usage to 53logging. The reason codes are very specific and may change over time. 54 55 56## Memory allocation 57 58BoringSSL allocates memory via `OPENSSL_malloc`, found in `mem.h`. Use 59`OPENSSL_free`, found in the same header file, to release it. BoringSSL 60functions will fail gracefully on allocation error, but it is recommended to use 61a `malloc` implementation that `abort`s on failure. 62 63 64## Pointers and slices 65 66Unless otherwise specified, pointer parameters that refer to a single object, 67either as an input or output parameter, may not be `NULL`. In this case, 68BoringSSL often will not check for `NULL` before dereferencing, so passing 69`NULL` may crash or exhibit other undefined behavior. (Sometimes the function 70will check for `NULL` anyway, for OpenSSL compatibility, but we still consider 71passing `NULL` to be a caller error.) 72 73Pointer parameters may also refer to a contiguous sequence of objects, sometimes 74referred to as a *slice*. These will typically be a pair of pointer and length 75parameters named like `plaintext` and `plaintext_len`, or `objs` and `num_objs`. 76We prefer the former for byte buffers and the latter for sequences of other 77types. The documentation will usually refer to both parameters together, e.g. 78"`EVP_DigestUpdate` hashes `len` bytes from `data`." 79 80Parameters in C and C++ that use array syntax, such as 81`uint8_t out[SHA256_DIGEST_LENGTH]`, are really pointers. In BoringSSL's uses of 82this syntax, the pointer must point to the specified number of values. 83 84In other cases, the documentation will describe how the function parameters 85determine the slice's length. For example, a slice's length may be measured in 86units other than element count, multiple slice parameters may share a length, or 87a slice's length may be implicitly determined by other means like RSA key size. 88 89By default, BoringSSL follows C++'s 90[slice conventions](https://davidben.net/2024/01/15/empty-slices.html) 91for pointers. That is, unless otherwise specified, pointers for non-empty 92(non-zero length) slices must be represented by a valid pointer to that many 93objects in memory. Pointers for empty (zero length) slices must either be `NULL` 94or point within some sequence of objects of a compatible type. 95 96WARNING: The dangling, non-null pointer used by Rust empty slices may *not* be 97passed into BoringSSL. Rust FFIs must adjust such pointers to before passing to 98BoringSSL. For example, see the `FfiSlice` abstraction in `bssl-crypto`. (We may 99relax this if pointer arithmetic rules in C/C++ are adjusted to permit Rust's 100pointers. Until then, it is impractical for a C/C++ library to act on such a 101slice representation. See 102[this document](https://davidben.net/2024/01/15/empty-slices.html) for more 103discussion.) 104 105In some cases, OpenSSL compatibility requires that a function will treat `NULL` 106slice pointers differently from non-`NULL` pointers. Such behavior will be 107described in documentation. For examples, see `EVP_EncryptUpdate`, 108`EVP_DigestSignFinal`, and `HMAC_Init_ex`. Callers passing potentially empty 109slices into such functions should take care that the `NULL` case is either 110unreachable or still has the desired behavior. 111 112If a `const char *` parameter is described as a "NUL-terminated string" or a 113"C string", it must point to a sequence of `char` values containing a NUL (zero) 114value, which determines the length. Unless otherwise specified, the pointer may 115not be `NULL`, matching the C standard library. 116 117For purposes of C and C++'s 118[strict aliasing](https://en.cppreference.com/w/c/language/object#Strict_aliasing) 119requirements, objects passed by pointers must be accessible as the specified 120type. `uint8_t` may be assumed to be the same type as `unsigned char` and thus 121may be the pointer type for all object types. BoringSSL does not support 122platforms where `uint8_t` is a non-character type. However, there is no 123strict aliasing sanitizer, very few C and C++ codebases are valid by strict 124aliasing, and BoringSSL itself has some 125[known strict aliasing bugs](https://crbug.com/boringssl/444), thus we strongly 126recommend consumers build with `-fno-strict-aliasing`. 127 128Pointer parameters additionally have ownership and lifetime requirements, 129discussed in the section below. 130 131 132## Object initialization and cleanup 133 134BoringSSL defines a number of structs for use in its APIs. It is a C library, 135so the caller is responsible for ensuring these structs are properly 136initialized and released. Consult the documentation for a module for the 137proper use of its types. Some general conventions are listed below. 138 139 140### Heap-allocated types 141 142Some types, such as `RSA`, are heap-allocated. All instances will be allocated 143and returned from BoringSSL's APIs. It is an error to instantiate a heap- 144allocated type on the stack or embedded within another object. 145 146Heap-allocated types may have functioned named like `RSA_new` which allocates a 147fresh blank `RSA`. Other functions may also return newly-allocated instances. 148For example, `RSA_parse_public_key` is documented to return a newly-allocated 149`RSA` object. 150 151Heap-allocated objects must be released by the corresponding free function, 152named like `RSA_free`. Like C's `free` and C++'s `delete`, all free functions 153internally check for `NULL`. It is redundant to check for `NULL` before calling. 154 155A heap-allocated type may be reference-counted. In this case, a function named 156like `RSA_up_ref` will be available to take an additional reference count. The 157free function must be called to decrement the reference count. It will only 158release resources when the final reference is released. For OpenSSL 159compatibility, these functions return `int`, but callers may assume they always 160successfully return one because reference counts use saturating arithmetic. 161 162C++ consumers are recommended to use `bssl::UniquePtr` to manage heap-allocated 163objects. `bssl::UniquePtr<T>`, like other types, is forward-declared in 164`openssl/base.h`. Code that needs access to the free functions, such as code 165which destroys a `bssl::UniquePtr`, must include the corresponding module's 166header. (This matches `std::unique_ptr`'s relationship with forward 167declarations.) Note, despite the name, `bssl::UniquePtr` is also used with 168reference-counted types. It owns a single reference to the object. To take an 169additional reference, use the `bssl::UpRef` function, which will return a 170separate `bssl::UniquePtr`. 171 172 173### Stack-allocated types 174 175Other types in BoringSSL are stack-allocated, such as `EVP_MD_CTX`. These 176types may be allocated on the stack or embedded within another object. 177However, they must still be initialized before use. 178 179Every stack-allocated object in BoringSSL has a *zero state*, analogous to 180initializing a pointer to `NULL`. In this state, the object may not be 181completely initialized, but it is safe to call cleanup functions. Entering the 182zero state cannot fail. (It is usually `memset(0)`.) 183 184The function to enter the zero state is named like `EVP_MD_CTX_init` or 185`CBB_zero` and will always return `void`. To release resources associated with 186the type, call the cleanup function, named like `EVP_MD_CTX_cleanup`. The 187cleanup function must be called on all codepaths, regardless of success or 188failure. For example: 189 190 uint8_t md[EVP_MAX_MD_SIZE]; 191 unsigned md_len; 192 EVP_MD_CTX ctx; 193 EVP_MD_CTX_init(&ctx); /* Enter the zero state. */ 194 int ok = EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) && 195 EVP_DigestUpdate(&ctx, "hello ", 6) && 196 EVP_DigestUpdate(&ctx, "world", 5) && 197 EVP_DigestFinal_ex(&ctx, md, &md_len); 198 EVP_MD_CTX_cleanup(&ctx); /* Release |ctx|. */ 199 200Note that `EVP_MD_CTX_cleanup` is called whether or not the `EVP_Digest*` 201operations succeeded. More complex C functions may use the `goto err` pattern: 202 203 int ret = 0; 204 EVP_MD_CTX ctx; 205 EVP_MD_CTX_init(&ctx); 206 207 if (!some_other_operation()) { 208 goto err; 209 } 210 211 uint8_t md[EVP_MAX_MD_SIZE]; 212 unsigned md_len; 213 if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) || 214 !EVP_DigestUpdate(&ctx, "hello ", 6) || 215 !EVP_DigestUpdate(&ctx, "world", 5) || 216 !EVP_DigestFinal_ex(&ctx, md, &md_len) { 217 goto err; 218 } 219 220 ret = 1; 221 222 err: 223 EVP_MD_CTX_cleanup(&ctx); 224 return ret; 225 226Note that, because `ctx` is set to the zero state before any failures, 227`EVP_MD_CTX_cleanup` is safe to call even if the first operation fails before 228`EVP_DigestInit_ex`. However, it would be illegal to move the `EVP_MD_CTX_init` 229below the `some_other_operation` call. 230 231As a rule of thumb, enter the zero state of stack-allocated structs in the 232same place they are declared. 233 234C++ consumers are recommended to use the wrappers named like 235`bssl::ScopedEVP_MD_CTX`, defined in the corresponding module's header. These 236wrappers are automatically initialized to the zero state and are automatically 237cleaned up. 238 239 240### Data-only types 241 242A few types, such as `SHA_CTX`, are data-only types and do not require cleanup. 243These are usually for low-level cryptographic operations. These types may be 244used freely without special cleanup conventions. 245 246 247### Ownership and lifetime 248 249When working with allocated objects, it is important to think about *ownership* 250of each object, or what code is responsible for releasing it. This matches the 251corresponding notion in higher-level languages like C++ and Rust. 252 253Ownership applies to both uniquely-owned types and reference-counted types. For 254the latter, ownership means the code is responsible for releasing one 255reference. Note a *reference* in BoringSSL refers to an increment (and eventual 256decrement) of an object's reference count, not `T&` in C++. Thus, to "take a 257reference" means to increment the reference count and take ownership of 258decrementing it. 259 260As BoringSSL's APIs are primarily in C, ownership and lifetime obligations are 261not rigorously annotated in the type signatures or checked at compile-time. 262Instead, they are described in 263[API documentation](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html). 264This section describes some conventions. 265 266Unless otherwise documented, functions do not take ownership of pointer 267arguments. The pointer typically must remain valid for the duration of the 268function call. The function may internally copy information from the argument or 269take a reference, but the caller is free to release its copy or reference at any 270point after the call completes. 271 272A function may instead be documented to *take* or *transfer* ownership of a 273pointer. The caller must own the object before the function call and, after 274transfer, no longer owns it. As a corollary, the caller may no longer reference 275the object without a separate guarantee on the lifetime. The function may even 276release the object before returning. Callers that wish to independently retain a 277transfered object must therefore take a reference or make a copy before 278transferring. Callers should also take note of whether the function is 279documented to transfer pointers unconditionally or only on success. Unlike C++ 280and Rust, functions in BoringSSL typically only transfer on success. 281 282Likewise, output pointers may be owning or non-owning. Unless otherwise 283documented, functions output non-owning pointers. The caller is not responsible 284for releasing the output pointer, but it must not use the pointer beyond its 285lifetime. The pointer may be released when the parent object is released or even 286sooner on state change in the parent object. 287 288If documented to output a *newly-allocated* object or a *reference* or *copy* of 289one, the caller is responsible for releasing the object when it is done. 290 291By convention, functions named `get0` return non-owning pointers. Functions 292named `new` or `get1` return owning pointers. Functions named `set0` take 293ownership of arguments. Functions named `set1` do not. They typically take a 294reference or make a copy internally. These names originally referred to the 295effect on a reference count, but the convention applies equally to 296non-reference-counted types. 297 298API documentation may also describe more complex obligations. For instance, an 299object may borrow a pointer for longer than the duration of a single function 300call, in which case the caller must ensure the lifetime extends accordingly. 301 302Memory errors are one of the most common and dangerous bugs in C and C++, so 303callers are encouraged to make use of tools such as 304[AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) and 305higher-level languages. 306 307 308## Thread safety 309 310BoringSSL is internally aware of the platform threading library and calls into 311it as needed. Consult the API documentation for the threading guarantees of 312particular objects. In general, stateless reference-counted objects like `RSA` 313or `EVP_PKEY` which represent keys may typically be used from multiple threads 314simultaneously, provided no thread mutates the key. 315