Exemplo n.º 1
0
void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderSize, byte* fingerprint)
{
    // compute Whirlpool+SHA512 fingerprint of bootloader including MBR
    // we skip user configuration fields:
    // TC_BOOT_SECTOR_PIM_VALUE_OFFSET = 400
    // TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
    //  => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
    // TC_BOOT_SECTOR_USER_MESSAGE_OFFSET     = 406
    //  => TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH = 24
    // TC_BOOT_SECTOR_USER_CONFIG_OFFSET      = 438
    //
    // we have: TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET + TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE

    WHIRLPOOL_CTX whirlpool;
    sha512_ctx sha2;

    WHIRLPOOL_init (&whirlpool);
    sha512_begin (&sha2);

    WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &whirlpool);
    sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2);

    WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &whirlpool);
    sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2);

    WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)), &whirlpool);
    sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1, (TC_MAX_MBR_BOOT_CODE_SIZE - (TC_BOOT_SECTOR_USER_CONFIG_OFFSET + 1)), &sha2);

    WHIRLPOOL_add (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &whirlpool);
    sha512_hash (bootLoaderBuf + TC_SECTOR_SIZE_BIOS, (bootLoaderSize - TC_SECTOR_SIZE_BIOS), &sha2);

    WHIRLPOOL_finalize (&whirlpool, fingerprint);
    sha512_end (&fingerprint [WHIRLPOOL_DIGESTSIZE], &sha2);
}
Exemplo n.º 2
0
alsz_snd_check_t ALSZOTExtSnd::UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, channel* check_chan) {
	uint64_t rowbytelen = m_nBlockSizeBytes * numblocks;
	uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH);
	//uint8_t* tmpbuf = (uint8_t*) malloc(rowbytelen);
	uint8_t** tmpbuf = (uint8_t**) malloc(2 * sizeof(uint8_t*));
	uint8_t *idaptr, *idbptr;
	alsz_snd_check_t check_buf;
	check_buf.rcv_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES);
	check_buf.seed_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES);
	uint8_t *seedcheckbufptr = check_buf.seed_chk_buf, *rcvcheckbufptr = check_buf.rcv_chk_buf;
	uint32_t iters = rowbytelen/sizeof(uint64_t);
	for(uint32_t i = 0; i < 2; i++) {
		tmpbuf[i] = (uint8_t*) malloc(rowbytelen);
	}
	check_buf.otid = otid;
	check_buf.numblocks = numblocks;
	check_buf.perm = (linking_t*) malloc(sizeof(linking_t*) * m_nChecks);
	genRandomPermutation(check_buf.perm, m_nBaseOTs, m_nChecks);

	//right now the rowbytelen needs to be a multiple of AES_BYTES
	assert(ceil_divide(rowbytelen, OWF_BYTES) * OWF_BYTES == rowbytelen);
#ifdef DEBUG_ALSZ_CHECKS
	cout << "rowbytelen = " << rowbytelen << endl;
	m_vU.PrintHex();
#endif
	uint8_t *pas, *pbs, *par, *pbr;
	for(uint64_t i = 0; i < m_nChecks; i++, seedcheckbufptr+=OWF_BYTES, rcvcheckbufptr+=OWF_BYTES) {
		//memset(tmpbuf, 0, rowbytelen);
#ifdef DEBUG_ALSZ_CHECKS
		cout << i << "-th check between " << check_buf.perm[i].ida << " and " << check_buf.perm[i].idb << ": " << endl;
#endif
		pas = tocheckseed + check_buf.perm[i].ida * rowbytelen;
		pbs = tocheckseed + check_buf.perm[i].idb * rowbytelen;
		par = tocheckrcv + check_buf.perm[i].ida * rowbytelen;
		pbr = tocheckrcv + check_buf.perm[i].idb * rowbytelen;
		for(uint64_t j = 0; j < iters; j++) {
			((uint64_t*) tmpbuf[0])[j] = ((uint64_t*) pas)[j] ^ ((uint64_t*) pbs)[j];
			((uint64_t*) tmpbuf[1])[j] = ((uint64_t*) tmpbuf[0])[j] ^ ((uint64_t*) par)[j] ^ ((uint64_t*) pbr)[j];
		}
		sha512_hash(seedcheckbufptr, OWF_BYTES, tmpbuf[0], rowbytelen, hash_buf);
		sha512_hash(rcvcheckbufptr, OWF_BYTES, tmpbuf[1], rowbytelen, hash_buf);
		/*XORandOWF(tocheckseed + check_buf.perm[i].ida * rowbytelen, tocheckseed + check_buf.perm[i].idb * rowbytelen,
				rowbytelen, tmpbuf, seedcheckbufptr, hash_buf);
		XORandOWF(tocheckrcv + check_buf.perm[i].ida * rowbytelen, tocheckrcv + check_buf.perm[i].idb * rowbytelen,
				rowbytelen, tmpbuf, rcvcheckbufptr, hash_buf);*/
	}

	for(uint32_t i = 0; i < 2; i++)
		free(tmpbuf[i]);
	free(tmpbuf);
	//free(tmpbuf);
	free(hash_buf);

	//Send the permutation over to the receiver
	check_chan->send_id_len((uint8_t*) check_buf.perm, sizeof(linking_t) * m_nChecks, otid, numblocks);

	return check_buf;
}
Exemplo n.º 3
0
void _stdcall sha512_hmac(const void *k, size_t k_len, const void *d, size_t d_len, char *out)
{
    sha512_ctx    ctx;
    unsigned char buf[SHA512_BLOCK_SIZE];
    unsigned char hval[SHA512_DIGEST_SIZE];
    unsigned long i;

    // zero key buffer
    memset(buf, 0, sizeof(buf));

    // compress hmac key
    if (k_len > SHA512_BLOCK_SIZE) {
        sha512_init(&ctx);
        sha512_hash(&ctx, (const unsigned char*)k, k_len);
        sha512_done(&ctx, buf);
    } else {
        memcpy(buf, k, k_len);
    }

    // create the hash initial vector
    for (i = 0; i < (SHA512_BLOCK_SIZE / 4); i++) {
        ((unsigned long*)buf)[i] ^= 0x36363636;
    }

    // hash key and data
    sha512_init(&ctx);
    sha512_hash(&ctx, buf, SHA512_BLOCK_SIZE);
    sha512_hash(&ctx, (const unsigned char*)d, d_len);
    sha512_done(&ctx, hval);

    // create the second HMAC vector
    for (i = 0; i < (SHA512_BLOCK_SIZE / 4); i++) {
        ((unsigned long*)buf)[i] ^= 0x6A6A6A6A;
    }

    // calculate "outer" hash
    sha512_init(&ctx);
    sha512_hash(&ctx, buf, SHA512_BLOCK_SIZE);
    sha512_hash(&ctx, hval, SHA512_DIGEST_SIZE);
    sha512_done(&ctx, (unsigned char*)out);

    // test buffers size alignment at compile-time
    static_assert( !(sizeof(buf) % sizeof(unsigned long)), "sizeof must be 4 byte aligned");
    static_assert( !(sizeof(hval) % sizeof(unsigned long)), "sizeof must be 4 byte aligned");
    static_assert( !(sizeof(ctx) % sizeof(unsigned long)), "sizeof must be 4 byte aligned");

    // prevent leaks
    __stosd((unsigned long*)&buf, 0, (sizeof(buf) / sizeof(unsigned long)));
    __stosd((unsigned long*)&hval, 0, (sizeof(hval) / sizeof(unsigned long)));
    __stosd((unsigned long*)&ctx, 0, (sizeof(ctx) / sizeof(unsigned long)));
}
Exemplo n.º 4
0
    void digestBuf()
    {
        // Mangle the data
        for(size_t j = 0; j < 3; j++)
        {
            // Taint the bytes
            GAssert(DIGEST_BYTES >= 32);
            if(m_pTaint)
                Taint_buffer(m_pBuf, m_pTaint + (m_rand.next() % (DIGEST_BYTES - 32)), 32, j);

            // Shuffle the bytes
            shuffleBytes(m_pBuf, DIGEST_BYTES);

            // Hash each 64-bit chunk with sha-512
            unsigned char* pChunk = m_pBuf;
            for(size_t i = 0; i < (DIGEST_BYTES / 64); i++)
            {
                sha512_ctx ctx;
                sha512_begin(&ctx);
                sha512_hash(pChunk, 64, &ctx);
                sha512_end(pChunk, &ctx);
                pChunk += 64;
            }
        }

        // Add it to the hash
        uint64_t* pA = (uint64_t*)m_pBuf;
        uint64_t* pB = (uint64_t*)m_pHash;
        for(size_t i = 0; i < (DIGEST_BYTES / sizeof(uint64_t)); i++)
        {
            (*pB) += (*pA);
            pB++;
            pA++;
        }
    }
