277 lines
6.1 KiB
Go
277 lines
6.1 KiB
Go
|
package crypt
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
)
|
||
|
|
||
|
var PC1_C = []byte{
|
||
|
57, 49, 41, 33, 25, 17, 9,
|
||
|
1, 58, 50, 42, 34, 26, 18,
|
||
|
10, 2, 59, 51, 43, 35, 27,
|
||
|
19, 11, 3, 60, 52, 44, 36,
|
||
|
}
|
||
|
|
||
|
var PC1_D = []byte{
|
||
|
63, 55, 47, 39, 31, 23, 15,
|
||
|
7, 62, 54, 46, 38, 30, 22,
|
||
|
14, 6, 61, 53, 45, 37, 29,
|
||
|
21, 13, 5, 28, 20, 12, 4,
|
||
|
}
|
||
|
|
||
|
var PC2_C = []byte{
|
||
|
14, 17, 11, 24, 1, 5,
|
||
|
3, 28, 15, 6, 21, 10,
|
||
|
23, 19, 12, 4, 26, 8,
|
||
|
16, 7, 27, 20, 13, 2,
|
||
|
}
|
||
|
var PC2_D = []byte{
|
||
|
41, 52, 31, 37, 47, 55,
|
||
|
30, 40, 51, 45, 33, 48,
|
||
|
44, 49, 39, 56, 34, 53,
|
||
|
46, 42, 50, 36, 29, 32,
|
||
|
}
|
||
|
|
||
|
var e2 = []byte{
|
||
|
32, 1, 2, 3, 4, 5,
|
||
|
4, 5, 6, 7, 8, 9,
|
||
|
8, 9, 10, 11, 12, 13,
|
||
|
12, 13, 14, 15, 16, 17,
|
||
|
16, 17, 18, 19, 20, 21,
|
||
|
20, 21, 22, 23, 24, 25,
|
||
|
24, 25, 26, 27, 28, 29,
|
||
|
28, 29, 30, 31, 32, 1,
|
||
|
}
|
||
|
|
||
|
var IP = []byte{
|
||
|
58, 50, 42, 34, 26, 18, 10, 2,
|
||
|
60, 52, 44, 36, 28, 20, 12, 4,
|
||
|
62, 54, 46, 38, 30, 22, 14, 6,
|
||
|
64, 56, 48, 40, 32, 24, 16, 8,
|
||
|
57, 49, 41, 33, 25, 17, 9, 1,
|
||
|
59, 51, 43, 35, 27, 19, 11, 3,
|
||
|
61, 53, 45, 37, 29, 21, 13, 5,
|
||
|
63, 55, 47, 39, 31, 23, 15, 7,
|
||
|
}
|
||
|
|
||
|
var FP = []byte{
|
||
|
40, 8, 48, 16, 56, 24, 64, 32,
|
||
|
39, 7, 47, 15, 55, 23, 63, 31,
|
||
|
38, 6, 46, 14, 54, 22, 62, 30,
|
||
|
37, 5, 45, 13, 53, 21, 61, 29,
|
||
|
36, 4, 44, 12, 52, 20, 60, 28,
|
||
|
35, 3, 43, 11, 51, 19, 59, 27,
|
||
|
34, 2, 42, 10, 50, 18, 58, 26,
|
||
|
33, 1, 41, 9, 49, 17, 57, 25,
|
||
|
}
|
||
|
|
||
|
var S = [][]byte{
|
||
|
[]byte{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||
|
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
||
|
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||
|
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
|
||
|
[]byte{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||
|
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
||
|
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||
|
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
|
||
|
[]byte{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||
|
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
||
|
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||
|
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
|
||
|
[]byte{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||
|
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
||
|
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||
|
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
|
||
|
[]byte{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||
|
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
||
|
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||
|
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
|
||
|
[]byte{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||
|
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
||
|
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||
|
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
|
||
|
[]byte{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||
|
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
||
|
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||
|
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
|
||
|
[]byte{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||
|
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
||
|
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||
|
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
|
||
|
}
|
||
|
|
||
|
var P = []byte{
|
||
|
16, 7, 20, 21, 29, 12, 28, 17,
|
||
|
1, 15, 23, 26, 5, 18, 31, 10,
|
||
|
2, 8, 24, 14, 32, 27, 3, 9,
|
||
|
19, 13, 30, 6, 22, 11, 4, 25,
|
||
|
}
|
||
|
|
||
|
var shift = []int{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}
|
||
|
|
||
|
// Crypt is a implementation of crypt(3) like as perl or ruby and ...etc.
|
||
|
//
|
||
|
// Behavior of this func is same as perl-5.18.2's crypt on OSX Yosemite.
|
||
|
func Crypt(pw string, salt string) string {
|
||
|
if sLen := len(salt); sLen < 2 {
|
||
|
src := []byte(salt)
|
||
|
for len(src) < 2 {
|
||
|
src = append(src, 0x00)
|
||
|
}
|
||
|
salt = string(src)
|
||
|
}
|
||
|
|
||
|
block := make([]byte, 66)
|
||
|
|
||
|
for i := 0; i < 8 && i < len(pw); i++ {
|
||
|
for j := 0; j < 7; j++ {
|
||
|
block[(8*i)+j] = (pw[i] >> byte(6-j)) & 1
|
||
|
}
|
||
|
}
|
||
|
|
||
|
C := make([]byte, 28)
|
||
|
D := make([]byte, 28)
|
||
|
|
||
|
for i := 0; i < 28; i++ {
|
||
|
C[i] = block[PC1_C[i]-1]
|
||
|
D[i] = block[PC1_D[i]-1]
|
||
|
}
|
||
|
|
||
|
KS := make([][]byte, 16)
|
||
|
for i := 0; i < 16; i++ {
|
||
|
KS[i] = make([]byte, 48)
|
||
|
}
|
||
|
|
||
|
for i := 0; i < 16; i++ {
|
||
|
for k := 0; k < shift[i]; k++ {
|
||
|
t := C[0]
|
||
|
for j := 0; j < 28-1; j++ {
|
||
|
C[j] = C[j+1]
|
||
|
}
|
||
|
C[27] = t
|
||
|
t = D[0]
|
||
|
for j := 0; j < 28-1; j++ {
|
||
|
D[j] = D[j+1]
|
||
|
}
|
||
|
D[27] = t
|
||
|
}
|
||
|
for j := 0; j < 24; j++ {
|
||
|
KS[i][j] = C[PC2_C[j]-1]
|
||
|
KS[i][j+24] = D[PC2_D[j]-28-1]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
E := make([]byte, 48)
|
||
|
for i := 0; i < 48; i++ {
|
||
|
E[i] = e2[i]
|
||
|
}
|
||
|
|
||
|
iobuf := make([]byte, 16)
|
||
|
for i := 0; i < 2; i++ {
|
||
|
c := byte(salt[i])
|
||
|
iobuf[i] = c
|
||
|
|
||
|
if c > 'Z' {
|
||
|
c -= 6
|
||
|
}
|
||
|
if c > '9' {
|
||
|
c -= 7
|
||
|
}
|
||
|
|
||
|
c -= '.'
|
||
|
|
||
|
for j := 0; j < 6; j++ {
|
||
|
if (c>>byte(j))&1 != 0 {
|
||
|
k := E[6*i+j]
|
||
|
E[6*i+j] = E[6*i+j+24]
|
||
|
E[6*i+j+24] = k
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := 0; i < 66; i++ {
|
||
|
block[i] = 0
|
||
|
}
|
||
|
|
||
|
R := make([]byte, 32)
|
||
|
L := make([]byte, 32)
|
||
|
DMY := make([]byte, 32)
|
||
|
preS := make([]byte, 48)
|
||
|
f := make([]byte, 32)
|
||
|
dmy_block := make([]byte, 64)
|
||
|
|
||
|
for m := 0; m < 25; m++ {
|
||
|
for i := 0; i < 32; i++ {
|
||
|
L[i] = block[IP[i]-1]
|
||
|
}
|
||
|
for i := 32; i < 64; i++ {
|
||
|
R[i-32] = block[IP[i]-1]
|
||
|
}
|
||
|
|
||
|
for i := 0; i < 16; i++ {
|
||
|
for j := 0; j < 32; j++ {
|
||
|
DMY[j] = R[j]
|
||
|
}
|
||
|
for j := 0; j < 48; j++ {
|
||
|
preS[j] = R[E[j]-1] ^ KS[i][j]
|
||
|
}
|
||
|
for j := 0; j < 8; j++ {
|
||
|
t := 6 * j
|
||
|
k := S[j][(preS[t+0]<<5)+
|
||
|
(preS[t+1]<<3)+
|
||
|
(preS[t+2]<<2)+
|
||
|
(preS[t+3]<<1)+
|
||
|
(preS[t+4]<<0)+
|
||
|
(preS[t+5]<<4)]
|
||
|
|
||
|
t = 4 * j
|
||
|
f[t+0] = (k >> 3) & 01
|
||
|
f[t+1] = (k >> 2) & 01
|
||
|
f[t+2] = (k >> 1) & 01
|
||
|
f[t+3] = (k >> 0) & 01
|
||
|
}
|
||
|
for j := 0; j < 32; j++ {
|
||
|
R[j] = L[j] ^ f[P[j]-1]
|
||
|
}
|
||
|
for j := 0; j < 32; j++ {
|
||
|
L[j] = DMY[j]
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for i := 0; i < 32; i++ {
|
||
|
L[i], R[i] = R[i], L[i]
|
||
|
}
|
||
|
|
||
|
for i := 0; i < 32; i++ {
|
||
|
dmy_block[i] = L[i]
|
||
|
}
|
||
|
for i := 32; i < 64; i++ {
|
||
|
dmy_block[i] = R[i-32]
|
||
|
}
|
||
|
for i := 0; i < 64; i++ {
|
||
|
block[i] = dmy_block[FP[i]-1]
|
||
|
}
|
||
|
}
|
||
|
var i int
|
||
|
for i = 0; i < 11; i++ {
|
||
|
c := byte(0)
|
||
|
for j := 0; j < 6; j++ {
|
||
|
c = c << 1
|
||
|
c = c | block[6*i+j]
|
||
|
}
|
||
|
c = c + '.'
|
||
|
|
||
|
if c > '9' {
|
||
|
c += 7
|
||
|
}
|
||
|
if c > 'Z' {
|
||
|
c += 6
|
||
|
}
|
||
|
|
||
|
iobuf[i+2] = c
|
||
|
}
|
||
|
|
||
|
iobuf[i+2] = 0
|
||
|
|
||
|
return string(bytes.Replace(iobuf, []byte{0x00}, []byte{}, -1))
|
||
|
}
|