Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers des.c Source File

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