Undocumented Windows cryptography
The last time we described semi- and undocumented functions in Windows, these were compression functions. Today’s subject is cryptographic functions. There are such functions in Windows core that allows you to use few cryptographic primitives easier, without whole CAPI overhead and hassle. Here is an example of how to generate secure random numbers and calculate SHA-1 hash.
First, a C header file capix.h which you may use in your own programs right away:
/* =======================================================================
CAPIx
Few cryptographic primitives for direct usage without CAPI overhead.
Based on un(semi)documented Windows XP+ interface
========================================================================= */
#pragma warning (push, 1)
#define WINDOWS_MEAN_AND_LEAN
#include <windows.h>
#pragma warning(pop)
typedef struct {
ULONG SomeJunk[6];
ULONG State[5];
ULONG Count[2];
UCHAR Buffer[64];
} SHA_CONTEXT, *PSHA_CONTEXT;
typedef BOOL (__stdcall *RtlGenRandom_Fn)(OUT PVOID, IN ULONG);
typedef PVOID (__stdcall *SHA_Init_Fn)(IN OUT PSHA_CONTEXT);
typedef PVOID (__stdcall *SHA_Update_Fn)(IN OUT PSHA_CONTEXT, IN PCHAR, IN UINT);
typedef PVOID (__stdcall *SHA_Final_Fn)(IN OUT PSHA_CONTEXT, OUT PVOID);
static HANDLE hAA32DLL = NULL;
static RtlGenRandom_Fn pf_rand = NULL;
static SHA_Init_Fn pf_sha_init = NULL;
static SHA_Update_Fn pf_sha_update = NULL;
static SHA_Final_Fn pf_sha_final = NULL;
BOOL InitCAPIX (void)
{
hAA32DLL = LoadLibrary ("advapi32.dll");
if ( hAA32DLL != NULL )
{
pf_rand = (RtlGenRandom_Fn) GetProcAddress(hAA32DLL, "SystemFunction036");
pf_sha_init = (SHA_Init_Fn) GetProcAddress(hAA32DLL, "A_SHAInit");
pf_sha_update = (SHA_Update_Fn) GetProcAddress(hAA32DLL, "A_SHAUpdate");
pf_sha_final = (SHA_Final_Fn) GetProcAddress(hAA32DLL, "A_SHAFinal");
}
return ( hAA32DLL != NULL );
} /* initcapix */
void _inline ReleaseCAPIX (void)
{
pf_rand = NULL;
pf_sha_init = NULL;
pf_sha_update = NULL;
pf_sha_final = NULL;
while (!FreeLibrary (hAA32DLL) );
hAA32DLL = NULL;
} /* donecapix */
#define random_s(x,y) ((pf_rand != NULL)?(*pf_rand)(x,y):FALSE)
#define sha1_init(x) ((pf_sha_init != NULL)?(*pf_sha_init)(x):NULL)
#define sha1_update(x,y,z) ((pf_sha_update != NULL)?(*pf_sha_update)(x,(PCHAR)y,z):NULL)
#define sha1_final(x,y) ((pf_sha_final != NULL)?(*pf_sha_final)(x,y):NULL)
Next is a C demo program that uses capix.h:
#pragma warning (push, 1)
#include "capix.h"
#include <stdlib.h>
#include <stdio.h>
#pragma warning(pop)
int main (void)
{
BYTE hash[20] = {0}, buf[12] = {0};
SHA_CONTEXT ctx;
PVOID dw;
register BYTE i;
InitCAPIX();
if ( !random_s(buf, sizeof(buf)) ) printf("Failed at generate randomn");
printf("data: ");
for (i = 0; i< sizeof(buf); i++) printf("%02x", buf[i]);
printf("n");
dw = sha1_init(&ctx);
if ( dw ) dw = sha1_update(&ctx, buf, sizeof(buf));
if ( dw ) dw = sha1_final(&ctx, hash);
if ( dw )
{
printf("hash: ");
for (i = 0; i< sizeof(hash); i++) printf("%02x", hash[i]);
printf("n");
}
else printf("SHA1 functions failedn");
ReleaseCAPIX();
return 0;
}
Subscribe to RSS feed
Do you know why they’re undocumented? Because they are implementation details subject to change in future versions of Windows. Anyone using this is likely to wind up with a broken application. You are performing a public disservice.
December 20, 2006 @ 7:03 am
Dan,
I’m very well aware about that, thank you very much. As anyone else, who would understand this without an explicit disclaimer. You’ve missed two points:
- tag ‘zanymatics’
- this is not a tech course
December 20, 2006 @ 7:24 am
Oh, sorry, I missed the obscure, if not invented term in your tiny tag cloud tucked away on the right. However, I did notice: “First, a C header file capix.h which you may use in your own programs right away.” Retard.
December 20, 2006 @ 7:47 am
How lovely!
Is it just Wednesday, or you are like this 24/7/365?
December 20, 2006 @ 8:45 am
Microsoft is using Crypto++ code. The are aiding in the Library’s FIPS certification.
See www.crytpopp.com
December 30, 2006 @ 8:13 pm
Whoops… www.cryptopp.com
December 30, 2006 @ 8:14 pm
@Jeff:
Why do you think so? Is it because of SHA_CONTEXT structure of what? From what I see there is nothing firm enough to support such conclusion.
January 4, 2007 @ 9:47 am
hey can sum1 help me…i hv this huge asssignment due 2mrw .. im doin my IT degree…i need information on the UNIX and Windows encryption in terms of passwords and the use of hashing and block ciphers in both…. thanks alot…
July 3, 2007 @ 3:23 am
@student:
http://www.hmug.org/man/3/crypt.php
http://en.wikipedia.org/wiki/LM_hash
http://en.wikipedia.org/wiki/NTLM
http://en.wikipedia.org/wiki/BitLocker_Drive_Encryption
and Google of course :)
July 3, 2007 @ 5:43 am
this is the question:
compare the way UNIX passwords and Windows Lan Manager passwords are encrypted with a block cipher. Explain why seemingly similar algorithms have such different properties.
July 3, 2007 @ 6:31 am
thanx 4 the other links but i already had that i need more help… another question:
what are the objectives of an attacker performing reconnaissance?
July 3, 2007 @ 6:33 am
and 3 good sources of information for this purpose- reconnaissance
July 3, 2007 @ 6:34 am
@student
The purpose of reconnaissance (”information gathering”) is to learn the target and identify the attack points.
http://en.wikipedia.org/wiki/Reconnaissance
You may google for the rest :)
July 3, 2007 @ 10:38 am