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.Enforced() {
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 clear(c.s[:])
59 c.i, c.j = 0, 0
60 }
61
62
63
64 func (c *Cipher) XORKeyStream(dst, src []byte) {
65 if len(src) == 0 {
66 return
67 }
68 if alias.InexactOverlap(dst[:len(src)], src) {
69 panic("crypto/rc4: invalid buffer overlap")
70 }
71 i, j := c.i, c.j
72 _ = dst[len(src)-1]
73 dst = dst[:len(src)]
74 for k, v := range src {
75 i += 1
76 x := c.s[i]
77 j += uint8(x)
78 y := c.s[j]
79 c.s[i], c.s[j] = y, x
80 dst[k] = v ^ uint8(c.s[uint8(x+y)])
81 }
82 c.i, c.j = i, j
83 }
84
View as plain text