-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathevp.go
48 lines (43 loc) · 1.47 KB
/
evp.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
package evp
import (
"crypto/aes"
"crypto/md5"
"crypto/sha256"
"fmt"
"hash"
)
const (
pkcs5SaltLen = 8
aes265KeyLen = 32
)
// BytesToKey implements the Openssl EVP_BytesToKey logic.
// It takes the salt, data, a hash type and the key/block length used by that type.
// As such it differs considerably from the openssl method in C.
func BytesToKey(salt, data []byte, h hash.Hash, keyLen, blockLen int) (key, iv []byte) {
saltLen := len(salt)
if saltLen > 0 && saltLen != pkcs5SaltLen {
panic(fmt.Sprintf("Salt length is %d, expected %d", saltLen, pkcs5SaltLen))
}
var (
concat []byte
lastHash []byte
totalLen = keyLen + blockLen
)
for ; len(concat) < totalLen; h.Reset() {
// concatenate lastHash, data and salt and write them to the hash
h.Write(append(lastHash, append(data, salt...)...))
// passing nil to Sum() will return the current hash value
lastHash = h.Sum(nil)
// append lastHash to the running total bytes
concat = append(concat, lastHash...)
}
return concat[:keyLen], concat[keyLen:totalLen]
}
// BytesToKeyAES256CBC implements the SHA256 version of EVP_BytesToKey using AES CBC
func BytesToKeyAES256CBC(salt, data []byte) (key []byte, iv []byte) {
return BytesToKey(salt, data, sha256.New(), aes265KeyLen, aes.BlockSize)
}
// BytesToKeyAES256CBCMD5 implements the MD5 version of EVP_BytesToKey using AES CBC
func BytesToKeyAES256CBCMD5(salt, data []byte) (key []byte, iv []byte) {
return BytesToKey(salt, data, md5.New(), aes265KeyLen, aes.BlockSize)
}