/
aead_wrapper.go
98 lines (81 loc) · 2.48 KB
/
aead_wrapper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package cipher
import (
"crypto/cipher"
"errors"
"github.com/wfusion/gofusion/common/utils"
)
const (
blockSizeTimes = 1 << 10 // 1024 times
defaultBlockSize = 16 // 16 bytes
)
type abstractAEADWrapper struct {
cipher.AEAD
overheadSize int
nonceSize int
blockSize int
plainBlockSize int
cipherBlockSize int
sealedSize int
mode Mode
}
func newAbstractAEADWrapper(cipherAEAD cipher.AEAD, blockSize int, mode Mode) abstractAEADWrapper {
plainBlockSize := blockSize * blockSizeTimes
return abstractAEADWrapper{
AEAD: cipherAEAD,
overheadSize: cipherAEAD.Overhead(),
nonceSize: cipherAEAD.NonceSize(),
blockSize: blockSize,
plainBlockSize: plainBlockSize,
cipherBlockSize: cipherAEAD.NonceSize() + cipherAEAD.Overhead() + plainBlockSize,
sealedSize: cipherAEAD.Overhead() + plainBlockSize,
mode: mode,
}
}
func (a *abstractAEADWrapper) PlainBlockSize() int { return a.plainBlockSize }
func (a *abstractAEADWrapper) CipherBlockSize() int { return a.cipherBlockSize }
func (a *abstractAEADWrapper) CipherMode() Mode { return a.mode }
type aeadEncryptWrapper struct {
abstractAEADWrapper
}
func newAEADEncryptWrapper(cipherAEAD cipher.AEAD, blockSize int, mode Mode) blockMode {
return &aeadEncryptWrapper{abstractAEADWrapper: newAbstractAEADWrapper(cipherAEAD, blockSize, mode)}
}
func (a *aeadEncryptWrapper) CryptBlocks(dst, src, buf []byte) (n int, err error) {
if len(src) == 0 {
return
}
nonce, cb := utils.BytesPool.Get(a.nonceSize)
defer cb()
if _, err = utils.CryptoRandom(nonce); err != nil {
return
}
sealed := a.Seal(buf[:0], nonce, src[:utils.Min(a.plainBlockSize, len(src))], nil)
copy(dst[:a.nonceSize], nonce)
copy(dst[a.nonceSize:], sealed)
n = len(nonce) + len(sealed)
return
}
type aeadDecryptWrapper struct {
abstractAEADWrapper
}
func newAEADDecryptWrapper(cipherAEAD cipher.AEAD, blockSize int, mode Mode) blockMode {
return &aeadDecryptWrapper{abstractAEADWrapper: newAbstractAEADWrapper(cipherAEAD, blockSize, mode)}
}
func (a *aeadDecryptWrapper) CryptBlocks(dst, src, buf []byte) (n int, err error) {
if len(src) == 0 {
return
}
sealedSize := utils.Min(a.sealedSize, len(src)-a.nonceSize)
if sealedSize < 0 {
return 0, errors.New("input not full blocks when decrypt")
}
nonce := src[:a.nonceSize]
src = src[a.nonceSize:]
unsealed, err := a.Open(buf[:0], nonce, src[:sealedSize], nil)
if err != nil {
return
}
copy(dst, unsealed)
n = len(unsealed)
return
}