...
1
2
3
4
5
6
7 package packet
8
9 import (
10 "crypto/cipher"
11 )
12
13 type ocfbEncrypter struct {
14 b cipher.Block
15 fre []byte
16 outUsed int
17 }
18
19
20
21 type OCFBResyncOption bool
22
23 const (
24 OCFBResync OCFBResyncOption = true
25 OCFBNoResync OCFBResyncOption = false
26 )
27
28
29
30
31
32
33
34 func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) {
35 blockSize := block.BlockSize()
36 if len(randData) != blockSize {
37 return nil, nil
38 }
39
40 x := &ocfbEncrypter{
41 b: block,
42 fre: make([]byte, blockSize),
43 outUsed: 0,
44 }
45 prefix := make([]byte, blockSize+2)
46
47 block.Encrypt(x.fre, x.fre)
48 for i := 0; i < blockSize; i++ {
49 prefix[i] = randData[i] ^ x.fre[i]
50 }
51
52 block.Encrypt(x.fre, prefix[:blockSize])
53 prefix[blockSize] = x.fre[0] ^ randData[blockSize-2]
54 prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1]
55
56 if resync {
57 block.Encrypt(x.fre, prefix[2:])
58 } else {
59 x.fre[0] = prefix[blockSize]
60 x.fre[1] = prefix[blockSize+1]
61 x.outUsed = 2
62 }
63 return x, prefix
64 }
65
66 func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) {
67 for i := 0; i < len(src); i++ {
68 if x.outUsed == len(x.fre) {
69 x.b.Encrypt(x.fre, x.fre)
70 x.outUsed = 0
71 }
72
73 x.fre[x.outUsed] ^= src[i]
74 dst[i] = x.fre[x.outUsed]
75 x.outUsed++
76 }
77 }
78
79 type ocfbDecrypter struct {
80 b cipher.Block
81 fre []byte
82 outUsed int
83 }
84
85
86
87
88
89
90
91
92 func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
93 blockSize := block.BlockSize()
94 if len(prefix) != blockSize+2 {
95 return nil
96 }
97
98 x := &ocfbDecrypter{
99 b: block,
100 fre: make([]byte, blockSize),
101 outUsed: 0,
102 }
103 prefixCopy := make([]byte, len(prefix))
104 copy(prefixCopy, prefix)
105
106 block.Encrypt(x.fre, x.fre)
107 for i := 0; i < blockSize; i++ {
108 prefixCopy[i] ^= x.fre[i]
109 }
110
111 block.Encrypt(x.fre, prefix[:blockSize])
112 prefixCopy[blockSize] ^= x.fre[0]
113 prefixCopy[blockSize+1] ^= x.fre[1]
114
115 if prefixCopy[blockSize-2] != prefixCopy[blockSize] ||
116 prefixCopy[blockSize-1] != prefixCopy[blockSize+1] {
117 return nil
118 }
119
120 if resync {
121 block.Encrypt(x.fre, prefix[2:])
122 } else {
123 x.fre[0] = prefix[blockSize]
124 x.fre[1] = prefix[blockSize+1]
125 x.outUsed = 2
126 }
127 copy(prefix, prefixCopy)
128 return x
129 }
130
131 func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
132 for i := 0; i < len(src); i++ {
133 if x.outUsed == len(x.fre) {
134 x.b.Encrypt(x.fre, x.fre)
135 x.outUsed = 0
136 }
137
138 c := src[i]
139 dst[i] = x.fre[x.outUsed] ^ src[i]
140 x.fre[x.outUsed] = c
141 x.outUsed++
142 }
143 }
144
View as plain text