des3.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /* des3.c
  2. *
  3. * Copyright (C) 2006-2011 Sawtooth Consulting Ltd.
  4. *
  5. * This file is part of CyaSSL.
  6. *
  7. * CyaSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * CyaSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  20. */
  21. #ifndef NO_DES3
  22. #include "des3.h"
  23. #ifdef NO_INLINE
  24. #include "misc.h"
  25. #else
  26. #include "misc.c"
  27. #endif
  28. /* permuted choice table (key) */
  29. static const byte pc1[] = {
  30. 57, 49, 41, 33, 25, 17, 9,
  31. 1, 58, 50, 42, 34, 26, 18,
  32. 10, 2, 59, 51, 43, 35, 27,
  33. 19, 11, 3, 60, 52, 44, 36,
  34. 63, 55, 47, 39, 31, 23, 15,
  35. 7, 62, 54, 46, 38, 30, 22,
  36. 14, 6, 61, 53, 45, 37, 29,
  37. 21, 13, 5, 28, 20, 12, 4
  38. };
  39. /* number left rotations of pc1 */
  40. static const byte totrot[] = {
  41. 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28
  42. };
  43. /* permuted choice key (table) */
  44. static const byte pc2[] = {
  45. 14, 17, 11, 24, 1, 5,
  46. 3, 28, 15, 6, 21, 10,
  47. 23, 19, 12, 4, 26, 8,
  48. 16, 7, 27, 20, 13, 2,
  49. 41, 52, 31, 37, 47, 55,
  50. 30, 40, 51, 45, 33, 48,
  51. 44, 49, 39, 56, 34, 53,
  52. 46, 42, 50, 36, 29, 32
  53. };
  54. /* End of DES-defined tables */
  55. /* bit 0 is left-most in byte */
  56. static const int bytebit[] = {
  57. 0200,0100,040,020,010,04,02,01
  58. };
  59. const word32 Spbox[8][64] = {
  60. {
  61. 0x01010400,0x00000000,0x00010000,0x01010404,
  62. 0x01010004,0x00010404,0x00000004,0x00010000,
  63. 0x00000400,0x01010400,0x01010404,0x00000400,
  64. 0x01000404,0x01010004,0x01000000,0x00000004,
  65. 0x00000404,0x01000400,0x01000400,0x00010400,
  66. 0x00010400,0x01010000,0x01010000,0x01000404,
  67. 0x00010004,0x01000004,0x01000004,0x00010004,
  68. 0x00000000,0x00000404,0x00010404,0x01000000,
  69. 0x00010000,0x01010404,0x00000004,0x01010000,
  70. 0x01010400,0x01000000,0x01000000,0x00000400,
  71. 0x01010004,0x00010000,0x00010400,0x01000004,
  72. 0x00000400,0x00000004,0x01000404,0x00010404,
  73. 0x01010404,0x00010004,0x01010000,0x01000404,
  74. 0x01000004,0x00000404,0x00010404,0x01010400,
  75. 0x00000404,0x01000400,0x01000400,0x00000000,
  76. 0x00010004,0x00010400,0x00000000,0x01010004},
  77. {
  78. 0x80108020,0x80008000,0x00008000,0x00108020,
  79. 0x00100000,0x00000020,0x80100020,0x80008020,
  80. 0x80000020,0x80108020,0x80108000,0x80000000,
  81. 0x80008000,0x00100000,0x00000020,0x80100020,
  82. 0x00108000,0x00100020,0x80008020,0x00000000,
  83. 0x80000000,0x00008000,0x00108020,0x80100000,
  84. 0x00100020,0x80000020,0x00000000,0x00108000,
  85. 0x00008020,0x80108000,0x80100000,0x00008020,
  86. 0x00000000,0x00108020,0x80100020,0x00100000,
  87. 0x80008020,0x80100000,0x80108000,0x00008000,
  88. 0x80100000,0x80008000,0x00000020,0x80108020,
  89. 0x00108020,0x00000020,0x00008000,0x80000000,
  90. 0x00008020,0x80108000,0x00100000,0x80000020,
  91. 0x00100020,0x80008020,0x80000020,0x00100020,
  92. 0x00108000,0x00000000,0x80008000,0x00008020,
  93. 0x80000000,0x80100020,0x80108020,0x00108000},
  94. {
  95. 0x00000208,0x08020200,0x00000000,0x08020008,
  96. 0x08000200,0x00000000,0x00020208,0x08000200,
  97. 0x00020008,0x08000008,0x08000008,0x00020000,
  98. 0x08020208,0x00020008,0x08020000,0x00000208,
  99. 0x08000000,0x00000008,0x08020200,0x00000200,
  100. 0x00020200,0x08020000,0x08020008,0x00020208,
  101. 0x08000208,0x00020200,0x00020000,0x08000208,
  102. 0x00000008,0x08020208,0x00000200,0x08000000,
  103. 0x08020200,0x08000000,0x00020008,0x00000208,
  104. 0x00020000,0x08020200,0x08000200,0x00000000,
  105. 0x00000200,0x00020008,0x08020208,0x08000200,
  106. 0x08000008,0x00000200,0x00000000,0x08020008,
  107. 0x08000208,0x00020000,0x08000000,0x08020208,
  108. 0x00000008,0x00020208,0x00020200,0x08000008,
  109. 0x08020000,0x08000208,0x00000208,0x08020000,
  110. 0x00020208,0x00000008,0x08020008,0x00020200},
  111. {
  112. 0x00802001,0x00002081,0x00002081,0x00000080,
  113. 0x00802080,0x00800081,0x00800001,0x00002001,
  114. 0x00000000,0x00802000,0x00802000,0x00802081,
  115. 0x00000081,0x00000000,0x00800080,0x00800001,
  116. 0x00000001,0x00002000,0x00800000,0x00802001,
  117. 0x00000080,0x00800000,0x00002001,0x00002080,
  118. 0x00800081,0x00000001,0x00002080,0x00800080,
  119. 0x00002000,0x00802080,0x00802081,0x00000081,
  120. 0x00800080,0x00800001,0x00802000,0x00802081,
  121. 0x00000081,0x00000000,0x00000000,0x00802000,
  122. 0x00002080,0x00800080,0x00800081,0x00000001,
  123. 0x00802001,0x00002081,0x00002081,0x00000080,
  124. 0x00802081,0x00000081,0x00000001,0x00002000,
  125. 0x00800001,0x00002001,0x00802080,0x00800081,
  126. 0x00002001,0x00002080,0x00800000,0x00802001,
  127. 0x00000080,0x00800000,0x00002000,0x00802080},
  128. {
  129. 0x00000100,0x02080100,0x02080000,0x42000100,
  130. 0x00080000,0x00000100,0x40000000,0x02080000,
  131. 0x40080100,0x00080000,0x02000100,0x40080100,
  132. 0x42000100,0x42080000,0x00080100,0x40000000,
  133. 0x02000000,0x40080000,0x40080000,0x00000000,
  134. 0x40000100,0x42080100,0x42080100,0x02000100,
  135. 0x42080000,0x40000100,0x00000000,0x42000000,
  136. 0x02080100,0x02000000,0x42000000,0x00080100,
  137. 0x00080000,0x42000100,0x00000100,0x02000000,
  138. 0x40000000,0x02080000,0x42000100,0x40080100,
  139. 0x02000100,0x40000000,0x42080000,0x02080100,
  140. 0x40080100,0x00000100,0x02000000,0x42080000,
  141. 0x42080100,0x00080100,0x42000000,0x42080100,
  142. 0x02080000,0x00000000,0x40080000,0x42000000,
  143. 0x00080100,0x02000100,0x40000100,0x00080000,
  144. 0x00000000,0x40080000,0x02080100,0x40000100},
  145. {
  146. 0x20000010,0x20400000,0x00004000,0x20404010,
  147. 0x20400000,0x00000010,0x20404010,0x00400000,
  148. 0x20004000,0x00404010,0x00400000,0x20000010,
  149. 0x00400010,0x20004000,0x20000000,0x00004010,
  150. 0x00000000,0x00400010,0x20004010,0x00004000,
  151. 0x00404000,0x20004010,0x00000010,0x20400010,
  152. 0x20400010,0x00000000,0x00404010,0x20404000,
  153. 0x00004010,0x00404000,0x20404000,0x20000000,
  154. 0x20004000,0x00000010,0x20400010,0x00404000,
  155. 0x20404010,0x00400000,0x00004010,0x20000010,
  156. 0x00400000,0x20004000,0x20000000,0x00004010,
  157. 0x20000010,0x20404010,0x00404000,0x20400000,
  158. 0x00404010,0x20404000,0x00000000,0x20400010,
  159. 0x00000010,0x00004000,0x20400000,0x00404010,
  160. 0x00004000,0x00400010,0x20004010,0x00000000,
  161. 0x20404000,0x20000000,0x00400010,0x20004010},
  162. {
  163. 0x00200000,0x04200002,0x04000802,0x00000000,
  164. 0x00000800,0x04000802,0x00200802,0x04200800,
  165. 0x04200802,0x00200000,0x00000000,0x04000002,
  166. 0x00000002,0x04000000,0x04200002,0x00000802,
  167. 0x04000800,0x00200802,0x00200002,0x04000800,
  168. 0x04000002,0x04200000,0x04200800,0x00200002,
  169. 0x04200000,0x00000800,0x00000802,0x04200802,
  170. 0x00200800,0x00000002,0x04000000,0x00200800,
  171. 0x04000000,0x00200800,0x00200000,0x04000802,
  172. 0x04000802,0x04200002,0x04200002,0x00000002,
  173. 0x00200002,0x04000000,0x04000800,0x00200000,
  174. 0x04200800,0x00000802,0x00200802,0x04200800,
  175. 0x00000802,0x04000002,0x04200802,0x04200000,
  176. 0x00200800,0x00000000,0x00000002,0x04200802,
  177. 0x00000000,0x00200802,0x04200000,0x00000800,
  178. 0x04000002,0x04000800,0x00000800,0x00200002},
  179. {
  180. 0x10001040,0x00001000,0x00040000,0x10041040,
  181. 0x10000000,0x10001040,0x00000040,0x10000000,
  182. 0x00040040,0x10040000,0x10041040,0x00041000,
  183. 0x10041000,0x00041040,0x00001000,0x00000040,
  184. 0x10040000,0x10000040,0x10001000,0x00001040,
  185. 0x00041000,0x00040040,0x10040040,0x10041000,
  186. 0x00001040,0x00000000,0x00000000,0x10040040,
  187. 0x10000040,0x10001000,0x00041040,0x00040000,
  188. 0x00041040,0x00040000,0x10041000,0x00001000,
  189. 0x00000040,0x10040040,0x00001000,0x00041040,
  190. 0x10001000,0x00000040,0x10000040,0x10040000,
  191. 0x10040040,0x10000000,0x00040000,0x10001040,
  192. 0x00000000,0x10041040,0x00040040,0x10000040,
  193. 0x10040000,0x10001000,0x10001040,0x00000000,
  194. 0x10041040,0x00041000,0x00041000,0x00001040,
  195. 0x00001040,0x00040040,0x10000000,0x10041000}
  196. };
  197. static INLINE void IPERM(word32* left, word32* right)
  198. {
  199. word32 work;
  200. *right = rotlFixed(*right, 4U);
  201. work = (*left ^ *right) & 0xf0f0f0f0;
  202. *left ^= work;
  203. *right = rotrFixed(*right^work, 20U);
  204. work = (*left ^ *right) & 0xffff0000;
  205. *left ^= work;
  206. *right = rotrFixed(*right^work, 18U);
  207. work = (*left ^ *right) & 0x33333333;
  208. *left ^= work;
  209. *right = rotrFixed(*right^work, 6U);
  210. work = (*left ^ *right) & 0x00ff00ff;
  211. *left ^= work;
  212. *right = rotlFixed(*right^work, 9U);
  213. work = (*left ^ *right) & 0xaaaaaaaa;
  214. *left = rotlFixed(*left^work, 1U);
  215. *right ^= work;
  216. }
  217. static INLINE void FPERM(word32* left, word32* right)
  218. {
  219. word32 work;
  220. *right = rotrFixed(*right, 1U);
  221. work = (*left ^ *right) & 0xaaaaaaaa;
  222. *right ^= work;
  223. *left = rotrFixed(*left^work, 9U);
  224. work = (*left ^ *right) & 0x00ff00ff;
  225. *right ^= work;
  226. *left = rotlFixed(*left^work, 6U);
  227. work = (*left ^ *right) & 0x33333333;
  228. *right ^= work;
  229. *left = rotlFixed(*left^work, 18U);
  230. work = (*left ^ *right) & 0xffff0000;
  231. *right ^= work;
  232. *left = rotlFixed(*left^work, 20U);
  233. work = (*left ^ *right) & 0xf0f0f0f0;
  234. *right ^= work;
  235. *left = rotrFixed(*left^work, 4U);
  236. }
  237. static void DesSetKey(const byte* key, int dir, word32* out)
  238. {
  239. byte buffer[56+56+8];
  240. byte *const pc1m = buffer; /* place to modify pc1 into */
  241. byte *const pcr = pc1m + 56; /* place to rotate pc1 into */
  242. byte *const ks = pcr + 56;
  243. register int i,j,l;
  244. int m;
  245. for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */
  246. l = pc1[j] - 1; /* integer bit location */
  247. m = l & 07; /* find bit */
  248. pc1m[j] = (key[l >> 3] & /* find which key byte l is in */
  249. bytebit[m]) /* and which bit of that byte */
  250. ? 1 : 0; /* and store 1-bit result */
  251. }
  252. for (i = 0; i < 16; i++) { /* key chunk for each iteration */
  253. XMEMSET(ks, 0, 8); /* Clear key schedule */
  254. for (j = 0; j < 56; j++) /* rotate pc1 the right amount */
  255. pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28];
  256. /* rotate left and right halves independently */
  257. for (j = 0; j < 48; j++){ /* select bits individually */
  258. /* check bit that goes to ks[j] */
  259. if (pcr[pc2[j] - 1]){
  260. /* mask it in if it's there */
  261. l= j % 6;
  262. ks[j/6] |= bytebit[l] >> 2;
  263. }
  264. }
  265. /* Now convert to odd/even interleaved form for use in F */
  266. out[2*i] = ((word32)ks[0] << 24)
  267. | ((word32)ks[2] << 16)
  268. | ((word32)ks[4] << 8)
  269. | ((word32)ks[6]);
  270. out[2*i + 1] = ((word32)ks[1] << 24)
  271. | ((word32)ks[3] << 16)
  272. | ((word32)ks[5] << 8)
  273. | ((word32)ks[7]);
  274. }
  275. /* reverse key schedule order */
  276. if (dir == DES_DECRYPTION)
  277. for (i = 0; i < 16; i += 2) {
  278. word32 swap = out[i];
  279. out[i] = out[DES_KS_SIZE - 2 - i];
  280. out[DES_KS_SIZE - 2 - i] = swap;
  281. swap = out[i + 1];
  282. out[i + 1] = out[DES_KS_SIZE - 1 - i];
  283. out[DES_KS_SIZE - 1 - i] = swap;
  284. }
  285. }
  286. static INLINE int Reverse(int dir)
  287. {
  288. return !dir;
  289. }
  290. void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir)
  291. {
  292. DesSetKey(key, dir, des->key);
  293. XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
  294. }
  295. void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir)
  296. {
  297. DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]);
  298. DesSetKey(key + 8, Reverse(dir), des->key[1]);
  299. DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]);
  300. XMEMCPY(des->reg, iv, DES_BLOCK_SIZE);
  301. }
  302. void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr)
  303. {
  304. word32 l = *lIn, r = *rIn, i;
  305. for (i=0; i<8; i++)
  306. {
  307. word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0];
  308. l ^= Spbox[6][(work) & 0x3f]
  309. ^ Spbox[4][(work >> 8) & 0x3f]
  310. ^ Spbox[2][(work >> 16) & 0x3f]
  311. ^ Spbox[0][(work >> 24) & 0x3f];
  312. work = r ^ kptr[4*i+1];
  313. l ^= Spbox[7][(work) & 0x3f]
  314. ^ Spbox[5][(work >> 8) & 0x3f]
  315. ^ Spbox[3][(work >> 16) & 0x3f]
  316. ^ Spbox[1][(work >> 24) & 0x3f];
  317. work = rotrFixed(l, 4U) ^ kptr[4*i+2];
  318. r ^= Spbox[6][(work) & 0x3f]
  319. ^ Spbox[4][(work >> 8) & 0x3f]
  320. ^ Spbox[2][(work >> 16) & 0x3f]
  321. ^ Spbox[0][(work >> 24) & 0x3f];
  322. work = l ^ kptr[4*i+3];
  323. r ^= Spbox[7][(work) & 0x3f]
  324. ^ Spbox[5][(work >> 8) & 0x3f]
  325. ^ Spbox[3][(work >> 16) & 0x3f]
  326. ^ Spbox[1][(work >> 24) & 0x3f];
  327. }
  328. *lIn = l; *rIn = r;
  329. }
  330. static void DesProcessBlock(Des* des, const byte* in, byte* out)
  331. {
  332. word32 l, r;
  333. XMEMCPY(&l, in, sizeof(l));
  334. XMEMCPY(&r, in + sizeof(l), sizeof(r));
  335. #ifdef LITTLE_ENDIAN_ORDER
  336. l = ByteReverseWord32(l);
  337. r = ByteReverseWord32(r);
  338. #endif
  339. IPERM(&l,&r);
  340. DesRawProcessBlock(&l, &r, des->key);
  341. FPERM(&l,&r);
  342. #ifdef LITTLE_ENDIAN_ORDER
  343. l = ByteReverseWord32(l);
  344. r = ByteReverseWord32(r);
  345. #endif
  346. XMEMCPY(out, &r, sizeof(r));
  347. XMEMCPY(out + sizeof(r), &l, sizeof(l));
  348. }
  349. static void Des3ProcessBlock(Des3* des, const byte* in, byte* out)
  350. {
  351. word32 l, r;
  352. XMEMCPY(&l, in, sizeof(l));
  353. XMEMCPY(&r, in + sizeof(l), sizeof(r));
  354. #ifdef LITTLE_ENDIAN_ORDER
  355. l = ByteReverseWord32(l);
  356. r = ByteReverseWord32(r);
  357. #endif
  358. IPERM(&l,&r);
  359. DesRawProcessBlock(&l, &r, des->key[0]);
  360. DesRawProcessBlock(&r, &l, des->key[1]);
  361. DesRawProcessBlock(&l, &r, des->key[2]);
  362. FPERM(&l,&r);
  363. #ifdef LITTLE_ENDIAN_ORDER
  364. l = ByteReverseWord32(l);
  365. r = ByteReverseWord32(r);
  366. #endif
  367. XMEMCPY(out, &r, sizeof(r));
  368. XMEMCPY(out + sizeof(r), &l, sizeof(l));
  369. }
  370. void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz)
  371. {
  372. word32 blocks = sz / DES_BLOCK_SIZE;
  373. while (blocks--) {
  374. xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
  375. DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
  376. XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
  377. out += DES_BLOCK_SIZE;
  378. in += DES_BLOCK_SIZE;
  379. }
  380. }
  381. void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz)
  382. {
  383. word32 blocks = sz / DES_BLOCK_SIZE;
  384. byte hold[16];
  385. while (blocks--) {
  386. XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
  387. DesProcessBlock(des, (byte*)des->tmp, out);
  388. xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
  389. XMEMCPY(hold, des->reg, DES_BLOCK_SIZE);
  390. XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
  391. XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE);
  392. out += DES_BLOCK_SIZE;
  393. in += DES_BLOCK_SIZE;
  394. }
  395. }
  396. void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz)
  397. {
  398. word32 blocks = sz / DES_BLOCK_SIZE;
  399. while (blocks--) {
  400. xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE);
  401. Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg);
  402. XMEMCPY(out, des->reg, DES_BLOCK_SIZE);
  403. out += DES_BLOCK_SIZE;
  404. in += DES_BLOCK_SIZE;
  405. }
  406. }
  407. void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz)
  408. {
  409. word32 blocks = sz / DES_BLOCK_SIZE;
  410. while (blocks--) {
  411. XMEMCPY(des->tmp, in, DES_BLOCK_SIZE);
  412. Des3ProcessBlock(des, (byte*)des->tmp, out);
  413. xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE);
  414. XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE);
  415. out += DES_BLOCK_SIZE;
  416. in += DES_BLOCK_SIZE;
  417. }
  418. }
  419. #endif /* NO_DES3 */