Commit d8e49b85d0 for openssl.org
commit d8e49b85d003d4f3c4636b702f5a088bc530eaa8
Author: Bob Beck <beck@openssl.org>
Date: Mon Dec 1 15:10:48 2025 -0700
Add a STYLE.md file and link it from CONTRIBUTING.md
This is effectively, the current coding style policy web page
changed to accomodate clang-format. This is more or less the
same file I have had in the various clang-format sample PR's since
September.
It does include an additional sections on Integers and on
Return Values that are not in the original coding style
policy
It is changed from the September version in that it does not
have mention of keeping include files self contained. I believe
that is achievable and desirable, but I think should be done
as a separate change from this.
There were a number of issues brought up in discussion of this
file in the clang-format PR's. I recorded those in 818, 819,
820, 821, 822, 823, 824, 825, and 826, which we can
link in there to the appropriate section of the document.
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Milan Broz <mbroz@openssl.org>
MergeDate: Fri Jul 10 15:37:13 2026
(Merged from https://github.com/openssl/openssl/pull/29295)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 63eaf4397d..213125c255 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -127,8 +127,9 @@ guidelines:
often. We do not accept merge commits, you will have to remove them
(usually by rebasing) before it will be acceptable.
- 5. Code provided should follow our [coding style] and [documentation policy]
+ 5. Code provided should follow our [coding style](STYLE.md) and [documentation policy]
and compile without warnings.
+
Consistent formatting is enforced by using `clang-format` with configuration
stored in [.clang-format](.clang-format). OpenSSL uses `WebKit` style.
You can configure git pre-commit to automatically reformat your code with
@@ -142,7 +143,6 @@ guidelines:
Clean builds via GitHub Actions are required. They are started automatically
whenever a PR is created or updated by committers.
- [coding style]: https://openssl-library.org/policies/technical/coding-style/
[documentation policy]: https://openssl-library.org/policies/technical/documentation-policy/
6. When at all possible, code contributions should include tests. These can
@@ -195,7 +195,8 @@ guidelines:
the commit should include the line:
```
- Fixes #XXXXX
+ Fixes: LINK
```
- where XXXXX is the issue number.
+ where LINK is the https link to the issue in github.
+
diff --git a/STYLE.md b/STYLE.md
new file mode 100644
index 0000000000..f102cb9128
--- /dev/null
+++ b/STYLE.md
@@ -0,0 +1,689 @@
+# OpenSSL Style Guide
+
+## How to use this guide.
+
+A brief metaphor to serve as a guide both for reviewers and
+contributors.
+
+This guide is intended to be applied like Electrical Wiring rules for
+a house.
+
+OpenSSL is a large codebase with a long history. Just as a house may
+be older than the latest technology and standards for residential
+electrical installations, OpenSSL is older than many current
+language standards and best practices.
+
+Electrical Wiring rules typically do not require that you rip open
+your house with every revision of the rules, and change everything in
+your house to the most modern standard of compliance. They do require
+that changes need to be made reasonably, to ensure safety and improved
+compliance, which can include bringing an area up to date if
+significant changes are made to it and it could impact other
+areas. Similarly, that is that the intention of the application of
+the rules in this guide.
+
+All code in OpenSSL does not conform to this document. This document
+is meant to establish the standards required for new code, and for
+significant refactors of existing code. For example, if your household
+kitchen has old knob and tube wiring, that is correctly installed and
+safe and working, you are not required to open up your walls and
+rewire your entire kitchen to fix one broken electrical outlet.
+
+However, if you did choose to replace your kitchen wiring for a
+renovation, but then hack together something to feed the knob and tube
+wiring that contines to the bedroom, You will be asked by the
+electrical inspector to bring the bedroom up to date as well.
+
+It is the desire that new contributions meet this standard, and
+contributions that significantly change existing areas should bring
+them up to this standard where possible and reasonable to do so.
+
+## Webkit style
+
+OpenSSL follows the
+[Webkit coding style for C code](https://webkit.org/code-style-guidelines/)
+The rest of this document describes differences and clarifications on
+top of the base guide.
+
+## Whitespace Indenting and Formatting
+
+The basic style for indenting and whitespace is as per the WebKit
+C coding style. This style is enforced by clang-format using the
+.clang-format file in this directory. Your changes should be formatted
+with clang-format and whatever indentation and line wrapping
+clang-format does to them should be deemed correct.
+
+In rare situations it may be necessary to disable clang-format
+on a piece of code. This may be done by the comments:
+
+```
+/* clang-format off */
+I am doing something nasty here.
+Reviewers should be triggered.
+/* clang-format on */
+```
+This should be used sparingly, and should not be used if
+there is any other way to do what you are doing.
+
+The use of clang-format is intended to ensure basic consistency
+and to ease review. Nevertheless, clang-format can not enforce
+other necessary aspects of style, and these are documented here.
+
+## Language
+
+The majority of the project is in C, so C++ specific rules in the
+aforementioned coding standards do not apply.
+
+To maximise portability the version of C defined in ISO/IEC 9899:1999
+should be used. This is more commonly referred to as C99. More modern
+version of the C language are not yet supported on some platforms that
+OpenSSL is used on and therefore should be avoided.
+
+## Naming
+
+C is a Spartan language, and so should your naming be.
+
+Local variable names should be short, and to the point. If you have
+some random integer loop counter, it should probably be called i or j.
+
+Avoid single-letter names when they can be visually confusing, such as
+I and O. Avoid other single-letter names unless they are telling in
+the given context. For instance, m for modulus and s for SSL pointers
+are fine.
+
+Use simple variable names like tmp and name as long as they are
+non-ambiguous in the given context.
+
+If you are afraid that someone might mix up your local variable names,
+perhaps the function is too long; see the chapter on functions.
+
+Global variables (to be used only if you REALLY need them) need to
+have descriptive names, as do global functions. If you have a function
+that counts the number of active users, you should call that
+count_active_users() or similar, you should NOT call it cntusr().
+
+For getter functions returning a pointer and functions setting a
+pointer given as a parameter, use names containing get0_ or get1_
+(rather than get_) or set0_ or set1_ (rather than set_) or push0_ or
+push1_ (rather than push_) to indicate whether the structure referred
+to by the pointer remains as it is or it is duplicated/up-ref’ed such
+that an additional free() will be needed.
+
+Use lowercase prefix like ossl_ for internal symbols unless they are
+static (i.e., local to the source file).
+
+Use uppercase prefix like EVP_ or OSSL_CMP_ for public (API) symbols.
+
+Do not encode the type into a name (so-called Hungarian notation,
+e.g., int iAge).
+
+Align names to terms and wording used in standards and RFCs.
+
+Avoid mixed-case unless needed by other rules. Especially never use
+FirstCharacterUpperCase. For instance, use EVP_PKEY_do_something
+rather than EVP_DigestDoSomething.
+
+Make sure that names do not contain spelling errors.
+
+## Comments
+
+Use the classic /* ... */ comment markers. Don’t use // ... markers.
+Place comments above or to the right of the code they refer to.
+Comments are good, but there is also a danger of over-commenting. NEVER try to
+explain HOW your code works in a comment. It is much better to write the code
+so that it is obvious, and it’s a waste of time to explain badly written code.
+You want your comments to tell WHAT your code does, not HOW.
+The preferred style for long (multi-line) comments is:
+
+```
+/*-
+ * This is the preferred style for multi-line
+ * comments in the OpenSSL source code.
+ * Please use it consistently.
+ *
+ * Description: A column of asterisks on the left side,
+ * with beginning and ending almost-blank lines.
+ */
+```
+
+Note the initial hyphen to prevent indent and clang-format from
+modifying the comment block. Use this if the comment has particular
+formatting that must be preserved.
+
+It’s also important to comment data, whether they are basic types or derived
+types. To this end, use just one data declaration per line (no commas for
+multiple data declarations). This leaves you room for a small comment on each
+item, explaining its use.
+
+In an effort to better translate our source code into documentation that is
+more easily understandable to future developers, please also consider adding
+Doxygen style comments to any function/data structures/macros/etc that you
+alter or create in the development of patches for OpenSSL. The intent is to
+provide a more robust set of documentation for our entire code base (with
+particular focus on our internal functions and data structures). Please use the
+following sample code as a guideline:
+
+```
+/*
+ * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/**
+ * @file doxysample.c
+ * This is a brief file description that you may add
+ * Subsequent lines contain more detailed information about what you will
+ * find defined in this file. It is not currently required that you add a file
+ * description, but it's available if you like.
+ */
+
+ /**
+ * @def MAX(x, y)
+ * document a macro that returns the maximum of two inputs.
+ * @param x integer input value
+ * @param y integer input value
+ * @returns the maximum of x and y
+ */
+ #define MAX(x, y) (x > y ? x : y)
+
+/**
+ * @struct foo_st
+ * @brief description of the foo_st struct.
+ * Optional more detailed description here.
+ */
+typedef foo_st {
+ int a; /**< Describe the a field here */
+ char b; /**< Describe the b field here */
+} FOO;
+
+
+/**
+ * \brief Describe the function add briefly.
+ * Add a more detailed description here, like sums two inputs and returns the
+ * results.
+ * \param a - input integer to add
+ * \param b - input integer to add
+ * \returns the sum of a and b
+ */
+int add(int a, int b)
+{
+ return a + b;
+}
+```
+
+## Typedefs
+
+OpenSSL uses typedef’s extensively. For structures, they are all
+uppercase and are usually declared like this:
+
+typedef struct name_st NAME;
+
+For examples, look in <openssl/types.h>, but note that there are many
+exceptions such as BN_CTX. Typedef’d enum is used much less often and
+there is no convention, so consider not using a typedef. When doing
+that, the enum name should be lowercase and the values (mostly)
+uppercase. Note that enum arguments to public functions are not
+permitted.
+
+The ASN.1 structures are an exception to this. The rationale is that
+if a structure (and its fields) is already defined in a standard it’s
+more convenient to use a similar name. For example, in the CMS code, a
+CMS_ prefix is used so ContentInfo becomes CMS_ContentInfo,
+RecipientInfo becomes CMS_RecipientInfo etc. Some older code uses an
+all uppercase name instead. For example, RecipientInfo for the PKCS#7
+code uses PKCS7_RECIP_INFO.
+
+Be careful about common names which might cause conflicts. For
+example, Windows headers use X509 and X590_NAME. Consider using a
+prefix, as with CMS_ContentInfo, if the name is common or generic. Of
+course, you often don’t find out until the code is ported to other
+platforms.
+
+A final word on struct’s. OpenSSL has historically made all struct
+definitions public; this has caused problems with maintaining binary
+compatibility and adding features. Our stated direction is to have
+struct’s be opaque and only expose pointers in the API. The actual
+struct definition should be defined in a local header file that is not
+exported.
+
+## Integers
+
+*When not constrained by legacy code*:
+
+Prefer using explicitly-sized integers where appropriate rather than
+generic C ones. For instance, to represent a byte, use `uint8_t`, not
+`unsigned char`. Likewise, represent a two-byte field as `uint16_t`, not
+`unsigned short`.
+
+Sizes should be represented as `size_t`. When converting to/from an
+`int` for legacy purposes ensure to account for overflow/underflow
+conditions.
+
+Within structs that are retained across the lifetime of a connection,
+for new integer values whose size are known and it's easy to do, use a
+smaller integer type like `uint8_t`. This is a "free" connection
+footprint optimization for servers. Don't make code significantly more
+complex for it, and do still check the bounds when passing in and out
+of the struct. This narrowing should not propagate to local variables
+and function parameters which should use more conventional integer
+types in order to not add complexity for the users of such
+functions. Do not retroactively apply this rule to existing integer
+values in structures as this could cause ABI breakage.
+
+When doing arithmetic, account for overflow conditions.
+
+Except in platform specific code, do not use `ssize_t`. MSVC lacks it,
+and prefer out-of-band error signaling for `size_t` (see Return
+Values).
+
+## Preprocessor Directives
+
+Prefer #if defined(FOO) and #if !defined(FOO) to #ifdef and
+#ifndef. This allows you to use logical operations when conditional
+compilation is dependant on more than one variable instead of nesting
+multiple blocks.
+
+All #endif blocks must have a comment matching their #if.
+
+```
+#if defined(OPENSSL_LINUX) && (!defined(OPENSSL_NO_HOOBLA) || !defined(OPENSSL_BULA)
+...
+...
+#endif /* defined(OPENSSL_LINUX) && (!defined(OPENSSL_NO_HOOBLA) || !defined(OPENSSL_BULA) */
+```
+
+Always prefer to isolate conditional compilation in one place, or use
+separate files. If you need to do "stuff" in many places that can be
+done many different ways. It is very undesirable to have:
+
+```
+#if defined(OPENSSL_OS_FOO) || defined (OPENSSL_OS_BAR)
+stuff the way foo or bar does it;
+#elif defined(OPENSSL_OS_BLAH) || defined (OPENSSL_WOOF)
+stuff the way blah or woof does it;
+#elif
+...
+...
+...
+#endif /* defined(OPENSSL_OS_BLAH) || defined (OPENSSL_WOOF) */
+#endif /* defined(OPENSSL_OS_FOO) || defined (OPENSSL_OS_BAR) */
+```
+
+in many places.
+
+If you need this you should consider making one function that contains
+the os dependent "stuff" with the conditional compilation directives
+only in that function, or if this is large, make separate files
+(stuff_foo.c stuff_blah.c) which implement the same function and
+choose the implementation to include in the build process. The latter
+method is friendlier to non mainstream platforms as os dependent
+implementations can be maintained in separate files rather than
+intrusive code patches.
+
+## Macros and Enums
+OpenSSL has historically made extensive use of macros in C, and the C
+preprocessor. This was normal practice in older C codebases, when C
+compilers were simple things and unable to avoid significant function
+call overhead. This is no longer the case, so it is desirable to
+reduce this and avoid it in new code.
+
+Macros and labels in enums should be named in
+ALL_CAPS_WITH_UNDERSCORES. This convention helps distinguish macros
+from functions and variables.
+
+```
+#define OPENSSL_MAGIC_FOO 0x12345
+```
+
+Enums are preferred when defining several related constants. Note,
+however, that enum arguments to public functions are not permitted.
+
+### Avoid Complex Macros
+
+Generally, avoid overly complex or "clever" macros that are difficult
+to read, debug, or maintain. Nesting of macros calling other macros
+should be avoided. Prioritize clarity and simplicity.
+
+### Avoid Function-like Macros
+
+Functions should be preferred to function-like macros. New code or
+refactors should be with functions. Do not 'pre-optimize' for the
+overhead of a function call without first implementing with a function
+and obtaining measurements to indicate function call overhead is a
+significant problem. Only at this point you can consider inlining the
+function in preference to a function-like macro, if you can then
+measure a significant performance from inlining that does not generate
+an undesirable code size increase.
+
+### Macro Parenthesizetion
+
+Always parenthesize arguments in function-like macros to prevent
+operator precedence issues during expansion.
+
+Enclose the entire macro definition in parentheses if it expands to an
+expression to ensure correct evaluation when used within larger
+expressions. For example:
+
+```
+#define BOB(blah) ((blah) + 42 - 23 / (blah))
+```
+
+### Multi Statement Macros
+
+Enclose multi statement macros in a do {} while(0) loop. Do not
+include a semicolon at the end of macros. Do not enclose macros in
+braces. This ensures they can be used without problems. For example:
+
+```
+/* This is bad */
+#define KERMIT(x) muppet((x)); frog((x)); green((x))
+if (soemthing)
+ KERMIT(bob);
+else /* This now breaks */
+
+/* This is also bad, because now you have to omit the semicolon. */
+#define KERMIT(x) { muppet((x)); frog((x)); green((x)) }
+if (something)
+ KERMIT(bob) /* No semicolon */
+else
+
+/* This does not break */
+#define KERMIT(x) do { muppet((x)); frog((x)); green((x)) } while (0)
+/* Now this works sensibly */
+if (something)
+ KERMIT(bob);
+else
+
+/*
+ * But just use a function - Note we now know that x is an
+ * integer that has something to do with froggieness and we
+ * gain some type safety.
+ */
+static void kermit(int frogginess)
+{
+ muppet(froggieness);
+ frog(froggieness);
+ green(froggieness);
+}
+if (something)
+ kermit(bob);
+else
+```
+
+### Do not include files as multi-line macros
+
+Do not put code in a file and include it inline
+
+```
+ ...
+ printf "Yolo\n";
+#include "./abagfullofcode.inc"
+ printf "That was fun\n";
+ ...
+```
+
+Either make a function out of the code and call it or just put the
+code in place.
+
+### Avoid Macros With Side Effects:
+
+Be extremely cautious with arguments that may have side effects. as they might be
+evaluated multiple times in the macro expansion, leading to unexpected
+behavior. Do not make macros that depend upon modifiying a particular
+magic name:
+
+```
+#define FOO(val) bar(index, (val))
+```
+
+It is confusing to the reader and is prone to breakage from seemingly innocent
+changes.
+
+Do not write macros that are l-values:
+
+```
+FOO(x) = y
+```
+
+## Functions
+
+Ideally, functions should be short and sweet, and do just
+one thing. A rule of thumb is that they should fit on one or two
+screenfuls of text (25 lines as we all know), and do one thing and do
+that well.
+
+The maximum length of a function is often inversely proportional to
+the complexity and indentation level of that function. So, if you have
+a conceptually simple function that is just one long (but simple)
+switch statement, where you have to do lots of small things for a lot
+of different cases, it’s okay to have a longer function.
+
+If you have a complex function, however, consider using helper
+functions with descriptive names. You can ask the compiler to in-line
+them if you think it’s performance-critical, and it will probably do a
+better job of it than you would have done.
+
+Another measure of complexity is the number of local variables. If
+there are more than five to 10, consider splitting it into smaller
+pieces. A human brain can generally easily keep track of about seven
+different things; anything more and it gets confused. Often things
+which are simple and clear now are much less obvious two weeks from
+now, or to someone else. An exception to this is the command-line
+applications which support many options.
+
+In source files, separate functions with one blank line. In function
+prototypes, include parameter names with their data types. Although
+this is not required by the C language, it is preferred in OpenSSL
+because it is a simple way to add valuable information for the
+reader. The name in the prototype declaration should match the name in
+the function definition.
+
+### Checking function arguments
+
+A public function should verify that its arguments are sensible. This
+includes, but is not limited to, verifying that:
+
+* Non-optional pointer arguments are not NULL and,
+* numeric arguments are within expected ranges.
+
+Where an argument is not sensible, an error should be returned.
+
+### Extending existing functions
+
+From time to time it is necessary to extend an existing function. Typically
+this will mean adding additional arguments, but it may also include removal of
+some.
+
+Where an extended function should be added the original function should be kept
+and a new version created with the same name and an _ex suffix. For example,
+the RAND_bytes function has an extended form called RAND_bytes_ex.
+
+Where an extended version of a function already exists and a second extended
+version needs to be created then it should have an _ex2 suffix, and so on for
+further extensions.
+
+When an extended version of a function is created the order of existing
+parameters from the original function should be retained. However new
+parameters may be inserted at any point (they do not have to be at the end),
+and no longer required parameters may be removed.
+
+### Centralized exiting of functions
+
+The goto statement comes in handy when a function exits from multiple locations
+and some common work such as cleanup has to be done. If there is no cleanup
+needed then just return directly. The rationale for this is as follows:
+
+* Unconditional statements are easier to understand and follow
+* It can reduce excessive control structures and nesting
+* It avoids errors caused by failing to update multiple exit points when
+ the code is modified
+* It saves the compiler work to optimize redundant code away ;)
+
+For example:
+```
+int fun(int a)
+{
+ int result = 0;
+ char *buffer = OPENSSL_malloc(SIZE);
+
+ if (buffer == NULL)
+ return -1;
+
+ if (condition1) {
+ while (loop1) {
+ ...
+ }
+ result = 1;
+ goto out;
+ }
+ ...
+out:
+ OPENSSL_free(buffer);
+ return result;
+}
+```
+## Return Values
+
+### Return values in legacy code
+Historically, functions in OpenSSL can return values of many different
+kinds, and one of the most common is a value indicating whether the
+function succeeded or failed. Usually this is:
+
+* 1: success
+* 0: failure
+
+Sometimes an additional value is used:
+
+* -1: something bad (e.g., internal error or memory allocation failure)
+
+Other APIs use the following pattern:
+
+* \>= 1: success, with value returning additional information
+* <= 0: failure with return value indicating why things failed
+
+Sometimes a return value of -1 can mean “should retry” (e.g., BIO,
+SSL, et al). Functions whose return value is the actual result of a
+computation, rather than an indication of whether the computation
+succeeded, are not subject to these rules.
+
+When constrained by legacy code, you should follow the existing API's
+convention for return values. Be certain you are aware of what this is
+when modifying such code.
+
+### Return values in new code
+
+For new code, functions should return `int` with one on
+success and zero on error. Do not overload the return value to both
+signal success/failure and output an integer. For example:
+
+```
+ /**
+ * \brief ossl_snuffle_thingamabob snuffles a thingamabob from bytes of input.
+ * If a valid thingamabob is snuffled, the result is stored in
+ * |*out_thingamabob|. On failure a snuffling error code is stored
+ * in |*out_err|.
+ * \param input - pointer to the bytes to snuffle
+ * \param input_len - the number of bytes available to snuffle from |input|.
+ * \param out_err - pointer to a integer to store an error code.
+ * \param out_thingamabob - pointer to a thingamabob to store the output.
+ * \returns 1 if a thingamabob was snuffled and stored, 0 otherwise.
+ */
+ int ossl_snuffle_thingamabob(uint8_t *input, size_t input_len,
+ int *out_err, thingamabob *out_thingamabob);
+```
+
+If a function outputs a pointer to an object on success and there are *no
+other outputs*, and you are certain there never would be other outputs,
+return the pointer directly and `NULL` on error.
+
+## Allocating memory
+OpenSSL provides many general purpose memory utilities, including, but not
+limited to: OPENSSL_malloc(), OPENSSL_zalloc(), OPENSSL_realloc(), OPENSSL_
+memdup(), OPENSSL_strdup() and OPENSSL_free(). Please refer to the API
+documentation for further information about them.
+
+OpenSSL provides special purpose allocators for arrays, including
+OPENSSL_malloc_array() and OPENSSL_realloc_array() which take
+arguments of the element size and number of elements desired. Always
+use these for array allocation, as these functions check for integer
+overflow conditions safely when computing the size of the allocation.
+
+If you design an API that requires internal memory allocations before use,
+ensure you provide both an initialization API to do the allocation before
+using it, and a completion API to de-allocate the memory that consumers
+of your API can call when finished.
+
+## Processor-specific code
+In OpenSSL’s case the only reason to resort to processor-specific code is for
+performance. As it still exists in a general platform-independent algorithm
+context, it always has to be backed up by a neutral pure C one. This implies
+certain limitations.
+
+The most common way to resolve this conflict is to opt for
+short inline assembly function-like snippets, customarily implemented as
+macros, so that they can be easily interchanged with other platform-specific or
+neutral code. As with any macro, try to implement it as single expression.
+You may need to mark your asm statement as volatile, to prevent GCC from
+removing it if GCC doesn’t notice any side effects. You don’t always need to do
+so, though, and doing so unnecessarily can limit optimization.
+
+When writing a single inline assembly statement containing multiple
+instructions, put each instruction on a separate line in a separate quoted
+string, and end each string except the last with \n\t to properly indent the
+next instruction in the assembly output:
+
+```
+asm ("magic %reg1, #42\n\t"
+ "more_magic %reg2, %reg3"
+ : /* outputs */ : /* inputs */ : /* clobbers */);
+```
+
+Large, non-trivial assembly functions go in pure assembly modules, with
+corresponding C prototypes defined in C. The preferred way to implement this is
+so-called “perlasm”: instead of writing real .s file, you write a perl script
+that generates one. This allows use symbolic names for variables (register as
+well as locals allocated on stack) that are independent on specific assembler.
+It simplifies implementation of recurring instruction sequences with regular
+permutation of inputs. By adhering to specific coding rules, perlasm is also
+used to support multiple ABIs and assemblers, see crypto/perlasm/x86_64-
+xlate.pl for an example.
+
+Another option for processor-specific (primarily SIMD) capabilities is called
+compiler intrinsics. We avoid this, because it’s not very much less complicated
+than coding pure assembly, and it doesn’t provide the same performance
+guarantee across different micro-architecture. Nor is it portable enough to
+meet our multi-platform support goals.
+
+## Asserts
+We have 3 kind of asserts. The behaviour depends on being a debug or release
+build:
+```
+Function failure release failure debug success release success debug
+assert not evaluated abort not evaluated nothing
+ossl_assert returns 0 abort returns 1 returns 1
+OPENSSL_assert abort abort nothing nothing
+```
+
+Use OPENSSL_assert() only in the following cases:
+
+* In the libraries when the global state of the software is corrupted and
+ there is no way to recover it
+* In applications, test programs and fuzzers
+
+Use ossl_assert() in the libraries when the state can be recovered and an error
+can be returned. Example code:
+
+```
+if (!ossl_assert(!should_not_happen)) {
+ /* push internal error onto error stack */
+ return BAD;
+}
+```
+
+Use assert() in libraries when no error can be returned, and what you are checking
+is not a run-time dependent condition (such as failure to allocate resources or open
+a file) but a programmer error.