Embedded systems coursework 2.
Fork of Crypto_light by
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Wed Jul 20 2022 22:55:43 by 1.7.2