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