diff --git a/core/crypto/_chacha20/chacha20.odin b/core/crypto/_chacha20/chacha20.odin index 7d94d8a95..40ca9fb25 100644 --- a/core/crypto/_chacha20/chacha20.odin +++ b/core/crypto/_chacha20/chacha20.odin @@ -1,5 +1,6 @@ package _chacha20 +import "base:intrinsics" import "core:crypto" import "core:encoding/endian" import "core:math/bits" @@ -108,11 +109,16 @@ check_counter_limit :: proc(ctx: ^Context, nr_blocks: int) { ctr_ok: bool if ctx._is_ietf_flavor { - ctr_ok = u64(ctx._s[12]) + u64(nr_blocks) <= MAX_CTR_IETF + if intrinsics.unlikely(ctx._s[12] == MAX_CTR_IETF && nr_blocks > 1) { + // Allow the final block. + ctr_ok = false + } else { + ctr_ok = u64(ctx._s[12]) + u64(nr_blocks) <= MAX_CTR_IETF + } } else { ctr := (u64(ctx._s[13]) << 32) | u64(ctx._s[12]) - _, carry := bits.add_u64(ctr, u64(nr_blocks), 0) - ctr_ok = carry == 0 + new_ctr, carry := bits.add_u64(ctr, u64(nr_blocks), 0) + ctr_ok = carry == 0 || new_ctr != 0 // Allow the final block. } ensure(ctr_ok, "crypto/chacha20: maximum (X)ChaCha20 keystream per IV reached") diff --git a/core/crypto/kmac/kmac.odin b/core/crypto/kmac/kmac.odin index f0c27739a..f09176edc 100644 --- a/core/crypto/kmac/kmac.odin +++ b/core/crypto/kmac/kmac.odin @@ -35,6 +35,10 @@ sum :: proc(sec_strength: int, dst, msg, key, domain_sep: []byte) { // strength, key and domain separator over msg and return true if and only if (⟺) the // tag is valid. verify :: proc(sec_strength: int, tag, msg, key, domain_sep: []byte, allocator := context.temp_allocator) -> bool { + if len(tag) < MIN_TAG_SIZE { + return false + } + derived_tag := make([]byte, len(tag), allocator) defer(delete(derived_tag)) diff --git a/core/crypto/mlkem/api.odin b/core/crypto/mlkem/api.odin index 3e3956ba8..6cbbd3249 100644 --- a/core/crypto/mlkem/api.odin +++ b/core/crypto/mlkem/api.odin @@ -269,7 +269,7 @@ params :: proc(k: ^$T) -> Parameters where (T == Encapsulation_Key || T == Decap @(require_results) key_size :: proc(k: ^$T) -> int where (T == Encapsulation_Key || T == Decapsulation_Key) { when T == Encapsulation_Key { - return ENCAPSULATION_KEY_SIZES[k.pke_ek.k] + return ENCAPSULATION_KEY_SIZES[params(k)] } else { return DECAPSULATION_KEY_SEED_SIZE } diff --git a/core/crypto/noise/protocol.odin b/core/crypto/noise/protocol.odin index 7327e638b..4bbe858da 100644 --- a/core/crypto/noise/protocol.odin +++ b/core/crypto/noise/protocol.odin @@ -217,7 +217,7 @@ cipherstate_encrypt_with_ad :: proc(self: ^Cipher_State, ad, plaintext, dst: []b } _encrypt(&self.ctx, self.n, ad, plaintext, dst) self.n += 1 - if self.n == 0 { + if self.n == max(u64) { self.n_exhausted = true } } else { @@ -249,7 +249,7 @@ cipherstate_decrypt_with_ad :: proc(self: ^Cipher_State, ad, ciphertext, dst: [] return nil, status } self.n += 1 - if self.n == 0 { + if self.n == max(u64) { self.n_exhausted = true } } else { diff --git a/core/crypto/pbkdf2/pbkdf2.odin b/core/crypto/pbkdf2/pbkdf2.odin index c27ec4aa2..ef7fda0d5 100644 --- a/core/crypto/pbkdf2/pbkdf2.odin +++ b/core/crypto/pbkdf2/pbkdf2.odin @@ -19,6 +19,8 @@ derive :: proc( iterations: u32, dst: []byte, ) { + ensure(iterations > 0, "crypto/pbkdf2: non-zero iterations required") + h_len := hash.DIGEST_SIZES[hmac_hash] // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long"