/* ======================================================================== Routine Description: 1. Append bit 1 to end of the message 2. Append the length of message in rightmost 64 bits 3. Transform the Hash Value to digest message Arguments: pMD5_CTX Pointer to MD5_CTX_STRUC Return Value: digestMessage Digest message Note: None ======================================================================== */ VOID MD5_End ( IN MD5_CTX_STRUC *pMD5_CTX, OUT UINT8 DigestMessage[]) { UINT index; UINT64 message_length_bits; /* append 1 bits to end of the message */ NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80); /* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */ if (pMD5_CTX->BlockLen > 55) MD5_Hash(pMD5_CTX); /* End of if */ /* Append the length of message in rightmost 64 bits */ message_length_bits = pMD5_CTX->MessageLen*8; message_length_bits = cpu2le64(message_length_bits); NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8); MD5_Hash(pMD5_CTX); /* Return message digest, transform the UINT32 hash value to bytes */ for (index = 0; index < 4;index++) pMD5_CTX->HashValue[index] = cpu2le32(pMD5_CTX->HashValue[index]); /* End of for */ NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE); } /* End of MD5_End */
/* ======================================================================== Routine Description: The message is appended to block. If block size > 64 bytes, the MD5_Hash will be called. Arguments: pMD5_CTX Pointer to MD5_CTX_STRUC message Message context messageLen The length of message in bytes Return Value: None Note: None ======================================================================== */ VOID MD5_Append ( IN MD5_CTX_STRUC *pMD5_CTX, IN const UINT8 Message[], IN UINT MessageLen) { UINT appendLen = 0; UINT diffLen = 0; while (appendLen != MessageLen) { diffLen = MessageLen - appendLen; if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) { NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, Message + appendLen, diffLen); pMD5_CTX->BlockLen += diffLen; appendLen += diffLen; } else { NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, Message + appendLen, MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen); pMD5_CTX->BlockLen = MD5_BLOCK_SIZE; MD5_Hash(pMD5_CTX); } /* End of if */ } /* End of while */ pMD5_CTX->MessageLen += MessageLen; } /* End of MD5_Append */
int wmain( _In_ int argc, _In_ wchar_t* argv[]) { #elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX)) int main(int argc, char *argv[]) { #endif #if defined(ENABLE_LIBSODIUM) //Initialization(Part 1) #if defined(PLATFORM_WIN) std::wstring FileName, Command; #elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX)) std::string FileName, Command; #endif //Read commands. if (argc < 2) { PrintDescription(); return EXIT_SUCCESS; } else if (argc == 2) //File name only, use default hash function. { //Commands check Command = argv[1U]; CaseConvert(true, Command); if (Command == COMMAND_LONG_PRINT_VERSION || Command == COMMAND_SHORT_PRINT_VERSION) { fwprintf_s(stderr, L"FileHash "); fwprintf_s(stderr, FULL_VERSION); fwprintf_s(stderr, L"\n"); return EXIT_SUCCESS; } else if (Command == COMMAND_LONG_HELP || Command == COMMAND_SHORT_HELP || Command == COMMAND_SIGN_HELP) { PrintDescription(); return EXIT_SUCCESS; } else if (Command == COMMAND_LIB_VERSION) { std::wstring LibVersion; if (MBSToWCSString(SODIUM_VERSION_STRING, strlen(SODIUM_VERSION_STRING), LibVersion)) fwprintf_s(stderr, L"LibSodium version %ls\n", LibVersion.c_str()); return EXIT_SUCCESS; } else { //Mark filename. FileName = argv[1U]; } } else if (argc == 3) //File name with hash function command { Command = argv[1U]; FileName = argv[2U]; //Commands check if (Command.length() < 3U) { fwprintf_s(stderr, L"Commands error.\n"); return EXIT_FAILURE; } else { CaseConvert(true, Command); } //CRC family if (Command.find(HASH_COMMAND_CRC) == 0) { HashFamilyID = HASH_ID_CRC; if (!ReadCommand_CRC(Command)) return EXIT_FAILURE; } //Internet Protocol Checksum else if (Command == HASH_COMMAND_CHECKSUM) { HashFamilyID = HASH_ID_CHECKSUM; } //MD2 else if (Command == HASH_COMMAND_MD2) { HashFamilyID = HASH_ID_MD2; } //MD4 family else if (Command == HASH_COMMAND_MD4) { HashFamilyID = HASH_ID_MD4; } else if (Command == HASH_COMMAND_ED2K) { HashFamilyID = HASH_ID_ED2K; } //MD5 else if (Command == HASH_COMMAND_MD || Command == HASH_COMMAND_MD5) { HashFamilyID = HASH_ID_MD5; } //SHA-1 else if (Command.find(HASH_COMMAND_SHA1) == 0) { HashFamilyID = HASH_ID_SHA1; } //SHA-2 family else if (Command == HASH_COMMAND_SHA2_384 || Command.find(HASH_COMMAND_SHA2_512) == 0 || Command.find(HASH_COMMAND_SHA2) == 0) { HashFamilyID = HASH_ID_SHA2; if (!ReadCommand_SHA2(Command)) return EXIT_FAILURE; } //SHA-3 family else if (Command == HASH_COMMAND_SHA || Command.find(HASH_COMMAND_SHA3) == 0) { HashFamilyID = HASH_ID_SHA3; if (!ReadCommand_SHA3(Command)) return EXIT_FAILURE; } //Commands error else { fwprintf_s(stderr, L"Commands error.\n"); return EXIT_FAILURE; } } else { fwprintf_s(stderr, L"Commands error.\n"); return EXIT_FAILURE; } Command.clear(); Command.shrink_to_fit(); //Open file. FILE *Input = nullptr; #if defined(PLATFORM_WIN) if (_wfopen_s(&Input, FileName.c_str(), L"rb") != 0 || Input == nullptr) #elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX)) Input = fopen(FileName.c_str(), "rb"); if (Input == nullptr) #endif { fwprintf_s(stderr, L"Open file error.\n"); return EXIT_FAILURE; } else { if (HashFamilyID == HASH_ID_CRC && !CRC_Hash(Input) || //CRC family HashFamilyID == HASH_ID_CHECKSUM && !Checksum_Hash(Input) || //Internet Protocol Checksum HashFamilyID == HASH_ID_MD2 && !MD2_Hash(Input) || //MD2 (HashFamilyID == HASH_ID_MD4 || HashFamilyID == HASH_ID_ED2K) && !MD4_Hash(Input) || //MD4 family HashFamilyID == HASH_ID_MD5 && !MD5_Hash(Input) || //MD5 HashFamilyID == HASH_ID_SHA1 && !SHA1_Hash(Input) || //SHA-1 HashFamilyID == HASH_ID_SHA2 && !SHA2_Hash(Input) || //SHA-2 family HashFamilyID == HASH_ID_SHA3 && !SHA3_Hash(Input)) //SHA-3 family { fclose(Input); return EXIT_FAILURE; } } fclose(Input); #else #if defined(PLATFORM_WIN) fwprintf_s(stderr, L"LibSodium is disable.\n\n"); system("PAUSE"); #elif (defined(PLATFORM_LINUX) || defined(PLATFORM_MACX)) fwprintf(stderr, L"LibSodium is disable.\n\n"); #endif #endif return EXIT_SUCCESS; }