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); }
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)); }
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++; } }
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); }
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)); }
/* 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; }
void Sha512::GetDigest (const BufferPtr &buffer) { if_debug (ValidateDigestParameters (buffer)); sha512_end (buffer, (sha512_ctx *) Context.Ptr()); }
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; }
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)); }