This library implements some hash and cryptographic algorithms.

Dependents:   mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DES.cpp Source File

DES.cpp

00001 #include "DES.h"
00002 #include <string.h>
00003 
00004 
00005 static const uint8_t S1[] =
00006 {
00007     14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
00008      0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
00009      4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0, 
00010     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13 
00011 };
00012 
00013 static const uint8_t S2[] =
00014 {
00015     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
00016      3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
00017      0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
00018     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9 
00019 };
00020 
00021 static const uint8_t S3[] = 
00022 {
00023     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
00024     13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
00025     13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
00026      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12 
00027 };
00028 
00029 static const uint8_t S4[] =
00030 {
00031      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
00032     13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
00033     10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
00034      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14 
00035 };
00036 
00037 static const uint8_t S5[] = 
00038 {
00039      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
00040     14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
00041      4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
00042     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3 
00043 };
00044 
00045 static const uint8_t S6[] =
00046 {
00047     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
00048     10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
00049      9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
00050      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13 
00051 };
00052 
00053 static const uint8_t S7[] =
00054 {
00055      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
00056     13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
00057      1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
00058      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12 
00059 };
00060 
00061 static const uint8_t S8[] =
00062 {
00063     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
00064      1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
00065      7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
00066      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11 
00067 };
00068 
00069 static void pc1(uint8_t *k, uint8_t *key)
00070 {
00071     memset(k, 0, 7);
00072     for(int i = 0; i < 8; ++i)
00073     {
00074         k[0] = (k[0] << 1) | (key[i] & 0x01);
00075         k[1] = (k[1] << 1) | ((key[i] & 0x02) >> 1);
00076         k[2] = (k[2] << 1) | ((key[i] & 0x04) >> 2);
00077     }
00078     for(int i = 0 ; i < 4; ++i)
00079     {
00080         k[3] = (k[3] << 1) | ((key[4+i] & 0x40) >> 6);
00081         k[4] = (k[4] << 1) | ((key[4+i] & 0x20) >> 5);
00082         k[5] = (k[5] << 1) | ((key[4+i] & 0x10) >> 4);
00083         k[6] = (k[6] << 1) | ((key[i] & 0x08) >> 3);
00084     }
00085     for(int i = 0 ; i < 4; ++i)
00086     {
00087         k[3] = (k[3] << 1) | ((key[4+i] & 0x08) >> 3);
00088         k[4] = (k[4] << 1) | ((key[i] & 0x40) >> 6);
00089         k[5] = (k[5] << 1) | ((key[i] & 0x20) >> 5);
00090         k[6] = (k[6] << 1) | ((key[i] & 0x10) >> 4);
00091     }       
00092 }
00093 
00094 static void leftShift(uint8_t *k)
00095 {
00096     uint8_t tmp = k[0] & 0x01, tmp2 = k[3] & 0x10;
00097     k[0] = (k[0] >> 1) | ((k[1] & 0x01) << 7);
00098     k[1] = (k[1] >> 1) | ((k[2] & 0x01) << 7);
00099     k[2] = (k[2] >> 1) | ((k[3] & 0x01) << 7);
00100     
00101     k[3] = ((k[3] & 0x0E) >> 1) | (tmp << 3) | ((k[3] & 0xE0) >> 1) | ((k[4] & 0x01) << 7);
00102     
00103     k[4] = (k[4] >> 1) | ((k[5] & 0x01) << 7);
00104     k[5] = (k[5] >> 1) | ((k[6] & 0x01) << 7);
00105     k[6] = (k[6] >> 1) | (tmp2 << 3);
00106         
00107 }
00108 
00109 void pc2(uint8_t *subKey, uint8_t *k)
00110 {
00111     subKey[0] = ((k[1] & 0x20) >> 5) | ((k[2] & 0x01) << 1) | (k[1] & 0x04) | ((k[2] & 0x80) >> 4) | ((k[0] & 0x01) << 4) | ((k[0] & 0x10) << 1) | ((k[0] & 0x04) << 4) | ((k[3] & 0x08) << 4);
00112     subKey[1] = ((k[1] & 0x40) >> 6) | ((k[0] & 0x20) >> 4) | ((k[2] & 0x10) >> 2) | ((k[1] & 0x02) << 2) | ((k[2] & 0x40) >> 2) | ((k[2] & 0x04) << 3) | ((k[1] & 0x08) << 3) | ((k[0] & 0x08) << 4);
00113     subKey[2] = ((k[3] & 0x02) >> 1) | ((k[0] & 0x80) >> 6) | ((k[1] & 0x80) >> 5) | ((k[0] & 0x40) >> 3) | ((k[3] & 0x04) << 2) | ((k[2] & 0x08) << 2) | ((k[1] & 0x10) << 2) | ((k[0] & 0x02) << 6);
00114     subKey[3] = (k[5] & 0x01) | ((k[6] & 0x08) >> 2) | ((k[3] & 0x40) >> 4) | ((k[4] & 0x10) >> 1) | ((k[5] & 0x40) >> 2) | ((k[6] & 0x40) >> 1) | ((k[3] & 0x20) << 1) | (k[4] & 0x80);
00115     subKey[4] = ((k[6] & 0x04) >> 2) | ((k[5] & 0x10) >> 3) | ((k[4] & 0x01) << 2) | ((k[5] & 0x80) >> 4) | ((k[5] & 0x08) << 1) | ((k[6] & 0x01) << 5) | (k[4] & 0x40) | (k[6] & 0x80);
00116     subKey[5] = ((k[4] & 0x02) >> 1) | ((k[6] & 0x10) >> 3) | ((k[5] & 0x20) >> 3) | ((k[5] & 0x02) << 2) | ((k[6] & 0x02) << 3) | ((k[4] & 0x08) << 2) | ((k[3] & 0x10) << 2) | (k[3] & 0x80);
00117 }
00118 
00119 
00120 static void initialPermutation(uint8_t *in)
00121 {
00122     uint8_t tmp[8];
00123     memcpy(tmp, in, 8);
00124     for(int i = 0; i < 8; ++i)
00125     {
00126         tmp[4] = (tmp[4] << 1) | (in[i] & 0x01);
00127         tmp[5] = (tmp[5] << 1) | ((in[i] & 0x04) >> 2);
00128         tmp[6] = (tmp[6] << 1) | ((in[i] & 0x10) >> 4);
00129         tmp[7] = (tmp[7] << 1) | ((in[i] & 0x40) >> 6);
00130         
00131         tmp[0] = (tmp[0] << 1) | ((in[i] & 0x02) >> 1);
00132         tmp[1] = (tmp[1] << 1) | ((in[i] & 0x08) >> 3);
00133         tmp[2] = (tmp[2] << 1) | ((in[i] & 0x20) >> 5);
00134         tmp[3] = (tmp[3] << 1) | ((in[i] & 0x80) >> 7); 
00135     }
00136     
00137     memcpy(in, tmp, 8);
00138 }
00139 
00140 static void invInitialPermutation(uint8_t *out)
00141 {
00142     uint8_t tmp[8];
00143     memcpy(tmp, out , 8);
00144     for(int i = 3; i >= 0; --i)
00145     {
00146         out[0] = (out[0] << 2) | ((tmp[4+i] & 0x80) >> 7) | ((tmp[i] & 0x80) >> 6); 
00147         out[1] = (out[1] << 2) | ((tmp[4+i] & 0x40) >> 6) | ((tmp[i] & 0x40) >> 5);
00148         out[2] = (out[2] << 2) | ((tmp[4+i] & 0x20) >> 5) | ((tmp[i] & 0x20) >> 4);
00149         out[3] = (out[3] << 2) | ((tmp[4+i] & 0x10) >> 4) | ((tmp[i] & 0x10) >> 3);
00150         out[4] = (out[4] << 2) | ((tmp[4+i] & 0x08) >> 3) | ((tmp[i] & 0x08) >> 2);
00151         out[5] = (out[5] << 2) | ((tmp[4+i] & 0x04) >> 2) | ((tmp[i] & 0x04) >> 1);
00152         out[6] = (out[6] << 2) | ((tmp[4+i] & 0x02) >> 1) | (tmp[i] & 0x02);
00153         out[7] = (out[7] << 2) | (tmp[4+i] & 0x01)      | ((tmp[i] & 0x01) << 1);
00154     }
00155 }
00156 
00157 static void expand(uint8_t *e, uint8_t *r)
00158 {
00159     
00160     e[0] = ((r[3] & 0x80) >> 7) | ((r[0] & 0x1F) << 1) | ((r[0] & 0x18) << 3);
00161     e[1] = ((r[0] & 0xE0) >> 5) | ((r[1] & 0x01) << 3) | ((r[0] & 0x80) >> 3) | ((r[1] & 0x07) << 5);
00162     e[2] = ((r[1] & 0x18) >> 3) | ((r[1] & 0xF8) >> 1) | ((r[2] & 0x01) << 7);                
00163     e[3] = ((r[1] & 0x80) >> 7) | ((r[2] & 0x1F) << 1) | ((r[2] & 0x18) << 3);
00164     e[4] = ((r[2] & 0xE0) >> 5) | ((r[3] & 0x01) << 3) | ((r[2] & 0x80) >> 3) | ((r[3] & 0x07) << 5);
00165     e[5] = ((r[3] & 0x18) >> 3) | ((r[3] & 0xF8) >> 1) | ((r[0] & 0x01) << 7);
00166     
00167 }
00168 
00169 static void permutation(uint8_t *r)
00170 {
00171     uint8_t buffer[4];
00172     
00173     buffer[0] = ((r[1] & 0x80) >> 7) | ((r[0] & 0x40) >> 5) | ((r[2] & 0x08) >> 1) | ((r[2] & 0x10) >> 1) | (r[3] & 0x10) | ((r[1] & 0x08) << 2) | ((r[3] & 0x08) << 3) | ((r[2] & 0x01) << 7);
00174     buffer[1] = (r[0] & 0x01) | ((r[1] & 0x40) >> 5) | ((r[2] & 0x40) >> 4) | ((r[3] & 0x02) << 2) | (r[0] & 0x10) | ((r[2] & 0x02) << 4) | (r[3] & 0x40) | ((r[1] & 0x02) << 6);
00175     buffer[2] = ((r[0] & 0x02) >> 1) | ((r[0] & 0x80) >> 6) | ((r[2] & 0x80) >> 5) | ((r[1] & 0x20) >> 2) | ((r[3] & 0x80) >> 3) | ((r[3] & 0x04) << 3) | ((r[0] & 0x04) << 4) | ((r[1] & 0x01) << 7);
00176     buffer[3] = ((r[2] & 0x04) >> 2) |  ((r[1] & 0x10) >> 3) | ((r[3] & 0x20) >> 3) | ((r[0] & 0x20) >> 2) | ((r[2] & 0x20) >> 1) | ((r[1] & 0x04) << 3) | ((r[0] & 0x08) << 3) | ((r[3] & 0x01) << 7);
00177     
00178     memcpy(r, buffer,4);
00179 }
00180 
00181 static void substitute(uint8_t *r, uint8_t *e)
00182 {
00183     int index = ((e[0] & 0x01) << 5) | ((e[0] & 0x02) << 2) | (e[0] & 0x04)  | ((e[0] & 0x08) >> 2) | ((e[0] & 0x10) >> 4) | ((e[0] & 0x20) >> 1);
00184     int index2 = ((e[0] & 0x40) >> 1) | ((e[0] & 0x80) >> 4) | ((e[1] & 0x01) << 2) | (e[1] & 0x02) | ((e[1] & 0x04) >> 2) | ((e[1] & 0x08) << 1);  
00185     r[0] = ((S2[index2] & 0x08) >> 3) | ((S2[index2] & 0x04) >> 1) | ((S2[index2] & 0x02) << 1) | ((S2[index2] & 0x01) << 3);
00186     r[0] <<= 4;
00187     r[0] |= ((S1[index] & 0x08) >> 3) | ((S1[index] & 0x04) >> 1) | ((S1[index] & 0x02) << 1) | ((S1[index] & 0x01) << 3);
00188 
00189 
00190     index = ((e[1] & 0x10) << 1) | ((e[1] & 0x20) >> 2) | ((e[1] & 0x40) >> 4) | ((e[1] & 0x80) >> 6) | (e[2] & 0x01) | ((e[2] & 0x02) << 3);
00191     index2 = ((e[2] & 0x04) << 3) | (e[2] & 0x08) | ((e[2] & 0x10) >> 2) | ((e[2] & 0x20) >> 4) | ((e[2] & 0x40) >> 6) | ((e[2] & 0x80) >> 3);
00192 
00193 
00194     r[1] = ((S4[index2] & 0x08) >> 3) | ((S4[index2] & 0x04) >> 1) | ((S4[index2] & 0x02) << 1) | ((S4[index2] & 0x01) << 3);
00195     r[1] <<= 4;
00196     r[1] |= ((S3[index] & 0x08) >> 3) | ((S3[index] & 0x04) >> 1) | ((S3[index] & 0x02) << 1) | ((S3[index] & 0x01) << 3);
00197     
00198     
00199     index = ((e[3] & 0x01) << 5) | ((e[3] & 0x02) << 2) | (e[3] & 0x04)  | ((e[3] & 0x08) >> 2) | ((e[3] & 0x10) >> 4) | ((e[3] & 0x20) >> 1);
00200     index2 = ((e[3] & 0x40) >> 1) | ((e[3] & 0x80) >> 4) | ((e[4] & 0x01) << 2) | (e[4] & 0x02) | ((e[4] & 0x04) >> 2) | ((e[4] & 0x08) << 1);  
00201     r[2] = ((S6[index2] & 0x08) >> 3) | ((S6[index2] & 0x04) >> 1) | ((S6[index2] & 0x02) << 1) | ((S6[index2] & 0x01) << 3);
00202     r[2] <<= 4;
00203     r[2] |= ((S5[index] & 0x08) >> 3) | ((S5[index] & 0x04) >> 1) | ((S5[index] & 0x02) << 1) | ((S5[index] & 0x01) << 3);
00204 
00205 
00206     index = ((e[4] & 0x10) << 1) | ((e[4] & 0x20) >> 2) | ((e[4] & 0x40) >> 4) | ((e[4] & 0x80) >> 6) | (e[5] & 0x01) | ((e[5] & 0x02) << 3);
00207     index2 = ((e[5] & 0x04) << 3) | (e[5] & 0x08) | ((e[5] & 0x10) >> 2) | ((e[5] & 0x20) >> 4) | ((e[5] & 0x40) >> 6) | ((e[5] & 0x80) >> 3);
00208 
00209     r[3] = ((S8[index2] & 0x08) >> 3) | ((S8[index2] & 0x04) >> 1) | ((S8[index2] & 0x02) << 1) | ((S8[index2] & 0x01) << 3);
00210     r[3] <<= 4;
00211     r[3] |= ((S7[index] & 0x08) >> 3) | ((S7[index] & 0x04) >> 1) | ((S7[index] & 0x02) << 1) | ((S7[index] & 0x01) << 3);
00212 }
00213 
00214 
00215 DES::DES(uint8_t *key):
00216 BlockCipher(8,ECB_MODE)
00217 {
00218     generateSubKeys(key);
00219 }
00220 
00221 DES::DES(uint8_t *key, uint8_t *iv):
00222 BlockCipher(8,CBC_MODE, iv)
00223 {
00224     generateSubKeys(key);
00225 }
00226 
00227 void DES::generateSubKeys(uint8_t *key)
00228 {
00229 
00230     for(int i = 0; i < 8; ++i)
00231         key[i] = ((key[i] & 0x01) << 7) | ((key[i] & 0x02) << 5) | ((key[i] & 0x04) << 3) | ((key[i] & 0x08) << 1)  | ((key[i] & 0x10) >> 1) | ((key[i] & 0x20) >> 3) | ((key[i] & 0x40) >> 5) | ((key[i] & 0x80) >> 7);
00232     
00233     uint8_t workingKey[7];
00234     pc1(workingKey, key);
00235     
00236     for(int i = 1; i <= 16; ++i)
00237     {
00238         leftShift(workingKey);
00239         if(i != 9 && i >= 3 && i <=15)
00240             leftShift(workingKey);
00241         pc2(subKeys[i-1], workingKey);
00242     }   
00243 }
00244 
00245 void DES::encryptBlock(uint8_t *out, uint8_t *in)
00246 {
00247     uint8_t tmp[8];
00248     memcpy(tmp, in, 8);
00249     for(int i = 0; i < 8; ++i)
00250         tmp[i] = ((tmp[i] & 0x01) << 7) | ((tmp[i] & 0x02) << 5) | ((tmp[i] & 0x04) << 3) | ((tmp[i] & 0x08) << 1)  | ((tmp[i] & 0x10) >> 1) | ((tmp[i] & 0x20) >> 3) | ((tmp[i] & 0x40) >> 5) | ((tmp[i] & 0x80) >> 7);
00251 
00252 
00253     uint8_t l[4], r[4], tmpR[4], e[6];
00254     initialPermutation(tmp);
00255     memcpy(l, tmp, 4);
00256     memcpy(r, &tmp[4], 4);
00257     for(int i = 0; i < 16; ++i)
00258     {
00259         memcpy(tmpR, r, 4);
00260         expand(e, r);
00261         for(int j = 0; j < 6; ++j)
00262             e[j] ^= subKeys[i][j];
00263         substitute(r,e);
00264         permutation(r);
00265         for(int j = 0; j < 4; ++j)
00266             r[j] ^= l[j];
00267         
00268         memcpy(l, tmpR, 4);
00269 
00270     }
00271     memcpy(tmp, r, 4);
00272     memcpy(&tmp[4], l, 4);
00273     
00274     invInitialPermutation(tmp);
00275     
00276     for(int i = 0; i < 8; ++i)
00277     {
00278         out[i] = ((tmp[i] & 0x01) << 3) | ((tmp[i] & 0x02) << 1) | ((tmp[i] & 0x04) >> 1) | ((tmp[i] & 0x08) >> 3);
00279         out[i] <<= 4;
00280         tmp[i] >>= 4;
00281         out[i] |= ((tmp[i] & 0x01) << 3) | ((tmp[i] & 0x02) << 1) | ((tmp[i] & 0x04) >> 1) | ((tmp[i] & 0x08) >> 3);
00282     }
00283 }
00284 
00285 
00286 void DES::decryptBlock(uint8_t *out, uint8_t *in)
00287 {
00288     uint8_t tmp[8];
00289     memcpy(tmp, in, 8);
00290     for(int i = 0; i < 8; ++i)
00291         tmp[i] = ((tmp[i] & 0x01) << 7) | ((tmp[i] & 0x02) << 5) | ((tmp[i] & 0x04) << 3) | ((tmp[i] & 0x08) << 1)  | ((tmp[i] & 0x10) >> 1) | ((tmp[i] & 0x20) >> 3) | ((tmp[i] & 0x40) >> 5) | ((tmp[i] & 0x80) >> 7);
00292     
00293     uint8_t l[4], r[4], tmpL[4], e[6];
00294     initialPermutation(tmp);
00295     memcpy(l, tmp, 4);
00296     memcpy(r, &tmp[4], 4);
00297     
00298     for(int i = 15; i >= 0; --i)
00299     {
00300         memcpy(tmpL, r, 4);
00301         expand(e, r);
00302         for(int j = 0; j < 6; ++j)
00303             e[j] ^= subKeys[i][j];
00304         substitute(r,e);
00305         permutation(r);
00306         for(int j = 0; j < 4; ++j)
00307             r[j] ^= l[j];
00308         
00309         memcpy(l, tmpL, 4);
00310     }
00311     
00312     memcpy(&tmp[4], l, 4);
00313     memcpy(tmp, r, 4); 
00314     invInitialPermutation(tmp);
00315     
00316 
00317     for(int i = 0; i < 8; ++i)
00318     {
00319         out[i] = ((tmp[i] & 0x01) << 3) | ((tmp[i] & 0x02) << 1) | ((tmp[i] & 0x04) >> 1) | ((tmp[i] & 0x08) >> 3);
00320         out[i] <<= 4;
00321         tmp[i] >>= 4;
00322         out[i] |= ((tmp[i] & 0x01) << 3) | ((tmp[i] & 0x02) << 1) | ((tmp[i] & 0x04) >> 1) | ((tmp[i] & 0x08) >> 3);
00323     }
00324 }