...
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 func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream {
92 blockSize := block.BlockSize()
93 if len(prefix) != blockSize+2 {
94 return nil
95 }
96
97 x := &ocfbDecrypter{
98 b: block,
99 fre: make([]byte, blockSize),
100 outUsed: 0,
101 }
102 prefixCopy := make([]byte, len(prefix))
103 copy(prefixCopy, prefix)
104
105 block.Encrypt(x.fre, x.fre)
106 for i := 0; i < blockSize; i++ {
107 prefixCopy[i] ^= x.fre[i]
108 }
109
110 block.Encrypt(x.fre, prefix[:blockSize])
111 prefixCopy[blockSize] ^= x.fre[0]
112 prefixCopy[blockSize+1] ^= x.fre[1]
113
114 if resync {
115 block.Encrypt(x.fre, prefix[2:])
116 } else {
117 x.fre[0] = prefix[blockSize]
118 x.fre[1] = prefix[blockSize+1]
119 x.outUsed = 2
120 }
121 copy(prefix, prefixCopy)
122 return x
123 }
124
125 func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) {
126 for i := 0; i < len(src); i++ {
127 if x.outUsed == len(x.fre) {
128 x.b.Encrypt(x.fre, x.fre)
129 x.outUsed = 0
130 }
131
132 c := src[i]
133 dst[i] = x.fre[x.outUsed] ^ src[i]
134 x.fre[x.outUsed] = c
135 x.outUsed++
136 }
137 }
138
View as plain text