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  }