From 7077e304aa1245f2b674067082e36545bac5194b Mon Sep 17 00:00:00 2001 From: Don Ho Date: Sat, 17 Jun 2023 03:46:44 +0200 Subject: [PATCH] Add CSHA1 --- PowerEditor/src/MISC/md5/md5Dlgs.cpp | 96 ++++-- PowerEditor/src/MISC/sha1/cal_sha1.cpp | 10 + PowerEditor/src/MISC/sha1/cal_sha1.h | 3 + PowerEditor/src/MISC/sha1/sha1.cpp | 328 +++++++++++++++------ PowerEditor/src/MISC/sha1/sha1.h | 283 +++++++++++++++++- PowerEditor/src/Notepad_plus.cpp | 4 + PowerEditor/src/Notepad_plus.h | 2 + PowerEditor/src/Notepad_plus.rc | 6 + PowerEditor/src/NppCommands.cpp | 48 ++- PowerEditor/src/menuCmdID.h | 3 + PowerEditor/visual.net/notepadPlus.vcxproj | 17 ++ 11 files changed, 675 insertions(+), 125 deletions(-) create mode 100644 PowerEditor/src/MISC/sha1/cal_sha1.cpp create mode 100644 PowerEditor/src/MISC/sha1/cal_sha1.h diff --git a/PowerEditor/src/MISC/md5/md5Dlgs.cpp b/PowerEditor/src/MISC/md5/md5Dlgs.cpp index c25d22cf8..d98d87de7 100644 --- a/PowerEditor/src/MISC/md5/md5Dlgs.cpp +++ b/PowerEditor/src/MISC/md5/md5Dlgs.cpp @@ -17,6 +17,7 @@ #include "md5.h" #include #include "sha-256.h" +#include "cal_sha1.h" #include "md5Dlgs.h" #include "md5Dlgs_rc.h" #include "CustomFileDialog.h" @@ -127,30 +128,38 @@ intptr_t CALLBACK HashFromFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPA hashResultStr += TEXT("\r\n"); } } - else if (_ht == hashType::hash_sha256) + else { std::string content = getFileContent(it.c_str()); - uint8_t sha2hash[32]{}; - calc_sha_256(sha2hash, reinterpret_cast(content.c_str()), content.length()); + bool isSha256 = (_ht == hashType::hash_sha256); - wchar_t sha2hashStr[65] = { '\0' }; - for (size_t i = 0; i < 32; i++) - wsprintf(sha2hashStr + i * 2, TEXT("%02x"), sha2hash[i]); + uint8_t hash[32]{}; // align to the longest hash (SHA-256) + wchar_t hashStr[65]{}; // align to the longest hash (SHA-256) + size_t hashLen = 0; + if (isSha256) + { + calc_sha_256(hash, reinterpret_cast(content.c_str()), content.length()); + hashLen = 32; + } + else + { + calc_sha1(hash, reinterpret_cast(content.c_str()), content.length()); + hashLen = 20; + } + + for (size_t i = 0; i < hashLen; i++) + wsprintf(hashStr + i * 2, TEXT("%02x"), hash[i]); files2check += it; files2check += TEXT("\r\n"); wchar_t* fileName = ::PathFindFileName(it.c_str()); - hashResultStr += sha2hashStr; + hashResultStr += hashStr; hashResultStr += TEXT(" "); hashResultStr += fileName; hashResultStr += TEXT("\r\n"); } - else - { - // unknown - } } if (!files2check.empty() && !hashResultStr.empty()) @@ -227,6 +236,14 @@ void HashFromFilesDlg::doDialog(bool isRTL) generic_string buttonText = TEXT("Choose files to &generate SHA-256..."); ::SetDlgItemText(_hSelf, IDC_HASH_FILEBROWSER_BUTTON, buttonText.c_str()); } + else if (_ht == hash_sha1) + { + generic_string title = TEXT("Generate SHA-1 digest from files"); + ::SetWindowText(_hSelf, title.c_str()); + + generic_string buttonText = TEXT("Choose files to &generate SHA-1..."); + ::SetDlgItemText(_hSelf, IDC_HASH_FILEBROWSER_BUTTON, buttonText.c_str()); + } } // Adjust the position in the center @@ -235,7 +252,7 @@ void HashFromFilesDlg::doDialog(bool isRTL) void HashFromTextDlg::generateHash() { - if (_ht != hash_md5 && _ht != hash_sha256) + if (_ht != hash_md5 && _ht != hash_sha256 && _ht != hash_sha1) return; int len = static_cast(::SendMessage(::GetDlgItem(_hSelf, IDC_HASH_TEXT_EDIT), WM_GETTEXTLENGTH, 0, 0)); @@ -253,16 +270,28 @@ void HashFromTextDlg::generateHash() char* md5Result = md5.digestString(newText); ::SetDlgItemTextA(_hSelf, IDC_HASH_RESULT_FOMTEXT_EDIT, md5Result); } - else if (_ht == hash_sha256) + else { - uint8_t sha2hash[32]{}; - calc_sha_256(sha2hash, reinterpret_cast(newText), strlen(newText)); + uint8_t hash[32]{}; // align to the longest hash (SHA-256) + wchar_t hashStr[65]{}; // align to the longest hash (SHA-256) + size_t hashLen = 0; + bool isSha256 = (_ht == hash_sha256); - wchar_t sha2hashStr[65] = { '\0' }; - for (size_t i = 0; i < 32; i++) - wsprintf(sha2hashStr + i * 2, TEXT("%02x"), sha2hash[i]); + if (isSha256) + { + calc_sha_256(hash, reinterpret_cast(newText), strlen(newText)); + hashLen = 32; + } + else + { + calc_sha1(hash, reinterpret_cast(newText), strlen(newText)); + hashLen = 20; + } - ::SetDlgItemText(_hSelf, IDC_HASH_RESULT_FOMTEXT_EDIT, sha2hashStr); + for (size_t i = 0; i < hashLen; i++) + wsprintf(hashStr + i * 2, TEXT("%02x"), hash[i]); + + ::SetDlgItemText(_hSelf, IDC_HASH_RESULT_FOMTEXT_EDIT, hashStr); } delete[] text; } @@ -304,16 +333,28 @@ void HashFromTextDlg::generateHashPerLine() result += md5Result; result += "\r\n"; } - else if (_ht == hash_sha256) + else { - uint8_t sha2hash[32]; - calc_sha_256(sha2hash, reinterpret_cast(newText), strlen(newText)); + uint8_t hash[32]{}; // align to the longest hash (SHA-256) + char hashStr[65]{}; // align to the longest hash (SHA-256) + size_t hashLen = 0; + bool isSha256 = (_ht == hash_sha256); - char sha2hashStr[65] = { '\0' }; + if (isSha256) + { + calc_sha_256(hash, reinterpret_cast(newText), strlen(newText)); + hashLen = 32; + } + else + { + calc_sha1(hash, reinterpret_cast(newText), strlen(newText)); + hashLen = 20; + } + for (size_t i = 0; i < 32; i++) - sprintf(sha2hashStr + i * 2, "%02x", sha2hash[i]); + sprintf(hashStr + i * 2, "%02x", hash[i]); - result += sha2hashStr; + result += hashStr; result += "\r\n"; } } @@ -466,6 +507,11 @@ void HashFromTextDlg::doDialog(bool isRTL) generic_string title = TEXT("Generate SHA-256 digest"); ::SetWindowText(_hSelf, title.c_str()); } + else if (_ht == hash_sha1) + { + generic_string title = TEXT("Generate SHA-1 digest"); + ::SetWindowText(_hSelf, title.c_str()); + } } // Adjust the position in the center diff --git a/PowerEditor/src/MISC/sha1/cal_sha1.cpp b/PowerEditor/src/MISC/sha1/cal_sha1.cpp new file mode 100644 index 000000000..96867545c --- /dev/null +++ b/PowerEditor/src/MISC/sha1/cal_sha1.cpp @@ -0,0 +1,10 @@ +#include "cal_sha1.h" +#include "sha1.h" + +void calc_sha1(unsigned char hash[20], const void *input, size_t len) +{ + CSHA1 sha1; + sha1.Update((const uint8_t*)input, static_cast(len)); + sha1.Final(); + sha1.GetHash(hash); +} diff --git a/PowerEditor/src/MISC/sha1/cal_sha1.h b/PowerEditor/src/MISC/sha1/cal_sha1.h new file mode 100644 index 000000000..33c22c017 --- /dev/null +++ b/PowerEditor/src/MISC/sha1/cal_sha1.h @@ -0,0 +1,3 @@ +#pragma once + +void calc_sha1(unsigned char hash[20], const void *input, size_t len); diff --git a/PowerEditor/src/MISC/sha1/sha1.cpp b/PowerEditor/src/MISC/sha1/sha1.cpp index adc16ce27..742a2f75e 100644 --- a/PowerEditor/src/MISC/sha1/sha1.cpp +++ b/PowerEditor/src/MISC/sha1/sha1.cpp @@ -1,104 +1,256 @@ -#include -#include -#include +/* + 100% free public domain implementation of the SHA-1 algorithm + by Dominik Reichl + Web: http://www.dominik-reichl.de/ -uint32_t leftrotate(uint32_t x, uint32_t c) { - return (x << c) | (x >> (32-c)); + See header file for version history and test vectors. +*/ + +// If compiling with MFC, you might want to add #include "StdAfx.h" + +//#define _CRT_SECURE_NO_WARNINGS +#include "sha1.h" + +#define SHA1_MAX_FILE_BUFFER (32 * 20 * 820) + +// Rotate p_val32 by p_nBits bits to the left +#ifndef ROL32 +#ifdef _MSC_VER +#define ROL32(p_val32,p_nBits) _rotl(p_val32,p_nBits) +#else +#define ROL32(p_val32,p_nBits) (((p_val32)<<(p_nBits))|((p_val32)>>(32-(p_nBits)))) +#endif +#endif + +#ifdef SHA1_LITTLE_ENDIAN +#define SHABLK0(i) (m_block->l[i] = \ + (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) +#else +#define SHABLK0(i) (m_block->l[i]) +#endif + +#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ \ + m_block->l[(i+8)&15] ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) + +// SHA-1 rounds +#define S_R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} +#define S_R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);} +#define S_R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,30);} +#define S_R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w=ROL32(w,30);} +#define S_R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,30);} + +#pragma warning(push) +// Disable compiler warning 'Conditional expression is constant' +#pragma warning(disable: 4127) + +CSHA1::CSHA1() +{ + m_block = (SHA1_WORKSPACE_BLOCK*)m_workspace; + + Reset(); } -uint32_t from_bytes(const unsigned char * p) { - return (((uint32_t)p[3]) << 24) - | (((uint32_t)p[2]) << 16) - | (((uint32_t)p[1]) << 8) - | ((uint32_t)p[0]); +#ifdef SHA1_WIPE_VARIABLES +CSHA1::~CSHA1() +{ + Reset(); +} +#endif + +void CSHA1::Reset() +{ + // SHA1 initialization constants + m_state[0] = 0x67452301; + m_state[1] = 0xEFCDAB89; + m_state[2] = 0x98BADCFE; + m_state[3] = 0x10325476; + m_state[4] = 0xC3D2E1F0; + + m_count[0] = 0; + m_count[1] = 0; } -void to_bytes(uint32_t val, unsigned char * p) { - p[3] = unsigned char(val >> 24); - p[2] = unsigned char(val >> 16); - p[1] = unsigned char(val >> 8); - p[0] = unsigned char(val >> 0); +void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer) +{ + UINT_32 a = pState[0], b = pState[1], c = pState[2], d = pState[3], e = pState[4]; + + memcpy(m_block, pBuffer, 64); + + // 4 rounds of 20 operations each, loop unrolled + S_R0(a,b,c,d,e, 0); S_R0(e,a,b,c,d, 1); S_R0(d,e,a,b,c, 2); S_R0(c,d,e,a,b, 3); + S_R0(b,c,d,e,a, 4); S_R0(a,b,c,d,e, 5); S_R0(e,a,b,c,d, 6); S_R0(d,e,a,b,c, 7); + S_R0(c,d,e,a,b, 8); S_R0(b,c,d,e,a, 9); S_R0(a,b,c,d,e,10); S_R0(e,a,b,c,d,11); + S_R0(d,e,a,b,c,12); S_R0(c,d,e,a,b,13); S_R0(b,c,d,e,a,14); S_R0(a,b,c,d,e,15); + S_R1(e,a,b,c,d,16); S_R1(d,e,a,b,c,17); S_R1(c,d,e,a,b,18); S_R1(b,c,d,e,a,19); + S_R2(a,b,c,d,e,20); S_R2(e,a,b,c,d,21); S_R2(d,e,a,b,c,22); S_R2(c,d,e,a,b,23); + S_R2(b,c,d,e,a,24); S_R2(a,b,c,d,e,25); S_R2(e,a,b,c,d,26); S_R2(d,e,a,b,c,27); + S_R2(c,d,e,a,b,28); S_R2(b,c,d,e,a,29); S_R2(a,b,c,d,e,30); S_R2(e,a,b,c,d,31); + S_R2(d,e,a,b,c,32); S_R2(c,d,e,a,b,33); S_R2(b,c,d,e,a,34); S_R2(a,b,c,d,e,35); + S_R2(e,a,b,c,d,36); S_R2(d,e,a,b,c,37); S_R2(c,d,e,a,b,38); S_R2(b,c,d,e,a,39); + S_R3(a,b,c,d,e,40); S_R3(e,a,b,c,d,41); S_R3(d,e,a,b,c,42); S_R3(c,d,e,a,b,43); + S_R3(b,c,d,e,a,44); S_R3(a,b,c,d,e,45); S_R3(e,a,b,c,d,46); S_R3(d,e,a,b,c,47); + S_R3(c,d,e,a,b,48); S_R3(b,c,d,e,a,49); S_R3(a,b,c,d,e,50); S_R3(e,a,b,c,d,51); + S_R3(d,e,a,b,c,52); S_R3(c,d,e,a,b,53); S_R3(b,c,d,e,a,54); S_R3(a,b,c,d,e,55); + S_R3(e,a,b,c,d,56); S_R3(d,e,a,b,c,57); S_R3(c,d,e,a,b,58); S_R3(b,c,d,e,a,59); + S_R4(a,b,c,d,e,60); S_R4(e,a,b,c,d,61); S_R4(d,e,a,b,c,62); S_R4(c,d,e,a,b,63); + S_R4(b,c,d,e,a,64); S_R4(a,b,c,d,e,65); S_R4(e,a,b,c,d,66); S_R4(d,e,a,b,c,67); + S_R4(c,d,e,a,b,68); S_R4(b,c,d,e,a,69); S_R4(a,b,c,d,e,70); S_R4(e,a,b,c,d,71); + S_R4(d,e,a,b,c,72); S_R4(c,d,e,a,b,73); S_R4(b,c,d,e,a,74); S_R4(a,b,c,d,e,75); + S_R4(e,a,b,c,d,76); S_R4(d,e,a,b,c,77); S_R4(c,d,e,a,b,78); S_R4(b,c,d,e,a,79); + + // Add the working vars back into state + pState[0] += a; + pState[1] += b; + pState[2] += c; + pState[3] += d; + pState[4] += e; + + // Wipe variables +#ifdef SHA1_WIPE_VARIABLES + a = b = c = d = e = 0; +#endif } -void calc_sha1(uint8_t hash[20], const void *input, size_t len) { - uint32_t h0 = 0x67452301; - uint32_t h1 = 0xEFCDAB89; - uint32_t h2 = 0x98BADCFE; - uint32_t h3 = 0x10325476; - uint32_t h4 = 0xC3D2E1F0; +void CSHA1::Update(const UINT_8* pbData, UINT_32 uLen) +{ + UINT_32 j = ((m_count[0] >> 3) & 0x3F); - unsigned char *msg = NULL; + if((m_count[0] += (uLen << 3)) < (uLen << 3)) + ++m_count[1]; // Overflow - size_t new_len, offset; - uint32_t w[80]; - uint32_t a, b, c, d, e, f, k, temp; + m_count[1] += (uLen >> 29); - new_len = len + 1; - while (new_len % 64 != 56) { - new_len++; - } + UINT_32 i; + if((j + uLen) > 63) + { + i = 64 - j; + memcpy(&m_buffer[j], pbData, i); + Transform(m_state, m_buffer); - msg = (unsigned char*)malloc(new_len + 8); - memcpy(msg, input, len); - msg[len] = 0x80; - for (offset = len + 1; offset < new_len; offset++) { - msg[offset] = 0; - } + for( ; (i + 63) < uLen; i += 64) + Transform(m_state, &pbData[i]); - to_bytes(uint32_t(len * 8), msg + new_len); - new_len += 8; + j = 0; + } + else i = 0; - for(offset=0; offset 0) + Update(pbData, static_cast(uRead)); + + if(uRead < SHA1_MAX_FILE_BUFFER) + { + if(feof(fpIn) == 0) bSuccess = false; + break; + } + } + + fclose(fpIn); + delete[] pbData; + return bSuccess; +} +#endif + +void CSHA1::Final() +{ + UINT_32 i; + + UINT_8 pbFinalCount[8]; + for(i = 0; i < 8; ++i) + pbFinalCount[i] = static_cast((m_count[((i >= 4) ? 0 : 1)] >> + ((3 - (i & 3)) * 8) ) & 0xFF); // Endian independent + + Update((UINT_8*)"\200", 1); + + while((m_count[0] & 504) != 448) + Update((UINT_8*)"\0", 1); + + Update(pbFinalCount, 8); // Cause a Transform() + + for(i = 0; i < 20; ++i) + m_digest[i] = static_cast((m_state[i >> 2] >> ((3 - + (i & 3)) * 8)) & 0xFF); + + // Wipe variables for security reasons +#ifdef SHA1_WIPE_VARIABLES + memset(m_buffer, 0, 64); + memset(m_state, 0, 20); + memset(m_count, 0, 8); + memset(pbFinalCount, 0, 8); + Transform(m_state, m_buffer); +#endif +} + +#ifdef SHA1_UTILITY_FUNCTIONS +bool CSHA1::ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType) const +{ + if(tszReport == NULL) return false; + + TCHAR tszTemp[16]; + + if((rtReportType == REPORT_HEX) || (rtReportType == REPORT_HEX_SHORT)) + { + _sntprintf(tszTemp, 15, _T("%02X"), m_digest[0]); + _tcscpy(tszReport, tszTemp); + + const TCHAR* lpFmt = ((rtReportType == REPORT_HEX) ? _T(" %02X") : _T("%02X")); + for(size_t i = 1; i < 20; ++i) + { + _sntprintf(tszTemp, 15, lpFmt, m_digest[i]); + _tcscat(tszReport, tszTemp); + } + } + else if(rtReportType == REPORT_DIGIT) + { + _sntprintf(tszTemp, 15, _T("%u"), m_digest[0]); + _tcscpy(tszReport, tszTemp); + + for(size_t i = 1; i < 20; ++i) + { + _sntprintf(tszTemp, 15, _T(" %u"), m_digest[i]); + _tcscat(tszReport, tszTemp); + } + } + else return false; + + return true; +} +#endif + +#ifdef SHA1_STL_FUNCTIONS +bool CSHA1::ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType) const +{ + TCHAR tszOut[84]; + const bool bResult = ReportHash(tszOut, rtReportType); + if(bResult) strOut = tszOut; + return bResult; +} +#endif + +bool CSHA1::GetHash(UINT_8* pbDest20) const +{ + if(pbDest20 == NULL) return false; + memcpy(pbDest20, m_digest, 20); + return true; +} + +#pragma warning(pop) diff --git a/PowerEditor/src/MISC/sha1/sha1.h b/PowerEditor/src/MISC/sha1/sha1.h index 6705a3646..da32b9f99 100644 --- a/PowerEditor/src/MISC/sha1/sha1.h +++ b/PowerEditor/src/MISC/sha1/sha1.h @@ -1,3 +1,282 @@ -#pragma once +/* + 100% free public domain implementation of the SHA-1 algorithm + by Dominik Reichl + Web: http://www.dominik-reichl.de/ -void calc_sha1(uint8_t hash[20], const void *input, size_t len); \ No newline at end of file + Version 2.1 - 2012-06-19 + - Deconstructor (resetting internal variables) is now only + implemented if SHA1_WIPE_VARIABLES is defined (which is the + default). + - Renamed inclusion guard to contain a GUID. + - Demo application is now using C++/STL objects and functions. + - Unicode build of the demo application now outputs the hashes of both + the ANSI and Unicode representations of strings. + - Various other demo application improvements. + + Version 2.0 - 2012-06-14 + - Added 'limits.h' include. + - Renamed inclusion guard and macros for compliancy (names beginning + with an underscore are reserved). + + Version 1.9 - 2011-11-10 + - Added Unicode test vectors. + - Improved support for hashing files using the HashFile method that + are larger than 4 GB. + - Improved file hashing performance (by using a larger buffer). + - Disabled unnecessary compiler warnings. + - Internal variables are now private. + + Version 1.8 - 2009-03-16 + - Converted project files to Visual Studio 2008 format. + - Added Unicode support for HashFile utility method. + - Added support for hashing files using the HashFile method that are + larger than 2 GB. + - HashFile now returns an error code instead of copying an error + message into the output buffer. + - GetHash now returns an error code and validates the input parameter. + - Added ReportHashStl STL utility method. + - Added REPORT_HEX_SHORT reporting mode. + - Improved Linux compatibility of test program. + + Version 1.7 - 2006-12-21 + - Fixed buffer underrun warning that appeared when compiling with + Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the + patch). + - Breaking change: ReportHash writes the final hash to the start + of the buffer, i.e. it's not appending it to the string anymore. + - Made some function parameters const. + - Added Visual Studio 2005 project files to demo project. + + Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches) + - You can set the endianness in your files, no need to modify the + header file of the CSHA1 class anymore. + - Aligned data support. + - Made support/compilation of the utility functions (ReportHash and + HashFile) optional (useful when bytes count, for example in embedded + environments). + + Version 1.5 - 2005-01-01 + - 64-bit compiler compatibility added. + - Made variable wiping optional (define SHA1_WIPE_VARIABLES). + - Removed unnecessary variable initializations. + - ROL32 improvement for the Microsoft compiler (using _rotl). + + Version 1.4 - 2004-07-22 + - CSHA1 now compiles fine with GCC 3.3 under Mac OS X (thanks to Larry + Hastings). + + Version 1.3 - 2003-08-17 + - Fixed a small memory bug and made a buffer array a class member to + ensure correct working when using multiple CSHA1 class instances at + one time. + + Version 1.2 - 2002-11-16 + - Borlands C++ compiler seems to have problems with string addition + using sprintf. Fixed the bug which caused the digest report function + not to work properly. CSHA1 is now Borland compatible. + + Version 1.1 - 2002-10-11 + - Removed two unnecessary header file includes and changed BOOL to + bool. Fixed some minor bugs in the web page contents. + + Version 1.0 - 2002-06-20 + - First official release. + + ================ Test Vectors ================ + + SHA1("abc" in ANSI) = + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + SHA1("abc" in Unicode LE) = + 9F04F41A 84851416 2050E3D6 8C1A7ABB 441DC2B5 + + SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + in ANSI) = + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + in Unicode LE) = + 51D7D876 9AC72C40 9C5B0E3F 69C60ADC 9A039014 + + SHA1(A million repetitions of "a" in ANSI) = + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F + SHA1(A million repetitions of "a" in Unicode LE) = + C4609560 A108A0C6 26AA7F2B 38A65566 739353C5 +*/ + +#ifndef SHA1_H_A545E61D43E9404E8D736869AB3CBFE7 +#define SHA1_H_A545E61D43E9404E8D736869AB3CBFE7 + +#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS) +#define SHA1_UTILITY_FUNCTIONS +#endif + +#if !defined(SHA1_STL_FUNCTIONS) && !defined(SHA1_NO_STL_FUNCTIONS) +#define SHA1_STL_FUNCTIONS +#if !defined(SHA1_UTILITY_FUNCTIONS) +#error STL functions require SHA1_UTILITY_FUNCTIONS. +#endif +#endif + +#include +#include + +#ifdef SHA1_UTILITY_FUNCTIONS +#include +#include +#endif + +#ifdef SHA1_STL_FUNCTIONS +#include +#endif + +#ifdef _MSC_VER +#include +#endif + +// You can define the endian mode in your files without modifying the SHA-1 +// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN +// in your files, before including the SHA1.h header file. If you don't +// define anything, the class defaults to little endian. +#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN) +#define SHA1_LITTLE_ENDIAN +#endif + +// If you want variable wiping, #define SHA1_WIPE_VARIABLES, if not, +// #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it +// defaults to wiping. +#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES) +#define SHA1_WIPE_VARIABLES +#endif + +#if defined(SHA1_HAS_TCHAR) +#include +#else +#ifdef _MSC_VER +#include +#else +#ifndef TCHAR +#define TCHAR char +#endif +#ifndef _T +#define _T(__x) (__x) +#define _tmain main +#define _tprintf printf +#define _getts gets +#define _tcslen strlen +#define _tfopen fopen +#define _tcscpy strcpy +#define _tcscat strcat +#define _sntprintf snprintf +#endif +#endif +#endif + +/////////////////////////////////////////////////////////////////////////// +// Define variable types + +#ifndef UINT_8 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define UINT_8 unsigned __int8 +#else // !_MSC_VER +#define UINT_8 unsigned char +#endif // _MSC_VER +#endif + +#ifndef UINT_32 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define UINT_32 unsigned __int32 +#else // !_MSC_VER +#if (ULONG_MAX == 0xFFFFFFFFUL) +#define UINT_32 unsigned long +#else +#define UINT_32 unsigned int +#endif +#endif // _MSC_VER +#endif // UINT_32 + +#ifndef INT_64 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define INT_64 __int64 +#else // !_MSC_VER +#define INT_64 long long +#endif // _MSC_VER +#endif // INT_64 + +#ifndef UINT_64 +#ifdef _MSC_VER // Compiling with Microsoft compiler +#define UINT_64 unsigned __int64 +#else // !_MSC_VER +#define UINT_64 unsigned long long +#endif // _MSC_VER +#endif // UINT_64 + +/////////////////////////////////////////////////////////////////////////// +// Declare SHA-1 workspace + +typedef union +{ + UINT_8 c[64]; + UINT_32 l[16]; +} SHA1_WORKSPACE_BLOCK; + +class CSHA1 +{ +public: +#ifdef SHA1_UTILITY_FUNCTIONS + // Different formats for ReportHash(Stl) + enum REPORT_TYPE + { + REPORT_HEX = 0, + REPORT_DIGIT = 1, + REPORT_HEX_SHORT = 2 + }; +#endif + + // Constructor and destructor + CSHA1(); + +#ifdef SHA1_WIPE_VARIABLES + ~CSHA1(); +#endif + + void Reset(); + + // Hash in binary data and strings + void Update(const UINT_8* pbData, UINT_32 uLen); + +#ifdef SHA1_UTILITY_FUNCTIONS + // Hash in file contents + bool HashFile(const TCHAR* tszFileName); +#endif + + // Finalize hash; call it before using ReportHash(Stl) + void Final(); + +#ifdef SHA1_UTILITY_FUNCTIONS + bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const; +#endif + +#ifdef SHA1_STL_FUNCTIONS + bool ReportHashStl(std::basic_string& strOut, REPORT_TYPE rtReportType = + REPORT_HEX) const; +#endif + + // Get the raw message digest (20 bytes) + bool GetHash(UINT_8* pbDest20) const; + +private: + // Private SHA-1 transformation + void Transform(UINT_32* pState, const UINT_8* pBuffer); + + // Member variables + UINT_32 m_state[5]; + UINT_32 m_count[2]; + UINT_32 m_reserved0[1]; // Memory alignment padding + UINT_8 m_buffer[64]; + UINT_8 m_digest[20]; + UINT_32 m_reserved1[3]; // Memory alignment padding + + UINT_8 m_workspace[64]; + SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above +}; + +#endif // SHA1_H_A545E61D43E9404E8D736869AB3CBFE7 diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index d2ef9f35a..54233bc45 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -713,6 +713,10 @@ LRESULT Notepad_plus::init(HWND hwnd) _sha2FromFilesDlg.setHashType(hash_sha256); _sha2FromTextDlg.init(_pPublicInterface->getHinst(), hwnd); _sha2FromTextDlg.setHashType(hash_sha256); + _sha1FromFilesDlg.init(_pPublicInterface->getHinst(), hwnd); + _sha1FromFilesDlg.setHashType(hash_sha1); + _sha1FromTextDlg.init(_pPublicInterface->getHinst(), hwnd); + _sha1FromTextDlg.setHashType(hash_sha1); //--User Define Dialog Section--// diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 9d0107fcf..c12d42736 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -314,6 +314,8 @@ private: HashFromTextDlg _md5FromTextDlg; HashFromFilesDlg _sha2FromFilesDlg; HashFromTextDlg _sha2FromTextDlg; + HashFromFilesDlg _sha1FromFilesDlg; + HashFromTextDlg _sha1FromTextDlg; GoToLineDlg _goToLineDlg; ColumnEditorDlg _colEditorDlg; WordStyleDlg _configStyleDlg; diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index e0330a593..31ecf5a94 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -1173,6 +1173,12 @@ BEGIN MENUITEM "Generate from files...", IDM_TOOL_MD5_GENERATEFROMFILE MENUITEM "Generate from selection into clipboard", IDM_TOOL_MD5_GENERATEINTOCLIPBOARD END + POPUP "SHA-1" + BEGIN + MENUITEM "Generate...", IDM_TOOL_SHA1_GENERATE + MENUITEM "Generate from files...", IDM_TOOL_SHA1_GENERATEFROMFILE + MENUITEM "Generate from selection into clipboard", IDM_TOOL_SHA1_GENERATEINTOCLIPBOARD + END POPUP "SHA-256" BEGIN MENUITEM "Generate...", IDM_TOOL_SHA256_GENERATE diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 3d0cb9e69..9bb4b6a97 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -33,7 +33,7 @@ #include "verifySignedfile.h" #include "md5.h" #include "sha-256.h" -#include "sha1.h" +#include "cal_sha1.h" using namespace std; @@ -3233,7 +3233,26 @@ void Notepad_plus::command(int id) } break; + case IDM_TOOL_SHA1_GENERATE: + { + bool isFirstTime = !_sha1FromTextDlg.isCreated(); + _sha1FromTextDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_sha1FromTextDlg.getHSelf(), "SHA1FromTextDlg"); + } + break; + + case IDM_TOOL_SHA1_GENERATEFROMFILE: + { + bool isFirstTime = !_sha1FromFilesDlg.isCreated(); + _sha1FromFilesDlg.doDialog(_nativeLangSpeaker.isRTL()); + if (isFirstTime) + _nativeLangSpeaker.changeDlgLang(_sha1FromFilesDlg.getHSelf(), "SHA1FromFilesDlg"); + } + break; + case IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD: + case IDM_TOOL_SHA1_GENERATEINTOCLIPBOARD: { if (_pEditView->execute(SCI_GETSELECTIONS) == 1) { @@ -3247,17 +3266,26 @@ void Notepad_plus::command(int id) char *selectedStr = new char[strSize]; _pEditView->execute(SCI_GETSELTEXT, 0, reinterpret_cast(selectedStr)); - //uint8_t sha2hash[32]; - //calc_sha_256(sha2hash, reinterpret_cast(selectedStr), strlen(selectedStr)); - uint8_t sha1hash[20]; - calc_sha1(sha1hash, reinterpret_cast(selectedStr), strlen(selectedStr)); + bool isSha256 = (id == IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD); - wchar_t sha2hashStr[65] = { '\0' }; - //for (size_t i = 0; i < 32; i++) - for (size_t i = 0; i < 20; i++) - wsprintf(sha2hashStr + i * 2, TEXT("%02x"), sha1hash[i]); + uint8_t hash[32] {}; // align to the longest hash (SHA-256) + wchar_t hashStr[65] {}; // align to the longest hash (SHA-256) + size_t hashLen = 0; + if (isSha256) + { + calc_sha_256(hash, reinterpret_cast(selectedStr), strlen(selectedStr)); + hashLen = 32; + } + else // SHA1 + { + calc_sha1(hash, reinterpret_cast(selectedStr), strlen(selectedStr)); + hashLen = 20; + } + + for (size_t i = 0; i < hashLen; i++) + wsprintf(hashStr + i * 2, TEXT("%02x"), hash[i]); - str2Clipboard(sha2hashStr, _pPublicInterface->getHSelf()); + str2Clipboard(hashStr, _pPublicInterface->getHSelf()); delete[] selectedStr; } diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 6a3d91848..cde8825e4 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -593,6 +593,9 @@ #define IDM_TOOL_SHA256_GENERATE (IDM_TOOL + 4) #define IDM_TOOL_SHA256_GENERATEFROMFILE (IDM_TOOL + 5) #define IDM_TOOL_SHA256_GENERATEINTOCLIPBOARD (IDM_TOOL + 6) + #define IDM_TOOL_SHA1_GENERATE (IDM_TOOL + 7) + #define IDM_TOOL_SHA1_GENERATEFROMFILE (IDM_TOOL + 8) + #define IDM_TOOL_SHA1_GENERATEINTOCLIPBOARD (IDM_TOOL + 9) #define IDM_EXECUTE (IDM + 9000) diff --git a/PowerEditor/visual.net/notepadPlus.vcxproj b/PowerEditor/visual.net/notepadPlus.vcxproj index bf31d8a2a..e99b05013 100755 --- a/PowerEditor/visual.net/notepadPlus.vcxproj +++ b/PowerEditor/visual.net/notepadPlus.vcxproj @@ -94,12 +94,24 @@ arm64\$(Configuration)\ + + ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\md5;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories) + + + ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\md5;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories) + + + ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\md5;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories) + + + ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\md5;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories) + @@ -107,11 +119,15 @@ + + ..\src;..\src\MISC;..\src\MISC\Common;..\src\MISC\Exception;..\src\MISC\md5;..\src\MISC\PluginsManager;..\src\MISC\Process;..\src\MISC\RegExt;..\src\MISC\sha1;..\src\MISC\sha2;..\src\MISC\SysMsg;..\src\ScintillaComponent;..\src\Win32Explr;..\src\WinControls;..\src\WinControls\AboutDlg;..\src\WinControls\AnsiCharPanel;..\src\WinControls\ClipboardHistory;..\src\WinControls\ColourPicker;..\src\WinControls\ContextMenu;..\src\WinControls\DockingWnd;..\src\WinControls\DocumentMap;..\src\WinControls\FileBrowser;..\src\WinControls\FindCharsInRange;..\src\WinControls\FunctionList;..\src\WinControls\Grid;..\src\WinControls\ImageListSet;..\src\WinControls\OpenSaveFileDialog;..\src\WinControls\PluginsAdmin;..\src\WinControls\Preference;..\src\WinControls\ProjectPanel;..\src\WinControls\ReadDirectoryChanges;..\src\WinControls\shortcut;..\src\WinControls\SplitterContainer;..\src\WinControls\StaticDialog;..\src\WinControls\StaticDialog\RunDlg;..\src\WinControls\StatusBar;..\src\WinControls\TabBar;..\src\WinControls\TaskList;..\src\WinControls\ToolBar;..\src\WinControls\ToolTip;..\src\WinControls\TrayIcon;..\src\WinControls\TreeView;..\src\WinControls\VerticalFileSwitcher;..\src\WinControls\WindowsDlg;%(AdditionalIncludeDirectories) + + @@ -250,6 +266,7 @@ +