MAGIC - use internal package

This commit is contained in:
Emman 2021-04-29 15:14:22 +08:00
parent ba210a2d48
commit 7a7384f389
12 changed files with 73 additions and 64 deletions

View File

@ -2,11 +2,14 @@ package cipher
import (
goCipher "crypto/cipher"
"crypto/subtle"
goSubtle "crypto/subtle"
"encoding/binary"
"math"
"errors"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/internal/xor"
)
const (
@ -109,14 +112,14 @@ func (c *ccm) deriveCounter(counter *[ccmBlockSize]byte, nonce []byte) {
func (c *ccm) cmac(out, data []byte) {
for len(data) >= ccmBlockSize {
XorBytes(out, out, data)
xor.XorBytes(out, out, data)
c.cipher.Encrypt(out, out)
data = data[ccmBlockSize:]
}
if len(data) > 0 {
var block [ccmBlockSize]byte
copy(block[:], data)
XorBytes(out, out, data)
xor.XorBytes(out, out, data)
c.cipher.Encrypt(out, out)
}
}
@ -165,7 +168,7 @@ func (c *ccm) auth(nonce, plaintext, additionalData []byte, tagMask *[ccmBlockSi
if len(plaintext) > 0 {
c.cmac(out[:], plaintext)
}
XorWords(out[:], out[:], tagMask[:])
xor.XorWords(out[:], out[:], tagMask[:])
return out[:c.tagSize]
}
@ -176,8 +179,8 @@ func (c *ccm) Seal(dst, nonce, plaintext, data []byte) []byte {
if uint64(len(plaintext)) > uint64(c.MaxLength()) {
panic("cipher: message too large for CCM")
}
ret, out := SliceForAppend(dst, len(plaintext)+c.tagSize)
if InexactOverlap(out, plaintext) {
ret, out := subtle.SliceForAppend(dst, len(plaintext)+c.tagSize)
if subtle.InexactOverlap(out, plaintext) {
panic("cipher: invalid buffer overlap")
}
@ -222,8 +225,8 @@ func (c *ccm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
c.deriveCounter(&counter, nonce)
c.cipher.Encrypt(tagMask[:], counter[:])
ret, out := SliceForAppend(dst, len(ciphertext))
if InexactOverlap(out, ciphertext) {
ret, out := subtle.SliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
panic("cipher: invalid buffer overlap")
}
@ -231,7 +234,7 @@ func (c *ccm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
ctr := goCipher.NewCTR(c.cipher, counter[:])
ctr.XORKeyStream(out, ciphertext)
expectedTag := c.auth(nonce, out, data, &tagMask)
if subtle.ConstantTimeCompare(expectedTag, tag) != 1 {
if goSubtle.ConstantTimeCompare(expectedTag, tag) != 1 {
// The AESNI code decrypts and authenticates concurrently, and
// so overwrites dst in the event of a tag mismatch. That
// behavior is mimicked here in order to be consistent across

View File

@ -5,6 +5,9 @@ import (
"encoding/binary"
"errors"
"sync"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/internal/xor"
)
const GF128_FDBK byte = 0x87
@ -86,7 +89,7 @@ func (c *xts) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
if len(plaintext) < blockSize {
panic("xts: plaintext length is smaller than the block size")
}
if InexactOverlap(ciphertext[:len(plaintext)], plaintext) {
if subtle.InexactOverlap(ciphertext[:len(plaintext)], plaintext) {
panic("xts: invalid buffer overlap")
}
@ -109,18 +112,18 @@ func (c *xts) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
copy(tweaks[blockSize*i:], tweak[:])
mul2(tweak)
}
XorBytes(ciphertext, plaintext, tweaks)
xor.XorBytes(ciphertext, plaintext, tweaks)
concCipher.EncryptBlocks(ciphertext, ciphertext)
XorBytes(ciphertext, ciphertext, tweaks)
xor.XorBytes(ciphertext, ciphertext, tweaks)
plaintext = plaintext[batchSize:]
lastCiphertext = ciphertext[batchSize-blockSize:]
ciphertext = ciphertext[batchSize:]
}
}
for len(plaintext) >= blockSize {
XorBytes(ciphertext, plaintext, tweak[:])
xor.XorBytes(ciphertext, plaintext, tweak[:])
c.k1.Encrypt(ciphertext, ciphertext)
XorBytes(ciphertext, ciphertext, tweak[:])
xor.XorBytes(ciphertext, ciphertext, tweak[:])
plaintext = plaintext[blockSize:]
lastCiphertext = ciphertext
ciphertext = ciphertext[blockSize:]
@ -136,11 +139,11 @@ func (c *xts) Encrypt(ciphertext, plaintext []byte, sectorNum uint64) {
//Steal ciphertext to complete the block
copy(x[remain:], lastCiphertext[remain:blockSize])
//Merge the tweak into the input block
XorBytes(x[:], x[:], tweak[:])
xor.XorBytes(x[:], x[:], tweak[:])
//Encrypt the final block using K1
c.k1.Encrypt(x[:], x[:])
//Merge the tweak into the output block
XorBytes(lastCiphertext, x[:], tweak[:])
xor.XorBytes(lastCiphertext, x[:], tweak[:])
}
tweakPool.Put(tweak)
}
@ -155,7 +158,7 @@ func (c *xts) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
if len(ciphertext) < blockSize {
panic("xts: ciphertext length is smaller than the block size")
}
if InexactOverlap(plaintext[:len(ciphertext)], ciphertext) {
if subtle.InexactOverlap(plaintext[:len(ciphertext)], ciphertext) {
panic("xts: invalid buffer overlap")
}
@ -176,18 +179,18 @@ func (c *xts) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
copy(tweaks[blockSize*i:], tweak[:])
mul2(tweak)
}
XorBytes(plaintext, ciphertext, tweaks)
xor.XorBytes(plaintext, ciphertext, tweaks)
concCipher.DecryptBlocks(plaintext, plaintext)
XorBytes(plaintext, plaintext, tweaks)
xor.XorBytes(plaintext, plaintext, tweaks)
plaintext = plaintext[batchSize:]
ciphertext = ciphertext[batchSize:]
}
}
for len(ciphertext) >= 2*blockSize {
XorBytes(plaintext, ciphertext, tweak[:])
xor.XorBytes(plaintext, ciphertext, tweak[:])
c.k1.Decrypt(plaintext, plaintext)
XorBytes(plaintext, plaintext, tweak[:])
xor.XorBytes(plaintext, plaintext, tweak[:])
plaintext = plaintext[blockSize:]
ciphertext = ciphertext[blockSize:]
@ -200,9 +203,9 @@ func (c *xts) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
var tt [blockSize]byte
copy(tt[:], tweak[:])
mul2(&tt)
XorBytes(x[:], ciphertext, tt[:])
xor.XorBytes(x[:], ciphertext, tt[:])
c.k1.Decrypt(x[:], x[:])
XorBytes(plaintext, x[:], tt[:])
xor.XorBytes(plaintext, x[:], tt[:])
//Retrieve the length of the final block
remain -= blockSize
@ -217,9 +220,9 @@ func (c *xts) Decrypt(plaintext, ciphertext []byte, sectorNum uint64) {
//The last block contains exactly 128 bits
copy(x[:], ciphertext)
}
XorBytes(x[:], x[:], tweak[:])
xor.XorBytes(x[:], x[:], tweak[:])
c.k1.Decrypt(x[:], x[:])
XorBytes(plaintext, x[:], tweak[:])
xor.XorBytes(plaintext, x[:], tweak[:])
}
tweakPool.Put(tweak)

View File

@ -1,4 +1,4 @@
package cipher
package subtle
import "unsafe"

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package cipher
package xor
// XorBytes xors the bytes in a and b. The destination should have enough
// space, otherwise xorBytes will panic. Returns the number of bytes xor'd.

View File

@ -4,7 +4,7 @@
// +build !amd64
package cipher
package xor
import (
"runtime"

View File

@ -3,7 +3,8 @@ package sm4
import (
"crypto/cipher"
smcipher "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/internal/xor"
)
// Assert that sm4CipherAsm implements the cbcDecAble interfaces.
@ -33,7 +34,7 @@ func (x *cbc) CryptBlocks(dst, src []byte) {
if len(dst) < len(src) {
panic("cipher: output smaller than input")
}
if smcipher.InexactOverlap(dst[:len(src)], src) {
if subtle.InexactOverlap(dst[:len(src)], src) {
panic("cipher: invalid buffer overlap")
}
if len(src) == 0 {
@ -46,10 +47,10 @@ func (x *cbc) CryptBlocks(dst, src []byte) {
var src64 []byte = make([]byte, FourBlocksSize)
for start > 0 {
encryptBlocksAsm(&x.b.dec[0], &temp[0], &src[start:end][0])
smcipher.XorBytes(dst[end-BlockSize:end], temp[FourBlocksSize-BlockSize:FourBlocksSize], src[end-2*BlockSize:end-BlockSize])
smcipher.XorBytes(dst[end-2*BlockSize:end-BlockSize], temp[FourBlocksSize-2*BlockSize:FourBlocksSize-BlockSize], src[end-3*BlockSize:end-2*BlockSize])
smcipher.XorBytes(dst[end-3*BlockSize:end-2*BlockSize], temp[FourBlocksSize-3*BlockSize:FourBlocksSize-2*BlockSize], src[end-4*BlockSize:end-3*BlockSize])
smcipher.XorBytes(dst[end-4*BlockSize:end-3*BlockSize], temp[:BlockSize], src[end-5*BlockSize:end-4*BlockSize])
xor.XorBytes(dst[end-BlockSize:end], temp[FourBlocksSize-BlockSize:FourBlocksSize], src[end-2*BlockSize:end-BlockSize])
xor.XorBytes(dst[end-2*BlockSize:end-BlockSize], temp[FourBlocksSize-2*BlockSize:FourBlocksSize-BlockSize], src[end-3*BlockSize:end-2*BlockSize])
xor.XorBytes(dst[end-3*BlockSize:end-2*BlockSize], temp[FourBlocksSize-3*BlockSize:FourBlocksSize-2*BlockSize], src[end-4*BlockSize:end-3*BlockSize])
xor.XorBytes(dst[end-4*BlockSize:end-3*BlockSize], temp[:BlockSize], src[end-5*BlockSize:end-4*BlockSize])
end = start
start -= FourBlocksSize
@ -59,10 +60,10 @@ func (x *cbc) CryptBlocks(dst, src []byte) {
encryptBlocksAsm(&x.b.dec[0], &temp[0], &src[:end][0])
count := end / BlockSize
for i := count; i > 1; i-- {
smcipher.XorBytes(dst[end-BlockSize:end], temp[end-BlockSize:end], src[end-2*BlockSize:end-BlockSize])
xor.XorBytes(dst[end-BlockSize:end], temp[end-BlockSize:end], src[end-2*BlockSize:end-BlockSize])
end -= BlockSize
}
smcipher.XorBytes(dst[0:end], temp[0:end], x.iv[:])
xor.XorBytes(dst[0:end], temp[0:end], x.iv[:])
// Set the new iv to the first block we copied earlier.
x.iv, x.tmp = x.tmp, x.iv
}

View File

@ -4,7 +4,7 @@ import (
"crypto/cipher"
"fmt"
smcipher "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/internal/subtle"
)
// BlockSize the sm4 block size in bytes.
@ -48,7 +48,7 @@ func (c *sm4Cipher) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("sm4: output not full block")
}
if smcipher.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("sm4: invalid buffer overlap")
}
encryptBlockGo(c.enc, dst, src)
@ -61,7 +61,7 @@ func (c *sm4Cipher) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("sm4: output not full block")
}
if smcipher.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("sm4: invalid buffer overlap")
}
decryptBlockGo(c.dec, dst, src)

View File

@ -5,7 +5,7 @@ package sm4
import (
"crypto/cipher"
smcipher "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/internal/subtle"
"golang.org/x/sys/cpu"
)
@ -52,7 +52,7 @@ func (c *sm4CipherAsm) Encrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("sm4: output not full block")
}
if smcipher.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("sm4: invalid buffer overlap")
}
encryptBlockAsm(&c.enc[0], &dst[0], &src[0])
@ -65,7 +65,7 @@ func (c *sm4CipherAsm) EncryptBlocks(dst, src []byte) {
if len(dst) < FourBlocksSize {
panic("sm4: output not full blocks")
}
if smcipher.InexactOverlap(dst[:FourBlocksSize], src[:FourBlocksSize]) {
if subtle.InexactOverlap(dst[:FourBlocksSize], src[:FourBlocksSize]) {
panic("sm4: invalid buffer overlap")
}
encryptBlocksAsm(&c.enc[0], &dst[0], &src[0])
@ -78,7 +78,7 @@ func (c *sm4CipherAsm) Decrypt(dst, src []byte) {
if len(dst) < BlockSize {
panic("sm4: output not full block")
}
if smcipher.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
if subtle.InexactOverlap(dst[:BlockSize], src[:BlockSize]) {
panic("sm4: invalid buffer overlap")
}
encryptBlockAsm(&c.dec[0], &dst[0], &src[0])
@ -91,7 +91,7 @@ func (c *sm4CipherAsm) DecryptBlocks(dst, src []byte) {
if len(dst) < FourBlocksSize {
panic("sm4: output not full blocks")
}
if smcipher.InexactOverlap(dst[:FourBlocksSize], src[:FourBlocksSize]) {
if subtle.InexactOverlap(dst[:FourBlocksSize], src[:FourBlocksSize]) {
panic("sm4: invalid buffer overlap")
}
encryptBlocksAsm(&c.dec[0], &dst[0], &src[0])

View File

@ -3,7 +3,8 @@ package sm4
import (
"crypto/cipher"
smcipher "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/internal/xor"
)
// Assert that sm4CipherAsm implements the ctrAble interface.
@ -80,14 +81,14 @@ func (x *ctr) XORKeyStream(dst, src []byte) {
if len(dst) < len(src) {
panic("cipher: output smaller than input")
}
if smcipher.InexactOverlap(dst[:len(src)], src) {
if subtle.InexactOverlap(dst[:len(src)], src) {
panic("cipher: invalid buffer overlap")
}
for len(src) > 0 {
if x.outUsed >= len(x.out)-BlockSize {
x.refill()
}
n := smcipher.XorBytes(dst, src, x.out[x.outUsed:])
n := xor.XorBytes(dst, src, x.out[x.outUsed:])
dst = dst[n:]
src = src[n:]
x.outUsed += n

View File

@ -2,11 +2,12 @@ package sm4
import (
"crypto/cipher"
"crypto/subtle"
goSubtle "crypto/subtle"
"encoding/binary"
"errors"
smcipher "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/internal/subtle"
"github.com/emmansun/gmsm/internal/xor"
)
// Assert that sm4CipherAsm implements the gcmAble interface.
@ -82,8 +83,8 @@ func (g *gcm) Seal(dst, nonce, plaintext, data []byte) []byte {
panic("cipher: message too large for GCM")
}
ret, out := smcipher.SliceForAppend(dst, len(plaintext)+g.tagSize)
if smcipher.InexactOverlap(out, plaintext) {
ret, out := subtle.SliceForAppend(dst, len(plaintext)+g.tagSize)
if subtle.InexactOverlap(out, plaintext) {
panic("cipher: invalid buffer overlap")
}
@ -133,12 +134,12 @@ func (g *gcm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
var expectedTag [gcmTagSize]byte
g.auth(expectedTag[:], ciphertext, data, &tagMask)
ret, out := smcipher.SliceForAppend(dst, len(ciphertext))
if smcipher.InexactOverlap(out, ciphertext) {
ret, out := subtle.SliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
panic("cipher: invalid buffer overlap")
}
if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
if goSubtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
// The AESNI code decrypts and authenticates concurrently, and
// so overwrites dst in the event of a tag mismatch. That
// behavior is mimicked here in order to be consistent across
@ -275,7 +276,7 @@ func (g *gcm) counterCrypt(out, in []byte, counter *[gcmBlockSize]byte) {
encryptBlocksAsm(&g.cipher.enc[0], &mask[0], &couters[0])
gcmInc32(counter)
smcipher.XorWords(out, in, mask[:])
xor.XorWords(out, in, mask[:])
out = out[FourBlocksSize:]
in = in[FourBlocksSize:]
}
@ -287,7 +288,7 @@ func (g *gcm) counterCrypt(out, in []byte, counter *[gcmBlockSize]byte) {
gcmInc32(counter)
}
encryptBlocksAsm(&g.cipher.enc[0], &mask[0], &couters[0])
smcipher.XorBytes(out, in, mask[:blocks*gcmBlockSize])
xor.XorBytes(out, in, mask[:blocks*gcmBlockSize])
}
}
@ -329,5 +330,5 @@ func (g *gcm) auth(out, ciphertext, additionalData []byte, tagMask *[gcmTagSize]
binary.BigEndian.PutUint64(out, y.low)
binary.BigEndian.PutUint64(out[8:], y.high)
smcipher.XorWords(out, out, tagMask[:])
xor.XorWords(out, out, tagMask[:])
}

View File

@ -3,9 +3,9 @@ package sm4
import (
"crypto/cipher"
"crypto/subtle"
goSubtle "crypto/subtle"
smcipher "github.com/emmansun/gmsm/cipher"
"github.com/emmansun/gmsm/internal/subtle"
)
// sm4CipherGCM implements crypto/cipher.gcmAble so that crypto/cipher.NewGCM
@ -82,8 +82,8 @@ func (g *gcmAsm) Seal(dst, nonce, plaintext, data []byte) []byte {
gcmSm4Data(&g.bytesProductTable, data, &tagOut)
ret, out := smcipher.SliceForAppend(dst, len(plaintext)+g.tagSize)
if smcipher.InexactOverlap(out[:len(plaintext)], plaintext) {
ret, out := subtle.SliceForAppend(dst, len(plaintext)+g.tagSize)
if subtle.InexactOverlap(out[:len(plaintext)], plaintext) {
panic("cipher: invalid buffer overlap")
}
@ -138,8 +138,8 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
var expectedTag [gcmTagSize]byte
gcmSm4Data(&g.bytesProductTable, data, &expectedTag)
ret, out := smcipher.SliceForAppend(dst, len(ciphertext))
if smcipher.InexactOverlap(out, ciphertext) {
ret, out := subtle.SliceForAppend(dst, len(ciphertext))
if subtle.InexactOverlap(out, ciphertext) {
panic("cipher: invalid buffer overlap")
}
if len(ciphertext) > 0 {
@ -147,7 +147,7 @@ func (g *gcmAsm) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) {
}
gcmSm4Finish(&g.bytesProductTable, &tagMask, &expectedTag, uint64(len(ciphertext)), uint64(len(data)))
if subtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
if goSubtle.ConstantTimeCompare(expectedTag[:g.tagSize], tag) != 1 {
for i := range out {
out[i] = 0
}