HmacSha256.apply hands a zeroed array to HMAC and never checks what comes back:
let arr = Array[U8].init(0, size)
@HMAC(@EVP_sha256(), key.cpointer(), key.size().i32(),
data.cpointer(), data.size(), arr.cpointer(), Pointer[U32])
arr
HMAC returns NULL when it fails. apply returns arr either way, and the caller gets no error.
When HMAC fails before writing anything, and an allocation failure inside it is the ordinary case, arr still holds the 32 zero bytes it was initialized with. apply hands those back as the MAC. A MAC of 32 zero bytes is one an attacker can supply: a verifier that compares the result against an attacker-supplied value accepts, and ConstantTimeCompare reports the two equal.
apply returns Array[U8] val and is not partial, so it cannot report the failure without a breaking signature change.
HmacSha256.applyhands a zeroed array toHMACand never checks what comes back:HMACreturns NULL when it fails.applyreturnsarreither way, and the caller gets no error.When
HMACfails before writing anything, and an allocation failure inside it is the ordinary case,arrstill holds the 32 zero bytes it was initialized with.applyhands those back as the MAC. A MAC of 32 zero bytes is one an attacker can supply: a verifier that compares the result against an attacker-supplied value accepts, andConstantTimeComparereports the two equal.applyreturnsArray[U8] valand is not partial, so it cannot report the failure without a breaking signature change.