diff options
| author | Yawning Angel <yawning@schwanenlied.me> | 2023-11-16 12:51:49 +0900 |
|---|---|---|
| committer | Yawning Angel <yawning@schwanenlied.me> | 2023-11-17 19:31:51 +0900 |
| commit | e86bb3a7955b4ab116ce427c6beb99f3053c40ec (patch) | |
| tree | 89127dfcdd679ddcd14716995e571fbeaa770ebc /core/crypto | |
| parent | e3a836f93c21b1a6da4cdec411b55c5886b778da (diff) | |
core/crypto: Change hash asserts to panics
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.
Diffstat (limited to 'core/crypto')
| -rw-r--r-- | core/crypto/_blake2/blake2.odin | 8 | ||||
| -rw-r--r-- | core/crypto/_sha3/sha3.odin | 8 | ||||
| -rw-r--r-- | core/crypto/blake2b/blake2b.odin | 3 | ||||
| -rw-r--r-- | core/crypto/blake2s/blake2s.odin | 3 | ||||
| -rw-r--r-- | core/crypto/keccak/keccak.odin | 18 | ||||
| -rw-r--r-- | core/crypto/md5/md5.odin | 5 | ||||
| -rw-r--r-- | core/crypto/sha1/sha1.odin | 5 | ||||
| -rw-r--r-- | core/crypto/sha2/sha2.odin | 20 | ||||
| -rw-r--r-- | core/crypto/sha3/sha3.odin | 18 | ||||
| -rw-r--r-- | core/crypto/shake/shake.odin | 8 | ||||
| -rw-r--r-- | core/crypto/siphash/siphash.odin | 28 | ||||
| -rw-r--r-- | core/crypto/sm3/sm3.odin | 5 |
12 files changed, 44 insertions, 85 deletions
diff --git a/core/crypto/_blake2/blake2.odin b/core/crypto/_blake2/blake2.odin index c1b5c5dad..a522a390e 100644 --- a/core/crypto/_blake2/blake2.odin +++ b/core/crypto/_blake2/blake2.odin @@ -180,11 +180,17 @@ update :: proc "contextless" (ctx: ^$T, p: []byte) { ctx.nx += copy(ctx.x[ctx.nx:], p) } -final :: proc "contextless" (ctx: ^$T, hash: []byte) { +final :: proc(ctx: ^$T, hash: []byte) { when T == Blake2s_Context { + if len(hash) < BLAKE2S_SIZE { + panic("crypto/blake2s: invalid destination digest size") + } blake2s_final(ctx, hash) } when T == Blake2b_Context { + if len(hash) < BLAKE2B_SIZE { + panic("crypto/blake2b: invalid destination digest size") + } blake2b_final(ctx, hash) } } diff --git a/core/crypto/_sha3/sha3.odin b/core/crypto/_sha3/sha3.odin index f66ed09e3..917a763c1 100644 --- a/core/crypto/_sha3/sha3.odin +++ b/core/crypto/_sha3/sha3.odin @@ -121,7 +121,13 @@ update :: proc "contextless" (c: ^Sha3_Context, data: []byte) { c.pt = j } -final :: proc "contextless" (c: ^Sha3_Context, hash: []byte) { +final :: proc(c: ^Sha3_Context, hash: []byte) { + if len(hash) < c.mdlen { + if c.is_keccak { + panic("crypto/keccac: invalid destination digest size") + } + panic("crypto/sha3: invalid destination digest size") + } if c.is_keccak { c.st.b[c.pt] ~= 0x01 } else { diff --git a/core/crypto/blake2b/blake2b.odin b/core/crypto/blake2b/blake2b.odin index caa1758fe..17e40ad9c 100644 --- a/core/crypto/blake2b/blake2b.odin +++ b/core/crypto/blake2b/blake2b.odin @@ -53,7 +53,6 @@ hash_string_to_buffer :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer :: proc(data, hash: []byte) { - assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") ctx: _blake2.Blake2b_Context cfg: _blake2.Blake2_Config cfg.size = _blake2.BLAKE2B_SIZE @@ -122,6 +121,6 @@ update :: proc "contextless" (ctx: ^_blake2.Blake2b_Context, data: []byte) { _blake2.update(ctx, data) } -final :: proc "contextless" (ctx: ^_blake2.Blake2b_Context, hash: []byte) { +final :: proc(ctx: ^_blake2.Blake2b_Context, hash: []byte) { _blake2.final(ctx, hash) } diff --git a/core/crypto/blake2s/blake2s.odin b/core/crypto/blake2s/blake2s.odin index db9dcab38..1f607ffdd 100644 --- a/core/crypto/blake2s/blake2s.odin +++ b/core/crypto/blake2s/blake2s.odin @@ -54,7 +54,6 @@ hash_string_to_buffer :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer :: proc(data, hash: []byte) { - assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") ctx: _blake2.Blake2s_Context cfg: _blake2.Blake2_Config cfg.size = _blake2.BLAKE2S_SIZE @@ -122,6 +121,6 @@ update :: proc "contextless" (ctx: ^_blake2.Blake2s_Context, data: []byte) { _blake2.update(ctx, data) } -final :: proc "contextless" (ctx: ^_blake2.Blake2s_Context, hash: []byte) { +final :: proc(ctx: ^_blake2.Blake2s_Context, hash: []byte) { _blake2.final(ctx, hash) } diff --git a/core/crypto/keccak/keccak.odin b/core/crypto/keccak/keccak.odin index fc9131fa3..6e63af80f 100644 --- a/core/crypto/keccak/keccak.odin +++ b/core/crypto/keccak/keccak.odin @@ -56,10 +56,6 @@ hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_224, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_224 ctx.is_keccak = true @@ -141,10 +137,6 @@ hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_256, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_256 ctx.is_keccak = true @@ -226,10 +218,6 @@ hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_384, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_384 ctx.is_keccak = true @@ -311,10 +299,6 @@ hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_512, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_512 ctx.is_keccak = true @@ -381,6 +365,6 @@ update :: proc "contextless" (ctx: ^_sha3.Sha3_Context, data: []byte) { _sha3.update(ctx, data) } -final :: proc "contextless" (ctx: ^_sha3.Sha3_Context, hash: []byte) { +final :: proc(ctx: ^_sha3.Sha3_Context, hash: []byte) { _sha3.final(ctx, hash) } diff --git a/core/crypto/md5/md5.odin b/core/crypto/md5/md5.odin index e451afd20..05602c249 100644 --- a/core/crypto/md5/md5.odin +++ b/core/crypto/md5/md5.odin @@ -50,7 +50,6 @@ hash_string_to_buffer :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer :: proc(data, hash: []byte) { - assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") ctx: Md5_Context init(&ctx) update(&ctx, data) @@ -125,6 +124,10 @@ update :: proc(ctx: ^Md5_Context, data: []byte) { } final :: proc(ctx: ^Md5_Context, hash: []byte) { + if len(hash) < DIGEST_SIZE { + panic("crypto/md5: invalid destination digest size") + } + i := ctx.datalen if ctx.datalen < 56 { diff --git a/core/crypto/sha1/sha1.odin b/core/crypto/sha1/sha1.odin index c2cee8098..0d85a61f9 100644 --- a/core/crypto/sha1/sha1.odin +++ b/core/crypto/sha1/sha1.odin @@ -50,7 +50,6 @@ hash_string_to_buffer :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer :: proc(data, hash: []byte) { - assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") ctx: Sha1_Context init(&ctx) update(&ctx, data) @@ -130,6 +129,10 @@ update :: proc(ctx: ^Sha1_Context, data: []byte) { } final :: proc(ctx: ^Sha1_Context, hash: []byte) { + if len(hash) < DIGEST_SIZE { + panic("crypto/sha1: invalid destination digest size") + } + i := ctx.datalen if ctx.datalen < 56 { diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin index 7f87c4aa2..47ede9cf4 100644 --- a/core/crypto/sha2/sha2.odin +++ b/core/crypto/sha2/sha2.odin @@ -55,10 +55,6 @@ hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_224, - "Size of destination buffer is smaller than the digest size", - ) ctx: Sha256_Context ctx.md_bits = 224 init(&ctx) @@ -137,10 +133,6 @@ hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_256, - "Size of destination buffer is smaller than the digest size", - ) ctx: Sha256_Context ctx.md_bits = 256 init(&ctx) @@ -219,10 +211,6 @@ hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_384, - "Size of destination buffer is smaller than the digest size", - ) ctx: Sha512_Context ctx.md_bits = 384 init(&ctx) @@ -301,10 +289,6 @@ hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_512, - "Size of destination buffer is smaller than the digest size", - ) ctx: Sha512_Context ctx.md_bits = 512 init(&ctx) @@ -445,6 +429,10 @@ update :: proc(ctx: ^$T, data: []byte) { final :: proc(ctx: ^$T, hash: []byte) { block_nb, pm_len, len_b: u32 + if len(hash) * 8 < ctx.md_bits { + panic("crypto/sha2: invalid destination digest size") + } + when T == Sha256_Context {CURR_BLOCK_SIZE :: SHA256_BLOCK_SIZE} else when T == Sha512_Context {CURR_BLOCK_SIZE :: SHA512_BLOCK_SIZE} when T == Sha256_Context {block_nb = 1 + ((CURR_BLOCK_SIZE - 9) < (ctx.length % CURR_BLOCK_SIZE) ? 1 : 0)} else when T == Sha512_Context {block_nb = 1 + ((CURR_BLOCK_SIZE - 17) < (ctx.length % CURR_BLOCK_SIZE) ? 1 : 0)} diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index 6b7ad04a1..7dcaf211b 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -54,10 +54,6 @@ hash_string_to_buffer_224 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_224 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_224, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_224 _sha3.init(&ctx) @@ -136,10 +132,6 @@ hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_256, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_256 _sha3.init(&ctx) @@ -218,10 +210,6 @@ hash_string_to_buffer_384 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_384 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_384, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_384 _sha3.init(&ctx) @@ -300,10 +288,6 @@ hash_string_to_buffer_512 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_512 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_512, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_512 _sha3.init(&ctx) @@ -367,6 +351,6 @@ update :: proc "contextless" (ctx: ^_sha3.Sha3_Context, data: []byte) { _sha3.update(ctx, data) } -final :: proc "contextless" (ctx: ^_sha3.Sha3_Context, hash: []byte) { +final :: proc(ctx: ^_sha3.Sha3_Context, hash: []byte) { _sha3.final(ctx, hash) } diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index 70755069a..dc7eb3387 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -53,10 +53,6 @@ hash_string_to_buffer_128 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_128 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_128, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_128 _sha3.init(&ctx) @@ -138,10 +134,6 @@ hash_string_to_buffer_256 :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer_256 :: proc(data, hash: []byte) { - assert( - len(hash) >= DIGEST_SIZE_256, - "Size of destination buffer is smaller than the digest size", - ) ctx: _sha3.Sha3_Context ctx.mdlen = DIGEST_SIZE_256 _sha3.init(&ctx) diff --git a/core/crypto/siphash/siphash.odin b/core/crypto/siphash/siphash.odin index ab6532e4d..c51e38ab0 100644 --- a/core/crypto/siphash/siphash.odin +++ b/core/crypto/siphash/siphash.odin @@ -49,10 +49,6 @@ sum_string_to_buffer_1_3 :: proc(msg, key: string, dst: []byte) { // sum_bytes_to_buffer_1_3 will hash the given message with the key and write // the computed hash into the provided destination buffer sum_bytes_to_buffer_1_3 :: proc(msg, key, dst: []byte) { - assert( - len(dst) >= DIGEST_SIZE, - "crypto/siphash: Destination buffer needs to be at least of size 8", - ) hash := sum_bytes_1_3(msg, key) _collect_output(dst[:], hash) } @@ -109,10 +105,6 @@ sum_string_to_buffer_2_4 :: proc(msg, key: string, dst: []byte) { // sum_bytes_to_buffer_2_4 will hash the given message with the key and write // the computed hash into the provided destination buffer sum_bytes_to_buffer_2_4 :: proc(msg, key, dst: []byte) { - assert( - len(dst) >= DIGEST_SIZE, - "crypto/siphash: Destination buffer needs to be at least of size 8", - ) hash := sum_bytes_2_4(msg, key) _collect_output(dst[:], hash) } @@ -187,10 +179,6 @@ sum_string_to_buffer_4_8 :: proc(msg, key: string, dst: []byte) { // sum_bytes_to_buffer_4_8 will hash the given message with the key and write // the computed hash into the provided destination buffer sum_bytes_to_buffer_4_8 :: proc(msg, key, dst: []byte) { - assert( - len(dst) >= DIGEST_SIZE, - "crypto/siphash: Destination buffer needs to be at least of size 8", - ) hash := sum_bytes_4_8(msg, key) _collect_output(dst[:], hash) } @@ -226,17 +214,18 @@ verify_4_8 :: proc { */ init :: proc(ctx: ^Context, key: []byte, c_rounds, d_rounds: int) { - assert(len(key) == KEY_SIZE, "crypto/siphash: Invalid key size, want 16") + if len(key) != KEY_SIZE { + panic("crypto/siphash; invalid key size") + } ctx.c_rounds = c_rounds ctx.d_rounds = d_rounds is_valid_setting := (ctx.c_rounds == 1 && ctx.d_rounds == 3) || (ctx.c_rounds == 2 && ctx.d_rounds == 4) || (ctx.c_rounds == 4 && ctx.d_rounds == 8) - assert( - is_valid_setting, - "crypto/siphash: Incorrect rounds set up. Valid pairs are (1,3), (2,4) and (4,8)", - ) + if !is_valid_setting { + panic("crypto/siphash: incorrect rounds set up") + } ctx.k0 = endian.unchecked_get_u64le(key[:8]) ctx.k1 = endian.unchecked_get_u64le(key[8:]) ctx.v0 = 0x736f6d6570736575 ~ ctx.k0 @@ -341,7 +330,10 @@ _get_byte :: #force_inline proc "contextless" (byte_num: byte, into: u64) -> byt } @(private) -_collect_output :: #force_inline proc "contextless" (dst: []byte, hash: u64) { +_collect_output :: #force_inline proc(dst: []byte, hash: u64) { + if len(dst) < DIGEST_SIZE { + panic("crypto/siphash: invalid tag size") + } dst[0] = _get_byte(7, hash) dst[1] = _get_byte(6, hash) dst[2] = _get_byte(5, hash) diff --git a/core/crypto/sm3/sm3.odin b/core/crypto/sm3/sm3.odin index d12b254f7..4474af69b 100644 --- a/core/crypto/sm3/sm3.odin +++ b/core/crypto/sm3/sm3.odin @@ -49,7 +49,6 @@ hash_string_to_buffer :: proc(data: string, hash: []byte) { // computed hash into the second parameter. // It requires that the destination buffer is at least as big as the digest size hash_bytes_to_buffer :: proc(data, hash: []byte) { - assert(len(hash) >= DIGEST_SIZE, "Size of destination buffer is smaller than the digest size") ctx: Sm3_Context init(&ctx) update(&ctx, data) @@ -139,6 +138,10 @@ update :: proc(ctx: ^Sm3_Context, data: []byte) { } final :: proc(ctx: ^Sm3_Context, hash: []byte) { + if len(hash) < DIGEST_SIZE { + panic("crypto/sm3: invalid destination digest size") + } + length := ctx.length pad: [BLOCK_SIZE]byte |