zuc: eea, fix can't src/dst can't use same buffer issue #169

This commit is contained in:
emmansun 2023-09-29 09:57:27 +08:00
parent 5b3dfb6fa7
commit 400147ed3c
5 changed files with 23 additions and 42 deletions

View File

@ -237,11 +237,3 @@ func (s *zucState32) genKeywords(words []uint32) {
} }
genKeyStream(words, s) genKeyStream(words, s)
} }
func genKeyStreamRev32(keyStream []byte, pState *zucState32) {
for len(keyStream) >= 4 {
z := genKeyword(pState)
binary.BigEndian.PutUint32(keyStream, z)
keyStream = keyStream[4:]
}
}

View File

@ -25,7 +25,21 @@ func NewEEACipher(key []byte, count, bearer, direction uint32) (cipher.Stream, e
return newZUCState(key, iv) return newZUCState(key, iv)
} }
func xorKeyStreamGeneric(c *zucState32, dst, src []byte) { func genKeyStreamRev32Generic(keyStream []byte, pState *zucState32) {
for len(keyStream) >= 4 {
z := genKeyword(pState)
binary.BigEndian.PutUint32(keyStream, z)
keyStream = keyStream[4:]
}
}
func (c *zucState32) XORKeyStream(dst, src []byte) {
if len(dst) < len(src) {
panic("zuc: output smaller than input")
}
if alias.InexactOverlap(dst[:len(src)], src) {
panic("zuc: invalid buffer overlap")
}
words := (len(src) + 3) / 4 words := (len(src) + 3) / 4
rounds := words / RoundWords rounds := words / RoundWords
var keyBytes [RoundWords * 4]byte var keyBytes [RoundWords * 4]byte
@ -40,13 +54,3 @@ func xorKeyStreamGeneric(c *zucState32, dst, src []byte) {
subtle.XORBytes(dst, src, keyBytes[:]) subtle.XORBytes(dst, src, keyBytes[:])
} }
} }
func (c *zucState32) XORKeyStream(dst, src []byte) {
if len(dst) < len(src) {
panic("zuc: output smaller than input")
}
if alias.InexactOverlap(dst[:len(src)], src) {
panic("zuc: invalid buffer overlap")
}
xorKeyStream(c, dst, src)
}

View File

@ -3,29 +3,13 @@
package zuc package zuc
import (
"github.com/emmansun/gmsm/internal/subtle"
)
//go:noescape //go:noescape
func genKeyStreamRev32Asm(keyStream []byte, pState *zucState32) func genKeyStreamRev32Asm(keyStream []byte, pState *zucState32)
func xorKeyStream(c *zucState32, dst, src []byte) { func genKeyStreamRev32(keyStream []byte, pState *zucState32) {
if supportsAES { if supportsAES {
words := len(src) / 4 genKeyStreamRev32Asm(keyStream, pState)
// handle complete words first
if words > 0 {
dstWords := dst[:words*4]
genKeyStreamRev32Asm(dstWords, c)
subtle.XORBytes(dst, src, dstWords)
}
// handle remain bytes
if words*4 < len(src) {
var singleWord [4]byte
genKeyStreamRev32Asm(singleWord[:], c)
subtle.XORBytes(dst[words*4:], src[words*4:], singleWord[:])
}
} else { } else {
xorKeyStreamGeneric(c, dst, src) genKeyStreamRev32Generic(keyStream, pState)
} }
} }

View File

@ -3,6 +3,6 @@
package zuc package zuc
func xorKeyStream(c *zucState32, dst, src []byte) { func genKeyStreamRev32(keyStream []byte, pState *zucState32) {
xorKeyStreamGeneric(c, dst, src) genKeyStreamRev32Generic(keyStream, pState)
} }

View File

@ -50,11 +50,12 @@ func Test_EEA(t *testing.T) {
t.Error(err) t.Error(err)
} }
in, err := hex.DecodeString(test.in) in, err := hex.DecodeString(test.in)
out := make([]byte, len(in))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
c.XORKeyStream(out, in) out := make([]byte, len(in))
copy(out, in)
c.XORKeyStream(out, out)
if hex.EncodeToString(out) != test.out { if hex.EncodeToString(out) != test.out {
t.Errorf("case %d, expected=%s, result=%s\n", i+1, test.out, hex.EncodeToString(out)) t.Errorf("case %d, expected=%s, result=%s\n", i+1, test.out, hex.EncodeToString(out))
} }