Browse Source

core/crypto: Enforce aliasing restrictions

Yawning Angel 1 year ago
parent
commit
ff13ee3281
3 changed files with 17 additions and 6 deletions
  1. 5 3
      core/crypto/aes/aes_ctr.odin
  2. 7 0
      core/crypto/aes/aes_gcm.odin
  3. 5 3
      core/crypto/chacha20/chacha20.odin

+ 5 - 3
core/crypto/aes/aes_ctr.odin

@@ -1,5 +1,6 @@
 package aes
 
+import "core:bytes"
 import "core:crypto/_aes/ct64"
 import "core:encoding/endian"
 import "core:math/bits"
@@ -37,14 +38,15 @@ init_ctr :: proc(ctx: ^Context_CTR, key, iv: []byte, impl := Implementation.Hard
 xor_bytes_ctr :: proc(ctx: ^Context_CTR, dst, src: []byte) {
 	assert(ctx._is_initialized)
 
-	// TODO: Enforcing that dst and src alias exactly or not at all
-	// is a good idea, though odd aliasing should be extremely uncommon.
-
 	src, dst := src, dst
 	if dst_len := len(dst); dst_len < len(src) {
 		src = src[:dst_len]
 	}
 
+	if bytes.alias_inexactly(dst, src) {
+		panic("crypto/aes: dst and src alias inexactly")
+	}
+
 	for remaining := len(src); remaining > 0; {
 		// Process multiple blocks at once
 		if ctx._off == BLOCK_SIZE {

+ 7 - 0
core/crypto/aes/aes_gcm.odin

@@ -1,5 +1,6 @@
 package aes
 
+import "core:bytes"
 import "core:crypto"
 import "core:crypto/_aes"
 import "core:crypto/_aes/ct64"
@@ -39,6 +40,9 @@ seal_gcm :: proc(ctx: ^Context_GCM, dst, tag, nonce, aad, plaintext: []byte) {
 	if len(dst) != len(plaintext) {
 		panic("crypto/aes: invalid destination ciphertext size")
 	}
+	if bytes.alias_inexactly(dst, plaintext) {
+		panic("crypto/aes: dst and plaintext alias inexactly")
+	}
 
 	if impl, is_hw := ctx._impl.(Context_Impl_Hardware); is_hw {
 		gcm_seal_hw(&impl, dst, tag, nonce, aad, plaintext)
@@ -73,6 +77,9 @@ open_gcm :: proc(ctx: ^Context_GCM, dst, nonce, aad, ciphertext, tag: []byte) ->
 	if len(dst) != len(ciphertext) {
 		panic("crypto/aes: invalid destination plaintext size")
 	}
+	if bytes.alias_inexactly(dst, ciphertext) {
+		panic("crypto/aes: dst and ciphertext alias inexactly")
+	}
 
 	if impl, is_hw := ctx._impl.(Context_Impl_Hardware); is_hw {
 		return gcm_open_hw(&impl, dst, nonce, aad, ciphertext, tag)

+ 5 - 3
core/crypto/chacha20/chacha20.odin

@@ -7,6 +7,7 @@ See:
 */
 package chacha20
 
+import "core:bytes"
 import "core:encoding/endian"
 import "core:math/bits"
 import "core:mem"
@@ -121,14 +122,15 @@ seek :: proc(ctx: ^Context, block_nr: u64) {
 xor_bytes :: proc(ctx: ^Context, dst, src: []byte) {
 	assert(ctx._is_initialized)
 
-	// TODO: Enforcing that dst and src alias exactly or not at all
-	// is a good idea, though odd aliasing should be extremely uncommon.
-
 	src, dst := src, dst
 	if dst_len := len(dst); dst_len < len(src) {
 		src = src[:dst_len]
 	}
 
+	if bytes.alias_inexactly(dst, src) {
+		panic("crypto/chacha20: dst and src alias inexactly")
+	}
+
 	for remaining := len(src); remaining > 0; {
 		// Process multiple blocks at once
 		if ctx._off == _BLOCK_SIZE {