BeRTOS
|
00001 00048 #include "md2.h" 00049 00050 #include <string.h> //memset(), memcpy(); 00051 #include <cfg/compiler.h> 00052 #include <cfg/debug.h> //ASSERT() 00053 #include <cfg/macros.h> //MIN(), countof(), ROTR(); 00054 #include <cpu/pgm.h> 00055 00056 00057 #if CONFIG_MD2_STD_PERM 00058 /* 00059 * Official array of 256 byte pemutation contructed from digits of pi, defined 00060 * in the RFC 1319. 00061 */ 00062 static const uint8_t PROGMEM md2_perm[256] = 00063 { 00064 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 00065 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 00066 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 00067 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 00068 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 00069 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 00070 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 00071 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 00072 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 00073 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 00074 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 00075 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 00076 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 00077 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 00078 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, 00079 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, 00080 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, 00081 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 00082 }; 00083 00084 #define MD2_PERM(x) pgm_read8(&md2_perm[x]) 00085 #else 00086 00094 #define K1 5 00095 #define K2 3 00096 #define R 2 00097 #define X 172 00098 /*\}*/ 00099 00100 static uint8_t md2_perm(uint8_t i) 00101 { 00102 00103 i = i * K1; 00104 i = ROTR(i, R); 00105 i ^= X; 00106 i = i * K2; 00107 00108 return i; 00109 } 00110 00111 #define MD2_PERM(x) md2_perm(x) 00112 00113 #endif 00114 00115 00120 static void md2_pad(void *_block, size_t len_pad) 00121 { 00122 uint8_t *block; 00123 00124 block = (uint8_t *)_block; 00125 00126 ASSERT(len_pad <= CONFIG_MD2_BLOCK_LEN); 00127 00128 /* 00129 * Fill input block with len_pad char. 00130 */ 00131 memset(block, len_pad, len_pad); 00132 00133 } 00134 00135 static void md2_compute(void *_state, void *_checksum, void *_block) 00136 { 00137 int i = 0; 00138 uint16_t t = 0; 00139 uint8_t compute_array[COMPUTE_ARRAY_LEN]; 00140 uint8_t *state; 00141 uint8_t *checksum; 00142 uint8_t *block; 00143 00144 state = (uint8_t *)_state; 00145 checksum = (uint8_t *)_checksum; 00146 block = (uint8_t *)_block; 00147 00148 /* 00149 * Copy state and checksum context in compute array. 00150 */ 00151 memcpy(compute_array, state, CONFIG_MD2_BLOCK_LEN); 00152 memcpy(compute_array + CONFIG_MD2_BLOCK_LEN, block, CONFIG_MD2_BLOCK_LEN); 00153 00154 /* 00155 * Fill compute array with state XOR block 00156 */ 00157 for(i = 0; i < CONFIG_MD2_BLOCK_LEN; i++) 00158 compute_array[i + (CONFIG_MD2_BLOCK_LEN * 2)] = state[i] ^ block[i]; 00159 00160 /* 00161 * Encryt block. 00162 */ 00163 for(i = 0; i < NUM_COMPUTE_ROUNDS; i++) 00164 { 00165 for(int j = 0; j < COMPUTE_ARRAY_LEN; j++) 00166 { 00167 compute_array[j] ^= MD2_PERM(t); 00168 t = compute_array[j]; 00169 } 00170 00171 t = (t + i) & 0xff; //modulo 256. 00172 } 00173 /* 00174 * Update checksum. 00175 */ 00176 t = checksum[CONFIG_MD2_BLOCK_LEN - 1]; 00177 00178 for(i = 0; i < CONFIG_MD2_BLOCK_LEN; i++) 00179 { 00180 checksum[i] ^= MD2_PERM(block[i] ^ t); 00181 t = checksum[i]; 00182 } 00183 00184 /* 00185 * Update state and clean compute array. 00186 */ 00187 memcpy(state, compute_array, CONFIG_MD2_BLOCK_LEN); 00188 memset(compute_array, 0, sizeof(compute_array)); 00189 } 00190 00196 void md2_init(Md2Context *context) 00197 { 00198 00199 memset(context, 0, sizeof(Md2Context)); 00200 00201 } 00202 00206 void md2_update(Md2Context *context, const void *_block_in, size_t block_len) 00207 { 00208 00209 const uint8_t *block_in; 00210 size_t cpy_len; 00211 00212 00213 block_in = (const uint8_t *)_block_in; 00214 00215 while(block_len > 0) 00216 { 00217 /* 00218 * Choose a number of block that fill input context buffer. 00219 */ 00220 cpy_len = MIN(block_len, CONFIG_MD2_BLOCK_LEN - context->counter); 00221 00222 00223 /* 00224 * Copy in the buffer input block. 00225 */ 00226 memcpy(&context->buffer[context->counter], block_in, cpy_len); 00227 00228 /* 00229 * Update a context counter, input block length and remaning 00230 * context buffer block lenght. 00231 */ 00232 context->counter += cpy_len; 00233 block_len -= cpy_len; 00234 block_in += cpy_len; 00235 00236 /* 00237 * If buffer is full, compute it. 00238 */ 00239 if (context->counter >= CONFIG_MD2_BLOCK_LEN) 00240 { 00241 md2_compute(context->state, context->checksum, context->buffer); 00242 context->counter = 0; 00243 } 00244 } 00245 00246 00247 } 00256 uint8_t *md2_end(Md2Context *context) 00257 { 00258 00259 uint8_t buf[CONFIG_MD2_BLOCK_LEN]; 00260 00261 /* 00262 * Fill remaning empty context buffer. 00263 */ 00264 md2_pad(buf, CONFIG_MD2_BLOCK_LEN - context->counter); 00265 00266 /* 00267 * Update context buffer and compute it. 00268 */ 00269 md2_update(context, buf, CONFIG_MD2_BLOCK_LEN - context->counter); 00270 00271 /* 00272 * Add context checksum to message input. 00273 */ 00274 md2_update(context, context->checksum, CONFIG_MD2_BLOCK_LEN); 00275 00276 00277 return context->state; //return a pointer to message digest. 00278 } 00288 bool md2_test(void) 00289 { 00290 00291 Md2Context context; 00292 00293 const char *test[] = 00294 { 00295 "", 00296 "message digest", 00297 "abcdefghijklmnopqrstuvwxyz", 00298 "12345678901234567890123456789012345678901234567890123456789012345678901234567890" 00299 }; 00300 00301 00302 const char *result[] = { 00303 "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73", 00304 "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0", 00305 "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47\x94\x0b", 00306 "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3\xef\xd8", 00307 }; 00308 00309 00310 for (size_t i = 0; i < countof(test); i++) 00311 { 00312 md2_init(&context); 00313 md2_update(&context, test[i], strlen(test[i])); 00314 00315 if(memcmp(result[i], md2_end(&context), MD2_DIGEST_LEN)) 00316 return false; 00317 } 00318 00319 return true; 00320 } 00321 00322 #if 0 00323 00324 #include <stdio.h> 00325 int main(int argc, char * argv[]) 00326 { 00327 00328 if(md2_test()) 00329 printf("MD2 algorithm work well!\n"); 00330 else 00331 printf("MD2 algorithm doesn't work well.\n"); 00332 00333 } 00334 00335 #endif 00336