Versie 2.87: Crypto.hotp erbij

SHA1 library bijgewerkt naar versie 2.1

svn path=/Slnkdwf/trunk/; revision=16080
This commit is contained in:
Jos Groot Lipman
2012-11-22 20:15:06 +00:00
parent 2d9e297442
commit 9ff3dbc1c6
6 changed files with 121 additions and 46 deletions

View File

@@ -130,3 +130,56 @@ STDMETHODIMP CCrypto::hex_sha1_file(BSTR fname, BSTR* pVal)
return bstrString.CopyTo(pVal);
}
STDMETHODIMP CCrypto::hotp(BSTR hexseed, LONGLONG moving_factor, BYTE digits, BSTR* pVal)
{
BYTE digest[20];
CSHA1 sha1;
if (digits < 6 || digits > 8)
return E_INVALIDARG;
CString sseed(hexseed);
if (sseed.GetLength() > 40)
return E_INVALIDARG;
BYTE seed[20];
for(int i = 0; i < sizeof(seed); i++)
{
BYTE hi=sseed[2*i];
hi-=(hi<'A' ? '0' : 'A'-10);
BYTE lo=sseed[2*i+1];
lo-=(lo<'A' ? '0' : 'A'-10);
seed[i] = (hi<<4) | (lo & 0x0F); // " & 0x0F" deals with lower-case characters
}
ATLASSERT(sizeof(moving_factor) == 8);
BYTE counter[sizeof(moving_factor)];
for (int i = 0; i < sizeof (counter); i++)
counter[i] = (BYTE)(moving_factor >> ((sizeof (moving_factor) - i - 1) * 8)) & 0xFF;
CHMAC_SHA1 HMAC_SHA1 ;
HMAC_SHA1.HMAC_SHA1((BYTE *)(&counter), sizeof(counter), seed, sizeof(seed), digest) ;
CString res;
BYTE offset = digest[sizeof (digest) - 1] & 0x0f;
uint64_t S = (((digest[offset] & 0x7f) << 24)
| ((digest[offset + 1] & 0xff) << 16)
| ((digest[offset + 2] & 0xff) << 8) | ((digest[offset + 3] & 0xff)));
res.Format("%lld",1000000000L + S);
res = res.Right(digits);
/*
for(int i = 0; i < 20; i++)
{
res = res + hex_tab[digest[i] >> 4];
res = res + hex_tab[digest[i] & 0xF];
}
*/
CComBSTR bstrString(res);
bstrString.ToLower();
return bstrString.CopyTo(pVal);
}

View File

@@ -51,6 +51,7 @@ public:
STDMETHOD(hex_hmac_sha1)(BSTR key, BSTR data, BSTR* pVal);
STDMETHOD(hex_sha1)(BSTR data, BSTR* pVal);
STDMETHOD(hex_sha1_file)(BSTR fname, BSTR* pVal);
STDMETHOD(hotp)(BSTR hexseed, LONGLONG counter, BYTE digits, BSTR* pVal);
};

View File