Exemplo n.º 5
0
void ALSZOTExtSnd::XORandOWF(uint8_t* idaptr, uint8_t* idbptr, uint64_t rowbytelen, uint8_t* tmpbuf,
		uint8_t* resbuf, uint8_t* hash_buf) {

	for(uint64_t j = 0; j < rowbytelen/sizeof(uint64_t); j++) {
		((uint64_t*) tmpbuf)[j] = ((uint64_t*) tmpbuf)[j] ^ ((uint64_t*) idaptr)[j] ^ ((uint64_t*) idbptr)[j];
	}

#ifdef DEBUG_ALSZ_CHECKS_INPUT
		cout << "\t" << (hex);
		for(uint32_t t = 0; t < rowbytelen; t++) {
			cout << setw(2) << setfill('0') << (uint32_t) tmpbuf[t];
		}
		cout << (dec) << endl;
#endif
#ifdef AES_OWF
		owf(&aesowfkey, rowbytelen, tmpbuf, resbuf);
#else
	/*SHA512_CTX sha;
	SHA512_Init(&sha);
	SHA512_Update(&sha, tmpbuf, rowbytelen);
	SHA512_Final(hash_buf, &sha);
	memcpy(resbuf, hash_buf, OWF_BYTES);*/
	sha512_hash(resbuf, OWF_BYTES, tmpbuf, rowbytelen, hash_buf);
	//m_cCrypt->hash_buf(resbuf, OWF_BYTES, tmpbuf, rowbytelen, hash_buf);//hash_buf, rowbytelen, tmpbuf, resbuf, hash_buf);
#endif
#ifdef DEBUG_ALSZ_CHECKS_OUTPUT
		cout << "\t" << (hex);
		for(uint32_t t = 0; t < OWF_BYTES; t++) {
			cout << (uint32_t) resbuf[t];
		}
		cout << (dec) << endl;
#endif
}
Exemplo n.º 6
0
void hmac_sha512
(
	  char *k,		/* secret key */
	  int lk,		/* length of the key in bytes */
	  char *d,		/* data and also output buffer of at least 64 bytes */
	  int ld			/* length of data in bytes */	  
)
{
	hmac_sha512_ctx hmac;
	char key[SHA512_DIGESTSIZE];

    /* If the key is longer than the hash algorithm block size,
	   let key = sha512(key), as per HMAC specifications. */
	if (lk > SHA512_BLOCKSIZE)
	{
		sha512_ctx tctx;

		sha512_begin (&tctx);
		sha512_hash ((unsigned char *) k, lk, &tctx);
		sha512_end ((unsigned char *) key, &tctx);

		k = key;
		lk = SHA512_DIGESTSIZE;

		burn (&tctx, sizeof(tctx));		// Prevent leaks
	}

	hmac_sha512_internal (k, lk, d, ld, &hmac);

	/* Prevent leaks */
	burn (&hmac, sizeof(hmac));
	burn (key, sizeof(key));
}
Exemplo n.º 7
0
void sha512_hmac(const char *k, size_t k_len, const char *d, size_t d_len, char *out)
{
	sha512_ctx ctx;
	u8         buf[SHA512_BLOCK_SIZE];
	u8         hval[SHA512_DIGEST_SIZE];
	size_t     i;

	/* zero key buffer */
	zeroauto(buf, sizeof(buf));

	/* compress hmac key */
	if (k_len > SHA512_BLOCK_SIZE) {
		sha512_init(&ctx);
		sha512_hash(&ctx, k, k_len);
		sha512_done(&ctx, buf);
	} else {
		mincpy(buf, k, k_len);
	}

	/* create the hash initial vector */ 
	for (i = 0; i < SHA512_BLOCK_SIZE; i++) {
		buf[i] ^= 0x36;
	}

	/* hash key and data */
	sha512_init(&ctx);
	sha512_hash(&ctx, buf, SHA512_BLOCK_SIZE);
	sha512_hash(&ctx, d, d_len);
	sha512_done(&ctx, hval);

	/* create the second HMAC vector */
	for (i = 0; i < SHA512_BLOCK_SIZE; i++) {
        buf[i] ^= 0x6A;
    } 

	/* calculate "outer" hash */
	sha512_init(&ctx);
	sha512_hash(&ctx, buf, SHA512_BLOCK_SIZE);
	sha512_hash(&ctx, hval, SHA512_DIGEST_SIZE);
	sha512_done(&ctx, out);	

	/* prevent leaks */
	zeroauto(buf,  sizeof(buf));
	zeroauto(hval, sizeof(hval));
	zeroauto(&ctx, sizeof(ctx));
}
Exemplo n.º 8
0
void hmac_sha512_internal
(
	  char *k,		/* secret key */
	  int lk,		/* length of the key in bytes */
	  char *d,		/* data and also output buffer of at least 64 bytes */
	  int ld,			/* length of data in bytes */
	  hmac_sha512_ctx* hmac
)
{
	sha512_ctx* ctx = &(hmac->ctx);
	char* buf = hmac->buf;
	int i;

	/**** Inner Digest ****/

	sha512_begin (ctx);

	/* Pad the key for inner digest */
	for (i = 0; i < lk; ++i)
		buf[i] = (char) (k[i] ^ 0x36);
	for (i = lk; i < SHA512_BLOCKSIZE; ++i)
		buf[i] = 0x36;

	sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx);
	sha512_hash ((unsigned char *) d, ld, ctx);

	sha512_end ((unsigned char *) d, ctx);

	/**** Outer Digest ****/

	sha512_begin (ctx);

	for (i = 0; i < lk; ++i)
		buf[i] = (char) (k[i] ^ 0x5C);
	for (i = lk; i < SHA512_BLOCKSIZE; ++i)
		buf[i] = 0x5C;

	sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, ctx);
	sha512_hash ((unsigned char *) d, SHA512_DIGESTSIZE, ctx);

	sha512_end ((unsigned char *) d, ctx);
}
static int self_check(void) {
	int i;
	for (i = 0; i < sizeof(testCases) / sizeof(testCases[i]); i++) {
		struct testcase *tc = &testCases[i];
		uint64_t hash[8];
		sha512_hash(tc->message, strlen((const char *)tc->message), hash);
		if (memcmp(hash, tc->answer, sizeof(tc->answer)) != 0)
			return 0;
	}
	return 1;
}
Exemplo n.º 10
0
void sha512(const std::vector<std::uint8_t> &input, std::vector<std::uint8_t> &output)
{
    static const auto sha512_bytes = 64;

    output.resize(sha512_bytes);
    auto output_pointer_u64 = reinterpret_cast<std::uint64_t *>(output.data());

    sha512_hash(input.data(), input.size(), output_pointer_u64);

    byteswap(output_pointer_u64, sha512_bytes / sizeof(std::uint64_t));
}
Exemplo n.º 11
0
void rnd_add_buff(void *data, int size)
{
	sha512_ctx sha_ctx;
	ext_seed   seed;
	u8         hval[SHA512_DIGEST_SIZE];
	int        pos, i;

	/* add counter and timestamp to seed data to prevent hash recurrence */
	seed.seed1 = __rdtsc();
	seed.seed2 = reseed_cnt++;

	/* hash input data */
	sha512_init(&sha_ctx);
	sha512_hash(&sha_ctx, data, size);
	sha512_hash(&sha_ctx, pv(&seed), sizeof(seed));
	sha512_done(&sha_ctx, hval);

	/* add hash value to seed buffer */
	for (i = 0; i < SHA512_DIGEST_SIZE; i++)
	{
		if ( (pos = rnd_pos) >= RNG_POOL_SIZE) {
			pos = 0; 
		}

		rnd_pool[pos] += hval[i];
		rnd_pos        = pos + 1;
	}

	/* add hash value to key buffer */
	for (i = 0; i < SHA512_DIGEST_SIZE; i++) {
		key_pool[i % AES_KEY_SIZE] += hval[i];
	}
	
	/* prevent leaks */
	zeroauto(&sha_ctx, sizeof(sha_ctx));
	zeroauto(&hval, sizeof(hval));
	zeroauto(&seed, sizeof(seed));
}
Exemplo n.º 12
0
void derive_key_sha512 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen)
{
	hmac_sha512_ctx hmac;
	int b, l, r;
	char key[SHA512_DIGESTSIZE];

    /* If the password is longer than the hash algorithm block size,
	   let pwd = sha512(pwd), as per HMAC specifications. */
	if (pwd_len > SHA512_BLOCKSIZE)
	{
		sha512_ctx tctx;

		sha512_begin (&tctx);
		sha512_hash ((unsigned char *) pwd, pwd_len, &tctx);
		sha512_end ((unsigned char *) key, &tctx);

		pwd = key;
		pwd_len = SHA512_DIGESTSIZE;

		burn (&tctx, sizeof(tctx));		// Prevent leaks
	}

	if (dklen % SHA512_DIGESTSIZE)
	{
		l = 1 + dklen / SHA512_DIGESTSIZE;
	}
	else
	{
		l = dklen / SHA512_DIGESTSIZE;
	}

	r = dklen - (l - 1) * SHA512_DIGESTSIZE;

	/* first l - 1 blocks */
	for (b = 1; b < l; b++)
	{
		derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, b, &hmac);
		memcpy (dk, hmac.u, SHA512_DIGESTSIZE);
		dk += SHA512_DIGESTSIZE;
	}

	/* last block */
	derive_u_sha512 (pwd, pwd_len, salt, salt_len, iterations, b, &hmac);
	memcpy (dk, hmac.u, r);


	/* Prevent possible leaks. */
	burn (&hmac, sizeof(hmac));
	burn (key, sizeof(key));
}
Exemplo n.º 13
0
static void rnd_pool_mix()
{
	sha512_ctx sha_ctx;
	int        i, n;
	u8         hval[SHA512_DIGEST_SIZE];

	for (i = 0; i < RNG_POOL_SIZE; i += SHA512_DIGEST_SIZE)
	{
		sha512_init(&sha_ctx);
		sha512_hash(&sha_ctx, rnd_pool, sizeof(rnd_pool));
		sha512_done(&sha_ctx, hval);

		for (n = 0; n < SHA512_DIGEST_SIZE; n++) {
			rnd_pool[i + n] += hval[n];
		}
	}

	/* Prevent leaks */
	zeroauto(hval, sizeof(hval));
	zeroauto(&sha_ctx, sizeof(sha_ctx));
}
Exemplo n.º 14
0
/* The random pool mixing function */
BOOL Randmix ()
{
	if (bRandmixEnabled)
	{
		unsigned char hashOutputBuffer [MAX_DIGESTSIZE];
		WHIRLPOOL_CTX	wctx;
		RMD160_CTX		rctx;
		sha512_ctx		sctx;
		sha256_ctx		s256ctx;
		int poolIndex, digestIndex, digestSize;

		switch (HashFunction)
		{
		case RIPEMD160:
			digestSize = RIPEMD160_DIGESTSIZE;
			break;

		case SHA512:
			digestSize = SHA512_DIGESTSIZE;
			break;

		case SHA256:
			digestSize = SHA256_DIGESTSIZE;
			break;

		case WHIRLPOOL:
			digestSize = WHIRLPOOL_DIGESTSIZE;
			break;

		default:
			TC_THROW_FATAL_EXCEPTION;
		}

		if (RNG_POOL_SIZE % digestSize)
			TC_THROW_FATAL_EXCEPTION;

		for (poolIndex = 0; poolIndex < RNG_POOL_SIZE; poolIndex += digestSize)		
		{
			/* Compute the message digest of the entire pool using the selected hash function. */
			switch (HashFunction)
			{
			case RIPEMD160:
				RMD160Init(&rctx);
				RMD160Update(&rctx, pRandPool, RNG_POOL_SIZE);
				RMD160Final(hashOutputBuffer, &rctx);
				break;

			case SHA512:
				sha512_begin (&sctx);
				sha512_hash (pRandPool, RNG_POOL_SIZE, &sctx);
				sha512_end (hashOutputBuffer, &sctx);
				break;

			case SHA256:
				sha256_begin (&s256ctx);
				sha256_hash (pRandPool, RNG_POOL_SIZE, &s256ctx);
				sha256_end (hashOutputBuffer, &s256ctx);
				break;

			case WHIRLPOOL:
				WHIRLPOOL_init (&wctx);
				WHIRLPOOL_add (pRandPool, RNG_POOL_SIZE * 8, &wctx);
				WHIRLPOOL_finalize (&wctx, hashOutputBuffer);
				break;

			default:		
				// Unknown/wrong ID
				TC_THROW_FATAL_EXCEPTION;
			}

			/* XOR the resultant message digest to the pool at the poolIndex position. */
			for (digestIndex = 0; digestIndex < digestSize; digestIndex++)
			{
				pRandPool [poolIndex + digestIndex] ^= hashOutputBuffer [digestIndex];
			}
		}

		/* Prevent leaks */
		burn (hashOutputBuffer, MAX_DIGESTSIZE);	
		switch (HashFunction)
		{
		case RIPEMD160:
			burn (&rctx, sizeof(rctx));		
			break;

		case SHA512:
			burn (&sctx, sizeof(sctx));		
			break;

		case SHA256:
			burn (&s256ctx, sizeof(s256ctx));		
			break;

		case WHIRLPOOL:
			burn (&wctx, sizeof(wctx));		
			break;

		default:		
			// Unknown/wrong ID
			TC_THROW_FATAL_EXCEPTION;
		}
	}
	return TRUE;
}
Exemplo n.º 15
0
nnob_snd_check_t NNOBOTExtSnd::UpdateCheckBuf(uint8_t* tocheckseed, uint8_t* tocheckrcv, uint64_t otid, uint64_t numblocks, channel* check_chan) {
	uint64_t rowbytelen = m_nBlockSizeBytes * numblocks;
	uint64_t checkbytelen = min(rowbytelen, bits_in_bytes(m_nOTs - otid));

	uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH);
	uint8_t* tmpbuf = (uint8_t*) malloc(rowbytelen);
	uint8_t *idaptr, *idbptr;
	nnob_snd_check_t check_buf;
	//check_buf.rcv_chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES);
	check_buf.chk_buf = (uint8_t*) malloc(m_nChecks * OWF_BYTES);

	uint8_t *chk_buf_ptr = check_buf.chk_buf;
	uint8_t *idatmpbuf = (BYTE*) malloc(sizeof(BYTE) * rowbytelen);
	uint8_t *idbtmpbuf = (BYTE*) malloc(sizeof(BYTE) * rowbytelen);
	uint8_t *seedptr, *rcvptr;

	//uint32_t blockoffset = ceil_divide(otid, NUMOTBLOCKS * m_nBlockSizeBits);
	uint32_t blockid = 0; //TODO bring in as soon as 3-step OT is implemented

	check_buf.otid = otid;
	check_buf.numblocks = numblocks;
	check_buf.perm = (linking_t*) malloc(sizeof(linking_t*) * m_nChecks);
	check_buf.permchoicebits = (BYTE*) malloc(sizeof(uint8_t) * m_nChecks);

	genRandomMapping(check_buf.perm, m_nBaseOTs);

	for(uint32_t i = 0; i < m_nChecks; i++) {
		check_buf.permchoicebits[i] = m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].ida) ^ m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].idb);
	}

	//right now the checkbytelen needs to be a multiple of AES_BYTES
	assert(ceil_divide(rowbytelen, OWF_BYTES) * OWF_BYTES == rowbytelen);
