CyaSSL is an SSL library for devices like mbed.
Dependents: cyassl-client Sync
des3.c
00001 /* des3.c 00002 * 00003 * Copyright (C) 2006-2009 Sawtooth Consulting Ltd. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 00023 #ifndef NO_DES3 00024 00025 #include "des3.h" 00026 #ifdef NO_INLINE 00027 #include "misc.h" 00028 #else 00029 #include "misc.c" 00030 #endif 00031 00032 00033 /* permuted choice table (key) */ 00034 static const byte pc1[] = { 00035 57, 49, 41, 33, 25, 17, 9, 00036 1, 58, 50, 42, 34, 26, 18, 00037 10, 2, 59, 51, 43, 35, 27, 00038 19, 11, 3, 60, 52, 44, 36, 00039 00040 63, 55, 47, 39, 31, 23, 15, 00041 7, 62, 54, 46, 38, 30, 22, 00042 14, 6, 61, 53, 45, 37, 29, 00043 21, 13, 5, 28, 20, 12, 4 00044 }; 00045 00046 /* number left rotations of pc1 */ 00047 static const byte totrot[] = { 00048 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 00049 }; 00050 00051 /* permuted choice key (table) */ 00052 static const byte pc2[] = { 00053 14, 17, 11, 24, 1, 5, 00054 3, 28, 15, 6, 21, 10, 00055 23, 19, 12, 4, 26, 8, 00056 16, 7, 27, 20, 13, 2, 00057 41, 52, 31, 37, 47, 55, 00058 30, 40, 51, 45, 33, 48, 00059 44, 49, 39, 56, 34, 53, 00060 46, 42, 50, 36, 29, 32 00061 }; 00062 00063 /* End of DES-defined tables */ 00064 00065 /* bit 0 is left-most in byte */ 00066 static const int bytebit[] = { 00067 0200,0100,040,020,010,04,02,01 00068 }; 00069 00070 const word32 Spbox[8][64] = { 00071 { 00072 0x01010400,0x00000000,0x00010000,0x01010404, 00073 0x01010004,0x00010404,0x00000004,0x00010000, 00074 0x00000400,0x01010400,0x01010404,0x00000400, 00075 0x01000404,0x01010004,0x01000000,0x00000004, 00076 0x00000404,0x01000400,0x01000400,0x00010400, 00077 0x00010400,0x01010000,0x01010000,0x01000404, 00078 0x00010004,0x01000004,0x01000004,0x00010004, 00079 0x00000000,0x00000404,0x00010404,0x01000000, 00080 0x00010000,0x01010404,0x00000004,0x01010000, 00081 0x01010400,0x01000000,0x01000000,0x00000400, 00082 0x01010004,0x00010000,0x00010400,0x01000004, 00083 0x00000400,0x00000004,0x01000404,0x00010404, 00084 0x01010404,0x00010004,0x01010000,0x01000404, 00085 0x01000004,0x00000404,0x00010404,0x01010400, 00086 0x00000404,0x01000400,0x01000400,0x00000000, 00087 0x00010004,0x00010400,0x00000000,0x01010004}, 00088 { 00089 0x80108020,0x80008000,0x00008000,0x00108020, 00090 0x00100000,0x00000020,0x80100020,0x80008020, 00091 0x80000020,0x80108020,0x80108000,0x80000000, 00092 0x80008000,0x00100000,0x00000020,0x80100020, 00093 0x00108000,0x00100020,0x80008020,0x00000000, 00094 0x80000000,0x00008000,0x00108020,0x80100000, 00095 0x00100020,0x80000020,0x00000000,0x00108000, 00096 0x00008020,0x80108000,0x80100000,0x00008020, 00097 0x00000000,0x00108020,0x80100020,0x00100000, 00098 0x80008020,0x80100000,0x80108000,0x00008000, 00099 0x80100000,0x80008000,0x00000020,0x80108020, 00100 0x00108020,0x00000020,0x00008000,0x80000000, 00101 0x00008020,0x80108000,0x00100000,0x80000020, 00102 0x00100020,0x80008020,0x80000020,0x00100020, 00103 0x00108000,0x00000000,0x80008000,0x00008020, 00104 0x80000000,0x80100020,0x80108020,0x00108000}, 00105 { 00106 0x00000208,0x08020200,0x00000000,0x08020008, 00107 0x08000200,0x00000000,0x00020208,0x08000200, 00108 0x00020008,0x08000008,0x08000008,0x00020000, 00109 0x08020208,0x00020008,0x08020000,0x00000208, 00110 0x08000000,0x00000008,0x08020200,0x00000200, 00111 0x00020200,0x08020000,0x08020008,0x00020208, 00112 0x08000208,0x00020200,0x00020000,0x08000208, 00113 0x00000008,0x08020208,0x00000200,0x08000000, 00114 0x08020200,0x08000000,0x00020008,0x00000208, 00115 0x00020000,0x08020200,0x08000200,0x00000000, 00116 0x00000200,0x00020008,0x08020208,0x08000200, 00117 0x08000008,0x00000200,0x00000000,0x08020008, 00118 0x08000208,0x00020000,0x08000000,0x08020208, 00119 0x00000008,0x00020208,0x00020200,0x08000008, 00120 0x08020000,0x08000208,0x00000208,0x08020000, 00121 0x00020208,0x00000008,0x08020008,0x00020200}, 00122 { 00123 0x00802001,0x00002081,0x00002081,0x00000080, 00124 0x00802080,0x00800081,0x00800001,0x00002001, 00125 0x00000000,0x00802000,0x00802000,0x00802081, 00126 0x00000081,0x00000000,0x00800080,0x00800001, 00127 0x00000001,0x00002000,0x00800000,0x00802001, 00128 0x00000080,0x00800000,0x00002001,0x00002080, 00129 0x00800081,0x00000001,0x00002080,0x00800080, 00130 0x00002000,0x00802080,0x00802081,0x00000081, 00131 0x00800080,0x00800001,0x00802000,0x00802081, 00132 0x00000081,0x00000000,0x00000000,0x00802000, 00133 0x00002080,0x00800080,0x00800081,0x00000001, 00134 0x00802001,0x00002081,0x00002081,0x00000080, 00135 0x00802081,0x00000081,0x00000001,0x00002000, 00136 0x00800001,0x00002001,0x00802080,0x00800081, 00137 0x00002001,0x00002080,0x00800000,0x00802001, 00138 0x00000080,0x00800000,0x00002000,0x00802080}, 00139 { 00140 0x00000100,0x02080100,0x02080000,0x42000100, 00141 0x00080000,0x00000100,0x40000000,0x02080000, 00142 0x40080100,0x00080000,0x02000100,0x40080100, 00143 0x42000100,0x42080000,0x00080100,0x40000000, 00144 0x02000000,0x40080000,0x40080000,0x00000000, 00145 0x40000100,0x42080100,0x42080100,0x02000100, 00146 0x42080000,0x40000100,0x00000000,0x42000000, 00147 0x02080100,0x02000000,0x42000000,0x00080100, 00148 0x00080000,0x42000100,0x00000100,0x02000000, 00149 0x40000000,0x02080000,0x42000100,0x40080100, 00150 0x02000100,0x40000000,0x42080000,0x02080100, 00151 0x40080100,0x00000100,0x02000000,0x42080000, 00152 0x42080100,0x00080100,0x42000000,0x42080100, 00153 0x02080000,0x00000000,0x40080000,0x42000000, 00154 0x00080100,0x02000100,0x40000100,0x00080000, 00155 0x00000000,0x40080000,0x02080100,0x40000100}, 00156 { 00157 0x20000010,0x20400000,0x00004000,0x20404010, 00158 0x20400000,0x00000010,0x20404010,0x00400000, 00159 0x20004000,0x00404010,0x00400000,0x20000010, 00160 0x00400010,0x20004000,0x20000000,0x00004010, 00161 0x00000000,0x00400010,0x20004010,0x00004000, 00162 0x00404000,0x20004010,0x00000010,0x20400010, 00163 0x20400010,0x00000000,0x00404010,0x20404000, 00164 0x00004010,0x00404000,0x20404000,0x20000000, 00165 0x20004000,0x00000010,0x20400010,0x00404000, 00166 0x20404010,0x00400000,0x00004010,0x20000010, 00167 0x00400000,0x20004000,0x20000000,0x00004010, 00168 0x20000010,0x20404010,0x00404000,0x20400000, 00169 0x00404010,0x20404000,0x00000000,0x20400010, 00170 0x00000010,0x00004000,0x20400000,0x00404010, 00171 0x00004000,0x00400010,0x20004010,0x00000000, 00172 0x20404000,0x20000000,0x00400010,0x20004010}, 00173 { 00174 0x00200000,0x04200002,0x04000802,0x00000000, 00175 0x00000800,0x04000802,0x00200802,0x04200800, 00176 0x04200802,0x00200000,0x00000000,0x04000002, 00177 0x00000002,0x04000000,0x04200002,0x00000802, 00178 0x04000800,0x00200802,0x00200002,0x04000800, 00179 0x04000002,0x04200000,0x04200800,0x00200002, 00180 0x04200000,0x00000800,0x00000802,0x04200802, 00181 0x00200800,0x00000002,0x04000000,0x00200800, 00182 0x04000000,0x00200800,0x00200000,0x04000802, 00183 0x04000802,0x04200002,0x04200002,0x00000002, 00184 0x00200002,0x04000000,0x04000800,0x00200000, 00185 0x04200800,0x00000802,0x00200802,0x04200800, 00186 0x00000802,0x04000002,0x04200802,0x04200000, 00187 0x00200800,0x00000000,0x00000002,0x04200802, 00188 0x00000000,0x00200802,0x04200000,0x00000800, 00189 0x04000002,0x04000800,0x00000800,0x00200002}, 00190 { 00191 0x10001040,0x00001000,0x00040000,0x10041040, 00192 0x10000000,0x10001040,0x00000040,0x10000000, 00193 0x00040040,0x10040000,0x10041040,0x00041000, 00194 0x10041000,0x00041040,0x00001000,0x00000040, 00195 0x10040000,0x10000040,0x10001000,0x00001040, 00196 0x00041000,0x00040040,0x10040040,0x10041000, 00197 0x00001040,0x00000000,0x00000000,0x10040040, 00198 0x10000040,0x10001000,0x00041040,0x00040000, 00199 0x00041040,0x00040000,0x10041000,0x00001000, 00200 0x00000040,0x10040040,0x00001000,0x00041040, 00201 0x10001000,0x00000040,0x10000040,0x10040000, 00202 0x10040040,0x10000000,0x00040000,0x10001040, 00203 0x00000000,0x10041040,0x00040040,0x10000040, 00204 0x10040000,0x10001000,0x10001040,0x00000000, 00205 0x10041040,0x00041000,0x00041000,0x00001040, 00206 0x00001040,0x00040040,0x10000000,0x10041000} 00207 }; 00208 00209 00210 static INLINE void IPERM(word32* left, word32* right) 00211 { 00212 word32 work; 00213 00214 *right = rotlFixed(*right, 4U); 00215 work = (*left ^ *right) & 0xf0f0f0f0; 00216 *left ^= work; 00217 00218 *right = rotrFixed(*right^work, 20U); 00219 work = (*left ^ *right) & 0xffff0000; 00220 *left ^= work; 00221 00222 *right = rotrFixed(*right^work, 18U); 00223 work = (*left ^ *right) & 0x33333333; 00224 *left ^= work; 00225 00226 *right = rotrFixed(*right^work, 6U); 00227 work = (*left ^ *right) & 0x00ff00ff; 00228 *left ^= work; 00229 00230 *right = rotlFixed(*right^work, 9U); 00231 work = (*left ^ *right) & 0xaaaaaaaa; 00232 *left = rotlFixed(*left^work, 1U); 00233 *right ^= work; 00234 } 00235 00236 00237 static INLINE void FPERM(word32* left, word32* right) 00238 { 00239 word32 work; 00240 00241 *right = rotrFixed(*right, 1U); 00242 work = (*left ^ *right) & 0xaaaaaaaa; 00243 *right ^= work; 00244 00245 *left = rotrFixed(*left^work, 9U); 00246 work = (*left ^ *right) & 0x00ff00ff; 00247 *right ^= work; 00248 00249 *left = rotlFixed(*left^work, 6U); 00250 work = (*left ^ *right) & 0x33333333; 00251 *right ^= work; 00252 00253 *left = rotlFixed(*left^work, 18U); 00254 work = (*left ^ *right) & 0xffff0000; 00255 *right ^= work; 00256 00257 *left = rotlFixed(*left^work, 20U); 00258 work = (*left ^ *right) & 0xf0f0f0f0; 00259 *right ^= work; 00260 00261 *left = rotrFixed(*left^work, 4U); 00262 } 00263 00264 00265 static void DesSetKey(const byte* key, int dir, word32* out) 00266 { 00267 byte buffer[56+56+8]; 00268 byte *const pc1m = buffer; /* place to modify pc1 into */ 00269 byte *const pcr = pc1m + 56; /* place to rotate pc1 into */ 00270 byte *const ks = pcr + 56; 00271 register int i,j,l; 00272 int m; 00273 00274 for (j = 0; j < 56; j++) { /* convert pc1 to bits of key */ 00275 l = pc1[j] - 1; /* integer bit location */ 00276 m = l & 07; /* find bit */ 00277 pc1m[j] = (key[l >> 3] & /* find which key byte l is in */ 00278 bytebit[m]) /* and which bit of that byte */ 00279 ? 1 : 0; /* and store 1-bit result */ 00280 } 00281 for (i = 0; i < 16; i++) { /* key chunk for each iteration */ 00282 XMEMSET(ks, 0, 8); /* Clear key schedule */ 00283 for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ 00284 pcr[j] = pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l: l-28]; 00285 /* rotate left and right halves independently */ 00286 for (j = 0; j < 48; j++){ /* select bits individually */ 00287 /* check bit that goes to ks[j] */ 00288 if (pcr[pc2[j] - 1]){ 00289 /* mask it in if it's there */ 00290 l= j % 6; 00291 ks[j/6] |= bytebit[l] >> 2; 00292 } 00293 } 00294 /* Now convert to odd/even interleaved form for use in F */ 00295 out[2*i] = ((word32)ks[0] << 24) 00296 | ((word32)ks[2] << 16) 00297 | ((word32)ks[4] << 8) 00298 | ((word32)ks[6]); 00299 out[2*i + 1] = ((word32)ks[1] << 24) 00300 | ((word32)ks[3] << 16) 00301 | ((word32)ks[5] << 8) 00302 | ((word32)ks[7]); 00303 } 00304 00305 /* reverse key schedule order */ 00306 if (dir == DES_DECRYPTION) 00307 for (i = 0; i < 16; i += 2) { 00308 word32 swap = out[i]; 00309 out[i] = out[DES_KS_SIZE - 2 - i]; 00310 out[DES_KS_SIZE - 2 - i] = swap; 00311 00312 swap = out[i + 1]; 00313 out[i + 1] = out[DES_KS_SIZE - 1 - i]; 00314 out[DES_KS_SIZE - 1 - i] = swap; 00315 } 00316 00317 } 00318 00319 00320 static INLINE int Reverse(int dir) 00321 { 00322 return !dir; 00323 } 00324 00325 00326 void Des_SetKey(Des* des, const byte* key, const byte* iv, int dir) 00327 { 00328 DesSetKey(key, dir, des->key); 00329 00330 XMEMCPY(des->reg, iv, DES_BLOCK_SIZE); 00331 } 00332 00333 00334 void Des3_SetKey(Des3* des, const byte* key, const byte* iv, int dir) 00335 { 00336 DesSetKey(key + (dir == DES_ENCRYPTION ? 0 : 16), dir, des->key[0]); 00337 DesSetKey(key + 8, Reverse(dir), des->key[1]); 00338 DesSetKey(key + (dir == DES_DECRYPTION ? 0 : 16), dir, des->key[2]); 00339 00340 XMEMCPY(des->reg, iv, DES_BLOCK_SIZE); 00341 } 00342 00343 00344 void DesRawProcessBlock(word32* lIn, word32* rIn, const word32* kptr) 00345 { 00346 word32 l = *lIn, r = *rIn, i; 00347 00348 for (i=0; i<8; i++) 00349 { 00350 word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0]; 00351 l ^= Spbox[6][(work) & 0x3f] 00352 ^ Spbox[4][(work >> 8) & 0x3f] 00353 ^ Spbox[2][(work >> 16) & 0x3f] 00354 ^ Spbox[0][(work >> 24) & 0x3f]; 00355 work = r ^ kptr[4*i+1]; 00356 l ^= Spbox[7][(work) & 0x3f] 00357 ^ Spbox[5][(work >> 8) & 0x3f] 00358 ^ Spbox[3][(work >> 16) & 0x3f] 00359 ^ Spbox[1][(work >> 24) & 0x3f]; 00360 00361 work = rotrFixed(l, 4U) ^ kptr[4*i+2]; 00362 r ^= Spbox[6][(work) & 0x3f] 00363 ^ Spbox[4][(work >> 8) & 0x3f] 00364 ^ Spbox[2][(work >> 16) & 0x3f] 00365 ^ Spbox[0][(work >> 24) & 0x3f]; 00366 work = l ^ kptr[4*i+3]; 00367 r ^= Spbox[7][(work) & 0x3f] 00368 ^ Spbox[5][(work >> 8) & 0x3f] 00369 ^ Spbox[3][(work >> 16) & 0x3f] 00370 ^ Spbox[1][(work >> 24) & 0x3f]; 00371 } 00372 00373 *lIn = l; *rIn = r; 00374 } 00375 00376 00377 static void DesProcessBlock(Des* des, const byte* in, byte* out) 00378 { 00379 word32 l, r; 00380 00381 XMEMCPY(&l, in, sizeof(l)); 00382 XMEMCPY(&r, in + sizeof(l), sizeof(r)); 00383 #ifdef LITTLE_ENDIAN_ORDER 00384 l = ByteReverseWord32(l); 00385 r = ByteReverseWord32(r); 00386 #endif 00387 IPERM(&l,&r); 00388 00389 DesRawProcessBlock(&l, &r, des->key); 00390 00391 FPERM(&l,&r); 00392 #ifdef LITTLE_ENDIAN_ORDER 00393 l = ByteReverseWord32(l); 00394 r = ByteReverseWord32(r); 00395 #endif 00396 XMEMCPY(out, &r, sizeof(r)); 00397 XMEMCPY(out + sizeof(r), &l, sizeof(l)); 00398 } 00399 00400 00401 static void Des3ProcessBlock(Des3* des, const byte* in, byte* out) 00402 { 00403 word32 l, r; 00404 00405 XMEMCPY(&l, in, sizeof(l)); 00406 XMEMCPY(&r, in + sizeof(l), sizeof(r)); 00407 #ifdef LITTLE_ENDIAN_ORDER 00408 l = ByteReverseWord32(l); 00409 r = ByteReverseWord32(r); 00410 #endif 00411 IPERM(&l,&r); 00412 00413 DesRawProcessBlock(&l, &r, des->key[0]); 00414 DesRawProcessBlock(&r, &l, des->key[1]); 00415 DesRawProcessBlock(&l, &r, des->key[2]); 00416 00417 FPERM(&l,&r); 00418 #ifdef LITTLE_ENDIAN_ORDER 00419 l = ByteReverseWord32(l); 00420 r = ByteReverseWord32(r); 00421 #endif 00422 XMEMCPY(out, &r, sizeof(r)); 00423 XMEMCPY(out + sizeof(r), &l, sizeof(l)); 00424 } 00425 00426 00427 void Des_CbcEncrypt(Des* des, byte* out, const byte* in, word32 sz) 00428 { 00429 word32 blocks = sz / DES_BLOCK_SIZE; 00430 00431 while (blocks--) { 00432 xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); 00433 DesProcessBlock(des, (byte*)des->reg, (byte*)des->reg); 00434 XMEMCPY(out, des->reg, DES_BLOCK_SIZE); 00435 00436 out += DES_BLOCK_SIZE; 00437 in += DES_BLOCK_SIZE; 00438 } 00439 } 00440 00441 00442 void Des_CbcDecrypt(Des* des, byte* out, const byte* in, word32 sz) 00443 { 00444 word32 blocks = sz / DES_BLOCK_SIZE; 00445 byte hold[16]; 00446 00447 while (blocks--) { 00448 XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); 00449 DesProcessBlock(des, (byte*)des->tmp, out); 00450 xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE); 00451 00452 XMEMCPY(hold, des->reg, DES_BLOCK_SIZE); 00453 XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); 00454 XMEMCPY(des->tmp, hold, DES_BLOCK_SIZE); 00455 00456 out += DES_BLOCK_SIZE; 00457 in += DES_BLOCK_SIZE; 00458 } 00459 } 00460 00461 00462 void Des3_CbcEncrypt(Des3* des, byte* out, const byte* in, word32 sz) 00463 { 00464 word32 blocks = sz / DES_BLOCK_SIZE; 00465 00466 while (blocks--) { 00467 xorbuf((byte*)des->reg, in, DES_BLOCK_SIZE); 00468 Des3ProcessBlock(des, (byte*)des->reg, (byte*)des->reg); 00469 XMEMCPY(out, des->reg, DES_BLOCK_SIZE); 00470 00471 out += DES_BLOCK_SIZE; 00472 in += DES_BLOCK_SIZE; 00473 } 00474 } 00475 00476 00477 void Des3_CbcDecrypt(Des3* des, byte* out, const byte* in, word32 sz) 00478 { 00479 word32 blocks = sz / DES_BLOCK_SIZE; 00480 00481 while (blocks--) { 00482 XMEMCPY(des->tmp, in, DES_BLOCK_SIZE); 00483 Des3ProcessBlock(des, (byte*)des->tmp, out); 00484 xorbuf(out, (byte*)des->reg, DES_BLOCK_SIZE); 00485 XMEMCPY(des->reg, des->tmp, DES_BLOCK_SIZE); 00486 00487 out += DES_BLOCK_SIZE; 00488 in += DES_BLOCK_SIZE; 00489 } 00490 } 00491 00492 00493 #endif /* NO_DES3 */
Generated on Tue Jul 12 2022 18:43:19 by 1.7.2