1
2
3
4
5
6
7
8
9
10 package rc4
11
12 import (
13 "crypto/internal/fips140/alias"
14 "crypto/internal/fips140only"
15 "errors"
16 "strconv"
17 )
18
19
20 type Cipher struct {
21 s [256]uint32
22 i, j uint8
23 }
24
25 type KeySizeError int
26
27 func (k KeySizeError) Error() string {
28 return "crypto/rc4: invalid key size " + strconv.Itoa(int(k))
29 }
30
31
32
33 func NewCipher(key []byte) (*Cipher, error) {
34 if fips140only.Enabled {
35 return nil, errors.New("crypto/rc4: use of RC4 is not allowed in FIPS 140-only mode")
36 }
37 k := len(key)
38 if k < 1 || k > 256 {
39 return nil, KeySizeError(k)
40 }
41 var c Cipher
42 for i := 0; i < 256; i++ {
43 c.s[i] = uint32(i)
44 }
45 var j uint8 = 0
46 for i := 0; i < 256; i++ {
47 j += uint8(c.s[i]) + key[i%k]
48 c.s[i], c.s[j] = c.s[j], c.s[i]
49 }
50 return &c, nil
51 }
52
53
54
55
56
57 func (c *Cipher) Reset() {
58 for i := range c.s {
59 c.s[i] = 0
60 }
61 c.i, c.j = 0, 0
62 }
63
64
65
66 func (c *Cipher) XORKeyStream(dst, src []byte) {
67 if len(src) == 0 {
68 return
69 }
70 if alias.InexactOverlap(dst[:len(src)], src) {
71 panic("crypto/rc4: invalid buffer overlap")
72 }
73 i, j := c.i, c.j
74 _ = dst[len(src)-1]
75 dst = dst[:len(src)]
76 for k, v := range src {
77 i += 1
78 x := c.s[i]
79 j += uint8(x)
80 y := c.s[j]
81 c.s[i], c.s[j] = y, x
82 dst[k] = v ^ uint8(c.s[uint8(x+y)])
83 }
84 c.i, c.j = i, j
85 }
86
View as plain text