#ifdef DEBUG_NNOB_CHECKS
	m_vU.PrintHex();
#endif

	for(uint64_t i = 0; i < m_nChecks; i++, chk_buf_ptr+=OWF_BYTES) {

		if(m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].ida) == 0) {
			memcpy(idatmpbuf, tocheckseed + check_buf.perm[i].ida * rowbytelen, rowbytelen);
		} else {
			seedptr = tocheckseed + check_buf.perm[i].ida * rowbytelen;
			rcvptr = tocheckrcv + check_buf.perm[i].ida * rowbytelen;
			for(int j = 0; j < rowbytelen/sizeof(uint64_t); j++) {
				((uint64_t*) idatmpbuf)[j] = ((uint64_t*) seedptr)[j] ^ ((uint64_t*) rcvptr)[j];
			}
		}

		if(m_vU.GetBit(blockid * m_nBaseOTs + check_buf.perm[i].idb) == 0) {
			memcpy(idbtmpbuf, tocheckseed + check_buf.perm[i].idb * rowbytelen, rowbytelen);
		} else {
			seedptr = tocheckseed + check_buf.perm[i].idb * rowbytelen;
			rcvptr = tocheckrcv + check_buf.perm[i].idb * rowbytelen;
			for(int j = 0; j < rowbytelen/sizeof(uint64_t); j++) {
				((uint64_t*) idbtmpbuf)[j] = ((uint64_t*) seedptr)[j] ^ ((uint64_t*) rcvptr)[j];
			}
		}

	/*#ifdef DEBUG_NNOB_CHECKS
		cout << "seedA: " <<  (hex) << ((uint64_t*) (tocheckseed + check_buf.perm[i].ida * rowbytelen))[0] <<
				", rcvA: " << ((uint64_t*) (tocheckrcv + check_buf.perm[i].ida * rowbytelen))[0] << (dec) << endl;
		cout << "seedB: " <<  (hex) << ((uint64_t*) (tocheckseed + check_buf.perm[i].idb * rowbytelen))[0] <<
				", rcvB: " << ((uint64_t*) (tocheckrcv + check_buf.perm[i].idb * rowbytelen))[0] << (dec) << endl;
		cout << "input to owf " <<  (hex) << ((uint64_t*) idatmpbuf)[0] << ", " << ((uint64_t*) idbtmpbuf)[0] << (dec) << endl;
	#endif*/

		memset(tmpbuf, 0, rowbytelen);

		for(uint64_t j = 0; j < rowbytelen/sizeof(uint64_t); j++) {
			((uint64_t*) tmpbuf)[j] = ((uint64_t*) tmpbuf)[j] ^ ((uint64_t*) idatmpbuf)[j] ^ ((uint64_t*) idbtmpbuf)[j];
		}

