mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 20:26:19 +08:00
zuc: eea XORKeyStreamAt fix issue
This commit is contained in:
parent
fcd1aa22d2
commit
379396b688
40
zuc/eea.go
40
zuc/eea.go
@ -10,6 +10,7 @@ import (
|
|||||||
const (
|
const (
|
||||||
RoundWords = 32
|
RoundWords = 32
|
||||||
WordSize = 4
|
WordSize = 4
|
||||||
|
WordMask = WordSize - 1
|
||||||
RoundBytes = RoundWords * WordSize
|
RoundBytes = RoundWords * WordSize
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -86,8 +87,7 @@ func (c *eea) XORKeyStream(dst, src []byte) {
|
|||||||
src = src[RoundBytes:]
|
src = src[RoundBytes:]
|
||||||
}
|
}
|
||||||
if len(src) > 0 {
|
if len(src) > 0 {
|
||||||
words := (len(src) + WordSize - 1) / WordSize
|
byteLen := (len(src) + WordMask) &^ WordMask
|
||||||
byteLen := WordSize * words
|
|
||||||
genKeyStreamRev32(keyBytes[:byteLen], &c.zucState32)
|
genKeyStreamRev32(keyBytes[:byteLen], &c.zucState32)
|
||||||
n := subtle.XORBytes(dst, src, keyBytes[:])
|
n := subtle.XORBytes(dst, src, keyBytes[:])
|
||||||
// save remaining key bytes
|
// save remaining key bytes
|
||||||
@ -115,38 +115,44 @@ func (c *eea) XORKeyStreamAt(dst, src []byte, offset uint64) {
|
|||||||
if offset < c.used {
|
if offset < c.used {
|
||||||
// reset the state to the initial state
|
// reset the state to the initial state
|
||||||
c.reset()
|
c.reset()
|
||||||
} else if offset == c.used {
|
}
|
||||||
|
|
||||||
|
if offset == c.used {
|
||||||
c.XORKeyStream(dst, src)
|
c.XORKeyStream(dst, src)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
diff := offset - c.used
|
offsetDiff := offset - c.used
|
||||||
if diff <= uint64(c.xLen) {
|
if offsetDiff <= uint64(c.xLen) {
|
||||||
c.xLen -= int(diff)
|
c.xLen -= int(offsetDiff)
|
||||||
c.used += diff
|
c.used += offsetDiff
|
||||||
c.XORKeyStream(dst, src)
|
c.XORKeyStream(dst, src)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// consumed all remaining key bytes first
|
||||||
|
c.used += uint64(c.xLen)
|
||||||
|
offsetDiff -= uint64(c.xLen)
|
||||||
|
c.xLen = 0
|
||||||
|
|
||||||
// forward the state to the offset
|
// forward the state to the offset
|
||||||
// this part can be optimized by a little bit
|
|
||||||
stepLen := uint64(RoundBytes)
|
stepLen := uint64(RoundBytes)
|
||||||
var keys [RoundWords]uint32
|
var keyStream [RoundWords]uint32
|
||||||
for ; diff >= uint64(stepLen); diff -= stepLen {
|
for ; offsetDiff >= uint64(stepLen); offsetDiff -= stepLen {
|
||||||
genKeyStream(keys[:], &c.zucState32)
|
genKeyStream(keyStream[:], &c.zucState32)
|
||||||
c.used += stepLen
|
c.used += stepLen
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff > 0 {
|
if offsetDiff > 0 {
|
||||||
words := (diff + WordSize - 1) / WordSize
|
numWords := (offsetDiff + WordMask) / WordSize
|
||||||
genKeyStream(keys[:words], &c.zucState32)
|
genKeyStream(keyStream[:numWords], &c.zucState32)
|
||||||
partiallyUsed := int(diff % WordSize)
|
partiallyUsed := int(offsetDiff & WordMask)
|
||||||
c.used += words * WordSize
|
c.used += numWords * WordSize
|
||||||
if partiallyUsed > 0 {
|
if partiallyUsed > 0 {
|
||||||
// save remaining key bytes (less than 4 bytes)
|
// save remaining key bytes (less than 4 bytes)
|
||||||
c.xLen = WordSize - partiallyUsed
|
c.xLen = WordSize - partiallyUsed
|
||||||
c.used -= uint64(c.xLen)
|
c.used -= uint64(c.xLen)
|
||||||
byteorder.BEPutUint32(c.x[:], keys[words-1])
|
byteorder.BEPutUint32(c.x[:], keyStream[numWords-1])
|
||||||
copy(c.x[:], c.x[partiallyUsed:])
|
copy(c.x[:], c.x[partiallyUsed:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,13 @@ func TestXORStreamAt(t *testing.T) {
|
|||||||
t.Errorf("expected=%x, result=%x\n", expected[32:64], dst[32:64])
|
t.Errorf("expected=%x, result=%x\n", expected[32:64], dst[32:64])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for i := 1; i < 4; i++ {
|
||||||
|
c.XORKeyStreamAt(dst[:i], src[:i], 0)
|
||||||
|
c.XORKeyStreamAt(dst[32:64], src[32:64], 32)
|
||||||
|
if !bytes.Equal(dst[32:64], expected[32:64]) {
|
||||||
|
t.Errorf("expected=%x, result=%x\n", expected[32:64], dst[32:64])
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Jump and forward (skipped keys more than 128)", func(t *testing.T) {
|
t.Run("Jump and forward (skipped keys more than 128)", func(t *testing.T) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user