Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2## 

3## d3des.py - DES implementation 

4## 

5## Copyright (c) 2009 by Yusuke Shinyama 

6## 

7 

8# This is a Python rewrite of d3des.c by Richard Outerbridge. 

9# 

10# I referred to the original VNC viewer code for the changes that 

11# is necessary to maintain the exact behavior of the VNC protocol. 

12# Two constants and two functions were added to the original d3des 

13# code. These added parts were written in Python and marked 

14# below. I believe that the added parts do not make this program 

15# a "derivative work" of the VNC viewer (which is GPL'ed and 

16# written in C), but if there's any problem, let me know. 

17# 

18# Yusuke Shinyama (yusuke at cs dot nyu dot edu) 

19 

20 

21# D3DES (V5.09) - 

22# 

23# A portable, public domain, version of the Data Encryption Standard. 

24# 

25# Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. 

26# Thanks to: Dan Hoey for his excellent Initial and Inverse permutation 

27# code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis 

28# Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, 

29# for humouring me on. 

30# 

31# Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. 

32# (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. 

33# 

34 

35from struct import pack, unpack 

36 

37 

38################################################### 

39### 

40### start: changes made for VNC. 

41### 

42 

43# This constant was taken from vncviewer/rfb/vncauth.c: 

44vnckey = [ 23,82,107,6,35,78,88,7 ] 

45 

46# This is a departure from the original code. 

47#bytebit = [ 0o200, 0o100, 0o40, 0o20, 0o10, 0o4, 0o2, 0o1 ] # original 

48bytebit = [ 0o1, 0o2, 0o4, 0o10, 0o20, 0o40, 0o100, 0o200 ] # VNC version 

49 

50# two password functions for VNC protocol. 

51def decrypt_passwd(data): 

52 dk = deskey(pack('8B', *vnckey), True) 

53 return desfunc(data, dk) 

54 

55def generate_response(passwd, challange): 

56 ek = deskey((passwd+b'\x00'*8)[:8], False) 

57 return desfunc(challange[:8], ek) + desfunc(challange[8:], ek) 

58 

59### 

60### end: changes made for VNC. 

61### 

62################################################### 

63 

64 

65bigbyte = [ 

66 0x800000, 0x400000, 0x200000, 0x100000, 

67 0x80000, 0x40000, 0x20000, 0x10000, 

68 0x8000, 0x4000, 0x2000, 0x1000, 

69 0x800, 0x400, 0x200, 0x100, 

70 0x80, 0x40, 0x20, 0x10, 

71 0x8, 0x4, 0x2, 0x1, 

72 ] 

73 

74# Use the key schedule specified in the Standard (ANSI X3.92-1981). 

75 

76pc1 = [ 

77 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 

78 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 

79 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 

80 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 

81 ] 

82 

83totrot = [ 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 ] 

84 

85pc2 = [ 

86 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 

87 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 

88 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 

89 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 

90 ] 

91 

92def deskey(key, decrypt): # Thanks to James Gillogly & Phil Karn! 

93 key = unpack('8B', key) 

94 

95 pc1m = [0]*56 

96 pcr = [0]*56 

97 kn = [0]*32 

98 

99 for j in range(56): 

100 l = pc1[j] 

101 m = l & 0o7 

102 if key[l >> 3] & bytebit[m]: 

103 pc1m[j] = 1 

104 else: 

105 pc1m[j] = 0 

106 

107 for i in range(16): 

108 if decrypt: 

109 m = (15 - i) << 1 

110 else: 

111 m = i << 1 

112 n = m + 1 

113 kn[m] = kn[n] = 0 

114 for j in range(28): 

115 l = j + totrot[i] 

116 if l < 28: 

117 pcr[j] = pc1m[l] 

118 else: 

119 pcr[j] = pc1m[l - 28] 

120 for j in range(28, 56): 

121 l = j + totrot[i] 

122 if l < 56: 

123 pcr[j] = pc1m[l] 

124 else: 

125 pcr[j] = pc1m[l - 28] 

126 for j in range(24): 

127 if pcr[pc2[j]]: 

128 kn[m] |= bigbyte[j] 

129 if pcr[pc2[j+24]]: 

130 kn[n] |= bigbyte[j] 

131 

132 return cookey(kn) 

133 

134def cookey(raw): 

135 key = [] 

136 for i in range(0, 32, 2): 

137 (raw0, raw1) = (raw[i], raw[i+1]) 

138 k = (raw0 & 0x00fc0000) << 6 

139 k |= (raw0 & 0x00000fc0) << 10 

140 k |= (raw1 & 0x00fc0000) >> 10 

141 k |= (raw1 & 0x00000fc0) >> 6 

