-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrypto.go
136 lines (116 loc) · 3.66 KB
/
crypto.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
//Copyright 2013 Thomson Reuters Global Resources. BSD License please see License file for more information
package ntlm
import (
desP "crypto/des"
hmacP "crypto/hmac"
md5P "crypto/md5"
"crypto/rand"
rc4P "crypto/rc4"
crc32P "hash/crc32"
md4P "github.com/ThomsonReutersEikon/go-ntlm/ntlm/md4"
)
func md4(data []byte) []byte {
md4 := md4P.New()
md4.Write(data)
return md4.Sum(nil)
}
func md5(data []byte) []byte {
md5 := md5P.New()
md5.Write(data)
return md5.Sum(nil)
}
// Indicates the computation of a 16-byte HMAC-keyed MD5 message digest of the byte string M using the key K.
func hmacMd5(key []byte, data []byte) []byte {
mac := hmacP.New(md5P.New, key)
mac.Write(data)
return mac.Sum(nil)
}
// Indicates the computation of an N-byte cryptographic- strength random number.
func nonce(length int) []byte {
result := make([]byte, length)
rand.Read(result)
return result
}
func crc32(bytes []byte) uint32 {
crc := crc32P.New(crc32P.IEEETable)
crc.Write(bytes)
return crc.Sum32()
}
// Indicates the encryption of data item D with the key K using the RC4 algorithm.
func rc4K(key []byte, ciphertext []byte) ([]byte, error) {
cipher, err := rc4P.NewCipher(key)
if err != nil {
return nil, err
}
result := make([]byte, len(ciphertext))
cipher.XORKeyStream(result, ciphertext)
return result, nil
}
func rc4Init(key []byte) (cipher *rc4P.Cipher, err error) {
cipher, err = rc4P.NewCipher(key)
if err != nil {
return nil, err
}
return cipher, nil
}
func rc4(cipher *rc4P.Cipher, ciphertext []byte) []byte {
result := make([]byte, len(ciphertext))
cipher.XORKeyStream(result, ciphertext)
return result
}
// Indicates the encryption of an 8-byte data item D with the 7-byte key K using the Data Encryption Standard (DES)
// algorithm in Electronic Codebook (ECB) mode. The result is 8 bytes in length ([FIPS46-2]).
func des(key []byte, ciphertext []byte) ([]byte, error) {
calcKey := createDesKey(key)
cipher, err := desP.NewCipher(calcKey)
if err != nil {
return nil, err
}
result := make([]byte, len(ciphertext))
cipher.Encrypt(result, ciphertext)
return result, nil
}
// Indicates the encryption of an 8-byte data item D with the 16-byte key K using the Data Encryption Standard Long (DESL) algorithm.
// The result is 24 bytes in length. DESL(K, D) is computed as follows.
// Note K[] implies a key represented as a character array.
func desL(key []byte, cipherText []byte) ([]byte, error) {
out1, err := des(zeroPaddedBytes(key, 0, 7), cipherText)
if err != nil {
return nil, err
}
out2, err := des(zeroPaddedBytes(key, 7, 7), cipherText)
if err != nil {
return nil, err
}
out3, err := des(zeroPaddedBytes(key, 14, 7), cipherText)
if err != nil {
return nil, err
}
return concat(out1, out2, out3), nil
}
// Creates a DES encryption key from the given 7 byte key material.
func createDesKey(keyBytes []byte) []byte {
material := zeroBytes(8)
material[0] = keyBytes[0]
material[1] = (byte)(keyBytes[0]<<7 | (keyBytes[1]&0xff)>>1)
material[2] = (byte)(keyBytes[1]<<6 | (keyBytes[2]&0xff)>>2)
material[3] = (byte)(keyBytes[2]<<5 | (keyBytes[3]&0xff)>>3)
material[4] = (byte)(keyBytes[3]<<4 | (keyBytes[4]&0xff)>>4)
material[5] = (byte)(keyBytes[4]<<3 | (keyBytes[5]&0xff)>>5)
material[6] = (byte)(keyBytes[5]<<2 | (keyBytes[6]&0xff)>>6)
material[7] = (byte)(keyBytes[6] << 1)
oddParity(material)
return material
}
// Applies odd parity to the given byte array.
func oddParity(bytes []byte) {
for i := 0; i < len(bytes); i++ {
b := bytes[i]
needsParity := (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0
if needsParity {
bytes[i] = bytes[i] | byte(0x01)
} else {
bytes[i] = bytes[i] & byte(0xfe)
}
}
}