/* * This function stir entropy pool with MD2 function hash. * */ static void randpool_stir(EntropyPool *pool) { size_t entropy = pool->entropy; //Save current calue of entropy. Md2Context context; uint8_t tmp_buf[((sizeof(size_t) * 2) + sizeof(int)) * 2 + 1]; //Temporary buffer. md2_init(&context); //Init MD2 algorithm. randpool_add(pool, NULL, 0); for (int i = 0; i < (CONFIG_SIZE_ENTROPY_POOL / MD2_DIGEST_LEN); i++) { sprintf((char *)tmp_buf, "%0x%0x%0x", pool->counter, i, pool->pos_add); /* * Hash with MD2 algorithm the entropy pool. */ md2_update(&context, pool->pool_entropy, CONFIG_SIZE_ENTROPY_POOL); md2_update(&context, tmp_buf, sizeof(tmp_buf) - 1); /*Insert a message digest in entropy pool.*/ randpool_push(pool, md2_end(&context), MD2_DIGEST_LEN); pool->counter = pool->counter + 1; } /*Insert in pool the difference between a two call of this function (see above).*/ randpool_add(pool, NULL, 0); pool->entropy = entropy; //Restore old value of entropy. We haven't add entropy. }
/** * MD2 test fuction. * This function test MD2 algorithm with a standard string specified * in RFC 1319. * * \note This test work with official array of 256 byte pemutation * contructed from digits of pi, defined in the RFC 1319. * */ bool md2_test(void) { Md2Context context; const char *test[] = { "", "message digest", "abcdefghijklmnopqrstuvwxyz", "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }; const char *result[] = { "\x83\x50\xe5\xa3\xe2\x4c\x15\x3d\xf2\x27\x5c\x9f\x80\x69\x27\x73", "\xab\x4f\x49\x6b\xfb\x2a\x53\x0b\x21\x9f\xf3\x30\x31\xfe\x06\xb0", "\x4e\x8d\xdf\xf3\x65\x02\x92\xab\x5a\x41\x08\xc3\xaa\x47\x94\x0b", "\xd5\x97\x6f\x79\xd8\x3d\x3a\x0d\xc9\x80\x6c\x3c\x66\xf3\xef\xd8", }; for (size_t i = 0; i < countof(test); i++) { md2_init(&context); md2_update(&context, test[i], strlen(test[i])); if(memcmp(result[i], md2_end(&context), MD2_DIGEST_LEN)) return false; } return true; }
/** * Get \param n_byte from entropy pool. If n_byte is larger than number * byte of entropy in entropy pool, randpool_get continue * to generate pseudocasual value from previous state of * pool. * \param n_byte number fo bytes to read. * \param pool is the pool entropy context. * \param _data is the pointer to write the random data to. */ void randpool_get(EntropyPool *pool, void *_data, size_t n_byte) { Md2Context context; size_t i = pool->pos_get; size_t n = n_byte; size_t pos_write = 0; //Number of block has been written in data. size_t len = MIN((size_t)MD2_DIGEST_LEN, n_byte); uint8_t *data; data = (uint8_t *)_data; /* Test if i + CONFIG_MD2_BLOCK_LEN is inside of entropy pool.*/ ASSERT((MD2_DIGEST_LEN + i) <= CONFIG_SIZE_ENTROPY_POOL); md2_init(&context); while(n > 0) { /*Hash previous state of pool*/ md2_update(&context, &pool->pool_entropy[i], MD2_DIGEST_LEN); memcpy(&data[pos_write], md2_end(&context), len); pos_write += len; //Update number of block has been written in data. n -= len; //Number of byte copied in data. len = MIN(n,(size_t)MD2_DIGEST_LEN); i = (i + MD2_DIGEST_LEN) % CONFIG_SIZE_ENTROPY_POOL; /* If we haven't more entropy pool to hash, we stir it.*/ if(i < MD2_DIGEST_LEN) { randpool_stir(pool); i = pool->pos_get; } } pool->pos_get = i; //Current number of byte we get from pool. pool->entropy -= n_byte; //Update a entropy. }