142 key.append(k) 

143 k = (raw0 & 0x0003f000) << 12 

144 k |= (raw0 & 0x0000003f) << 16 

145 k |= (raw1 & 0x0003f000) >> 4 

146 k |= (raw1 & 0x0000003f) 

147 key.append(k) 

148 return key 

149 

150SP1 = [ 

151 0x01010400, 0x00000000, 0x00010000, 0x01010404, 

152 0x01010004, 0x00010404, 0x00000004, 0x00010000, 

153 0x00000400, 0x01010400, 0x01010404, 0x00000400, 

154 0x01000404, 0x01010004, 0x01000000, 0x00000004, 

155 0x00000404, 0x01000400, 0x01000400, 0x00010400, 

156 0x00010400, 0x01010000, 0x01010000, 0x01000404, 

157 0x00010004, 0x01000004, 0x01000004, 0x00010004, 

158 0x00000000, 0x00000404, 0x00010404, 0x01000000, 

159 0x00010000, 0x01010404, 0x00000004, 0x01010000, 

160 0x01010400, 0x01000000, 0x01000000, 0x00000400, 

161 0x01010004, 0x00010000, 0x00010400, 0x01000004, 

162 0x00000400, 0x00000004, 0x01000404, 0x00010404, 

163 0x01010404, 0x00010004, 0x01010000, 0x01000404, 

164 0x01000004, 0x00000404, 0x00010404, 0x01010400, 

165 0x00000404, 0x01000400, 0x01000400, 0x00000000, 

166 0x00010004, 0x00010400, 0x00000000, 0x01010004, 

167 ] 

168 

169SP2 = [ 

170 0x80108020, 0x80008000, 0x00008000, 0x00108020, 

171 0x00100000, 0x00000020, 0x80100020, 0x80008020, 

172 0x80000020, 0x80108020, 0x80108000, 0x80000000, 

173 0x80008000, 0x00100000, 0x00000020, 0x80100020, 

174 0x00108000, 0x00100020, 0x80008020, 0x00000000, 

175 0x80000000, 0x00008000, 0x00108020, 0x80100000, 

176 0x00100020, 0x80000020, 0x00000000, 0x00108000, 

177 0x00008020, 0x80108000, 0x80100000, 0x00008020, 

178 0x00000000, 0x00108020, 0x80100020, 0x00100000, 

179 0x80008020, 0x80100000, 0x80108000, 0x00008000, 

180 0x80100000, 0x80008000, 0x00000020, 0x80108020, 

181 0x00108020, 0x00000020, 0x00008000, 0x80000000, 

182 0x00008020, 0x80108000, 0x00100000, 0x80000020, 

183 0x00100020, 0x80008020, 0x80000020, 0x00100020, 

184 0x00108000, 0x00000000, 0x80008000, 0x00008020, 

185 0x80000000, 0x80100020, 0x80108020, 0x00108000, 

186 ] 

187 

188SP3 = [ 

189 0x00000208, 0x08020200, 0x00000000, 0x08020008, 

190 0x08000200, 0x00000000, 0x00020208, 0x08000200, 

191 0x00020008, 0x08000008, 0x08000008, 0x00020000, 

192 0x08020208, 0x00020008, 0x08020000, 0x00000208, 

193 0x08000000, 0x00000008, 0x08020200, 0x00000200, 

194 0x00020200, 0x08020000, 0x08020008, 0x00020208, 

195 0x08000208, 0x00020200, 0x00020000, 0x08000208, 

196 0x00000008, 0x08020208, 0x00000200, 0x08000000, 

197 0x08020200, 0x08000000, 0x00020008, 0x00000208, 

198 0x00020000, 0x08020200, 0x08000200, 0x00000000, 

199 0x00000200, 0x00020008, 0x08020208, 0x08000200, 

200 0x08000008, 0x00000200, 0x00000000, 0x08020008, 

201 0x08000208, 0x00020000, 0x08000000, 0x08020208, 

202 0x00000008, 0x00020208, 0x00020200, 0x08000008, 

203 0x08020000, 0x08000208, 0x00000208, 0x08020000, 

204 0x00020208, 0x00000008, 0x08020008, 0x00020200, 

205 ] 

206 

