Webserver+3d print
Embed:
(wiki syntax)
Show/hide line numbers
des.c
Go to the documentation of this file.
00001 /** 00002 * @file des.c 00003 * @brief DES (Data Encryption Standard) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @section Description 00026 * 00027 * DES is an encryption algorithm designed to encipher and decipher blocks of 00028 * 64 bits under control of a 64-bit key. Refer to FIPS 46-3 for more details 00029 * 00030 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00031 * @version 1.7.6 00032 **/ 00033 00034 //Switch to the appropriate trace level 00035 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00036 00037 //Dependencies 00038 #include <string.h> 00039 #include "crypto.h" 00040 #include "des.h" 00041 00042 //Check crypto library configuration 00043 #if (DES_SUPPORT == ENABLED || DES3_SUPPORT == ENABLED) 00044 00045 //Rotate left operation 00046 #define ROL28(a, n) ((((a) << (n)) | ((a) >> (28 - (n)))) & 0x0FFFFFFF) 00047 00048 //Initial permutation 00049 #define DES_IP(left, right) \ 00050 { \ 00051 temp = ((left >> 4) ^ right) & 0x0F0F0F0F; \ 00052 right ^= temp; \ 00053 left ^= temp << 4; \ 00054 temp = ((left >> 16) ^ right) & 0x0000FFFF; \ 00055 right ^= temp; \ 00056 left ^= temp << 16; \ 00057 temp = ((right >> 2) ^ left) & 0x33333333; \ 00058 left ^= temp; \ 00059 right ^= temp << 2; \ 00060 temp = ((right >> 8) ^ left) & 0x00FF00FF; \ 00061 left ^= temp; \ 00062 right ^= temp << 8; \ 00063 temp = ((left >> 1) ^ right) & 0x55555555; \ 00064 right ^= temp; \ 00065 left ^= temp << 1; \ 00066 left = ROL32(left, 1); \ 00067 right = ROL32(right, 1); \ 00068 } 00069 00070 //Final permutation 00071 #define DES_FP(left, right) \ 00072 { \ 00073 left = ROR32(left, 1); \ 00074 right = ROR32(right, 1); \ 00075 temp = ((left >> 1) ^ right) & 0x55555555; \ 00076 right ^= temp; \ 00077 left ^= temp << 1; \ 00078 temp = ((right >> 8) ^ left) & 0x00FF00FF; \ 00079 left ^= temp; \ 00080 right ^= temp << 8; \ 00081 temp = ((right >> 2) ^ left) & 0x33333333; \ 00082 left ^= temp; \ 00083 right ^= temp << 2; \ 00084 temp = ((left >> 16) ^ right) & 0x0000FFFF; \ 00085 right ^= temp; \ 00086 left ^= temp << 16; \ 00087 temp = ((left >> 4) ^ right) & 0x0F0F0F0F; \ 00088 right ^= temp; \ 00089 left ^= temp << 4; \ 00090 } 00091 00092 //DES round 00093 #define DES_ROUND(left, right, ks) \ 00094 { \ 00095 temp = right ^ *(ks); \ 00096 left ^= sp2[(temp >> 24) & 0x3F]; \ 00097 left ^= sp4[(temp >> 16) & 0x3F]; \ 00098 left ^= sp6[(temp >> 8) & 0x3F]; \ 00099 left ^= sp8[temp & 0x3F]; \ 00100 temp = ROR32(right, 4) ^ *(ks + 1); \ 00101 left ^= sp1[(temp >> 24) & 0x3F]; \ 00102 left ^= sp3[(temp >> 16) & 0x3F]; \ 00103 left ^= sp5[(temp >> 8) & 0x3F]; \ 00104 left ^= sp7[temp & 0x3F]; \ 00105 temp = right; \ 00106 right = left; \ 00107 left = temp; \ 00108 } 00109 00110 //Permuted choice 1 00111 #define DES_PC1(left, right) \ 00112 { \ 00113 uint32_t temp; \ 00114 temp = ((left >> 4) ^ right) & 0x0F0F0F0F; \ 00115 right ^= temp; \ 00116 left ^= (temp << 4); \ 00117 temp = ((right >> 16) ^ left) & 0x0000FFFF; \ 00118 left ^= temp; \ 00119 right ^= (temp << 16); \ 00120 temp = ((left >> 2) ^ right) & 0x33333333; \ 00121 right ^= temp; \ 00122 left ^= (temp << 2); \ 00123 temp = ((right >> 16) ^ left) & 0x0000FFFF; \ 00124 left ^= temp; \ 00125 right ^= (temp << 16); \ 00126 temp = ((left >> 1) ^ right) & 0x55555555; \ 00127 right ^= temp; \ 00128 left ^= (temp << 1); \ 00129 temp = ((right >> 8) ^ left) & 0x00FF00FF; \ 00130 left ^= temp; \ 00131 right ^= (temp << 8); \ 00132 temp = ((left >> 1) ^ right) & 0x55555555; \ 00133 right ^= temp; \ 00134 left ^= (temp << 1); \ 00135 temp = (left << 8) | ((right >> 20) & 0x000000F0); \ 00136 left = ((right << 20) & 0x0FF00000); \ 00137 left |= ((right << 4) & 0x000FF000); \ 00138 left |= ((right >> 12) & 0x00000FF0); \ 00139 left |= ((right >> 28) & 0x0000000F); \ 00140 right = temp >> 4; \ 00141 } 00142 00143 //Selection function 1 00144 static const uint32_t sp1[64] = 00145 { 00146 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000, 00147 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004, 00148 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404, 00149 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000, 00150 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400, 00151 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404, 00152 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400, 00153 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004 00154 }; 00155 00156 //Selection function 2 00157 static const uint32_t sp2[64] = 00158 { 00159 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020, 00160 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020, 00161 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000, 00162 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020, 00163 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000, 00164 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000, 00165 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020, 00166 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000 00167 }; 00168 00169 //Selection function 3 00170 static const uint32_t sp3[64] = 00171 { 00172 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200, 00173 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208, 00174 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208, 00175 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000, 00176 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000, 00177 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008, 00178 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008, 00179 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200 00180 }; 00181 00182 //Selection function 4 00183 static const uint32_t sp4[64] = 00184 { 00185 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001, 00186 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001, 00187 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080, 00188 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081, 00189 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000, 00190 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080, 00191 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081, 00192 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080 00193 }; 00194 00195 //Selection function 5 00196 static const uint32_t sp5[64] = 00197 { 00198 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000, 00199 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000, 00200 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100, 00201 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100, 00202 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100, 00203 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000, 00204 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000, 00205 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100 00206 }; 00207 00208 //Selection function 6 00209 static const uint32_t sp6[64] = 00210 { 00211 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000, 00212 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010, 00213 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010, 00214 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000, 00215 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010, 00216 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000, 00217 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010, 00218 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010 00219 }; 00220 00221 //Selection function 7 00222 static const uint32_t sp7[64] = 00223 { 00224 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800, 00225 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802, 00226 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002, 00227 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800, 00228 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002, 00229 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800, 00230 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802, 00231 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002 00232 }; 00233 00234 //Selection function 8 00235 static const uint32_t sp8[64] = 00236 { 00237 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000, 00238 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040, 00239 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000, 00240 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000, 00241 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040, 00242 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040, 00243 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000, 00244 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000 00245 }; 00246 00247 //Common interface for encryption algorithms 00248 const CipherAlgo desCipherAlgo = 00249 { 00250 "DES", 00251 sizeof(DesContext), 00252 CIPHER_ALGO_TYPE_BLOCK, 00253 DES_BLOCK_SIZE, 00254 (CipherAlgoInit) desInit, 00255 NULL, 00256 NULL, 00257 (CipherAlgoEncryptBlock) desEncryptBlock, 00258 (CipherAlgoDecryptBlock) desDecryptBlock 00259 }; 00260 00261 00262 /** 00263 * @brief Initialize a DES context using the supplied key 00264 * @param[in] context Pointer to the DES context to initialize 00265 * @param[in] key Pointer to the key 00266 * @param[in] keyLength Length of the key (must be set to 8) 00267 * @return Error code 00268 **/ 00269 00270 error_t desInit(DesContext *context, const uint8_t *key, size_t keyLength) 00271 { 00272 uint_t i; 00273 uint32_t c; 00274 uint32_t d; 00275 00276 //Check key length 00277 if(keyLength != 8) 00278 return ERROR_INVALID_KEY_LENGTH; 00279 00280 //Copy the key 00281 c = LOAD32BE(key + 0); 00282 d = LOAD32BE(key + 4); 00283 00284 //Permuted choice 1 00285 DES_PC1(c, d); 00286 00287 //Generate the key schedule 00288 for(i = 0; i < 16; i++) 00289 { 00290 //Individual blocks are shifted left 00291 if(i == 0 || i == 1 || i == 8 || i == 15) 00292 { 00293 c = ROL28(c, 1); 00294 d = ROL28(d, 1); 00295 } 00296 else 00297 { 00298 c = ROL28(c, 2); 00299 d = ROL28(d, 2); 00300 } 00301 00302 //Permuted choice 2 00303 context->ks[2 * i] = 00304 ((c << 4) & 0x24000000) | ((c << 28) & 0x10000000) | 00305 ((c << 14) & 0x08000000) | ((c << 18) & 0x02080000) | 00306 ((c << 6) & 0x01000000) | ((c << 9) & 0x00200000) | 00307 ((c >> 1) & 0x00100000) | ((c << 10) & 0x00040000) | 00308 ((c << 2) & 0x00020000) | ((c >> 10) & 0x00010000) | 00309 ((d >> 13) & 0x00002000) | ((d >> 4) & 0x00001000) | 00310 ((d << 6) & 0x00000800) | ((d >> 1) & 0x00000400) | 00311 ((d >> 14) & 0x00000200) | ((d) & 0x00000100) | 00312 ((d >> 5) & 0x00000020) | ((d >> 10) & 0x00000010) | 00313 ((d >> 3) & 0x00000008) | ((d >> 18) & 0x00000004) | 00314 ((d >> 26) & 0x00000002) | ((d >> 24) & 0x00000001); 00315 00316 context->ks[2 * i + 1] = 00317 ((c << 15) & 0x20000000) | ((c << 17) & 0x10000000) | 00318 ((c << 10) & 0x08000000) | ((c << 22) & 0x04000000) | 00319 ((c >> 2) & 0x02000000) | ((c << 1) & 0x01000000) | 00320 ((c << 16) & 0x00200000) | ((c << 11) & 0x00100000) | 00321 ((c << 3) & 0x00080000) | ((c >> 6) & 0x00040000) | 00322 ((c << 15) & 0x00020000) | ((c >> 4) & 0x00010000) | 00323 ((d >> 2) & 0x00002000) | ((d << 8) & 0x00001000) | 00324 ((d >> 14) & 0x00000808) | ((d >> 9) & 0x00000400) | 00325 ((d) & 0x00000200) | ((d << 7) & 0x00000100) | 00326 ((d >> 7) & 0x00000020) | ((d >> 3) & 0x00000011) | 00327 ((d << 2) & 0x00000004) | ((d >> 21) & 0x00000002); 00328 } 00329 00330 //No error to report 00331 return NO_ERROR; 00332 } 00333 00334 00335 /** 00336 * @brief Encrypt a 8-byte block using DES algorithm 00337 * @param[in] context Pointer to the DES context 00338 * @param[in] input Plaintext block to encrypt 00339 * @param[out] output Ciphertext block resulting from encryption 00340 **/ 00341 00342 void desEncryptBlock(DesContext *context, const uint8_t *input, uint8_t *output) 00343 { 00344 uint_t i; 00345 uint32_t left; 00346 uint32_t right; 00347 uint32_t temp; 00348 00349 //Key schedule 00350 uint32_t *ks = context->ks; 00351 00352 //Copy the plaintext from the input buffer 00353 left = LOAD32BE(input + 0); 00354 right = LOAD32BE(input + 4); 00355 00356 //Initial permutation 00357 DES_IP(left, right); 00358 00359 //16 rounds of computation are needed 00360 for(i = 0; i < 16; i++, ks += 2) 00361 { 00362 DES_ROUND(left, right, ks); 00363 } 00364 00365 //Inverse IP permutation 00366 DES_FP(right, left); 00367 00368 //Copy the resulting ciphertext 00369 STORE32BE(right, output + 0); 00370 STORE32BE(left, output + 4); 00371 } 00372 00373 00374 /** 00375 * @brief Decrypt a 8-byte block using DES algorithm 00376 * @param[in] context Pointer to the DES context 00377 * @param[in] input Ciphertext block to decrypt 00378 * @param[out] output Plaintext block resulting from decryption 00379 **/ 00380 00381 void desDecryptBlock(DesContext *context, const uint8_t *input, uint8_t *output) 00382 { 00383 uint_t i; 00384 uint32_t left; 00385 uint32_t right; 00386 uint32_t temp; 00387 00388 //Keys in the key schedule must be applied in reverse order 00389 uint32_t *ks = context->ks + 30; 00390 00391 //Copy the ciphertext from the input buffer 00392 left = LOAD32BE(input + 0); 00393 right = LOAD32BE(input + 4); 00394 00395 //Initial permutation 00396 DES_IP(left, right); 00397 00398 //16 rounds of computation are needed 00399 for(i = 0; i < 16; i++, ks -= 2) 00400 { 00401 DES_ROUND(left, right, ks); 00402 } 00403 00404 //Inverse IP permutation 00405 DES_FP(right, left); 00406 00407 //Copy the resulting plaintext 00408 STORE32BE(right, output + 0); 00409 STORE32BE(left, output + 4); 00410 } 00411 00412 #endif 00413
Generated on Tue Jul 12 2022 17:10:12 by
