aboutsummaryrefslogtreecommitdiff
path: root/API-CONVENTIONS.md
diff options
context:
space:
mode:
authorDavid Benjamin <davidben@google.com>2024-04-25 13:53:35 -0400
committerBoringssl LUCI CQ <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com>2024-04-25 21:15:15 +0000
commite1cfbf1898d77e851f2d9adb9b1f950f918f8e7e (patch)
tree3ce7a36df1c2f97420321cb214e71c10e26988cb /API-CONVENTIONS.md
parent54821d806d574dd8f2869a8c7f5725b65a67af42 (diff)
downloadboringssl-e1cfbf1898d77e851f2d9adb9b1f950f918f8e7e.zip
boringssl-e1cfbf1898d77e851f2d9adb9b1f950f918f8e7e.tar.gz
boringssl-e1cfbf1898d77e851f2d9adb9b1f950f918f8e7e.tar.bz2
Discuss pointer rules in even more detail in API-CONVENTIONS
This covers: - The empty slices mess, and specifically Rust's unsafe FFIs - Whether objects may be NULL by default - When we use C's array syntax for static lengths Also remove the note about ASN.1 and X.509 APIs being undocumented. We've now documented them. Change-Id: Ie12eee5ec16b9f87790076cbbe3a269f288dda03 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/68047 Reviewed-by: Adam Langley <agl@google.com> Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: David Benjamin <davidben@google.com>
Diffstat (limited to 'API-CONVENTIONS.md')
-rw-r--r--API-CONVENTIONS.md79
1 files changed, 71 insertions, 8 deletions
diff --git a/API-CONVENTIONS.md b/API-CONVENTIONS.md
index e36037b..5c891dd 100644
--- a/API-CONVENTIONS.md
+++ b/API-CONVENTIONS.md
@@ -2,7 +2,8 @@
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.
+both API consumers and developers. API documentation in BoringSSL may assume
+these conventions by default, rather than repeating them for every function.
## Documentation
@@ -11,11 +12,6 @@ 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).
-Some headers lack documention comments. These are functions and structures from
-OpenSSL's legacy ASN.1, X.509, and PEM implementation. If possible, avoid using
-them. These are left largely unmodified from upstream and are retained only for
-compatibility with existing OpenSSL consumers.
-
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.
@@ -65,6 +61,74 @@ 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,
@@ -86,8 +150,7 @@ For example, `RSA_parse_public_key` is documented to return a newly-allocated
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`. Consumers are not required to check for `NULL`
-before calling.
+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