So here is a more verbose explanation of some of the most common problems I'm seeing:
explicit_bzero() isn't.This function needs to ensure it cannot be optimized out. However, several projects are either using macros to define explicit_bzero as bzero, or are wrapping explicit_bzero() to bzero() without using any optimization parameters which will ensure the function call stays in. Especially problematic in the case of using link-time optimizations (LTO).
reallocarray() directly wrapped to realloc()The former function receives the size of the element, and how many elements we're dealing with, and the latter just takes a raw amount. It's a good thing to use reallocarray() when you need to reallocate say a struct whatever to a struct whatever, so you can pass sizeof(struct whatever) and 30000 as two separate parameters, as opposed to calulcating sizeof(struct whatever)*30000 which may overflow. But the naive implementations are just directly wrapping to realloc(), reintroducing the problem that reallocarray() is supposed to be fixing.
There's also issues of alignment to consider when blindly multiplying where small values are concerned, but I won't go into them here.
Poor arc4random_buf() implementationsThis function is supposed to fill a buffer using a cryptographically secure pseudorandom number generator. However, I'm seeing a whole class of dumbness here:
- Using classical pseudorandom number generators.
- Using older less secure implementations.
- Using poor sources of entropy like /dev/urandom on Linux, or worse, gettimeofday(), and using them to generate long-lived keys.
OpenBSD functions may be more secure than counterparts elsewhere
This is a generic issue where OpenBSD is deleting some silly platform wrappers, or reducing multiple functions calls with glue logic down to a single standardized function. OpenBSD is depending on the security of their implementation of said function, while the porters have no idea that their platform is less secure, and have no inkling that something is wrong, because there are no compiler errors about missing functions in this scenario. One common case where this scenario is true is with the calloc() function, where the OpenBSD implementation checks for issues, but several other platforms unfortunately do not.
The futureI've actually predicted all the above problems would appear in ports once I saw what OpenBSD is doing to OpenSSL, before any of the ports of LibreSSL became public. There's a couple of other significant mistakes I'm expecting to see appear in LibreSSL ports, but have not seen yet. These probably already exists in ports I haven't reviewed, or will exist in the wild soon enough. Chief among them is implementing timingsafe_bcmp(). I'm expecting to see implementations which directly wrap to regular bcmp(), which unlike the former, is not performed in constant-time, and can expose the application to timing attacks. I'm confident in this because it's not the first time I've seen OpenBSD projects ported, and all these issues exist till this day in various projects in the wild. If you're going to port a project, please take a moment to really understand the functions you're porting, reviewing the manpages and all the comments in the source code, and truly understanding the ramifications of what you're doing.
As I said before, avoid any LibreSSL port which is not from the LibreSSL team itself, or from another team with a proven track record for knowing how to develop a secure environment.
Lastly, here's some Google searches which may turn up some of the issues mentioned here, but is by no means exhaustive: