The LLVM intrinsics that live under `llvm.x86` are not actual functions,
so trying to invoke them as such using the platform's native C
calling convention causes incorrect types to be emitted in the IR.
Thanks to laytanl for assistance in testing.
`llvm_features` being empty is the default state, and implies the
presence of certain features.
Previously if any target features were explicitly enabled by the
`enable_target_feature` attribute, they were added comma separated
to `llvm_features`.
For example: `lzcnt,popcnt,...,sse4.2,sse`
This was causing LLVM to try to target a CPU that *ONLY* has the
explicitly enabled features. This now will prefix explicitly enabled
features with a `+`, and preserve the existing `llvm_features` string
by appending to it if it is set.
Multiple constraints on the same line are combined with logical OR,
while combining multiple negated constraints needs to be done with
logical AND (each constraint on a separate line).
- blake2s.Blake2s_Context -> blake2s.Context
- blake2b.Blake2b_Context -> blake2b.Context
- Fix the BLAKE2s low level API (context type was incorrect)
- Support the configurable output size
This is largely modeled off the SM3 versions of these routines, since
the relevant parts of the code are the same between SHA-256 and SM3,
and the alterations required to support SHA-512 are relatively simple.
The prior versions of update and the transform would leak memory, and
doing things this way also reduces the context buffer sizes by 1 block.
Assertions can be disabled, but at the point where cryptographic
anything is involved, a single branch has an infinitesimally small
performance impact.
The correct thing to do is to punch the caller in the face if they do
something that is blatantly incorrect, especially in a security critical
setting.
The `update` and `final` routines were written with the assumption that
update will only be called once, and that the underlying data does not
change between the calls.
- Use `intrinsics.unaligned_load`/`intrinsics.unaligned_store`
- Make all the routines contextless
- Add unchecked variants for code that "Knows What It Is Doing(TM)"
Someone ran into this on Discord, so adopt the same workaround that
chrome did, by checking both OSXSAVE and XSAVE before calling XGETBV.
The old way of detecting AVX is correct per Intel, but such is life.
Recent LLVM is getting smart to the point where the optimizer can change
a traditional constant-time conditional swap into a pointer swap.
Ensure that this does not happen by force-disabling optimization.
Additionally, disable inlining the relevant routines such that manual
inspection in optimized builds is still reasonably easy to do.
This adds `rand_bytes(dst: []byte)` which fills the destination buffer
with entropy from the cryptographic random number generator. This takes
the "simple is best" approach and just directly returns the OS CSPRNG
output instead of doing anything fancy (a la OpenBSD's arc4random).
Linux is in the unfortunate situation where the system call number is
architecture specific. This consolidates the system call number
definitions in a single location, adds some wrappers, and hopefully
fixes the existing non-portable invocations of the syscall intrinsic.
This package implements the ChaCha20 stream cipher as specified in
RFC 8439, and the somewhat non-standard XChaCha20 variant that supports
a 192-bit nonce.
While an IETF draft for XChaCha20 standardization exists,
implementations that pre-date the draft use a 64-bit counter, instead of
the IETF-style 32-bit one. This implementation opts for the latter as
compatibility with libsodium is more important than compatibility with
an expired IETF draft.
Using a constant-time comparison is required when comparing things like
MACs, password digests, and etc to avoid exposing sensitive data via
trivial timing attacks.
These routines could also live under core:mem, but they are somewhat
specialized, and are likely only useful for cryptographic applications.
FreeBSD's systemcall handler clears out R8, R9, and R10 prior to
`sysretq`, and additionally returns positive errno (with CF) set on
error. This modifies the syscall intrinsic such that LLVM knows
about the additional clobbered registers.
Note that propagating CF back to the caller of the syscall intrinsic
is left for a future PR. As far as I can tell, Darwin does not use
the syscall intrinsic at all, and FreeBSD only uses it for SYS_GETTID,
so this should be "ok" for now.
See: sys/amd64/amd64/exception.S in the FreeBSD src for more details.
The old assembly generated for the syscall intrinsic did not specify
clobber constraints. This adds RCX and R11 (that are clobbered by
the instruction itself), and memory (that is clobbered by some
system calls) to the assembly constraints.
Note: This is still incorrect on FreeBSD, which clobbers more registers
and uses the carry flag instead of -errno in rax to indicate an error.
This call is intended to provide the ability to securely scrub memory
without compiler interference, in a similar manner to explicit_bzero,
memset_s, SecureZeroMemory.
The approach taken is a volatile memset followed by a seqentially
consistent memory fence, to prevent the call from being optimized away
by DSE, and from being reordered. An identical approach is currently
being used by the zeroize Rust crate, and is effective in practice.
LLVM IR output:
```
; Function Attrs: nounwind
define internal i8* @mem.zero_explicit(i8* %0, i64 %1) #0 {
decls:
call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 %1, i1 true)
fence seq_cst
ret i8* %0
}
```