207SP4 = [ 

208 0x00802001, 0x00002081, 0x00002081, 0x00000080, 

209 0x00802080, 0x00800081, 0x00800001, 0x00002001, 

210 0x00000000, 0x00802000, 0x00802000, 0x00802081, 

211 0x00000081, 0x00000000, 0x00800080, 0x00800001, 

212 0x00000001, 0x00002000, 0x00800000, 0x00802001, 

213 0x00000080, 0x00800000, 0x00002001, 0x00002080, 

214 0x00800081, 0x00000001, 0x00002080, 0x00800080, 

215 0x00002000, 0x00802080, 0x00802081, 0x00000081, 

216 0x00800080, 0x00800001, 0x00802000, 0x00802081, 

217 0x00000081, 0x00000000, 0x00000000, 0x00802000, 

218 0x00002080, 0x00800080, 0x00800081, 0x00000001, 

219 0x00802001, 0x00002081, 0x00002081, 0x00000080, 

220 0x00802081, 0x00000081, 0x00000001, 0x00002000, 

221 0x00800001, 0x00002001, 0x00802080, 0x00800081, 

222 0x00002001, 0x00002080, 0x00800000, 0x00802001, 

223 0x00000080, 0x00800000, 0x00002000, 0x00802080, 

224 ] 

225 

226SP5 = [ 

227 0x00000100, 0x02080100, 0x02080000, 0x42000100, 

228 0x00080000, 0x00000100, 0x40000000, 0x02080000, 

229 0x40080100, 0x00080000, 0x02000100, 0x40080100, 

230 0x42000100, 0x42080000, 0x00080100, 0x40000000, 

231 0x02000000, 0x40080000, 0x40080000, 0x00000000, 

232 0x40000100, 0x42080100, 0x42080100, 0x02000100, 

233 0x42080000, 0x40000100, 0x00000000, 0x42000000, 

234 0x02080100, 0x02000000, 0x42000000, 0x00080100, 

235 0x00080000, 0x42000100, 0x00000100, 0x02000000, 

236 0x40000000, 0x02080000, 0x42000100, 0x40080100, 

237 0x02000100, 0x40000000, 0x42080000, 0x02080100, 

238 0x40080100, 0x00000100, 0x02000000, 0x42080000, 

239 0x42080100, 0x00080100, 0x42000000, 0x42080100, 

240 0x02080000, 0x00000000, 0x40080000, 0x42000000, 

241 0x00080100, 0x02000100, 0x40000100, 0x00080000, 

242 0x00000000, 0x40080000, 0x02080100, 0x40000100, 

243 ] 

244 

245SP6 = [ 

246 0x20000010, 0x20400000, 0x00004000, 0x20404010, 

247 0x20400000, 0x00000010, 0x20404010, 0x00400000, 

248 0x20004000, 0x00404010, 0x00400000, 0x20000010, 

249 0x00400010, 0x20004000, 0x20000000, 0x00004010, 

250 0x00000000, 0x00400010, 0x20004010, 0x00004000, 

251 0x00404000, 0x20004010, 0x00000010, 0x20400010, 

252 0x20400010, 0x00000000, 0x00404010, 0x20404000, 

253 0x00004010, 0x00404000, 0x20404000, 0x20000000, 

254 0x20004000, 0x00000010, 0x20400010, 0x00404000, 

255 0x20404010, 0x00400000, 0x00004010, 0x20000010, 

256 0x00400000, 0x20004000, 0x20000000, 0x00004010, 

257 0x20000010, 0x20404010, 0x00404000, 0x20400000, 

258 0x00404010, 0x20404000, 0x00000000, 0x20400010, 

259 0x00000010, 0x00004000, 0x20400000, 0x00404010, 

260 0x00004000, 0x00400010, 0x20004010, 0x00000000, 

261 0x20404000, 0x20000000, 0x00400010, 0x20004010, 

262 ] 

263 

264SP7 = [ 

265 0x00200000, 0x04200002, 0x04000802, 0x00000000, 

266 0x00000800, 0x04000802, 0x00200802, 0x04200800, 

267 0x04200802, 0x00200000, 0x00000000, 0x04000002, 

268 0x00000002, 0x04000000, 0x04200002, 0x00000802, 

269 0x04000800, 0x00200802, 0x00200002, 0x04000800, 

270 0x04000002, 0x04200000, 0x04200800, 0x00200002, 

271 0x04200000, 0x00000800, 0x00000802, 0x04200802, 

272 0x00200800, 0x00000002, 0x04000000, 0x00200800, 

273 0x04000000, 0x00200800, 0x00200000, 0x04000802, 

274 0x04000802, 0x04200002, 0x04200002, 0x00000002, 

275 0x00200002, 0x04000000, 0x04000800, 0x00200000, 

276 0x04200800, 0x00000802, 0x00200802, 0x04200800, 

277 0x00000802, 0x04000002, 0x04200802, 0x04200000, 

278 0x00200800, 0x00000000, 0x00000002, 0x04200802, 

279 0x00000000, 0x00200802, 0x04200000, 0x00000800, 

280 0x04000002, 0x04000800, 0x00000800, 0x00200002, 

281 ] 

