diff --git a/sm4/block.go b/sm4/block.go index fbdbdbe..71fc5e6 100644 --- a/sm4/block.go +++ b/sm4/block.go @@ -11,8 +11,10 @@ type convert func(uint32) uint32 // Encrypt one block from src into dst, using the expanded key xk. func encryptBlockGo(xk []uint32, dst, src []byte) { - _ = src[15] // early bounds check - _ = dst[15] // early bounds check + _ = src[15] // early bounds check + dst = dst[:16] // early bounds check + _ = xk[31] // bounds check elimination hint + var b0, b1, b2, b3 uint32 b0 = binary.BigEndian.Uint32(src[0:4]) b1 = binary.BigEndian.Uint32(src[4:8]) @@ -68,16 +70,22 @@ func encryptBlockGo(xk []uint32, dst, src []byte) { // Key expansion algorithm. func expandKeyGo(key []byte, enc, dec []uint32) { // Encryption key setup. + enc = enc[:rounds-1] var i int - var mk []uint32 + var mk [4]uint32 var k [rounds + 4]uint32 - nk := len(key) / 4 - mk = make([]uint32, nk) - for i = 0; i < nk; i++ { - mk[i] = binary.BigEndian.Uint32(key[4*i:]) - k[i] = mk[i] ^ fk[i] - } + key = key[:KeySize] + mk[0] = binary.BigEndian.Uint32(key) + k[0] = mk[0] ^ fk[0] + mk[1] = binary.BigEndian.Uint32(key[4:]) + k[1] = mk[1] ^ fk[1] + mk[2] = binary.BigEndian.Uint32(key[8:]) + k[2] = mk[2] ^ fk[2] + mk[3] = binary.BigEndian.Uint32(key[12:]) + k[3] = mk[3] ^ fk[3] + + _ = enc[rounds-1] for i = 0; i < rounds; i++ { k[i+4] = k[i] ^ t2(k[i+1]^k[i+2]^k[i+3]^ck[i]) enc[i] = k[i+4] @@ -87,6 +95,8 @@ func expandKeyGo(key []byte, enc, dec []uint32) { if dec == nil { return } + + dec = dec[:rounds-1] for i = 0; i < rounds; i++ { dec[i] = enc[rounds-1-i] } @@ -97,12 +107,12 @@ func decryptBlockGo(xk []uint32, dst, src []byte) { encryptBlockGo(xk, dst, src) } -//L(B) +// L(B) func l(b uint32) uint32 { return b ^ bits.RotateLeft32(b, 2) ^ bits.RotateLeft32(b, 10) ^ bits.RotateLeft32(b, 18) ^ bits.RotateLeft32(b, 24) } -//L'(B) +// L'(B) func l2(b uint32) uint32 { return b ^ bits.RotateLeft32(b, 13) ^ bits.RotateLeft32(b, 23) } @@ -116,12 +126,12 @@ func _t(in uint32, fn convert) uint32 { return fn(binary.BigEndian.Uint32(bytes[:])) } -//T +// T func t(in uint32) uint32 { return _t(in, l) } -//T' +// T' func t2(in uint32) uint32 { return _t(in, l2) } diff --git a/sm4/cbc_cipher_asm.go b/sm4/cbc_cipher_asm.go index d0da0a6..82691ba 100644 --- a/sm4/cbc_cipher_asm.go +++ b/sm4/cbc_cipher_asm.go @@ -78,8 +78,8 @@ func (x *cbc) CryptBlocks(dst, src []byte) { for start > 0 { x.b.DecryptBlocks(temp, src[start:end]) - copy(batchSrc, src[start-BlockSize:]) - subtle.XORBytes(dst[start:], temp, batchSrc) + subtle.XORBytes(temp, temp, src[start-BlockSize:end-BlockSize]) + copy(dst[start:], temp) end = start start -= x.b.blocksSize } diff --git a/sm4/const.go b/sm4/const.go index 0fed83b..742aae3 100644 --- a/sm4/const.go +++ b/sm4/const.go @@ -214,3 +214,5 @@ var ck = [32]uint32{ var fk = [4]uint32{ 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc, } + +const KeySize = 16 \ No newline at end of file