void hmac_sha256 ( char *k, /* secret key */ int lk, /* length of the key in bytes */ char *d, /* data */ int ld /* length of data in bytes */ ) { hmac_sha256_ctx hmac; char key[SHA256_DIGESTSIZE]; /* If the key is longer than the hash algorithm block size, let key = sha256(key), as per HMAC specifications. */ if (lk > SHA256_BLOCKSIZE) { sha256_ctx tctx; sha256_begin (&tctx); sha256_hash ((unsigned char *) k, lk, &tctx); sha256_end ((unsigned char *) key, &tctx); k = key; lk = SHA256_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } hmac_sha256_internal(k, lk, d, ld, &hmac); /* Prevent leaks */ burn(&hmac, sizeof(hmac)); burn(key, sizeof(key)); }
static void hmacSha256Final(hmacSha256Context *ctx, uint8_t *mac) { uint8_t tmpDigest[SHA256_DIGEST_SIZE]; /* finalize work hash context */ sha256_end(tmpDigest, &ctx->ctx); /* copy prepared outer hash to work hash */ memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha256_ctx)); /* hash inner digest to work (outer) hash context */ sha256_hash(tmpDigest, SHA256_DIGEST_SIZE, &ctx->ctx); /* finalize work hash context to get the hmac*/ sha256_end(mac, &ctx->ctx); }
static void calculateSHA(char *message, unsigned char *hval){ sha256_ctx sha_ctx[1]; sha256_begin(sha_ctx); sha256_hash(message, strlen(decrypted), sha_ctx); sha256_end(hval, sha_ctx); }
void hmac_sha256_internal ( char *k, /* secret key. It's ensured to be always <= 32 bytes */ int lk, /* length of the key in bytes */ char *d, /* input data. d pointer is guaranteed to be at least 32-bytes long */ int ld, /* length of input data in bytes */ hmac_sha256_ctx* hmac /* HMAC-SHA256 context which holds temporary variables */ ) { int i; sha256_ctx* ctx = &(hmac->ctx); char* buf = hmac->buf; /**** Inner Digest ****/ sha256_begin (ctx); /* Pad the key for inner digest */ for (i = 0; i < lk; ++i) buf[i] = (char) (k[i] ^ 0x36); for (i = lk; i < SHA256_BLOCKSIZE; ++i) buf[i] = 0x36; sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx); sha256_hash ((unsigned char *) d, ld, ctx); sha256_end ((unsigned char *) d, ctx); /* d = inner digest */ /**** Outer Digest ****/ sha256_begin (ctx); for (i = 0; i < lk; ++i) buf[i] = (char) (k[i] ^ 0x5C); for (i = lk; i < SHA256_BLOCKSIZE; ++i) buf[i] = 0x5C; sha256_hash ((unsigned char *) buf, SHA256_BLOCKSIZE, ctx); sha256_hash ((unsigned char *) d, SHA256_DIGESTSIZE, ctx); sha256_end ((unsigned char *) d, ctx); /* d = outer digest */ }
void derive_key_sha256 (char *pwd, int pwd_len, char *salt, int salt_len, uint32 iterations, char *dk, int dklen) { hmac_sha256_ctx hmac; int b, l, r; #ifndef TC_WINDOWS_BOOT char key[SHA256_DIGESTSIZE]; /* If the password is longer than the hash algorithm block size, let pwd = sha256(pwd), as per HMAC specifications. */ if (pwd_len > SHA256_BLOCKSIZE) { sha256_ctx tctx; sha256_begin (&tctx); sha256_hash ((unsigned char *) pwd, pwd_len, &tctx); sha256_end ((unsigned char *) key, &tctx); pwd = key; pwd_len = SHA256_DIGESTSIZE; burn (&tctx, sizeof(tctx)); // Prevent leaks } #endif if (dklen % SHA256_DIGESTSIZE) { l = 1 + dklen / SHA256_DIGESTSIZE; } else { l = dklen / SHA256_DIGESTSIZE; } r = dklen - (l - 1) * SHA256_DIGESTSIZE; /* first l - 1 blocks */ for (b = 1; b < l; b++) { derive_u_sha256 (pwd, pwd_len, salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, SHA256_DIGESTSIZE); dk += SHA256_DIGESTSIZE; } /* last block */ derive_u_sha256 (pwd, pwd_len, salt, salt_len, iterations, b, &hmac); memcpy (dk, hmac.u, r); /* Prevent possible leaks. */ burn (&hmac, sizeof(hmac)); #ifndef TC_WINDOWS_BOOT burn (key, sizeof(key)); #endif }
//---------------------------------------------------------------- void FileToSHA256(HANDLE Hfic, char *csha256) { if (SHA1_enable) { FileToSHA1(Hfic, csha256); return; } //ouverture du fichier en lecture partagé csha256[0]=0; DWORD taille_fic = GetFileSize(Hfic,NULL); if (taille_fic>0 && taille_fic!=INVALID_FILE_SIZE) { unsigned char *buffer = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned char*)*taille_fic+1); if (buffer == NULL)return; //lecture du fichier DWORD copiee, position = 0, increm = 0; if (taille_fic > DIXM)increm = DIXM; else increm = taille_fic; BOOL read = TRUE; while (position<taille_fic && increm!=0 && read)//gestion pour éviter les bug de sync permet une ouverture de fichiers énormes ^^ { copiee = 0; read = ReadFile(Hfic, buffer+position, increm,&copiee,0); position +=copiee; if (taille_fic-position < increm)increm = taille_fic-position ; } //traitement en SHA256 sha256_ctx m_sha256; unsigned char digest[32]; sha256_begin(&m_sha256); sha256_hash(buffer, taille_fic, &m_sha256); sha256_end(digest, &m_sha256); //génération du SHA256 en chaine unsigned short i; for(i=0;i<32;i++)snprintf(csha256+i*2,3,"%02x",digest[i]&0xFF); csha256[64]=0; HeapFree(GetProcessHeap(), 0,buffer); } }
// Encrypt the master key a few times to make brute-force key-search harder BOOL CEncryption::_TransformMasterKey(BYTE *pKeySeed) { Rijndael rijndael; RD_UINT8 aKey[32]; RD_UINT8 aTest[16]; RD_UINT8 aRef[16] = { // The Rijndael class will be tested, that's the expected ciphertext 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }; DWORD i; sha256_ctx sha2; ASSERT(pKeySeed != NULL); if(pKeySeed == NULL) return FALSE; if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, (const RD_UINT8 *)pKeySeed, Rijndael::Key32Bytes, 0) != RIJNDAEL_SUCCESS) { return FALSE; } memcpy(m_pTransformedMasterKey, m_pMasterKey, 32); for(i = 0; i < m_dwKeyEncRounds; i++) { rijndael.blockEncrypt((const RD_UINT8 *)m_pTransformedMasterKey, 256, (RD_UINT8 *)m_pTransformedMasterKey); } // Do a quick test if the Rijndael class worked correctly for(i = 0; i < 32; i++) aKey[i] = (RD_UINT8)i; for(i = 0; i < 16; i++) aTest[i] = ((RD_UINT8)i << 4) | (RD_UINT8)i; if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, aKey, Rijndael::Key32Bytes, NULL) != RIJNDAEL_SUCCESS) { ASSERT(FALSE); return FALSE; } if(rijndael.blockEncrypt(aTest, 128, aTest) != 128) { ASSERT(FALSE); } if(memcmp(aTest, aRef, 16) != 0) { ASSERT(FALSE); return FALSE; } // Hash once with SHA-256 sha256_begin(&sha2); sha256_hash(m_pTransformedMasterKey, 32, &sha2); sha256_end(m_pTransformedMasterKey, &sha2); return TRUE; }
char *TadsServerManager::gen_rand_id(void *obj) { /* set up a hashing buffer */ sha256_ctx s; sha256_begin(&s); /* add the current date/time to the hash */ os_time_t timer = os_time(0); struct tm *tblock = os_localtime(&timer); sha256_hash((unsigned char *)tblock, sizeof(*tblock), &s); /* add the system timer to the hash */ long systime = os_get_sys_clock_ms(); sha256_hash((unsigned char *)&systime, sizeof(systime), &s); /* add the object address to the hash */ sha256_hash((unsigned char *)obj, sizeof(obj), &s); /* add the current stack location to the hash */ sha256_hash((unsigned char *)&obj, sizeof(void *), &s); /* add some random bytes from the operating system */ unsigned char rbuf[128]; os_gen_rand_bytes(rbuf, sizeof(rbuf)); sha256_hash(rbuf, sizeof(rbuf), &s); /* compute the hash */ unsigned char hval[32]; sha256_end(hval, &s); /* convert it to hex, but just keep the low nybbles, for 32 digits */ char *ret = lib_alloc_str(32); int i; for (i = 0 ; i < 32 ; ++i) ret[i] = nybble2hex(hval[i]); /* null-terminate the string */ ret[i] = '\0'; /* return the allocated string */ return ret; }
static int32_t hmacSha256Init(hmacSha256Context *ctx, const uint8_t *key, uint32_t kLength) { int32_t i; uint8_t localPad[SHA256_BLOCK_SIZE] = {0}; uint8_t localKey[SHA256_BLOCK_SIZE] = {0}; if (key == NULL) return 0; memset(ctx, 0, sizeof(hmacSha256Context)); /* check key length and reduce it if necessary */ if (kLength > SHA256_BLOCK_SIZE) { sha256_begin(&ctx->ctx); sha256_hash(key, kLength, &ctx->ctx); sha256_end(localKey, &ctx->ctx); } else { memcpy(localKey, key, kLength); } /* prepare inner hash and hold the context */ for (i = 0; i < SHA256_BLOCK_SIZE; i++) localPad[i] = localKey[i] ^ 0x36; sha256_begin(&ctx->innerCtx); sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->innerCtx); /* prepare outer hash and hold the context */ for (i = 0; i < SHA256_BLOCK_SIZE; i++) localPad[i] = localKey[i] ^ 0x5c; sha256_begin(&ctx->outerCtx); sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->outerCtx); /* copy prepared inner hash to work hash - ready to process data */ memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx)); memset(localKey, 0, sizeof(localKey)); return 1; }
/// @brief bool FileInfoCache::file_util_get_hash( _In_ const wchar_t* file_path, _Out_ std::string& md5, _Out_ std::string& sha2) { handle_ptr file_handle( CreateFileW(file_path, GENERIC_READ, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL), [](HANDLE h) { if (INVALID_HANDLE_VALUE != h) { CloseHandle(h); } }); if (INVALID_HANDLE_VALUE == file_handle.get()) { log_err "CreateFileW() failed. path=%ws, gle = %u", file_path, GetLastError() log_end; return false; } if (INVALID_SET_FILE_POINTER == SetFilePointer(file_handle.get(), 0, NULL, FILE_BEGIN)) { log_err "SetFilePointer() failed. path=%ws, gle = %u", file_path, GetLastError() log_end; return false; } uint8_t sha2_buf[32]; MD5_CTX ctx_md5; sha256_ctx ctx_sha2; MD5Init(&ctx_md5, 0); sha256_begin(&ctx_sha2); const uint32_t read_buffer_size = 4096; uint8_t read_buffer[read_buffer_size]; DWORD read = read_buffer_size; while (read_buffer_size == read) { if (FALSE == ::ReadFile(file_handle.get(), read_buffer, read_buffer_size, &read, NULL)) { log_err "ReadFile() failed. path=%ws, gle = %u", file_path, GetLastError() log_end; return false; } if (0 != read) { MD5Update(&ctx_md5, read_buffer, read); sha256_hash(read_buffer, read, &ctx_sha2); } } MD5Final(&ctx_md5); sha256_end(sha2_buf, &ctx_sha2); // // Hash 바이너리 버퍼를 hex 문자열로 변환 // if (true != bin_to_hexa_fast(sizeof(ctx_md5.digest), ctx_md5.digest, false, md5)) { log_err "bin_to_hexa_fast() failed. " log_end; return false; } if (true != bin_to_hexa_fast(sizeof(sha2_buf), sha2_buf, false, sha2)) { log_err "bin_to_hexa_fast() failed. " log_end; return false; } return true; }
/* 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; }
bool CEncryption::Encrypt(const unsigned char* pInput, int nLenInput, const char* szPassword, unsigned char*& pOutput, int& nLenOutput) { bool bResult = false; TD_TLHEADER hdr; RD_UINT8 uFinalKey[32]; unsigned long uFileSize = 0, uAllocated = 0, pos = 0; int nEncryptedPartSize = 0; ASSERT(NULL != pInput); if(NULL == pInput) return FALSE; ASSERT(0 != nLenInput); if(0 == nLenInput) return FALSE; ASSERT(NULL != szPassword); if(NULL == szPassword) return FALSE; uFileSize = nLenInput + sizeof(TD_TLHEADER); // Allocate enough memory uAllocated = uFileSize + 16; pOutput = new unsigned char[uAllocated]; if(NULL != pOutput) { unsigned long uKeyLen; // Build header structure hdr.dwSignature1 = TD_TLSIG_1; hdr.dwSignature2 = TD_TLSIG_2; hdr.dwKeyEncRounds = m_dwKeyEncRounds; // Make up the master key hash seed and the encryption IV m_random.GetRandomBuffer(hdr.aMasterSeed, 16); m_random.GetRandomBuffer((BYTE *)hdr.aEncryptionIV, 16); m_random.GetRandomBuffer(hdr.aMasterSeed2, 32); // Create MasterKey by hashing szPassword uKeyLen = strlen(szPassword); ASSERT(0 != uKeyLen); if(0 != uKeyLen) { sha256_ctx sha32; sha256_begin(&sha32); sha256_hash((unsigned char *)szPassword, uKeyLen, &sha32); sha256_end(m_pMasterKey, &sha32); // Generate m_pTransformedMasterKey from m_pMasterKey if(TRUE == _TransformMasterKey(hdr.aMasterSeed2)) { // Hash the master password with the generated hash salt sha256_begin(&sha32); sha256_hash(hdr.aMasterSeed, 16, &sha32); sha256_hash(m_pTransformedMasterKey, 32, &sha32); sha256_end((unsigned char *)uFinalKey, &sha32); // Hash the tasklist contents sha256_begin(&sha32); sha256_hash((unsigned char *)pInput, nLenInput, &sha32); sha256_end((unsigned char *)hdr.aContentsHash, &sha32); // Hash the header sha256_begin(&sha32); sha256_hash((unsigned char *)&hdr + 32, sizeof(TD_TLHEADER) - 32, &sha32); sha256_end((unsigned char *)hdr.aHeaderHash, &sha32); bResult = true; } } } if (bResult) { bResult = false; // Now we have all to build up the header memcpy(pOutput, &hdr, sizeof(TD_TLHEADER)); Rijndael aes; // Initialize Rijndael/AES if(RIJNDAEL_SUCCESS == aes.init(Rijndael::CBC, Rijndael::Encrypt, uFinalKey, Rijndael::Key32Bytes, hdr.aEncryptionIV) ) { nEncryptedPartSize = aes.padEncrypt((RD_UINT8 *)pInput, nLenInput, (RD_UINT8 *)pOutput + sizeof(TD_TLHEADER)); // Check if all went correct ASSERT(0 <= nEncryptedPartSize); if(0 <= nEncryptedPartSize) { bResult = true; // data encrypted successfully } nLenOutput = sizeof(TD_TLHEADER) + nEncryptedPartSize; } } if (!bResult) { SAFE_DELETE_ARRAY(pOutput); } return (bResult); }
bool CEncryption::Decrypt(const unsigned char* pInput, int nLenInput, const char* szPassword, unsigned char*& pOutput, int& nLenOutput) { bool bResult = false; TD_TLHEADER hdr; RD_UINT8 uFinalKey[32]; sha256_ctx sha32; ASSERT(NULL != pInput); if(NULL == pInput) return FALSE; ASSERT(0 != nLenInput); if(0 == nLenInput) return FALSE; ASSERT(NULL != szPassword); if(NULL == szPassword) return FALSE; ASSERT(sizeof(TD_TLHEADER) <= nLenInput); if(sizeof(TD_TLHEADER) > nLenInput) return FALSE; // Extract header structure from memory file memcpy(&hdr, pInput, sizeof(TD_TLHEADER)); // Hash the header sha256_begin(&sha32); sha256_hash((unsigned char *)&hdr + 32, sizeof(TD_TLHEADER) - 32, &sha32); sha256_end((unsigned char *)uFinalKey, &sha32); // Check if hash of header is the same as stored hash // to verify integrity of header if(0 == memcmp(hdr.aHeaderHash, uFinalKey, 32)) { // Check if we can open this if((hdr.dwSignature1 == TD_TLSIG_1) && (hdr.dwSignature2 == TD_TLSIG_2)) { // Allocate enough memory pOutput = new unsigned char[nLenInput]; if(NULL != pOutput) { unsigned long uKeyLen = strlen(szPassword); // Create MasterKey by hashing szPassword ASSERT(0 != uKeyLen); if(0 != uKeyLen) { sha256_begin(&sha32); sha256_hash((unsigned char *)szPassword, uKeyLen, &sha32); sha256_end(m_pMasterKey, &sha32); m_dwKeyEncRounds = hdr.dwKeyEncRounds; // Generate m_pTransformedMasterKey from m_pMasterKey if(TRUE == _TransformMasterKey(hdr.aMasterSeed2)) { // Hash the master password with the generated hash salt sha256_begin(&sha32); sha256_hash(hdr.aMasterSeed, 16, &sha32); sha256_hash(m_pTransformedMasterKey, 32, &sha32); sha256_end((unsigned char *)uFinalKey, &sha32); bResult = true; } } } } } if (bResult) { bResult = false; Rijndael aes; // Initialize Rijndael/AES if(RIJNDAEL_SUCCESS == aes.init(Rijndael::CBC, Rijndael::Decrypt, uFinalKey, Rijndael::Key32Bytes, hdr.aEncryptionIV) ) { nLenOutput = aes.padDecrypt((RD_UINT8 *)pInput + sizeof(TD_TLHEADER), nLenInput - sizeof(TD_TLHEADER), (RD_UINT8 *)pOutput); // Check if all went correct ASSERT(0 <= nLenOutput); if(0 <= nLenOutput) { // Check contents correct (with high probability) sha256_begin(&sha32); sha256_hash((unsigned char *)pOutput, nLenOutput, &sha32); sha256_end((unsigned char *)uFinalKey, &sha32); if(0 == memcmp(hdr.aContentsHash, uFinalKey, 32)) { bResult = true; // data decrypted successfully } } } } if (!bResult) { SAFE_DELETE_ARRAY(pOutput); } return (bResult); }
/* -------------------------------------------------------------------------- * EcdsaSignerDoFinal * -------------------------------------------------------------------------- */ VLT_STS EcdsaSignerDoFinal( VLT_PU8 pu8Message, VLT_U32 u32MessageLen, VLT_U32 u32MessageCapacity, VLT_PU8 pu8Signature, VLT_PU32 pu32SignatureLen, VLT_U32 u32SignatureCapacity ) { E2n_Point P; E2n_Point R; E2n_Point Q; /* intermediate calculation storage */ DIGIT_T k[MAX_DIGITS]; DIGIT_T k1[MAX_DIGITS]; DIGIT_T tmp[MAX_DIGITS]; DIGIT_T r[MAX_DIGITS]; DIGIT_T s[MAX_DIGITS]; DIGIT_T u1[MAX_DIGITS]; DIGIT_T u2[MAX_DIGITS]; DIGIT_T v[MAX_DIGITS]; DIGIT_T yy[MAX_DIGITS]; DIGIT_T Px[MAX_DIGITS]; DIGIT_T Py[MAX_DIGITS]; DIGIT_T Rx[MAX_DIGITS]; DIGIT_T Ry[MAX_DIGITS]; DIGIT_T Qx[MAX_DIGITS]; DIGIT_T Qy[MAX_DIGITS]; /* SHA-256 storage */ DIGIT_T bdHash[MAX_DIGITS]; VLT_U8 bHash[HASH_BYTE_SIZE]; UINT len; UINT hashLen; sha256_ctx ctx; // context holder VLT_STS status = VLT_FAIL; if((ST_INITIALISED_SIGN != signerState) && (ST_INITIALISED_VERIFY != signerState)) { /* not initialised */ return EECDSAEXECUTIONERROR; } /* Initialise Point variables */ P.x = Px; P.y = Py; R.x = Rx; R.y = Ry; Q.x = Qx; Q.y = Qy; if ( ( NULL == pu8Message ) || ( NULL == pu8Signature ) || ( NULL == pu32SignatureLen ) ) { return ( EECDSAINUPNULLPARAM ); } /* hash of message used by both signing and verify */ /* e or e1 = SHA-256(M) */ sha256_begin(&ctx); sha256_hash(pu8Message, u32MessageLen, &ctx); sha256_end(bHash, &ctx); /* convert hash to big digits, same size as base point order if > hash size */ if (sNumBpOrderDigits > HASH_DIGIT_SIZE) hashLen = sNumBpOrderDigits; else hashLen = HASH_DIGIT_SIZE; mpConvFromOctets(bdHash, hashLen, bHash, HASH_BYTE_SIZE); /* ANS X9.62-2005 7.3.e // if bit length of hash is > bit length of base point order // then truncate hash by removing LSBs until bit length // equals the length of the base point order */ len = mpBitLength(E.r, E.rlen); if (len < HASH_SIZE) { /* take leftmost bits of message by shifting right */ mpShiftRight(tmp, bdHash, HASH_SIZE - len, hashLen); /* truncate to base point order size */ mpSetEqual(bdHash, tmp, E.rlen); } if (ST_INITIALISED_SIGN == signerState) { /* signing process as per ANS X9.62 Section 7.3 */ *pu32SignatureLen = 0; /* generate ephemeral private key k such that 0 < k < n */ if (VLT_OK != GenerateRandomDigits(tmp, E.rlen)) return EECDSAEXECUTIONERROR; mpModulo(k, tmp, E.rlen, E.r, E.rlen); if (mpIsZero(k, E.rlen)) { /* probability of a zero is 1/n */ if (VLT_OK != GenerateRandomDigits(tmp, E.rlen)) return EECDSAEXECUTIONERROR; mpModulo(k, tmp, E.rlen, E.r, E.rlen); if (mpIsZero(k, E.rlen)) { return EECDSAEXECUTIONERROR; } } /* generate ephemeral public key: P = kG */ e2n_point_mul(&E, &P, &E.G, k, E.rlen); /* convert P.x to integer j */ /* conversion is implicit for polynomial basis */ /* // r = j mod n, n = base point oder (E.r) */ mpModulo(r, P.x, E.rlen, E.r, E.rlen); /* // calculate s = k^-1 (e + dr) mod n */ /* Compute k' = k^-1 mod n */ mpModInv(k1, k, E.r, E.rlen); /* Compute s = (k^-1(SHA-xxx(M) + dr)) mod n */ /* d * r */ mpModMult(tmp, sPrivateKey, r, E.r, E.rlen); /* M + d * r */ mpModAdd(yy, tmp, bdHash, E.r, E.rlen); /* s = (k^-1)(M + dr) */ mpModMult(s, k1, yy, E.r, E.rlen); /* signing: convert back to byte format and construct r || s */ mpConvToOctets(r, sNumBpOrderDigits, pu8Signature, sNumBpOrderBytes); mpConvToOctets(s, sNumBpOrderDigits, pu8Signature + sNumBpOrderBytes, sNumBpOrderBytes); /* set the byte length of the output signature */ *pu32SignatureLen = sNumBpOrderBytes * 2; status = VLT_OK; } else { /* ANS X9.62-2005 Section 7.4.1: Verification with Public Key */; /* extract r & s and format as big digits */ mpConvFromOctets(r, E.rlen, pu8Signature, (*pu32SignatureLen) / 2); mpConvFromOctets(s, E.rlen, pu8Signature + (*pu32SignatureLen / 2), (*pu32SignatureLen) / 2); /* Compute u1 = e1(s1^-1) mod n */ mpModInv(tmp, s, E.r, E.rlen); mpModMult(u1, tmp, bdHash, E.r, E.rlen); /* Compute u2 = r1(s1^-1) mod n */ mpModMult(u2, tmp, r, E.r, E.rlen); /* use supplied public key */ mpSetEqual(Q.x, sPublicKeyQx, E.len); mpSetEqual(Q.y, sPublicKeyQy, E.len); /* compute R = u1G */ e2n_point_mul(&E, &R, &E.G, u1, E.rlen); /* P = u2Q */ e2n_point_mul(&E, &P, &Q, u2, E.rlen); /* R = R + P */ e2n_point_add(&E, &R, &R, &P); /* compute v = j mod n */ mpModulo(v, R.x, E.rlen, E.r, E.rlen); /* verify v == r */ if (mpEqual(v, r, E.rlen)) { status = VLT_OK; } else { status = VLT_FAIL; } } return ( status ); }
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; }
BOOL CPwCompatImpl::OpenDatabaseV1(CPwManager* pMgr, const TCHAR *pszFile) { FILE *fp; char *pVirtualFile; unsigned long uFileSize, uAllocated, uEncryptedPartSize; size_t i, j, pos; PW_DBHEADER_V1 hdr; sha256_ctx sha32; UINT8 uFinalKey[32]; DWORD dw, dw2; char *ptrTemp; char *ptrTitle; char *ptrUserName; char *ptrURL; char *ptrPassword; char *ptrAdditional; PW_TIME tNow; PW_GROUP pwTG; PW_ENTRY pwTE; _GetCurrentPwTime(&tNow); memset(&pwTG, 0, sizeof(PW_GROUP)); memset(&pwTE, 0, sizeof(PW_ENTRY)); pwTG.tCreation = tNow; pwTG.tExpire = g_pwTimeNever; pwTG.tLastAccess = tNow; pwTG.tLastMod = tNow; pwTE.tCreation = tNow; pwTE.tExpire = g_pwTimeNever; pwTE.tLastAccess = tNow; pwTE.tLastMod = tNow; ASSERT(sizeof(char) == 1); ASSERT(pszFile != NULL); if(pszFile == NULL) return FALSE; ASSERT(_tcslen(pszFile) != 0); if(_tcslen(pszFile) == 0) return FALSE; fp = NULL; _tfopen_s(&fp, pszFile, _T("rb")); if(fp == NULL) return FALSE; // Get file size fseek(fp, 0, SEEK_END); uFileSize = ftell(fp); fseek(fp, 0, SEEK_SET); if(uFileSize < sizeof(PW_DBHEADER_V1)) { fclose(fp); return FALSE; } // Allocate enough memory to hold the complete file uAllocated = uFileSize + 17; pVirtualFile = new char[uAllocated]; if(pVirtualFile == NULL) { fclose(fp); return FALSE; } pVirtualFile[uFileSize + 17 - 1] = 0; fread(pVirtualFile, 1, uFileSize, fp); fclose(fp); // Extract header structure from memory file memcpy(&hdr, pVirtualFile, sizeof(PW_DBHEADER_V1)); // Check if we can open this if((hdr.dwSignature1 != PWM_DBSIG_1) || (hdr.dwSignature2 != PWM_DBSIG_2)) { _OPENDB_FAIL; } if((hdr.dwFlags & PWM_FLAG_RIJNDAEL) != 0) pMgr->SetAlgorithm(ALGO_AES); else if((hdr.dwFlags & PWM_FLAG_TWOFISH) != 0) pMgr->SetAlgorithm(ALGO_TWOFISH); else { ASSERT(FALSE); _OPENDB_FAIL; } BYTE aMasterKeyU[32]; pMgr->GetRawMasterKey(aMasterKeyU); // Hash the master password with the salt in the file sha256_begin(&sha32); sha256_hash(hdr.aMasterSeed, 16, &sha32); sha256_hash(aMasterKeyU, 32, &sha32); sha256_end((unsigned char *)uFinalKey, &sha32); mem_erase(aMasterKeyU, 32); if(pMgr->GetAlgorithm() == ALGO_AES) { CRijndael aes; // Initialize Rijndael algorithm if(aes.Init(CRijndael::CBC, CRijndael::DecryptDir, uFinalKey, CRijndael::Key32Bytes, hdr.aEncryptionIV) != RIJNDAEL_SUCCESS) { _OPENDB_FAIL; } // Decrypt! The first 48 bytes aren't encrypted (that's the header) uEncryptedPartSize = (unsigned long)aes.PadDecrypt((UINT8 *)pVirtualFile + 48, uFileSize - 48, (UINT8 *)pVirtualFile + 48); } else if(pMgr->GetAlgorithm() == ALGO_TWOFISH) { CTwofish twofish; if(twofish.Init(uFinalKey, 32, hdr.aEncryptionIV) != true) { _OPENDB_FAIL }; uEncryptedPartSize = (unsigned long)twofish.PadDecrypt( (UINT8 *)pVirtualFile + 48, uFileSize - 48, (UINT8 *)pVirtualFile + 48); }
STDMETHODIMP CKpUtilitiesImpl::SHA256Final(void* pContext, BYTE* pOutHashBuf) { if((pContext == NULL) || (pOutHashBuf == NULL)) return E_POINTER; sha256_end(pOutHashBuf, (sha256_ctx*)pContext); return S_OK; }
void Sha256::GetDigest (const BufferPtr &buffer) { if_debug (ValidateDigestParameters (buffer)); sha256_end (buffer, (sha256_ctx *) Context.Ptr()); }
// If bIgnoreCorrupted is TRUE the manager will try to ignore all database file // errors, i.e. try to read as much as possible instead of breaking out at the // first error. // To open a file normally, set bIgnoreCorrupted to FALSE (default). // To open a file in rescue mode, set it to TRUE. int CPwManager::OpenDatabase(const TCHAR *pszFile, _Out_opt_ PWDB_REPAIR_INFO *pRepair) { char *pVirtualFile; unsigned long uFileSize, uAllocated, uEncryptedPartSize; unsigned long pos; PW_DBHEADER hdr; sha256_ctx sha32; UINT8 uFinalKey[32]; char *p; USHORT usFieldType; DWORD dwFieldSize; PW_GROUP pwGroupTemplate; PW_ENTRY pwEntryTemplate; BOOST_STATIC_ASSERT(sizeof(char) == 1); ASSERT(pszFile != NULL); if(pszFile == NULL) return PWE_INVALID_PARAM; ASSERT(pszFile[0] != 0); if(pszFile[0] == 0) return PWE_INVALID_PARAM; // Length != 0 RESET_PWG_TEMPLATE(&pwGroupTemplate); RESET_PWE_TEMPLATE(&pwEntryTemplate); if(pRepair != NULL) { ZeroMemory(pRepair, sizeof(PWDB_REPAIR_INFO)); } FILE *fp = NULL; _tfopen_s(&fp, pszFile, _T("rb")); if(fp == NULL) return PWE_NOFILEACCESS_READ; // Get file size fseek(fp, 0, SEEK_END); uFileSize = ftell(fp); fseek(fp, 0, SEEK_SET); if(uFileSize < sizeof(PW_DBHEADER)) { fclose(fp); return PWE_INVALID_FILEHEADER; } // Allocate enough memory to hold the complete file uAllocated = uFileSize + 16 + 1 + 64 + 4; // 16 = encryption buffer space, 1+64 = string terminating NULLs, 4 unused pVirtualFile = new char[uAllocated]; if(pVirtualFile == NULL) { fclose(fp); return PWE_NO_MEM; } memset(&pVirtualFile[uFileSize + 16], 0, 1 + 64); fread(pVirtualFile, 1, uFileSize, fp); fclose(fp); // Extract header structure from memory file memcpy(&hdr, pVirtualFile, sizeof(PW_DBHEADER)); // Check if it's a KDBX file created by KeePass 2.x if((hdr.dwSignature1 == PWM_DBSIG_1_KDBX_P) && (hdr.dwSignature2 == PWM_DBSIG_2_KDBX_P)) { _OPENDB_FAIL_LIGHT; return PWE_UNSUPPORTED_KDBX; } if((hdr.dwSignature1 == PWM_DBSIG_1_KDBX_R) && (hdr.dwSignature2 == PWM_DBSIG_2_KDBX_R)) { _OPENDB_FAIL_LIGHT; return PWE_UNSUPPORTED_KDBX; } // Check if we can open this if((hdr.dwSignature1 != PWM_DBSIG_1) || (hdr.dwSignature2 != PWM_DBSIG_2)) { _OPENDB_FAIL_LIGHT; return PWE_INVALID_FILESIGNATURE; } if((hdr.dwVersion & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)) { if((hdr.dwVersion == 0x00020000) || (hdr.dwVersion == 0x00020001) || (hdr.dwVersion == 0x00020002)) { if(pVirtualFile != NULL) { mem_erase((unsigned char *)pVirtualFile, uAllocated); SAFE_DELETE_ARRAY(pVirtualFile); } return ((CPwCompatImpl::OpenDatabaseV2(this, pszFile) != FALSE) ? PWE_SUCCESS : PWE_UNKNOWN); } else if(hdr.dwVersion <= 0x00010002) { if(pVirtualFile != NULL) { mem_erase((unsigned char *)pVirtualFile, uAllocated); SAFE_DELETE_ARRAY(pVirtualFile); } return ((CPwCompatImpl::OpenDatabaseV1(this, pszFile) != FALSE) ? PWE_SUCCESS : PWE_UNKNOWN); } else { ASSERT(FALSE); _OPENDB_FAIL; } } if(hdr.dwGroups == 0) { _OPENDB_FAIL_LIGHT; return PWE_DB_EMPTY; } // Select algorithm if((hdr.dwFlags & PWM_FLAG_RIJNDAEL) != 0) m_nAlgorithm = ALGO_AES; else if((hdr.dwFlags & PWM_FLAG_TWOFISH) != 0) m_nAlgorithm = ALGO_TWOFISH; else { ASSERT(FALSE); _OPENDB_FAIL; } m_dwKeyEncRounds = hdr.dwKeyEncRounds; // Generate m_pTransformedMasterKey from m_pMasterKey if(_TransformMasterKey(hdr.aMasterSeed2) == FALSE) { ASSERT(FALSE); _OPENDB_FAIL; } ProtectTransformedMasterKey(false); // Hash the master password with the salt in the file sha256_begin(&sha32); sha256_hash(hdr.aMasterSeed, 16, &sha32); sha256_hash(m_pTransformedMasterKey, 32, &sha32); sha256_end((unsigned char *)uFinalKey, &sha32); ProtectTransformedMasterKey(true); if(pRepair == NULL) { // ASSERT(((uFileSize - sizeof(PW_DBHEADER)) % 16) == 0); if(((uFileSize - sizeof(PW_DBHEADER)) % 16) != 0) { _OPENDB_FAIL_LIGHT; return PWE_INVALID_FILESIZE; } } else // Repair the database { if(((uFileSize - sizeof(PW_DBHEADER)) % 16) != 0) { uFileSize -= sizeof(PW_DBHEADER); ASSERT((uFileSize & 0xF) != 0); uFileSize &= ~0xFUL; uFileSize += sizeof(PW_DBHEADER); } ASSERT(((uFileSize - sizeof(PW_DBHEADER)) % 16) == 0); pRepair->dwOriginalGroupCount = hdr.dwGroups; pRepair->dwOriginalEntryCount = hdr.dwEntries; } if(m_nAlgorithm == ALGO_AES) { CRijndael aes; // Initialize Rijndael algorithm if(aes.Init(CRijndael::CBC, CRijndael::DecryptDir, uFinalKey, CRijndael::Key32Bytes, hdr.aEncryptionIV) != RIJNDAEL_SUCCESS) { _OPENDB_FAIL_LIGHT; return PWE_CRYPT_ERROR; } // Decrypt! The first bytes aren't encrypted (that's the header) uEncryptedPartSize = (unsigned long)aes.PadDecrypt((UINT8 *)pVirtualFile + sizeof(PW_DBHEADER), uFileSize - sizeof(PW_DBHEADER), (UINT8 *)pVirtualFile + sizeof(PW_DBHEADER)); } else if(m_nAlgorithm == ALGO_TWOFISH) { CTwofish twofish; if(twofish.Init(uFinalKey, 32, hdr.aEncryptionIV) != true) { _OPENDB_FAIL }; uEncryptedPartSize = (unsigned long)twofish.PadDecrypt((UINT8 *)pVirtualFile + sizeof(PW_DBHEADER), uFileSize - sizeof(PW_DBHEADER), (UINT8 *)pVirtualFile + sizeof(PW_DBHEADER)); }