-
Notifications
You must be signed in to change notification settings - Fork 17
/
helpers_hmac.go
148 lines (127 loc) · 3.73 KB
/
helpers_hmac.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package ipmi
import (
"crypto/aes"
"crypto/cipher"
"crypto/hmac"
"crypto/md5"
"crypto/rc4"
"crypto/sha1"
"crypto/sha256"
"fmt"
)
// generate_hmac generates message authentication code.
// Currently supported algorithms are: "md5", "sha1", "sha256"
//
// hmac, hash-based message authentication code
// mac, message authentication code
// md, message digest
func generate_hmac(alg string, data []byte, key []byte) ([]byte, error) {
switch alg {
case "md5":
h := hmac.New(md5.New, key)
_, err := h.Write(data)
if err != nil {
return nil, fmt.Errorf("hmac md5 failed, err: %s", err)
}
return h.Sum(nil), nil
case "sha1":
h := hmac.New(sha1.New, key)
_, err := h.Write(data)
if err != nil {
return nil, fmt.Errorf("hmac sha1 failed, err: %s", err)
}
return h.Sum(nil), nil
case "sha256":
h := hmac.New(sha256.New, key)
_, err := h.Write(data)
if err != nil {
return nil, fmt.Errorf("hmac sha256 failed, err: %s", err)
}
return h.Sum(nil), nil
default:
return nil, fmt.Errorf("not support for hmac algorithm %s", alg)
}
}
func generate_auth_hmac(authAlg interface{}, data []byte, key []byte) ([]byte, error) {
algorithm := ""
switch authAlg.(type) {
case AuthAlg:
switch authAlg {
case AuthAlgRAKP_HMAC_SHA1:
algorithm = "sha1"
case AuthAlgRAKP_HMAC_MD5:
algorithm = "md5"
case AuthAlgRAKP_HMAC_SHA256:
algorithm = "sha256"
default:
return nil, fmt.Errorf("not support for authentication algorithm %x", authAlg)
}
case IntegrityAlg:
switch authAlg {
case IntegrityAlg_HMAC_SHA1_96:
algorithm = "sha1"
case IntegrityAlg_HMAC_MD5_128:
algorithm = "md5"
case IntegrityAlg_HMAC_SHA256_128:
algorithm = "sha256"
default:
return nil, fmt.Errorf("not support for integrity algorithm %x", authAlg)
}
}
if len(algorithm) == 0 {
return []byte{}, nil
} else {
return generate_hmac(algorithm, data, key)
}
}
// The plainText must be already padded.
// The cipherKey length is either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
func encryptAES(plainText []byte, cipherKey []byte, iv []byte) ([]byte, error) {
if len(plainText)%aes.BlockSize != 0 {
return nil, fmt.Errorf("input plainText must be mutiple of aes block size (16)")
}
l := len(cipherKey)
if l != 16 && l != 24 && l != 32 {
return nil, fmt.Errorf("cipherKey length must be either 16, 24, 32")
}
cipherBlock, err := aes.NewCipher(cipherKey)
if err != nil {
return nil, fmt.Errorf("NewCipher failed, err: %s", err)
}
cipherText := make([]byte, len(plainText))
mode := cipher.NewCBCEncrypter(cipherBlock, iv)
mode.CryptBlocks(cipherText, plainText)
return cipherText, nil
}
func decryptAES(cipherText []byte, cipherKey []byte, iv []byte) ([]byte, error) {
l := len(cipherKey)
if l != 16 && l != 24 && l != 32 {
return nil, fmt.Errorf("cipherKey length must be either 16, 24, 32")
}
cipherBlock, err := aes.NewCipher(cipherKey)
if err != nil {
return nil, fmt.Errorf("NewCipher failed, err: %s", err)
}
plainText := make([]byte, len(cipherText))
mode := cipher.NewCBCDecrypter(cipherBlock, iv)
mode.CryptBlocks(plainText, cipherText)
return plainText, nil
}
func encryptRC4(plainText []byte, cipherKey []byte, iv []byte) ([]byte, error) {
rc4Cipher, err := rc4.NewCipher(cipherKey)
if err != nil {
return nil, fmt.Errorf("NewCipher failed, err: %s", err)
}
cipherText := make([]byte, len(plainText))
rc4Cipher.XORKeyStream(cipherText, plainText)
return cipherText, nil
}
func decryptRC4(cipherText []byte, cipherKey []byte, iv []byte) ([]byte, error) {
rc4Cipher, err := rc4.NewCipher(cipherKey)
if err != nil {
return nil, fmt.Errorf("NewCipher failed, err: %s", err)
}
plainText := make([]byte, len(cipherText))
rc4Cipher.XORKeyStream(plainText, cipherText)
return plainText, nil
}