|
| 1 | +# BoringSSL API Conventions |
| 2 | + |
| 3 | +This document describes conventions for BoringSSL APIs. The [style |
| 4 | +guide](/STYLE.md) also includes guidelines, but this document is targeted at |
| 5 | +both API consumers and developers. |
| 6 | + |
| 7 | + |
| 8 | +## Documentation |
| 9 | + |
| 10 | +All supported public APIs are documented in the public header files, found in |
| 11 | +`include/openssl`. The API documentation is also available |
| 12 | +[online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html). |
| 13 | + |
| 14 | +Some headers lack documention comments. These are functions and structures from |
| 15 | +OpenSSL's legacy ASN.1, X.509, and PEM implementation. If possible, avoid using |
| 16 | +them. These are left largely unmodified from upstream and are retained only for |
| 17 | +compatibility with existing OpenSSL consumers. |
| 18 | + |
| 19 | + |
| 20 | +## Forward declarations |
| 21 | + |
| 22 | +Do not write `typedef struct foo_st FOO` or try otherwise to define BoringSSL's |
| 23 | +types. Including `openssl/base.h` (or `openssl/ossl_typ.h` for consumers who |
| 24 | +wish to be OpenSSL-compatible) will forward-declare each type without importing |
| 25 | +the rest of the library or invasive macros. |
| 26 | + |
| 27 | + |
| 28 | +## Error-handling |
| 29 | + |
| 30 | +Most functions in BoringSSL may fail, either due to allocation failures or input |
| 31 | +errors. Functions which return an `int` typically return one on success and zero |
| 32 | +on failure. Functions which return a pointer typically return `NULL` on failure. |
| 33 | +However, due to legacy constraints, some functions are more complex. Consult the |
| 34 | +API documentation before using a function. |
| 35 | + |
| 36 | +On error, most functions also push errors on the error queue, an `errno`-like |
| 37 | +mechanism. See the documentation for |
| 38 | +[err.h](https://commondatastorage.googleapis.com/chromium-boringssl-docs/err.h.html) |
| 39 | +for more details. |
| 40 | + |
| 41 | +As with `errno`, callers must test the function's return value, not the error |
| 42 | +queue to determine whether an operation failed. Some codepaths may not interact |
| 43 | +with the error queue, and the error queue may have state from a previous failed |
| 44 | +operation. |
| 45 | + |
| 46 | +When ignoring a failed operation, it is recommended to call `ERR_clear_error` to |
| 47 | +avoid the state interacting with future operations. Failing to do so should not |
| 48 | +affect the actual behavior of any functions, but may result in errors from both |
| 49 | +operations being mixed in error logging. We hope to |
| 50 | +[improve](https://bugs.chromium.org/p/boringssl/issues/detail?id=38) this |
| 51 | +situation in the future. |
| 52 | + |
| 53 | +Where possible, avoid conditioning on specific reason codes and limit usage to |
| 54 | +logging. The reason codes are very specific and may change over time. |
| 55 | + |
| 56 | + |
| 57 | +## Memory allocation |
| 58 | + |
| 59 | +BoringSSL allocates memory via `OPENSSL_malloc`, found in `mem.h`. Use |
| 60 | +`OPENSSL_free`, found in the same header file, to release it. BoringSSL |
| 61 | +functions will fail gracefully on allocation error, but it is recommended to use |
| 62 | +a `malloc` implementation that `abort`s on failure. |
| 63 | + |
| 64 | + |
| 65 | +## Object initialization and cleanup |
| 66 | + |
| 67 | +BoringSSL defines a number of structs for use in its APIs. It is a C library, |
| 68 | +so the caller is responsible for ensuring these structs are properly |
| 69 | +initialized and released. Consult the documentation for a module for the |
| 70 | +proper use of its types. Some general conventions are listed below. |
| 71 | + |
| 72 | + |
| 73 | +### Heap-allocated types |
| 74 | + |
| 75 | +Some types, such as `RSA`, are heap-allocated. All instances will be allocated |
| 76 | +and returned from BoringSSL's APIs. It is an error to instantiate a heap- |
| 77 | +allocated type on the stack or embedded within another object. |
| 78 | + |
| 79 | +Heap-allocated types may have functioned named like `RSA_new` which allocates a |
| 80 | +fresh blank `RSA`. Other functions may also return newly-allocated instances. |
| 81 | +For example, `RSA_parse_public_key` is documented to return a newly-allocated |
| 82 | +`RSA` object. |
| 83 | + |
| 84 | +Heap-allocated objects must be released by the corresponding free function, |
| 85 | +named like `RSA_free`. Like C's `free` and C++'s `delete`, all free functions |
| 86 | +internally check for `NULL`. Consumers are not required to check for `NULL` |
| 87 | +before calling. |
| 88 | + |
| 89 | +A heap-allocated type may be reference-counted. In this case, a function named |
| 90 | +like `RSA_up_ref` will be available to take an additional reference count. The |
| 91 | +free function must be called to decrement the reference count. It will only |
| 92 | +release resources when the final reference is released. For OpenSSL |
| 93 | +compatibility, these functions return `int`, but callers may assume they always |
| 94 | +successfully return one because reference counts use saturating arithmetic. |
| 95 | + |
| 96 | +C++ consumers are recommended to use `bssl::UniquePtr` to manage heap-allocated |
| 97 | +objects. `bssl::UniquePtr<T>`, like other types, is forward-declared in |
| 98 | +`openssl/base.h`. Code that needs access to the free functions, such as code |
| 99 | +which destroys a `bssl::UniquePtr`, must include the corresponding module's |
| 100 | +header. (This matches `std::unique_ptr`'s relationship with forward |
| 101 | +declarations.) Note, despite the name, `bssl::UniquePtr` is also used with |
| 102 | +reference-counted types. It owns a single reference to the object. To take an |
| 103 | +additional reference, use the `bssl::UpRef` function, which will return a |
| 104 | +separate `bssl::UniquePtr`. |
| 105 | + |
| 106 | + |
| 107 | +### Stack-allocated types |
| 108 | + |
| 109 | +Other types in BoringSSL are stack-allocated, such as `EVP_MD_CTX`. These |
| 110 | +types may be allocated on the stack or embedded within another object. |
| 111 | +However, they must still be initialized before use. |
| 112 | + |
| 113 | +Every stack-allocated object in BoringSSL has a *zero state*, analogous to |
| 114 | +initializing a pointer to `NULL`. In this state, the object may not be |
| 115 | +completely initialized, but it is safe to call cleanup functions. Entering the |
| 116 | +zero state cannot fail. (It is usually `memset(0)`.) |
| 117 | + |
| 118 | +The function to enter the zero state is named like `EVP_MD_CTX_init` or |
| 119 | +`CBB_zero` and will always return `void`. To release resources associated with |
| 120 | +the type, call the cleanup function, named like `EVP_MD_CTX_cleanup`. The |
| 121 | +cleanup function must be called on all codepaths, regardless of success or |
| 122 | +failure. For example: |
| 123 | + |
| 124 | + uint8_t md[EVP_MAX_MD_SIZE]; |
| 125 | + unsigned md_len; |
| 126 | + EVP_MD_CTX ctx; |
| 127 | + EVP_MD_CTX_init(&ctx); /* Enter the zero state. */ |
| 128 | + int ok = EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) && |
| 129 | + EVP_DigestUpdate(&ctx, "hello ", 6) && |
| 130 | + EVP_DigestUpdate(&ctx, "world", 5) && |
| 131 | + EVP_DigestFinal_ex(&ctx, md, &md_len); |
| 132 | + EVP_MD_CTX_cleanup(&ctx); /* Release |ctx|. */ |
| 133 | + |
| 134 | +Note that `EVP_MD_CTX_cleanup` is called whether or not the `EVP_Digest*` |
| 135 | +operations succeeded. More complex C functions may use the `goto err` pattern: |
| 136 | + |
| 137 | + int ret = 0; |
| 138 | + EVP_MD_CTX ctx; |
| 139 | + EVP_MD_CTX_init(&ctx); |
| 140 | + |
| 141 | + if (!some_other_operation()) { |
| 142 | + goto err; |
| 143 | + } |
| 144 | + |
| 145 | + uint8_t md[EVP_MAX_MD_SIZE]; |
| 146 | + unsigned md_len; |
| 147 | + if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL) || |
| 148 | + !EVP_DigestUpdate(&ctx, "hello ", 6) || |
| 149 | + !EVP_DigestUpdate(&ctx, "world", 5) || |
| 150 | + !EVP_DigestFinal_ex(&ctx, md, &md_len) { |
| 151 | + goto err; |
| 152 | + } |
| 153 | + |
| 154 | + ret = 1; |
| 155 | + |
| 156 | + err: |
| 157 | + EVP_MD_CTX_cleanup(&ctx); |
| 158 | + return ret; |
| 159 | + |
| 160 | +Note that, because `ctx` is set to the zero state before any failures, |
| 161 | +`EVP_MD_CTX_cleanup` is safe to call even if the first operation fails before |
| 162 | +`EVP_DigestInit_ex`. However, it would be illegal to move the `EVP_MD_CTX_init` |
| 163 | +below the `some_other_operation` call. |
| 164 | + |
| 165 | +As a rule of thumb, enter the zero state of stack-allocated structs in the |
| 166 | +same place they are declared. |
| 167 | + |
| 168 | +C++ consumers are recommended to use the wrappers named like |
| 169 | +`bssl::ScopedEVP_MD_CTX`, defined in the corresponding module's header. These |
| 170 | +wrappers are automatically initialized to the zero state and are automatically |
| 171 | +cleaned up. |
| 172 | + |
| 173 | + |
| 174 | +### Data-only types |
| 175 | + |
| 176 | +A few types, such as `SHA_CTX`, are data-only types and do not require cleanup. |
| 177 | +These are usually for low-level cryptographic operations. These types may be |
| 178 | +used freely without special cleanup conventions. |
| 179 | + |
| 180 | + |
| 181 | +### Ownership and lifetime |
| 182 | + |
| 183 | +When working with allocated objects, it is important to think about *ownership* |
| 184 | +of each object, or what code is responsible for releasing it. This matches the |
| 185 | +corresponding notion in higher-level languages like C++ and Rust. |
| 186 | + |
| 187 | +Ownership applies to both uniquely-owned types and reference-counted types. For |
| 188 | +the latter, ownership means the code is responsible for releasing one |
| 189 | +reference. Note a *reference* in BoringSSL refers to an increment (and eventual |
| 190 | +decrement) of an object's reference count, not `T&` in C++. Thus, to "take a |
| 191 | +reference" means to increment the reference count and take ownership of |
| 192 | +decrementing it. |
| 193 | + |
| 194 | +As BoringSSL's APIs are primarily in C, ownership and lifetime obligations are |
| 195 | +not rigorously annotated in the type signatures or checked at compile-time. |
| 196 | +Instead, they are described in |
| 197 | +[API documentation](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html). |
| 198 | +This section describes some conventions. |
| 199 | + |
| 200 | +Unless otherwise documented, functions do not take ownership of pointer |
| 201 | +arguments. The pointer typically must remain valid for the duration of the |
| 202 | +function call. The function may internally copy information from the argument or |
| 203 | +take a reference, but the caller is free to release its copy or reference at any |
| 204 | +point after the call completes. |
| 205 | + |
| 206 | +A function may instead be documented to *take* or *transfer* ownership of a |
| 207 | +pointer. The caller must own the object before the function call and, after |
| 208 | +transfer, no longer owns it. As a corollary, the caller may no longer reference |
| 209 | +the object without a separate guarantee on the lifetime. The function may even |
| 210 | +release the object before returning. Callers that wish to independently retain a |
| 211 | +transfered object must therefore take a reference or make a copy before |
| 212 | +transferring. Callers should also take note of whether the function is |
| 213 | +documented to transfer pointers unconditionally or only on success. Unlike C++ |
| 214 | +and Rust, functions in BoringSSL typically only transfer on success. |
| 215 | + |
| 216 | +Likewise, output pointers may be owning or non-owning. Unless otherwise |
| 217 | +documented, functions output non-owning pointers. The caller is not responsible |
| 218 | +for releasing the output pointer, but it must not use the pointer beyond its |
| 219 | +lifetime. The pointer may be released when the parent object is released or even |
| 220 | +sooner on state change in the parent object. |
| 221 | + |
| 222 | +If documented to output a *newly-allocated* object or a *reference* or *copy* of |
| 223 | +one, the caller is responsible for releasing the object when it is done. |
| 224 | + |
| 225 | +By convention, functions named `get0` return non-owning pointers. Functions |
| 226 | +named `new` or `get1` return owning pointers. Functions named `set0` take |
| 227 | +ownership of arguments. Functions named `set1` do not. They typically take a |
| 228 | +reference or make a copy internally. These names originally referred to the |
| 229 | +effect on a reference count, but the convention applies equally to |
| 230 | +non-reference-counted types. |
| 231 | + |
| 232 | +API documentation may also describe more complex obligations. For instance, an |
| 233 | +object may borrow a pointer for longer than the duration of a single function |
| 234 | +call, in which case the caller must ensure the lifetime extends accordingly. |
| 235 | + |
| 236 | +Memory errors are one of the most common and dangerous bugs in C and C++, so |
| 237 | +callers are encouraged to make use of tools such as |
| 238 | +[AddressSanitizer](https://clang.llvm.org/docs/AddressSanitizer.html) and |
| 239 | +higher-level languages. |
| 240 | + |
| 241 | + |
| 242 | +## Thread safety |
| 243 | + |
| 244 | +BoringSSL is internally aware of the platform threading library and calls into |
| 245 | +it as needed. Consult the API documentation for the threading guarantees of |
| 246 | +particular objects. In general, stateless reference-counted objects like `RSA` |
| 247 | +or `EVP_PKEY` which represent keys may typically be used from multiple threads |
| 248 | +simultaneously, provided no thread mutates the key. |
0 commit comments