#ifdef DEBUG_NNOB_CHECKS_INPUT
		cout << "XOR-OWF Input:\t" << (hex);
		for(uint32_t t = 0; t < checkbytelen; t++) {
			cout << setw(2) << setfill('0') << (uint32_t) tmpbuf[t];
		}
		cout << (dec) << endl;
#endif
#ifdef AES_OWF
			owf(&aesowfkey, rowbytelen, tmpbuf, resbuf);
#else
		//m_cCrypt->hash_buf(chk_buf_ptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf);//hash_buf, rowbytelen, tmpbuf, resbuf, hash_buf);
		sha512_hash(chk_buf_ptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf);
#endif
#ifdef DEBUG_NNOB_CHECKS_OUTPUT
		cout << "XOR-OWF Output:\t" << (hex);
		for(uint32_t t = 0; t < OWF_BYTES; t++) {
			cout << (uint32_t) chk_buf_ptr[t];
		}
		cout << (dec) << endl;
#endif
		//XORandOWF(idatmpbuf, idbtmpbuf,	checkbytelen, tmpbuf, chk_buf_ptr, hash_buf);
	}

/*	for(uint64_t i = 0; i < m_nChecks; i++, seedcheckbufptr+=OWF_BYTES, rcvcheckbufptr+=OWF_BYTES) {
		memset(tmpbuf, 0, rowbytelen);
#ifdef DEBUG_ALSZ_CHECKS
		cout << i << "-th check between " << check_buf.perm[i].ida << " and " << check_buf.perm[i].idb << ": " << endl;
#endif
		XORandOWF(tocheckseed + check_buf.perm[i].ida * rowbytelen, tocheckseed + check_buf.perm[i].idb * rowbytelen,
				rowbytelen, tmpbuf, seedcheckbufptr, hash_buf);
		XORandOWF(tocheckrcv + check_buf.perm[i].ida * rowbytelen, tocheckrcv + check_buf.perm[i].idb * rowbytelen,
				rowbytelen, tmpbuf, rcvcheckbufptr, hash_buf);
	}*/

	free(tmpbuf);
	free(hash_buf);
	free(idatmpbuf);
	free(idbtmpbuf);

	//Send the permutation and the XORed bits over to the receiver
	check_chan->send_id_len((uint8_t*) check_buf.perm, sizeof(linking_t) * m_nChecks, otid, numblocks);
	check_chan->send(check_buf.permchoicebits, m_nChecks);

	return check_buf;
}
Exemplo n.º 16
0
static
int dc_add_single_kf(dc_pass *pass, wchar_t *path)
{
	kf_ctx *k_ctx;
	HANDLE  h_file;
	int     resl, i;
	int     succs;
	u32     bytes;

	h_file = NULL; k_ctx = NULL;
	do
	{
		if ( (k_ctx = secure_alloc(sizeof(kf_ctx))) == NULL ) {
			resl = ST_NOMEM; break;
		}

		h_file = CreateFile(
			path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

		if (h_file == INVALID_HANDLE_VALUE) {
			h_file = NULL; resl = ST_ACCESS_DENIED; break;
		}

		/* initialize sha512 for hashing keyfile */
		sha512_init(&k_ctx->sha);

		do
		{
			succs = ReadFile(h_file, k_ctx->kf_block, KF_BLOCK_SIZE, &bytes, NULL);

			if ( (succs == 0) || (bytes == 0) ) {
				break;
			}
			sha512_hash(&k_ctx->sha, k_ctx->kf_block, bytes);
		} while (1);		
	
		/* done hasing */
		sha512_done(&k_ctx->sha, k_ctx->hash);

		/* zero unused password buffer bytes */
		zeromem(
			p8(pass->pass) + pass->size, (MAX_PASSWORD*2) - pass->size);

		/* mix the keyfile hash and password */
		for (i = 0; i < (SHA512_DIGEST_SIZE / sizeof(u32)); i++) {
			p32(pass->pass)[i] += p32(k_ctx->hash)[i];
		}
		pass->size = max(pass->size, SHA512_DIGEST_SIZE); 
		resl = ST_OK;		
	} while (0);

	if (h_file != NULL) {
		CloseHandle(h_file);
	}

	if (k_ctx != NULL) {
		secure_free(k_ctx);
	}

	return resl;
}
Exemplo n.º 17
0
int rnd_get_bytes(u8 *buf, int len)
{
	sha512_ctx sha_ctx;
	u8         hval[SHA512_DIGEST_SIZE];
	int        c_len, idx, i;
	ext_seed   seed;
	int        fail;

	if (reseed_cnt < 256) {
		DbgMsg("RNG not have sufficient entropy (%d reseeds), collect it now\n", reseed_cnt);
	}
	/* in RNG not have sufficient entropy, then collect it now */
	while (reseed_cnt < 256) 
	{
		dc_delay(1); /* wait 1 millisecond */
		rnd_reseed_now();
	}

	wait_object_infinity(&rnd_mutex);

	/* derive AES key from key pool */
	aes256_asm_set_key(key_pool, rnd_key);

	/* mix pool state before get data from it */
	rnd_pool_mix();

	/* idx - position for extraction pool data */
	idx = 0; fail = 0;
	do
	{
		c_len      = min(len, SHA512_DIGEST_SIZE);
		seed.seed1 = getrnd_cnt++;
		seed.seed2 = len;

		/* collect additional entropy before extract data block */
		rnd_reseed_now();

		sha512_init(&sha_ctx);
		sha512_hash(&sha_ctx, rnd_pool + idx, SHA512_DIGEST_SIZE);
		sha512_hash(&sha_ctx, pv(&seed), sizeof(seed));
		sha512_done(&sha_ctx, hval);

		/* encrypt hash value with AES in ECB mode */		
		for (i = 0; i < SHA512_DIGEST_SIZE; i += AES_BLOCK_SIZE) {
			aes256_asm_encrypt(hval + i, hval + i, rnd_key);
		}

		/* copy data to output */
		__try {
			memcpy(buf, hval, c_len);
		}
		__except(EXCEPTION_EXECUTE_HANDLER) {
			fail = 1;
		}

		/* increment extraction pointer */
		if ( (idx += SHA512_DIGEST_SIZE) == RNG_POOL_SIZE ) {
			/* if all data from pool extracted then 
			  mix pool for use new entropy added with reseeds */
			rnd_pool_mix(); idx = 0; 
		}

		/* collect additional entropy after extract data block */		
		rnd_reseed_now();

		/* update buffer pointer and remaining length */
		buf += c_len; len -= c_len;
	} while ( (len != 0) && (fail == 0) );

	/* mix pool after get data to prevent "could boot" attacks to generated keys */
	rnd_pool_mix();

	/* Prevent leaks */
	zeroauto(rnd_key, sizeof(aes256_key));
	zeroauto(&sha_ctx, sizeof(sha_ctx));
	zeroauto(hval, sizeof(hval));
	zeroauto(&seed, sizeof(seed));

	KeReleaseMutex(&rnd_mutex, FALSE);

	return fail == 0;
}
Exemplo n.º 18
0
void NNOBOTExtRec::ComputeOWF(std::queue<nnob_rcv_check_t>* check_buf_q, channel* check_chan) {//linking_t* permbits, int nchecks, int otid, int processedOTs, BYTE* outhashes) {

	//Obtain T0 and T1 from the SeedPointers
	uint32_t receiver_hashes = 1;

	uint64_t tmpid, tmpnblocks;
	linking_t* perm;
	uint8_t* rcv_buf_perm = check_chan->blocking_receive_id_len((uint8_t**) &perm, &tmpid, &tmpnblocks);
	uint8_t* rcv_buf_permchoices = check_chan->blocking_receive();
	uint8_t* sender_permchoicebitptr = rcv_buf_permchoices;

	nnob_rcv_check_t check_buf = check_buf_q->front();

	check_buf_q->pop();

	assert(tmpid == check_buf.otid);
	assert(tmpnblocks == check_buf.numblocks);

	//the bufsize has to be padded to a multiple of the PRF-size since we will omit boundary checks there
	uint32_t i, j;
	uint64_t bufrowbytelen = m_nBlockSizeBytes * check_buf.numblocks;//seedptr->expstrbitlen>>3;//(CEIL_DIVIDE(processedOTs, wd_size_bits) * wd_size_bits) >>3;
	uint64_t checkbytelen = std::min(bufrowbytelen, bits_in_bytes(m_nOTs - check_buf.otid));
	//contains the T-matrix
	uint8_t* T0 = check_buf.T0;
	//contains the T-matrix XOR the receive bits
	//uint8_t* T1 = check_buf.T1;

	uint32_t outhashbytelen = m_nChecks * OWF_BYTES * receiver_hashes;
	uint8_t* outhashes = (uint8_t*) malloc(outhashbytelen);

#ifdef AES_OWF
	AES_KEY_CTX aesowfkey;
	MPC_AES_KEY_INIT(&aesowfkey);
#else
	uint8_t* hash_buf = (uint8_t*) malloc(SHA512_DIGEST_LENGTH);
#endif
	uint8_t* tmpbuf = (uint8_t*) malloc(bufrowbytelen);
	uint8_t **ka = (uint8_t**) malloc(2 * sizeof(uint8_t*));
	uint8_t **kb = (uint8_t**) malloc(2 * sizeof(uint8_t*));
	uint8_t  *kaptr, *kbptr;
	uint8_t* outptr = outhashes;

	uint8_t* receiver_choicebits = m_vChoices->GetArr() + ceil_divide(check_buf.otid, 8);
	CBitVector tmp;
	tmp.AttachBuf(tmpbuf, bufrowbytelen*8);

	//Compute all hashes for the permutations given Ta, Tb and the choice bits
	for(i = 0; i < m_nChecks; i++, sender_permchoicebitptr++) {
		ka[0] = T0 + perm[i].ida * bufrowbytelen;
		kb[0] = T0 + perm[i].idb * bufrowbytelen;

	#ifdef DEBUG_MALICIOUS
		std::cout << (std::dec) << i << "-th check: between " << perm[i].ida << ", and " << perm[i].idb << std::endl;
	#endif
		for(j = 0; j < receiver_hashes; j++, outptr+=OWF_BYTES) {
			kaptr = ka[0];
			kbptr = kb[0];

			assert((*sender_permchoicebitptr) == 0 || (*sender_permchoicebitptr == 1));

			tmp.SetXOR(kaptr, kbptr, 0, bufrowbytelen);
			if(*sender_permchoicebitptr == 1) {
				tmp.XORBytesReverse(receiver_choicebits, 0, checkbytelen);
			}

#ifdef DEBUG_NNOB_CHECKS_INPUT
			std::cout << "XOR-OWF Input:\t" << (std::hex);
			for(uint32_t t = 0; t < checkbytelen; t++) {
				std::cout << std::setw(2) << std::setfill('0') << (uint32_t) tmpbuf[t];
			}
			std::cout << (std::dec) << std::endl;
#endif
	#ifdef AES_OWF
			owf(&aesowfkey, rowbytelen, tmpbuf, outhashes);
	#else
			//m_cCrypt->hash_buf(outptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf);
			sha512_hash(outptr, OWF_BYTES, tmpbuf, checkbytelen, hash_buf);
	#endif
#ifdef DEBUG_NNOB_CHECKS_OUTPUT
			std::cout << "XOR-OWF Output:\t" << (std::hex);
			for(uint32_t t = 0; t < OWF_BYTES; t++) {
				std::cout << (uint32_t) outptr[t];
			}
			std::cout << (std::dec) << std::endl;
#endif
		}
	}
	check_chan->send_id_len(outhashes, outhashbytelen, check_buf.otid, check_buf.numblocks);

	free(rcv_buf_perm);
	free(rcv_buf_permchoices);
	//free(tmpbuf);
	free(ka);
	free(kb);
	free(check_buf.T0);
	//free(check_buf.T1);
	free(outhashes);
#ifndef AES_OWF
	free(hash_buf);
#endif
}
Exemplo n.º 19
0
void boot_main()
{
	list_entry *entry;
	hdd_inf    *hdd;
	prt_inf    *prt, *active;
	char       *error;
	int         login, i;
	int         n_mount;

	active = NULL; error = NULL;
	login = 0; n_mount = 0;

	/* init crypto */
	dc_init_crypto(conf.options & OP_HW_CRYPTO);

	/* prepare MBR copy buffer */
	autocpy(conf.save_mbr + 432, p8(0x7C00) + 432, 80);

	if (dc_scan_partitions() == 0) {
		error = "partitions not found\n";
		goto error;
	}

	if (hdd = find_hdd(boot_dsk))
	{
		/* find active partition on boot disk */
		entry = hdd->part_head.flink;
		
		while (entry != &hdd->part_head)
		{
			prt   = contain_record(entry, prt_inf, entry_hdd);
			entry = entry->flink;

			if (prt->active != 0) {
				active = prt; break;
			}
		}
	}
retry_auth:;	
	if (conf.logon_type & LT_GET_PASS) 
	{
		login = dc_get_password();

		if ( (conf.options & OP_NOPASS_ERROR) && (login == 0) ) 
		{
			dc_password_error(active);

			if (conf.error_type & ET_RETRY) {
				goto retry_auth;
			} else {
				/* halt system */
				__halt();
			}
		}
	}

	/* add embedded keyfile to password buffer */
	if (conf.logon_type & LT_EMBED_KEY) 
	{
		sha512_ctx sha;
		u8         hash[SHA512_DIGEST_SIZE];

		sha512_init(&sha);
		sha512_hash(&sha, conf.emb_key, sizeof(conf.emb_key));
		sha512_done(&sha, hash);

		/* mix the keyfile hash and password */
		for (i = 0; i < (SHA512_DIGEST_SIZE / sizeof(u32)); i++) {
			p32(bd_dat->password.pass)[i] += p32(hash)[i];
		}
		bd_dat->password.size = max(bd_dat->password.size, SHA512_DIGEST_SIZE);

		/* prevent leaks */
		zeroauto(hash, sizeof(hash));
		zeroauto(&sha, sizeof(sha));
	}

	if (bd_dat->password.size != 0) 
	{
		if (n_mount = dc_mount_parts()) {
			/* hook BIOS interrupts */
			bios_hook_ints();
		} else {
			/* clean password buffer to prevent leaks */
			zeroauto(&bd_dat->password, sizeof(dc_pass));
		}
	}

	if ( (n_mount == 0) && (login != 0) ) 
	{
		dc_password_error(active);

		if (conf.error_type & ET_RETRY) {
			goto retry_auth;
		} else {
			/* halt system */
			__halt();
		}
	}
	
	switch (conf.boot_type)
	{
		case BT_MBR_BOOT: 			  
		  {
			  if (hdd == NULL) {
				  error = "boot disk not found\n";
				  goto error;
			  }
			  boot_from_mbr(hdd, n_mount);
		  }
	    break;
		case BT_MBR_FIRST: 
		  {
			  if ( (hdd = find_bootable_hdd()) == NULL ) {
				  error = "boot disk not found\n";
				  goto error;
			  }			 			  
			  boot_from_mbr(hdd, n_mount);
		  }
	    break;
		case BT_ACTIVE:
		  {
			  if (active == NULL) {
				  error = "active partition not found\n";
				  goto error;
			  } else {	  
				  boot_from_partition(active, n_mount);
			  }
		  }
	  	break;
		case BT_AP_PASSWORD:
		  {
			  /* find first partition with appropriate password */
			  entry = prt_head.flink;

			  while (entry != &prt_head)
			  {
				  prt   = contain_record(entry, prt_inf, entry_glb);
				  entry = entry->flink;

				  if ( (prt->extend == 0) && (prt->mnt_ok != 0) ) {
					  boot_from_partition(prt, n_mount);
				  }
			  }

			  error = "bootable partition not mounted\n";
			  goto error;
		  }
	    break;
		case BT_DISK_ID:
		  {
			  /* find partition by disk_id */
			  entry = prt_head.flink;

			  while (entry != &prt_head)
			  {
				  prt   = contain_record(entry, prt_inf, entry_glb);
				  entry = entry->flink;

				  if ( (prt->extend == 0) && (prt->mnt_ok != 0) &&
					   (prt->disk_id == conf.disk_id) ) 
				  {
					  boot_from_partition(prt, n_mount);
				  }
			  }
			  
			  error = "disk_id equal partition not found\n";
			  goto error;
		  }
		break;
	}

error:;
	if (error != NULL) {
		puts(error); 
	}	
	while (1);
}
Exemplo n.º 20
0
void hmac_sha512
(
	  char *k,		/* secret key */
	  int lk,		/* length of the key in bytes */
	  char *d,		/* data */
	  int ld,		/* length of data in bytes */
	  char *out,		/* output buffer, at least "t" bytes */
	  int t
)
{
	sha512_ctx ictx, octx;
	char isha[SHA512_DIGESTSIZE], osha[SHA512_DIGESTSIZE];
	char key[SHA512_DIGESTSIZE];
	char buf[SHA512_BLOCKSIZE];
	int i;

    /* If the key is longer than the hash algorithm block size,
	   let key = sha512(key), as per HMAC specifications. */
	if (lk > SHA512_BLOCKSIZE)
	{
		sha512_ctx tctx;

		sha512_begin (&tctx);
		sha512_hash ((unsigned char *) k, lk, &tctx);
		sha512_end ((unsigned char *) key, &tctx);

		k = key;
		lk = SHA512_DIGESTSIZE;

		burn (&tctx, sizeof(tctx));		// Prevent leaks
	}

	/**** Inner Digest ****/

	sha512_begin (&ictx);

	/* Pad the key for inner digest */
	for (i = 0; i < lk; ++i)
		buf[i] = (char) (k[i] ^ 0x36);
	for (i = lk; i < SHA512_BLOCKSIZE; ++i)
		buf[i] = 0x36;

	sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &ictx);
	sha512_hash ((unsigned char *) d, ld, &ictx);

	sha512_end ((unsigned char *) isha, &ictx);

	/**** Outer Digest ****/

	sha512_begin (&octx);

	for (i = 0; i < lk; ++i)
		buf[i] = (char) (k[i] ^ 0x5C);
	for (i = lk; i < SHA512_BLOCKSIZE; ++i)
		buf[i] = 0x5C;

	sha512_hash ((unsigned char *) buf, SHA512_BLOCKSIZE, &octx);
	sha512_hash ((unsigned char *) isha, SHA512_DIGESTSIZE, &octx);

	sha512_end ((unsigned char *) osha, &octx);

	/* truncate and print the results */
	t = t > SHA512_DIGESTSIZE ? SHA512_DIGESTSIZE : t;
	hmac_truncate (osha, out, t);

	/* Prevent leaks */
	burn (&ictx, sizeof(ictx));
	burn (&octx, sizeof(octx));
	burn (isha, sizeof(isha));
	burn (osha, sizeof(osha));
	burn (buf, sizeof(buf));
	burn (key, sizeof(key));
}
Exemplo n.º 21
0
	void Sha512::ProcessData (const ConstBufferPtr &data)
	{
		if_debug (ValidateDataParameters (data));
		sha512_hash (data.Get(), (int) data.Size(), (sha512_ctx *) Context.Ptr());
	}