282 

283SP8 = [ 

284 0x10001040, 0x00001000, 0x00040000, 0x10041040, 

285 0x10000000, 0x10001040, 0x00000040, 0x10000000, 

286 0x00040040, 0x10040000, 0x10041040, 0x00041000, 

287 0x10041000, 0x00041040, 0x00001000, 0x00000040, 

288 0x10040000, 0x10000040, 0x10001000, 0x00001040, 

289 0x00041000, 0x00040040, 0x10040040, 0x10041000, 

290 0x00001040, 0x00000000, 0x00000000, 0x10040040, 

291 0x10000040, 0x10001000, 0x00041040, 0x00040000, 

292 0x00041040, 0x00040000, 0x10041000, 0x00001000, 

293 0x00000040, 0x10040040, 0x00001000, 0x00041040, 

294 0x10001000, 0x00000040, 0x10000040, 0x10040000, 

295 0x10040040, 0x10000000, 0x00040000, 0x10001040, 

296 0x00000000, 0x10041040, 0x00040040, 0x10000040, 

297 0x10040000, 0x10001000, 0x10001040, 0x00000000, 

298 0x10041040, 0x00041000, 0x00041000, 0x00001040, 

299 0x00001040, 0x00040040, 0x10000000, 0x10041000, 

300 ] 

301 

302def desfunc(block, keys): 

303 (leftt, right) = unpack('>II', block) 

304 

305 work = ((leftt >> 4) ^ right) & 0x0f0f0f0f 

306 right ^= work 

307 leftt ^= (work << 4) 

308 work = ((leftt >> 16) ^ right) & 0x0000ffff 

309 right ^= work 

310 leftt ^= (work << 16) 

311 work = ((right >> 2) ^ leftt) & 0x33333333 

312 leftt ^= work 

313 right ^= (work << 2) 

314 work = ((right >> 8) ^ leftt) & 0x00ff00ff 

315 leftt ^= work 

316 right ^= (work << 8) 

317 right = ((right << 1) | ((right >> 31) & 1)) & 0xffffffff 

318 work = (leftt ^ right) & 0xaaaaaaaa 

319 leftt ^= work 

320 right ^= work 

321 leftt = ((leftt << 1) | ((leftt >> 31) & 1)) & 0xffffffff 

322 

323 for i in range(0, 32, 4): 

324 work = (right << 28) | (right >> 4) 

325 work ^= keys[i] 

326 fval = SP7[ work & 0x3f] 

327 fval |= SP5[(work >> 8) & 0x3f] 

328 fval |= SP3[(work >> 16) & 0x3f] 

329 fval |= SP1[(work >> 24) & 0x3f] 

330 work = right ^ keys[i+1] 

331 fval |= SP8[ work & 0x3f] 

332 fval |= SP6[(work >> 8) & 0x3f] 

333 fval |= SP4[(work >> 16) & 0x3f] 

334 fval |= SP2[(work >> 24) & 0x3f] 

335 leftt ^= fval 

336 work = (leftt << 28) | (leftt >> 4) 

337 work ^= keys[i+2] 

338 fval = SP7[ work & 0x3f] 

339 fval |= SP5[(work >> 8) & 0x3f] 

340 fval |= SP3[(work >> 16) & 0x3f] 

341 fval |= SP1[(work >> 24) & 0x3f] 

342 work = leftt ^ keys[i+3] 

343 fval |= SP8[ work & 0x3f] 

344 fval |= SP6[(work >> 8) & 0x3f] 

345 fval |= SP4[(work >> 16) & 0x3f] 

346 fval |= SP2[(work >> 24) & 0x3f] 

347 right ^= fval 

348 

349 right = (right << 31) | (right >> 1) 

350 work = (leftt ^ right) & 0xaaaaaaaa 

351 leftt ^= work 

352 right ^= work 

353 leftt = (leftt << 31) | (leftt >> 1) 

354 work = ((leftt >> 8) ^ right) & 0x00ff00ff 

355 right ^= work 

356 leftt ^= (work << 8) 

357 work = ((leftt >> 2) ^ right) & 0x33333333 

358 right ^= work 

359 leftt ^= (work << 2) 

360 work = ((right >> 16) ^ leftt) & 0x0000ffff 

361 leftt ^= work 

362 right ^= (work << 16) 

363 work = ((right >> 4) ^ leftt) & 0x0f0f0f0f 

364 leftt ^= work 

365 right ^= (work << 4) 

366 

367 leftt &= 0xffffffff 

368 right &= 0xffffffff 

369 return pack('>II', right, leftt)