@@ -383,6 +383,7 @@ interface ICrypto : IDispatch{
[id(2), helpstring("method hex_hmac_sha1")] HRESULT hex_hmac_sha1([in] BSTR key, [in] BSTR data, [out,retval] BSTR* pVal);
[id(3), helpstring("method hex_sha1")] HRESULT hex_sha1([in] BSTR str, [out,retval] BSTR* pVal);
[id(4), helpstring("method hex_sha1_file")] HRESULT hex_sha1_file([in] BSTR fname, [out,retval] BSTR* pVal);
[id(5), helpstring("method hotp")] HRESULT hotp([in] BSTR hexseed, [in] LONGLONG counter, [in, defaultvalue(6)] BYTE digits, [out,retval] BSTR* pVal);
};
[
uuid(B6FCDE6E-141C-4601-B3AC-4DF4D5F25DF8),

View File

@@ -1,6 +1,6 @@
// Zorg dat versies alfabetisch altijd op elkaar volgen!
#define SLNK_MAJOR_VERSION 2
#define SLNK_MINOR_VERSION 86
#define SLNK_MINOR_VERSION 87
#define SLNK_BUILD_VERSION 0
// Define resource strings

View File

@@ -12,16 +12,14 @@
#define _CRT_SECURE_NO_WARNINGS
#include "SHA1.h"
#ifdef SHA1_UTILITY_FUNCTIONS
#define SHA1_MAX_FILE_BUFFER (32 * 20 * 820)
#endif
// Rotate _val32 by _nBits bits to the left
// Rotate p_val32 by p_nBits bits to the left
#ifndef ROL32
#ifdef _MSC_VER
#define ROL32(_val32,_nBits) _rotl(_val32,_nBits)
#define ROL32(p_val32,p_nBits) _rotl(p_val32,p_nBits)
#else
#define ROL32(_val32,_nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits))))
#define ROL32(p_val32,p_nBits) (((p_val32)<<(p_nBits))|((p_val32)>>(32-(p_nBits))))
#endif
#endif
@@ -36,11 +34,11 @@
m_block->l[(i+8)&15] ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))
// SHA-1 rounds
#define _R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);}
#define _R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5);w=ROL32(w,30);}
#define _R2(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5);w=ROL32(w,30);}
#define _R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5);w=ROL32(w,30);}
#define _R4(v,w,x,y,z,i) {z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5);w=ROL32(w,30);}
#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'
@@ -53,10 +51,12 @@ CSHA1::CSHA1()
Reset();
}
#ifdef SHA1_WIPE_VARIABLES
CSHA1::~CSHA1()
{
Reset();
}
#endif
void CSHA1::Reset()
{
@@ -78,26 +78,26 @@ void CSHA1::Transform(UINT_32* pState, const UINT_8* pBuffer)
memcpy(m_block, pBuffer, 64);
// 4 rounds of 20 operations each, loop unrolled
_R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
_R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
_R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
_R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
_R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
_R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
_R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
_R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
_R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
_R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
_R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
_R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
_R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
_R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
_R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
_R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
_R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
_R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
_R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
_R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);
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;
@@ -175,27 +175,28 @@ void CSHA1::Final()
{
UINT_32 i;
UINT_8 finalcount[8];
UINT_8 pbFinalCount[8];
for(i = 0; i < 8; ++i)
finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)]
>> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
pbFinalCount[i] = static_cast<UINT_8>((m_count[((i >= 4) ? 0 : 1)] >>
((3 - (i & 3)) * 8) ) & 0xFF); // Endian independent
Update((UINT_8*)"\200", 1);
while ((m_count[0] & 504) != 448)
while((m_count[0] & 504) != 448)
Update((UINT_8*)"\0", 1);
Update(finalcount, 8); // Cause a SHA1Transform()
Update(pbFinalCount, 8); // Cause a Transform()
for(i = 0; i < 20; ++i)
m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xFF);
m_digest[i] = static_cast<UINT_8>((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(finalcount, 0, 8);
memset(pbFinalCount, 0, 8);
Transform(m_state, m_buffer);
#endif
}

View File

@@ -3,6 +3,21 @@
by Dominik Reichl <dominik.reichl@t-online.de>
Web: http://www.dominik-reichl.de/
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
@@ -47,7 +62,7 @@
- ROL32 improvement for the Microsoft compiler (using _rotl).
Version 1.4 - 2004-07-22
- CSHA1 now compiles fine with GCC 3.3 under MacOS X (thanks to Larry
- CSHA1 now compiles fine with GCC 3.3 under Mac OS X (thanks to Larry
Hastings).
Version 1.3 - 2003-08-17
@@ -87,8 +102,8 @@
C4609560 A108A0C6 26AA7F2B 38A65566 739353C5
*/
#ifndef ___SHA1_HDR___
#define ___SHA1_HDR___
#ifndef SHA1_H_A545E61D43E9404E8D736869AB3CBFE7
#define SHA1_H_A545E61D43E9404E8D736869AB3CBFE7
#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
#define SHA1_UTILITY_FUNCTIONS
@@ -102,6 +117,7 @@
#endif
#include <memory.h>
#include <limits.h>
#ifdef SHA1_UTILITY_FUNCTIONS
#include <stdio.h>
@@ -159,7 +175,7 @@
#ifndef UINT_8
#ifdef _MSC_VER // Compiling with Microsoft compiler
#define UINT_8 unsigned __int8
#define UINT_8 unsigned __int8
#else // !_MSC_VER
#define UINT_8 unsigned char
#endif // _MSC_VER
@@ -169,7 +185,7 @@
#ifdef _MSC_VER // Compiling with Microsoft compiler
#define UINT_32 unsigned __int32
#else // !_MSC_VER
#if (ULONG_MAX == 0xFFFFFFFF)
#if (ULONG_MAX == 0xFFFFFFFFUL)
#define UINT_32 unsigned long
#else
#define UINT_32 unsigned int
@@ -206,7 +222,7 @@ class CSHA1
{
public:
#ifdef SHA1_UTILITY_FUNCTIONS
// Different formats for ReportHash
// Different formats for ReportHash(Stl)
enum REPORT_TYPE
{
REPORT_HEX = 0,
@@ -217,7 +233,10 @@ public:
// Constructor and destructor
CSHA1();
#ifdef SHA1_WIPE_VARIABLES
~CSHA1();
#endif
void Reset();
@@ -229,7 +248,7 @@ public:
bool HashFile(const TCHAR* tszFileName);
#endif
// Finalize hash, call before using ReportHash(Stl)
// Finalize hash; call it before using ReportHash(Stl)
void Final();
#ifdef SHA1_UTILITY_FUNCTIONS
@@ -260,4 +279,4 @@ private:
SHA1_WORKSPACE_BLOCK* m_block; // SHA1 pointer to the byte array above
};
#endif // ___SHA1_HDR___
#endif // SHA1_H_A545E61D43E9404E8D736869AB3CBFE7