github.com/Ptt-official-app/go-bbs@v0.12.0/crypt/crypt.go (about) 1 package crypt 2 3 //cFcrypt 4 // 5 //This is the go-implementation of 6 // 7 //https://github.com/ptt/pttbbs/blob/master/common/sys/crypt.c 8 //commit: 6bdd36898bde207683a441cdffe2981e95de5b20 9 // 10 //Params 11 // 12 // buf: input-buffer (raw) 13 // salt: salt 14 // buff: output-buffer (encrypted) 15 func cFcrypt(buf []uint8, salt []uint8, buff *[PASSLEN]uint8) { 16 if len(buf) > 8 { 17 buf = buf[:8] 18 } 19 20 // crypt.c: line 554 21 x := uint8('A') 22 if salt[0] != 0 { 23 x = salt[0] 24 } 25 buff[0] = x 26 27 // crypt.c: line 555 28 Eswap0 := uint32(conSalt[x]) 29 30 // crypt.c: line 556 31 x = uint8('A') 32 if salt[1] != 0 { 33 x = salt[1] 34 } 35 buff[1] = x 36 37 // crypt: line 557 38 Eswap1 := uint32(conSalt[x]) << 4 39 40 // crypt: line 559 41 key := desCBlock{} 42 for idx, c := range buf { 43 if c == 0 { 44 break 45 } 46 47 key[idx] = c << 1 48 } 49 50 // crypt: line 568 51 //log.Infof("fcrypt: key: %v", key) 52 ks := desKeySchedule{} 53 desSetKey(&key, &ks) 54 /* 55 for idx, each := range ks { 56 log.Infof("fcrypt: (%d/%d) after desSetKey: ks: %v", idx, len(ks), each) 57 } 58 */ 59 60 out := [2]uint32{} 61 out[0], out[1] = body(&ks, Eswap0, Eswap1) 62 63 //log.Infof("fcrypt: after body: out: %v", out) 64 65 bb := [9]uint8{} 66 b := &bb 67 l2c(out[0], b[0:4]) 68 l2c(out[1], b[4:8]) 69 70 y := 0 71 u := uint8(0x80) 72 bb[8] = 0 73 //log.Infof("fcrypt: bb: %v", bb) 74 for i := 2; i < 13; i++ { 75 c := 0 76 for j := 0; j < 6; j++ { 77 c <<= 1 78 if bb[y]&u != 0 { 79 c |= 1 80 } 81 u >>= 1 82 if u == 0 { 83 y++ 84 u = uint8(0x80) 85 } 86 } 87 buff[i] = cov2char[c] 88 //log.Infof("fcrypt: (%d/%d) c: %v buff: %v", i, 13, c, buff[i]) 89 } 90 buff[13] = 0 91 } 92 93 //cFcrypt 94 // 95 //This is the go-implementation of 96 // 97 //https://github.com/ptt/pttbbs/blob/master/common/sys/crypt.c 98 //commit: 6bdd36898bde207683a441cdffe2981e95de5b20 99 // 100 //Params 101 // 102 // key: input-key 103 // schedule: output-schedule 104 func desSetKey(key *desCBlock, schedule *desKeySchedule) { 105 in := (*[8]uint8)(key) 106 k := schedule 107 108 c := c2l(in[:4]) 109 d := c2l(in[4:8]) 110 t := uint32(0) 111 //log.Infof("desSetKey (1): to permOp: d: %v c: %v", d, c) 112 d, c = permOp(d, c, 4, 0x0f0f0f0f) 113 //log.Infof("desSetKey (1): after permOp: d: %v c: %v", d, c) 114 //log.Infof("desSetKey (2): to hPermOp: c: %v", c) 115 c = hPermOp(c, -2, 0xcccc0000) 116 //log.Infof("desSetKey (2): after hPermOp: c: %v", c) 117 //log.Infof("desSetKey (3): to hPermOp: d: %v", d) 118 d = hPermOp(d, -2, 0xcccc0000) 119 //log.Infof("desSetKey (3): after hPermOp: d: %v", d) 120 //log.Infof("desSetKey (4): to permOp: d: %v c: %v", d, c) 121 d, c = permOp(d, c, 1, 0x55555555) 122 //log.Infof("desSetKey (4): after permOp: d: %v c: %v", d, c) 123 //log.Infof("desSetKey (5): to permOp: c: %v d: %v", c, d) 124 c, d = permOp(c, d, 8, 0x00ff00ff) 125 //log.Infof("desSetKey (5): after permOp: c: %v d: %v", c, d) 126 //log.Infof("desSetKey (6): to permOp: d: %v c: %v", d, c) 127 d, c = permOp(d, c, 1, 0x55555555) 128 //log.Infof("desSetKey (6): after permOp: d: %v c: %v", d, c) 129 130 d = ((d & 0x000000ff) << 16) | (d & 0x0000ff00) | 131 ((d & 0x00ff0000) >> 16) | ((c & 0xf0000000) >> 4) 132 133 c &= 0x0fffffff 134 135 //log.Infof("desSetKey (7): to for-loop: c: %v d: %v", c, d) 136 137 s := uint32(0) 138 for i := 0; i < desIterations; i++ { 139 if shifts2[i] { 140 { 141 c = ((c >> 2) | (c << 26)) 142 d = ((d >> 2) | (d << 26)) 143 } 144 } else { 145 { 146 c = ((c >> 1) | (c << 27)) 147 d = ((d >> 1) | (d << 27)) 148 } 149 } 150 151 //log.Infof("desSetKey (8) (%v/%v): to &= 0x0fffffff: c: %v d: %v", i, ITERATIONS, c, d) 152 153 c &= 0x0fffffff 154 d &= 0x0fffffff 155 /* could be a few less shifts but I am to lazy at this 156 * point in time to investigate */ 157 s = skb[0][c&0x3f] | 158 skb[1][((c>>6)&0x03)|((c>>7)&0x3c)] | 159 skb[2][((c>>13)&0x0f)|((c>>14)&0x30)] | 160 skb[3][((c>>20)&0x01)|((c>>21)&0x06)| 161 ((c>>22)&0x38)] 162 t = skb[4][(d)&0x3f] | 163 skb[5][((d>>7)&0x03)|((d>>8)&0x3c)] | 164 skb[6][(d>>15)&0x3f] | 165 skb[7][((d>>21)&0x0f)|((d>>22)&0x30)] 166 //log.Infof("desSetKey (9) (%v/%v): to set k: s: %v t: %v", i, ITERATIONS, s, t) 167 168 /* table contained 0213 4657 */ 169 k[2*i] = ((t << 16) | (s & 0x0000ffff)) & 0xffffffff 170 s = ((s >> 16) | (t & 0xffff0000)) 171 172 s = (s << 4) | (s >> 28) 173 k[2*i+1] = s & 0xffffffff 174 175 //log.Infof("desSetKey (10) (%v/%v): after set k: (%v, %v)", i, ITERATIONS, k[2*i], k[2*i+1]) 176 } 177 } 178 179 func dEncrypt(L uint32, R uint32, S uint32, E0 uint32, E1 uint32, s []uint32, t uint32, u uint32) (retL uint32, retT uint32, retU uint32) { 180 t = (R ^ (R >> 16)) 181 //log.Infof("dEncrypt (1): after t: R: %v t: %v", R, t) 182 u = t & E0 183 //log.Infof("dEncrypt (2): after u: t: %v E0: %v u: %v E1: %v", t, E0, u, E1) 184 t = t & E1 185 //log.Infof("dEncrypt (4): to u: t: %v u: %v R: %v S: %v s[S]: %v", t, u, R, S, s[S]) 186 u = (u ^ (u << 16)) ^ R ^ s[S] 187 //log.Infof("dEncrypt (4): after u: u: %v", u) 188 189 //log.Infof("dEncrypt (5): to t: t: %v R :%v s[S+1]: %v", t, R, s[S+1]) 190 t = (t ^ (t << 16)) ^ R ^ s[S+1] 191 //log.Infof("dEncrypt (5): after t: t: %v", t) 192 193 t = (t >> 4) | (t << 28) 194 //log.Infof("dEncrypt (5): after t: t: %v", t) 195 196 L ^= spTrans[1][(t)&0x3f] | 197 spTrans[3][(t>>8)&0x3f] | 198 spTrans[5][(t>>16)&0x3f] | 199 spTrans[7][(t>>24)&0x3f] | 200 spTrans[0][(u)&0x3f] | 201 spTrans[2][(u>>8)&0x3f] | 202 spTrans[4][(u>>16)&0x3f] | 203 spTrans[6][(u>>24)&0x3f] 204 //log.Infof("dEncrypt (6): after L: L: %v t: %v u: %v", L, t, u) 205 206 return L, t, u 207 } 208 209 func body(ks *desKeySchedule, Eswap0 uint32, Eswap1 uint32) (uint32, uint32) { 210 // crypt.c line: 618 211 212 E0 := uint32(Eswap0) 213 E1 := uint32(Eswap1) 214 l := uint32(0) 215 r := uint32(0) 216 s := (*[32]uint32)(ks) 217 t := uint32(0) 218 u := uint32(0) 219 220 //log.Infof("body: to for-loop: E0: %v E1: %v", E0, E1) 221 for j := 0; j < 25; j++ { 222 for i := uint32(0); i < desIterations*2; i += 4 { 223 //log.Infof("body (%v/%v)(%v/%v) (1): to dEncrypt: l: %v r: %v t: %v u: %v", j, 25, i, ITERATIONS*2, l, r, t, u) 224 l, t, u = dEncrypt(l, r, i, E0, E1, s[:], t, u) 225 //log.Infof("body (%v/%v)(%v/%v) (1): after dEncrypt: l: %v r: %v t: %v u: %v", j, 25, i, ITERATIONS*2, l, r, t, u) 226 //log.Infof("body (%v/%v)(%v/%v) (2): to dEncrypt: l: %v r: %v t: %v u: %v", j, 25, i, ITERATIONS*2, l, r, t, u) 227 r, t, u = dEncrypt(r, l, i+2, E0, E1, s[:], t, u) 228 //log.Infof("body (%v/%v)(%v/%v) (2): after dEncrypt: l: %v r: %v t: %v u: %v", j, 25, i, ITERATIONS*2, l, r, t, u) 229 } 230 t = l 231 l = r 232 r = t 233 234 } 235 //log.Infof("body (3): after for-loop: l: %v r: %v t: %v u: %v", l, r, t, u) 236 237 t = r 238 r = (l >> 1) | (l << 31) 239 l = (t >> 1) | (t << 31) 240 241 l &= 0xffffffff 242 r &= 0xffffffff 243 244 //log.Infof("body (4): to permOp: l: %v r: %v", l, r) 245 r, l = permOp(r, l, 1, 0x55555555) 246 //log.Infof("body (4): after permOp: l: %v r: %v", l, r) 247 //log.Infof("body (5): to permOp: l: %v r: %v", l, r) 248 l, r = permOp(l, r, 8, 0x00ff00ff) 249 //log.Infof("body (5): after permOp: l: %v r: %v", l, r) 250 //log.Infof("body (6): to permOp: l: %v r: %v", l, r) 251 r, l = permOp(r, l, 2, 0x33333333) 252 //log.Infof("body (6): after permOp: l: %v r: %v", l, r) 253 //log.Infof("body (7): to permOp: l: %v r: %v", l, r) 254 l, r = permOp(l, r, 16, 0x0000ffff) 255 //log.Infof("body (7): after permOp: l: %v r: %v", l, r) 256 //log.Infof("body (8): to permOp: l: %v r: %v", l, r) 257 r, l = permOp(r, l, 4, 0x0f0f0f0f) 258 //log.Infof("body (8): after permOp: l: %v r: %v", l, r) 259 260 return l, r 261 }