Exemplo n.º 22
0
int CHashManager::HashFile(char *pszFile)
{
	FILE *fp = NULL;
	unsigned char pBuf[SIZE_HASH_BUFFER];
	unsigned long uRead = 0;
	unsigned char pTemp[256];
	char szTemp[RH_MAX_BUFFER];
	int i = 0;

	printf("File: <");
	printf(pszFile);
	printf(">");
	printf(CPS_NEWLINE);

	fp = fopen(pszFile, "rb");
	if(fp == NULL) return RH_CANNOT_OPEN_FILE;

	if(m_bAlgorithm[HASHID_CRC16]) crc16_init(&m_crc16);
	if(m_bAlgorithm[HASHID_CRC16CCITT]) crc16ccitt_init(&m_crc16ccitt);
	if(m_bAlgorithm[HASHID_CRC32]) crc32Init(&m_crc32);
	if(m_bAlgorithm[HASHID_FCS_16]) fcs16_init(&m_fcs16);
	if(m_bAlgorithm[HASHID_FCS_32]) fcs32_init(&m_fcs32);
	if(m_bAlgorithm[HASHID_GHASH_32_3] || m_bAlgorithm[HASHID_GHASH_32_5]) m_ghash.Init();
	if(m_bAlgorithm[HASHID_GOST]) gosthash_reset(&m_gost);
	if(m_bAlgorithm[HASHID_HAVAL]) haval_start(&m_haval);
	if(m_bAlgorithm[HASHID_MD2]) m_md2.Init();
	if(m_bAlgorithm[HASHID_MD4]) MD4Init(&m_md4);
	if(m_bAlgorithm[HASHID_MD5]) MD5Init(&m_md5, 0);
	if(m_bAlgorithm[HASHID_SHA1]) sha1_begin(&m_sha1);
	if(m_bAlgorithm[HASHID_SHA2_256]) sha256_begin(&m_sha256);
	if(m_bAlgorithm[HASHID_SHA2_384]) sha384_begin(&m_sha384);
	if(m_bAlgorithm[HASHID_SHA2_512]) sha512_begin(&m_sha512);
	if(m_bAlgorithm[HASHID_SIZE_32]) sizehash32_begin(&m_uSizeHash32);
	if(m_bAlgorithm[HASHID_TIGER]) tiger_init(&m_tiger);

	while(1)
	{
		uRead = fread(pBuf, 1, SIZE_HASH_BUFFER, fp);

		if(uRead != 0)
		{
			if(m_bAlgorithm[HASHID_CRC16])
				crc16_update(&m_crc16, pBuf, uRead);

			if(m_bAlgorithm[HASHID_CRC16CCITT])
				crc16ccitt_update(&m_crc16ccitt, pBuf, uRead);

			if(m_bAlgorithm[HASHID_CRC32])
				crc32Update(&m_crc32, pBuf, uRead);

			if(m_bAlgorithm[HASHID_FCS_16])
				fcs16_update(&m_fcs16, pBuf, uRead);

			if(m_bAlgorithm[HASHID_FCS_32])
				fcs32_update(&m_fcs32, pBuf, uRead);

			if(m_bAlgorithm[HASHID_GHASH_32_3] || m_bAlgorithm[HASHID_GHASH_32_5])
				m_ghash.Update(pBuf, uRead);

			if(m_bAlgorithm[HASHID_GOST])
				gosthash_update(&m_gost, pBuf, uRead);

			if(m_bAlgorithm[HASHID_HAVAL])
				haval_hash(&m_haval, pBuf, uRead);

			if(m_bAlgorithm[HASHID_MD2])
				m_md2.Update(pBuf, uRead);

			if(m_bAlgorithm[HASHID_MD4])
				MD4Update(&m_md4, pBuf, uRead);

			if(m_bAlgorithm[HASHID_MD5])
				MD5Update(&m_md5, pBuf, uRead);

			if(m_bAlgorithm[HASHID_SHA1])
				sha1_hash(pBuf, uRead, &m_sha1);

			if(m_bAlgorithm[HASHID_SHA2_256])
				sha256_hash(pBuf, uRead, &m_sha256);

			if(m_bAlgorithm[HASHID_SHA2_384])
				sha384_hash(pBuf, uRead, &m_sha384);

			if(m_bAlgorithm[HASHID_SHA2_512])
				sha512_hash(pBuf, uRead, &m_sha512);

			if(m_bAlgorithm[HASHID_SIZE_32])
				sizehash32_hash(&m_uSizeHash32, uRead);

			if(m_bAlgorithm[HASHID_TIGER])
				tiger_process(&m_tiger, pBuf, uRead);
		}

		if(uRead != SIZE_HASH_BUFFER) break;
	}

	fclose(fp); fp = NULL;

	// SizeHash-32 is the first hash, because it's the simplest one,
	// the fastest, and most widely used one. ;-)
	if(m_bAlgorithm[HASHID_SIZE_32])
	{
		sizehash32_end(&m_uSizeHash32);
		printf(SZ_SIZEHASH_32);
		printf(SZ_HASHPRE);

		printf("%08X", m_uSizeHash32);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_CRC16])
	{
		crc16_final(&m_crc16);
		printf(SZ_CRC16);
		printf(SZ_HASHPRE);

		printf("%04X", m_crc16);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_CRC16CCITT])
	{
		crc16ccitt_final(&m_crc16ccitt);
		printf(SZ_CRC16CCITT);
		printf(SZ_HASHPRE);

		printf("%04X", m_crc16ccitt);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_CRC32])
	{
		crc32Finish(&m_crc32);
		printf(SZ_CRC32);
		printf(SZ_HASHPRE);

		printf("%08X", m_crc32);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_FCS_16])
	{
		fcs16_final(&m_fcs16);
		printf(SZ_FCS_16);
		printf(SZ_HASHPRE);

		printf("%04X", m_fcs16);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_FCS_32])
	{
		fcs32_final(&m_fcs32);
		printf(SZ_FCS_32);
		printf(SZ_HASHPRE);

		printf("%08X", m_fcs32);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_GHASH_32_3])
	{
		m_ghash.FinalToStr(szTemp, 3);
		printf(SZ_GHASH_32_3);
		printf(SZ_HASHPRE);

		printf(szTemp);

		printf(CPS_NEWLINE);
	}
	if(m_bAlgorithm[HASHID_GHASH_32_5])
	{
		m_ghash.FinalToStr(szTemp, 5);
		printf(SZ_GHASH_32_5);
		printf(SZ_HASHPRE);

		printf(szTemp);

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_GOST])
	{
		gosthash_final(&m_gost, pTemp);
		printf(SZ_GOST);
		printf(SZ_HASHPRE);

		for(i = 0; i < 32; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_HAVAL])
	{
		haval_end(&m_haval, pTemp);
		printf(SZ_HAVAL);
		printf(SZ_HASHPRE);

		for(i = 0; i < 32; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_MD2])
	{
		m_md2.TruncatedFinal(pTemp, 16);
		printf(SZ_MD2);
		printf(SZ_HASHPRE);

		for(i = 0; i < 16; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_MD4])
	{
		MD4Final(pTemp, &m_md4);
		printf(SZ_MD4);
		printf(SZ_HASHPRE);

		for(i = 0; i < 16; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_MD5])
	{
		MD5Final(&m_md5);
		printf(SZ_MD5);
		printf(SZ_HASHPRE);

		for(i = 0; i < 16; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", m_md5.digest[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_SHA1])
	{
		sha1_end(pTemp, &m_sha1);
		printf(SZ_SHA1);
		printf(SZ_HASHPRE);

		for(i = 0; i < 20; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_SHA2_256])
	{
		sha256_end(pTemp, &m_sha256);
		printf(SZ_SHA2_256);
		printf(SZ_HASHPRE);

		for(i = 0; i < 32; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}
	if(m_bAlgorithm[HASHID_SHA2_384])
	{
		sha384_end(pTemp, &m_sha384);
		printf(SZ_SHA2_384);
		printf(SZ_HASHPRE);

		for(i = 0; i < 48; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}
	if(m_bAlgorithm[HASHID_SHA2_512])
	{
		sha512_end(pTemp, &m_sha512);
		printf(SZ_SHA2_512);
		printf(SZ_HASHPRE);

		for(i = 0; i < 64; i++)
		{
			fmtFixHashOutput(i);
			printf("%02X", pTemp[i]);
		}

		printf(CPS_NEWLINE);
	}

	if(m_bAlgorithm[HASHID_TIGER])
	{
		tiger_done(&m_tiger, pTemp);
		printf(SZ_TIGER);
		printf(SZ_HASHPRE);

		for(i = 0; i < 8; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[7-i]); }
		for(i = 8; i < 16; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[23-i]); }
		for(i = 16; i < 24; i++) { fmtFixHashOutput(i); printf("%02X", pTemp[39-i]); }

		printf(CPS_NEWLINE);
	}

	return RH_SUCCESS;
}