@@ -105,7 +105,14 @@ func safeANDBytes(dst, a, b []byte) int {
105105
106106// ORBytes ors the bytes in a and b. The destination is assumed to have enough
107107// space. Returns the number of bytes or'd.
108+ //
109+ // dst and x or y may overlap exactly or not at all,
110+ // otherwise ORBytes may panic.
108111func ORBytes (dst , a , b []byte ) int {
112+ n := min (len (a ), len (b ))
113+ if inexactOverlap (dst [:n ], a [:n ]) || inexactOverlap (dst [:n ], b [:n ]) {
114+ panic ("ORBytes: invalid overlap" )
115+ }
109116 return orBytes (dst , a , b )
110117}
111118
@@ -161,3 +168,26 @@ func safeTestBytes(p []byte) bool {
161168 }
162169 return false
163170}
171+
172+ // anyOverlap reports whether x and y share memory at any (not necessarily
173+ // corresponding) index. The memory beyond the slice length is ignored.
174+ // from: https://github.com/golang/go/blob/4a3cef2036097d323b6cc0bbe90fc4d8c7588660/src/crypto/internal/fips140/alias/alias.go#L13-L17
175+ func anyOverlap (x , y []byte ) bool {
176+ return len (x ) > 0 && len (y ) > 0 &&
177+ uintptr (unsafe .Pointer (& x [0 ])) <= uintptr (unsafe .Pointer (& y [len (y )- 1 ])) &&
178+ uintptr (unsafe .Pointer (& y [0 ])) <= uintptr (unsafe .Pointer (& x [len (x )- 1 ]))
179+ }
180+
181+ // inexactOverlap reports whether x and y share memory at any non-corresponding
182+ // index. The memory beyond the slice length is ignored. Note that x and y can
183+ // have different lengths and still not have any inexact overlap.
184+ //
185+ // inexactOverlap can be used to implement the requirements of the crypto/cipher
186+ // AEAD, Block, BlockMode and Stream interfaces.
187+ // from: https://github.com/golang/go/blob/4a3cef2036097d323b6cc0bbe90fc4d8c7588660/src/crypto/internal/fips140/alias/alias.go#L25-L30
188+ func inexactOverlap (x , y []byte ) bool {
189+ if len (x ) == 0 || len (y ) == 0 || & x [0 ] == & y [0 ] {
190+ return false
191+ }
192+ return anyOverlap (x , y )
193+ }
0 commit comments