mask.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in the
  3. // LICENSE file.
  4. //go:build !appengine
  5. // +build !appengine
  6. package websocket
  7. import "unsafe"
  8. // #nosec G103 -- (CWE-242) Has been audited
  9. const wordSize = int(unsafe.Sizeof(uintptr(0)))
  10. func maskBytes(key [4]byte, pos int, b []byte) int {
  11. // Mask one byte at a time for small buffers.
  12. if len(b) < 2*wordSize {
  13. for i := range b {
  14. b[i] ^= key[pos&3]
  15. pos++
  16. }
  17. return pos & 3
  18. }
  19. // Mask one byte at a time to word boundary.
  20. //#nosec G103 -- (CWE-242) Has been audited
  21. if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 {
  22. n = wordSize - n
  23. for i := range b[:n] {
  24. b[i] ^= key[pos&3]
  25. pos++
  26. }
  27. b = b[n:]
  28. }
  29. // Create aligned word size key.
  30. var k [wordSize]byte
  31. for i := range k {
  32. k[i] = key[(pos+i)&3]
  33. }
  34. //#nosec G103 -- (CWE-242) Has been audited
  35. kw := *(*uintptr)(unsafe.Pointer(&k))
  36. // Mask one word at a time.
  37. n := (len(b) / wordSize) * wordSize
  38. for i := 0; i < n; i += wordSize {
  39. //#nosec G103 -- (CWE-242) Has been audited
  40. *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw
  41. }
  42. // Mask one byte at a time for remaining bytes.
  43. b = b[n:]
  44. for i := range b {
  45. b[i] ^= key[pos&3]
  46. pos++
  47. }
  48. return pos & 3
  49. }